Merge "Fingerprint: get auth id for non-current user."
diff --git a/Android.mk b/Android.mk
index 22323c5..a1e9ed9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -265,8 +265,9 @@
 	core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \
 	core/java/android/service/autofill/IAutoFillAppCallback.aidl \
 	core/java/android/service/autofill/IAutoFillManagerService.aidl \
-	core/java/android/service/autofill/IAutoFillServerCallback.aidl \
 	core/java/android/service/autofill/IAutoFillService.aidl \
+	core/java/android/service/autofill/IFillCallback.aidl \
+	core/java/android/service/autofill/ISaveCallback.aidl \
 	core/java/android/service/carrier/ICarrierService.aidl \
 	core/java/android/service/carrier/ICarrierMessagingCallback.aidl \
 	core/java/android/service/carrier/ICarrierMessagingService.aidl \
@@ -294,6 +295,10 @@
 	core/java/android/print/IWriteResultCallback.aidl \
 	core/java/android/printservice/IPrintService.aidl \
 	core/java/android/printservice/IPrintServiceClient.aidl \
+	core/java/android/companion/ICompanionDeviceManager.aidl \
+	core/java/android/companion/ICompanionDeviceManagerService.aidl \
+	core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl \
+	core/java/android/companion/IOnAssociateCallback.aidl \
 	core/java/android/service/dreams/IDreamManager.aidl \
 	core/java/android/service/dreams/IDreamService.aidl \
 	core/java/android/service/persistentdata/IPersistentDataBlockService.aidl \
diff --git a/api/current.txt b/api/current.txt
index 4f63ff6..d772181 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -203,7 +203,6 @@
 
   public static final class R.attr {
     ctor public R.attr();
-    field public static final int __removed0 = 16844097; // 0x1010541
     field public static final int __removed1 = 16844099; // 0x1010543
     field public static final int absListViewStyle = 16842858; // 0x101006a
     field public static final int accessibilityEventTypes = 16843648; // 0x1010380
@@ -1270,6 +1269,7 @@
     field public static final int targetId = 16843740; // 0x10103dc
     field public static final int targetName = 16843853; // 0x101044d
     field public static final int targetPackage = 16842785; // 0x1010021
+    field public static final int targetProcess = 16844097; // 0x1010541
     field public static final int targetSandboxVersion = 16844110; // 0x101054e
     field public static final int targetSdkVersion = 16843376; // 0x1010270
     field public static final int taskAffinity = 16842770; // 0x1010012
@@ -2688,11 +2688,25 @@
 
 package android.accessibilityservice {
 
+  public final class AccessibilityButtonController {
+    method public boolean isAccessibilityButtonAvailable();
+    method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+    method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback, android.os.Handler);
+    method public void unregisterAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+  }
+
+  public static abstract class AccessibilityButtonController.AccessibilityButtonCallback {
+    ctor public AccessibilityButtonController.AccessibilityButtonCallback();
+    method public void onAvailabilityChanged(android.accessibilityservice.AccessibilityButtonController, boolean);
+    method public void onClicked(android.accessibilityservice.AccessibilityButtonController);
+  }
+
   public abstract class AccessibilityService extends android.app.Service {
     ctor public AccessibilityService();
     method public final void disableSelf();
     method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
+    method public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController();
     method public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
     method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
@@ -2805,6 +2819,7 @@
     field public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 128; // 0x80
     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 int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
@@ -2909,7 +2924,7 @@
   public class AccountManager {
     method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle);
-    method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.Integer, java.lang.Integer>);
+    method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>);
     method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean);
     method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]);
     method public java.lang.String blockingGetAuthToken(android.accounts.Account, java.lang.String, boolean) throws android.accounts.AuthenticatorException, java.io.IOException, android.accounts.OperationCanceledException;
@@ -2918,7 +2933,7 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public static android.accounts.AccountManager get(android.content.Context);
-    method public int getAccountVisibility(android.accounts.Account, int);
+    method public int getAccountVisibility(android.accounts.Account, java.lang.String);
     method public android.accounts.Account[] getAccounts();
     method public java.util.Map<android.accounts.Account, java.lang.Integer> getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String);
     method public android.accounts.Account[] getAccountsByType(java.lang.String);
@@ -2929,9 +2944,9 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
+    method public java.util.Map<java.lang.String, java.lang.Integer> getPackagesAndVisibilityForAccount(android.accounts.Account);
     method public java.lang.String getPassword(android.accounts.Account);
     method public java.lang.String getPreviousName(android.accounts.Account);
-    method public java.util.Map<java.lang.Integer, java.lang.Integer> getUidsAndVisibilityForAccount(android.accounts.Account);
     method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
     method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public void invalidateAuthToken(java.lang.String, java.lang.String);
@@ -2945,7 +2960,7 @@
     method public boolean removeAccountExplicitly(android.accounts.Account);
     method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
     method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
-    method public boolean setAccountVisibility(android.accounts.Account, int, int);
+    method public boolean setAccountVisibility(android.accounts.Account, java.lang.String, int);
     method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
     method public void setPassword(android.accounts.Account, java.lang.String);
     method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String);
@@ -2985,8 +3000,8 @@
     field public static final java.lang.String KEY_PASSWORD = "password";
     field public static final java.lang.String KEY_USERDATA = "userdata";
     field public static final deprecated java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
-    field public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; // 0xfffffffd
-    field public static final int UID_KEY_DEFAULT_VISIBILITY = -2; // 0xfffffffe
+    field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = "android.accounts.key_legacy_not_visible";
+    field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_VISIBLE = "android.accounts.key_legacy_visible";
     field public static final int VISIBILITY_NOT_VISIBLE = 3; // 0x3
     field public static final int VISIBILITY_UNDEFINED = 0; // 0x0
     field public static final int VISIBILITY_USER_MANAGED_NOT_VISIBLE = 4; // 0x4
@@ -4804,6 +4819,7 @@
     method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
     method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
     method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
+    method public void addResults(android.os.Bundle);
     method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
     method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
     method public void callActivityOnDestroy(android.app.Activity);
@@ -4828,6 +4844,7 @@
     method public android.os.Bundle getBinderCounts();
     method public android.content.ComponentName getComponentName();
     method public android.content.Context getContext();
+    method public java.lang.String getProcessName();
     method public android.content.Context getTargetContext();
     method public android.app.UiAutomation getUiAutomation();
     method public android.app.UiAutomation getUiAutomation(int);
@@ -5044,14 +5061,19 @@
     ctor public Notification(android.os.Parcel);
     method public android.app.Notification clone();
     method public int describeContents();
+    method public int getBadgeIcon();
     method public java.lang.String getChannel();
     method public java.lang.String getGroup();
     method public android.graphics.drawable.Icon getLargeIcon();
+    method public java.lang.String getShortcutId();
     method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
     method public long getTimeout();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
+    field public static final int BADGE_ICON_LARGE = 2; // 0x2
+    field public static final int BADGE_ICON_NONE = 0; // 0x0
+    field public static final int BADGE_ICON_SMALL = 1; // 0x1
     field public static final java.lang.String CATEGORY_ALARM = "alarm";
     field public static final java.lang.String CATEGORY_CALL = "call";
     field public static final java.lang.String CATEGORY_EMAIL = "email";
@@ -5143,7 +5165,7 @@
     field public deprecated int ledARGB;
     field public deprecated int ledOffMS;
     field public deprecated int ledOnMS;
-    field public deprecated int number;
+    field public int number;
     field public deprecated int priority;
     field public android.app.Notification publicVersion;
     field public deprecated android.net.Uri sound;
@@ -5231,6 +5253,7 @@
     method public android.app.Notification.Builder addExtras(android.os.Bundle);
     method public android.app.Notification.Builder addPerson(java.lang.String);
     method public android.app.Notification build();
+    method public android.app.Notification.Builder chooseBadgeIcon(int);
     method public android.widget.RemoteViews createBigContentView();
     method public android.widget.RemoteViews createContentView();
     method public android.widget.RemoteViews createHeadsUpContentView();
@@ -5263,13 +5286,14 @@
     method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
     method public deprecated android.app.Notification.Builder setLights(int, int, int);
     method public android.app.Notification.Builder setLocalOnly(boolean);
-    method public deprecated android.app.Notification.Builder setNumber(int);
+    method public android.app.Notification.Builder setNumber(int);
     method public android.app.Notification.Builder setOngoing(boolean);
     method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
     method public deprecated android.app.Notification.Builder setPriority(int);
     method public android.app.Notification.Builder setProgress(int, int, boolean);
     method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
     method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+    method public android.app.Notification.Builder setShortcutId(java.lang.String);
     method public android.app.Notification.Builder setShowWhen(boolean);
     method public android.app.Notification.Builder setSmallIcon(int);
     method public android.app.Notification.Builder setSmallIcon(int, int);
@@ -7941,6 +7965,65 @@
 
 }
 
+package android.companion {
+
+  public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
+  }
+
+  public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
+    method public android.companion.AssociationRequest<F> build();
+    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
+    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
+    method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
+    method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
+  }
+
+  public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.BluetoothDeviceFilter> CREATOR;
+  }
+
+  public static final class BluetoothDeviceFilter.Builder {
+    ctor public BluetoothDeviceFilter.Builder();
+    method public android.companion.BluetoothDeviceFilter.Builder addServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
+    method public android.companion.BluetoothDeviceFilter build();
+    method public android.companion.BluetoothDeviceFilter.Builder setAddress(java.lang.String);
+    method public android.companion.BluetoothDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+  }
+
+  public final class BluetoothLEDeviceFilter implements android.companion.DeviceFilter {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
+  }
+
+  public static final class BluetoothLEDeviceFilter.Builder {
+    ctor public BluetoothLEDeviceFilter.Builder();
+    method public android.companion.BluetoothLEDeviceFilter build();
+    method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+    method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
+  }
+
+  public final class CompanionDeviceManager {
+    method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+    field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
+  }
+
+  public static abstract class CompanionDeviceManager.Callback {
+    ctor public CompanionDeviceManager.Callback();
+    method public abstract void onDeviceFound(android.content.IntentSender);
+    method public abstract void onFailure(java.lang.CharSequence);
+  }
+
+  public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
+  }
+
+}
+
 package android.content {
 
   public abstract class AbstractThreadedSyncAdapter {
@@ -8553,6 +8636,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 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
@@ -9090,6 +9174,10 @@
     field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
     field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
+    field public static final java.lang.String EXTRA_AUTO_FILL_ASSIST_STRUCTURE = "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
+    field public static final java.lang.String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
+    field public static final java.lang.String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
+    field public static final java.lang.String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
     field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
     field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -9903,6 +9991,7 @@
     field public java.lang.String[] splitPublicSourceDirs;
     field public java.lang.String[] splitSourceDirs;
     field public java.lang.String targetPackage;
+    field public java.lang.String targetProcess;
   }
 
   public class LabeledIntent extends android.content.Intent {
@@ -10324,6 +10413,7 @@
     field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
     field public static final java.lang.String FEATURE_VR_MODE = "android.software.vr.mode";
     field public static final java.lang.String FEATURE_VR_MODE_HIGH_PERFORMANCE = "android.hardware.vr.high_performance";
+    field public static final java.lang.String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
     field public static final java.lang.String FEATURE_VULKAN_HARDWARE_LEVEL = "android.hardware.vulkan.level";
     field public static final java.lang.String FEATURE_VULKAN_HARDWARE_VERSION = "android.hardware.vulkan.version";
     field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch";
@@ -20440,6 +20530,7 @@
     method public int getContentType();
     method public int getFlags();
     method public int getUsage();
+    method public static int getVolumeControlStream(android.media.AudioAttributes);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
     field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
@@ -22162,6 +22253,7 @@
   }
 
   public static final class MediaMuxer.OutputFormat {
+    field public static final int MUXER_OUTPUT_3GPP = 2; // 0x2
     field public static final int MUXER_OUTPUT_MPEG_4 = 0; // 0x0
     field public static final int MUXER_OUTPUT_WEBM = 1; // 0x1
   }
@@ -23582,6 +23674,8 @@
 
   public final class MediaController {
     ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
+    method public void addQueueItem(android.media.MediaDescription);
+    method public void addQueueItem(android.media.MediaDescription, int);
     method public void adjustVolume(int, int);
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
     method public android.os.Bundle getExtras();
@@ -23600,6 +23694,8 @@
     method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.media.session.MediaController.Callback);
     method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
+    method public void removeQueueItem(android.media.MediaDescription);
+    method public void removeQueueItemAt(int);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void setVolumeTo(int, int);
     method public void unregisterCallback(android.media.session.MediaController.Callback);
@@ -23677,11 +23773,14 @@
     method public void setSessionActivity(android.app.PendingIntent);
     method public void setShuffleModeEnabled(boolean);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+    field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
   public static abstract class MediaSession.Callback {
     ctor public MediaSession.Callback();
+    method public void onAddQueueItem(android.media.MediaDescription);
+    method public void onAddQueueItem(android.media.MediaDescription, int);
     method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void onCustomAction(java.lang.String, android.os.Bundle);
     method public void onFastForward();
@@ -23695,6 +23794,8 @@
     method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
     method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
     method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
+    method public void onRemoveQueueItem(android.media.MediaDescription);
+    method public void onRemoveQueueItemAt(int);
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
@@ -23942,6 +24043,7 @@
     field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
     field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
     field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
     field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
     field public static final java.lang.String COLUMN_AUTHOR = "author";
     field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
@@ -23949,6 +24051,7 @@
     field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
     field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
     field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
@@ -23962,17 +24065,14 @@
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
     field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
     field public static final java.lang.String COLUMN_LIVE = "live";
-    field public static final java.lang.String COLUMN_LOGO = "logo";
+    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
     field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
     field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
     field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
     field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
-    field public static final java.lang.String COLUMN_PREVIEW_DURATION = "preview_duration";
-    field public static final java.lang.String COLUMN_PREVIEW_INTENT_URI = "preview_intent_uri";
-    field public static final java.lang.String COLUMN_PREVIEW_LAST_PLAYBACK_POSITION = "preview_last_playback_position";
     field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
-    field public static final java.lang.String COLUMN_PREVIEW_WEIGHT = "preview_weight";
     field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
     field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
     field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
@@ -23992,6 +24092,7 @@
     field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
     field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+    field public static final java.lang.String COLUMN_WEIGHT = "weight";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
     field public static final android.net.Uri CONTENT_URI;
@@ -25737,6 +25838,7 @@
 
   public class WifiManager {
     method public int addNetwork(android.net.wifi.WifiConfiguration);
+    method public boolean addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
     method public static int calculateSignalLevel(int, int);
     method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
     method public static int compareSignalLevel(int, int);
@@ -25749,6 +25851,7 @@
     method public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
     method public android.net.wifi.WifiInfo getConnectionInfo();
     method public android.net.DhcpInfo getDhcpInfo();
+    method public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
     method public java.util.List<android.net.wifi.ScanResult> getScanResults();
     method public int getWifiState();
     method public boolean is5GHzBandSupported();
@@ -25764,6 +25867,7 @@
     method public boolean reassociate();
     method public boolean reconnect();
     method public boolean removeNetwork(int);
+    method public boolean removePasspointConfiguration(java.lang.String);
     method public boolean saveConfiguration();
     method public void setTdlsEnabled(java.net.InetAddress, boolean);
     method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
@@ -25978,6 +26082,241 @@
 
 }
 
+package android.net.wifi.hotspot2 {
+
+  public final class ConfigParser {
+    method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(java.lang.String, byte[]);
+  }
+
+  public final class PasspointConfiguration implements android.os.Parcelable {
+    ctor public PasspointConfiguration();
+    ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+    method public int describeContents();
+    method public android.net.wifi.hotspot2.pps.Credential getCredential();
+    method public int getCredentialPriority();
+    method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
+    method public android.net.wifi.hotspot2.pps.Policy getPolicy();
+    method public long getSubscriptionCreationTimeInMs();
+    method public long getSubscriptionExpirationTimeInMs();
+    method public java.lang.String getSubscriptionType();
+    method public android.net.wifi.hotspot2.pps.UpdateParameter getSubscriptionUpdate();
+    method public java.util.Map<java.lang.String, byte[]> getTrustRootCertList();
+    method public int getUpdateIdentififer();
+    method public long getUsageLimitDataLimit();
+    method public long getUsageLimitStartTimeInMs();
+    method public long getUsageLimitTimeLimitInMinutes();
+    method public long getUsageLimitUsageTimePeriodInMinutes();
+    method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
+    method public void setCredentialPriority(int);
+    method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+    method public void setPolicy(android.net.wifi.hotspot2.pps.Policy);
+    method public void setSubscriptionCreationTimeInMs(long);
+    method public void setSubscriptionExpirationTimeInMs(long);
+    method public void setSubscriptionType(java.lang.String);
+    method public void setSubscriptionUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+    method public void setTrustRootCertList(java.util.Map<java.lang.String, byte[]>);
+    method public void setUpdateIdentifier(int);
+    method public void setUsageLimitDataLimit(long);
+    method public void setUsageLimitStartTimeInMs(long);
+    method public void setUsageLimitTimeLimitInMinutes(long);
+    method public void setUsageLimitUsageTimePeriodInMinutes(long);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
+  }
+
+}
+
+package android.net.wifi.hotspot2.omadm {
+
+  public final class PpsMoParser {
+    method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(java.lang.String);
+  }
+
+}
+
+package android.net.wifi.hotspot2.pps {
+
+  public final class Credential implements android.os.Parcelable {
+    ctor public Credential();
+    ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
+    method public int describeContents();
+    method public java.security.cert.X509Certificate getCaCertificate();
+    method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
+    method public boolean getCheckAaaServerStatus();
+    method public java.security.cert.X509Certificate[] getClientCertificateChain();
+    method public java.security.PrivateKey getClientPrivateKey();
+    method public long getCreationTimeInMs();
+    method public long getExpirationTimeInMs();
+    method public java.lang.String getRealm();
+    method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
+    method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
+    method public void setCaCertificate(java.security.cert.X509Certificate);
+    method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+    method public void setCheckAaaServerCertStatus(boolean);
+    method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
+    method public void setClientPrivateKey(java.security.PrivateKey);
+    method public void setCreationTimeInMs(long);
+    method public void setExpirationTimeInMs(long);
+    method public void setRealm(java.lang.String);
+    method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+    method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
+  }
+
+  public static final class Credential.CertificateCredential implements android.os.Parcelable {
+    ctor public Credential.CertificateCredential();
+    ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+    method public int describeContents();
+    method public byte[] getCertSha256Fingerprint();
+    method public java.lang.String getCertType();
+    method public void setCertSha256Fingerprint(byte[]);
+    method public void setCertType(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
+  }
+
+  public static final class Credential.SimCredential implements android.os.Parcelable {
+    ctor public Credential.SimCredential();
+    ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+    method public int describeContents();
+    method public int getEapType();
+    method public java.lang.String getImsi();
+    method public void setEapType(int);
+    method public void setImsi(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
+  }
+
+  public static final class Credential.UserCredential implements android.os.Parcelable {
+    ctor public Credential.UserCredential();
+    ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+    method public int describeContents();
+    method public boolean getAbleToShare();
+    method public int getEapType();
+    method public boolean getMachineManaged();
+    method public java.lang.String getNonEapInnerMethod();
+    method public java.lang.String getPassword();
+    method public java.lang.String getSoftTokenApp();
+    method public java.lang.String getUsername();
+    method public void setAbleToShare(boolean);
+    method public void setEapType(int);
+    method public void setMachineManaged(boolean);
+    method public void setNonEapInnerMethod(java.lang.String);
+    method public void setPassword(java.lang.String);
+    method public void setSoftTokenApp(java.lang.String);
+    method public void setUsername(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
+  }
+
+  public final class HomeSp implements android.os.Parcelable {
+    ctor public HomeSp();
+    ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+    method public int describeContents();
+    method public java.lang.String getFqdn();
+    method public java.lang.String getFriendlyName();
+    method public java.util.Map<java.lang.String, java.lang.Long> getHomeNetworkIds();
+    method public java.lang.String getIconUrl();
+    method public long[] getMatchAllOis();
+    method public long[] getMatchAnysOis();
+    method public java.lang.String[] getOtherHomePartners();
+    method public long[] getRoamingConsortiumOis();
+    method public void setFqdn(java.lang.String);
+    method public void setFriendlyName(java.lang.String);
+    method public void setHomeNetworkIds(java.util.Map<java.lang.String, java.lang.Long>);
+    method public void setIconUrl(java.lang.String);
+    method public void setMatchAllOis(long[]);
+    method public void setMatchAnyOis(long[]);
+    method public void setOtherHomePartners(java.lang.String[]);
+    method public void setRoamingConsortiumOis(long[]);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
+  }
+
+  public final class Policy implements android.os.Parcelable {
+    ctor public Policy();
+    ctor public Policy(android.net.wifi.hotspot2.pps.Policy);
+    method public int describeContents();
+    method public java.lang.String[] getExcludedSsidList();
+    method public int getMaximumBssLoadValue();
+    method public long getMinHomeDownlinkBandWidht();
+    method public long getMinHomeUplinkBandwidth();
+    method public long getMinRoamingDownlinkBandwidth();
+    method public long getMinRoamingUplinkBandwidth();
+    method public android.net.wifi.hotspot2.pps.UpdateParameter getPolicyUpdate();
+    method public java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> getPreferredRoamingPartnerList();
+    method public java.util.Map<java.lang.Integer, java.lang.String> getRequiredProtoPortMap();
+    method public void setExcludedSsidList(java.lang.String[]);
+    method public void setMaximumBssLoadValue(int);
+    method public void setMinHomeDownlinkBandwidth(long);
+    method public void setMinHomeUplinkBandwidth(long);
+    method public void setMinRoamingDownlinkBandwidth(long);
+    method public void setMinRoamingUplinkBandwidth(long);
+    method public void setPolicyUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+    method public void setPreferredRoamingPartnerList(java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner>);
+    method public void setRequiredProtoPortMap(java.util.Map<java.lang.Integer, java.lang.String>);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy> CREATOR;
+  }
+
+  public static final class Policy.RoamingPartner implements android.os.Parcelable {
+    ctor public Policy.RoamingPartner();
+    ctor public Policy.RoamingPartner(android.net.wifi.hotspot2.pps.Policy.RoamingPartner);
+    method public int describeContents();
+    method public java.lang.String getCountries();
+    method public java.lang.String getFqdn();
+    method public boolean getFqdnExactMatch();
+    method public int getPriority();
+    method public void setCountries(java.lang.String);
+    method public void setFqdn(java.lang.String);
+    method public void setFqdnExactMatch(boolean);
+    method public void setPriority(int);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> CREATOR;
+  }
+
+  public final class UpdateParameter implements android.os.Parcelable {
+    ctor public UpdateParameter();
+    ctor public UpdateParameter(android.net.wifi.hotspot2.pps.UpdateParameter);
+    method public int describeContents();
+    method public java.lang.String getBase64EncodedPassword();
+    method public java.lang.String getRestriction();
+    method public java.lang.String getServerUri();
+    method public byte[] getTrustRootCertSha256Fingerprint();
+    method public java.lang.String getTrustRootCertUrl();
+    method public long getUpdateIntervalInMinutes();
+    method public java.lang.String getUpdateMethod();
+    method public java.lang.String getUsername();
+    method public void setBase64EncodedPassword(java.lang.String);
+    method public void setRestriction(java.lang.String);
+    method public void setServerUri(java.lang.String);
+    method public void setTrustRootCertSha256Fingerprint(byte[]);
+    method public void setTrustRootCertUrl(java.lang.String);
+    method public void setUpdateIntervalInMinutes(long);
+    method public void setUpdateMethod(java.lang.String);
+    method public void setUsername(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.UpdateParameter> CREATOR;
+    field public static final long UPDATE_CHECK_INTERVAL_NEVER = 4294967295L; // 0xffffffffL
+    field public static final java.lang.String UPDATE_METHOD_OMADM = "OMA-DM-ClientInitiated";
+    field public static final java.lang.String UPDATE_METHOD_SSP = "SSP-ClientInitiated";
+    field public static final java.lang.String UPDATE_RESTRICTION_HOMESP = "HomeSP";
+    field public static final java.lang.String UPDATE_RESTRICTION_ROAMING_PARTNER = "RoamingPartner";
+    field public static final java.lang.String UPDATE_RESTRICTION_UNRESTRICTED = "Unrestricted";
+  }
+
+}
+
 package android.net.wifi.p2p {
 
   public class WifiP2pConfig implements android.os.Parcelable {
@@ -35854,26 +36193,19 @@
     ctor public AutoFillService();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
-    method public void onDatasetAuthenticationRequest(android.os.Bundle, int);
     method public void onDisconnected();
     method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public void onFillResponseAuthenticationRequest(android.os.Bundle, int);
     method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
-    field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS";
-    field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS";
-    field public static final int FLAG_AUTHENTICATION_ERROR = 4; // 0x4
-    field public static final int FLAG_AUTHENTICATION_REQUESTED = 1; // 0x1
-    field public static final int FLAG_AUTHENTICATION_SUCCESS = 2; // 0x2
-    field public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 8; // 0x8
     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";
   }
 
-  public final class FillCallback {
-    method public void onDatasetAuthentication(android.view.autofill.Dataset, int);
+  public final class FillCallback implements android.os.Parcelable {
+    method public int describeContents();
     method public void onFailure(java.lang.CharSequence);
-    method public void onFillResponseAuthentication(int);
     method public void onSuccess(android.view.autofill.FillResponse);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.autofill.FillCallback> CREATOR;
   }
 
   public final class SaveCallback {
@@ -41710,6 +42042,15 @@
     method public android.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
   }
 
+  public abstract class TransitionListenerAdapter implements android.transition.Transition.TransitionListener {
+    ctor public TransitionListenerAdapter();
+    method public void onTransitionCancel(android.transition.Transition);
+    method public void onTransitionEnd(android.transition.Transition);
+    method public void onTransitionPause(android.transition.Transition);
+    method public void onTransitionResume(android.transition.Transition);
+    method public void onTransitionStart(android.transition.Transition);
+  }
+
   public class TransitionManager {
     ctor public TransitionManager();
     method public static void beginDelayedTransition(android.view.ViewGroup);
@@ -44108,8 +44449,8 @@
     method public void drawableHotspotChanged(float, float);
     method protected void drawableStateChanged();
     method public android.view.View findFocus();
-    method public final <T extends android.view.View> T findViewById(int);
-    method public final <T extends android.view.View> T findViewWithTag(java.lang.Object);
+    method public final android.view.View findViewById(int);
+    method public final android.view.View findViewWithTag(java.lang.Object);
     method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
     method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
     method public android.view.View focusSearch(int);
@@ -45684,6 +46025,7 @@
     field public static final int TYPE_APPLICATION = 2; // 0x2
     field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
     field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
+    field public static final int TYPE_APPLICATION_OVERLAY = 2038; // 0x7f6
     field public static final int TYPE_APPLICATION_PANEL = 1000; // 0x3e8
     field public static final int TYPE_APPLICATION_STARTING = 3; // 0x3
     field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea
@@ -45693,17 +46035,17 @@
     field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
     field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
     field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
-    field public static final int TYPE_PHONE = 2002; // 0x7d2
-    field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+    field public static final deprecated int TYPE_PHONE = 2002; // 0x7d2
+    field public static final deprecated int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
     field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
     field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
     field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
     field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
-    field public static final int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
+    field public static final deprecated int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
     field public static final int TYPE_SYSTEM_DIALOG = 2008; // 0x7d8
-    field public static final int TYPE_SYSTEM_ERROR = 2010; // 0x7da
-    field public static final int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
-    field public static final int TYPE_TOAST = 2005; // 0x7d5
+    field public static final deprecated int TYPE_SYSTEM_ERROR = 2010; // 0x7da
+    field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
+    field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
     field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
     field public float alpha;
     field public float buttonBrightness;
@@ -46512,10 +46854,9 @@
   }
 
   public static final class Dataset.Builder {
-    ctor public Dataset.Builder(java.lang.CharSequence);
+    ctor public Dataset.Builder(java.lang.String, java.lang.CharSequence);
     method public android.view.autofill.Dataset build();
-    method public android.view.autofill.Dataset.Builder requiresCustomAuthentication(android.os.Bundle, int);
-    method public android.view.autofill.Dataset.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+    method public android.view.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
     method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
     method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
   }
@@ -46527,12 +46868,11 @@
   }
 
   public static final class FillResponse.Builder {
-    ctor public FillResponse.Builder();
+    ctor public FillResponse.Builder(java.lang.String);
     method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
     method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
     method public android.view.autofill.FillResponse build();
-    method public android.view.autofill.FillResponse.Builder requiresCustomAuthentication(android.os.Bundle, int);
-    method public android.view.autofill.FillResponse.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+    method public android.view.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
     method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
   }
 
@@ -46958,7 +47298,7 @@
 
   public final class TextClassificationManager {
     method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
-    method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+    method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier();
   }
 
   public final class TextClassificationResult {
@@ -50289,6 +50629,7 @@
     method public void setIs24HourView(java.lang.Boolean);
     method public void setMinute(int);
     method public void setOnTimeChangedListener(android.widget.TimePicker.OnTimeChangedListener);
+    method public boolean validateInput();
   }
 
   public static abstract interface TimePicker.OnTimeChangedListener {
@@ -50687,6 +51028,8 @@
     field public static final int OP_INVOKE_INTERFACE = 114; // 0x72
     field public static final int OP_INVOKE_INTERFACE_JUMBO = 9983; // 0x26ff
     field public static final int OP_INVOKE_INTERFACE_RANGE = 120; // 0x78
+    field public static final int OP_INVOKE_POLYMORPHIC = 250; // 0xfa
+    field public static final int OP_INVOKE_POLYMORPHIC_RANGE = 251; // 0xfb
     field public static final int OP_INVOKE_STATIC = 113; // 0x71
     field public static final int OP_INVOKE_STATIC_JUMBO = 9727; // 0x25ff
     field public static final int OP_INVOKE_STATIC_RANGE = 119; // 0x77
@@ -53981,12 +54324,15 @@
   }
 
   public abstract class MethodHandle {
+    method public java.lang.invoke.MethodHandle asCollector(java.lang.Class<?>, int);
     method public java.lang.invoke.MethodHandle asFixedArity();
+    method public java.lang.invoke.MethodHandle asSpreader(java.lang.Class<?>, int);
     method public java.lang.invoke.MethodHandle asType(java.lang.invoke.MethodType);
     method public java.lang.invoke.MethodHandle asVarargsCollector(java.lang.Class<?>);
     method public java.lang.invoke.MethodHandle bindTo(java.lang.Object);
     method public final java.lang.Object invoke(java.lang.Object...) throws java.lang.Throwable;
     method public final java.lang.Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
+    method public java.lang.Object invokeWithArguments(java.lang.Object...) throws java.lang.Throwable;
     method public java.lang.Object invokeWithArguments(java.util.List<?>) throws java.lang.Throwable;
     method public boolean isVarargsCollector();
     method public java.lang.invoke.MethodType type();
@@ -54020,17 +54366,23 @@
     method public static java.lang.invoke.MethodHandle arrayElementGetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
     method public static java.lang.invoke.MethodHandle arrayElementSetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
     method public static java.lang.invoke.MethodHandle catchException(java.lang.invoke.MethodHandle, java.lang.Class<? extends java.lang.Throwable>, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle collectArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle constant(java.lang.Class<?>, java.lang.Object);
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.lang.Class<?>...);
     method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+    method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
     method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle guardWithTest(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle identity(java.lang.Class<?>);
+    method public static java.lang.invoke.MethodHandle insertArguments(java.lang.invoke.MethodHandle, int, java.lang.Object...);
     method public static java.lang.invoke.MethodHandle invoker(java.lang.invoke.MethodType);
     method public static java.lang.invoke.MethodHandles.Lookup lookup();
     method public static java.lang.invoke.MethodHandle permuteArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, int...);
     method public static java.lang.invoke.MethodHandles.Lookup publicLookup();
+    method public static <T extends java.lang.reflect.Member> T reflectAs(java.lang.Class<T>, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle spreadInvoker(java.lang.invoke.MethodType, int);
     method public static java.lang.invoke.MethodHandle throwException(java.lang.Class<?>, java.lang.Class<? extends java.lang.Throwable>);
   }
 
@@ -54047,6 +54399,7 @@
     method public java.lang.invoke.MethodHandles.Lookup in(java.lang.Class<?>);
     method public java.lang.Class<?> lookupClass();
     method public int lookupModes();
+    method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
     method public void throwMakeAccessException(java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException;
     method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
     method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
diff --git a/api/system-current.txt b/api/system-current.txt
index 03710e6..6affa7f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -315,7 +315,6 @@
 
   public static final class R.attr {
     ctor public R.attr();
-    field public static final int __removed0 = 16844097; // 0x1010541
     field public static final int __removed1 = 16844099; // 0x1010543
     field public static final int absListViewStyle = 16842858; // 0x101006a
     field public static final int accessibilityEventTypes = 16843648; // 0x1010380
@@ -1386,6 +1385,7 @@
     field public static final int targetId = 16843740; // 0x10103dc
     field public static final int targetName = 16843853; // 0x101044d
     field public static final int targetPackage = 16842785; // 0x1010021
+    field public static final int targetProcess = 16844097; // 0x1010541
     field public static final int targetSandboxVersion = 16844110; // 0x101054e
     field public static final int targetSdkVersion = 16843376; // 0x1010270
     field public static final int taskAffinity = 16842770; // 0x1010012
@@ -2807,11 +2807,25 @@
 
 package android.accessibilityservice {
 
+  public final class AccessibilityButtonController {
+    method public boolean isAccessibilityButtonAvailable();
+    method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+    method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback, android.os.Handler);
+    method public void unregisterAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+  }
+
+  public static abstract class AccessibilityButtonController.AccessibilityButtonCallback {
+    ctor public AccessibilityButtonController.AccessibilityButtonCallback();
+    method public void onAvailabilityChanged(android.accessibilityservice.AccessibilityButtonController, boolean);
+    method public void onClicked(android.accessibilityservice.AccessibilityButtonController);
+  }
+
   public abstract class AccessibilityService extends android.app.Service {
     ctor public AccessibilityService();
     method public final void disableSelf();
     method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
+    method public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController();
     method public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
     method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
@@ -2924,6 +2938,7 @@
     field public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 128; // 0x80
     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 int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
@@ -3028,7 +3043,7 @@
   public class AccountManager {
     method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle);
-    method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.Integer, java.lang.Integer>);
+    method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>);
     method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean);
     method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]);
     method public java.lang.String blockingGetAuthToken(android.accounts.Account, java.lang.String, boolean) throws android.accounts.AuthenticatorException, java.io.IOException, android.accounts.OperationCanceledException;
@@ -3038,7 +3053,7 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSessionAsUser(android.os.Bundle, android.app.Activity, android.os.UserHandle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public static android.accounts.AccountManager get(android.content.Context);
-    method public int getAccountVisibility(android.accounts.Account, int);
+    method public int getAccountVisibility(android.accounts.Account, java.lang.String);
     method public android.accounts.Account[] getAccounts();
     method public java.util.Map<android.accounts.Account, java.lang.Integer> getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String);
     method public android.accounts.Account[] getAccountsByType(java.lang.String);
@@ -3049,9 +3064,9 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
+    method public java.util.Map<java.lang.String, java.lang.Integer> getPackagesAndVisibilityForAccount(android.accounts.Account);
     method public java.lang.String getPassword(android.accounts.Account);
     method public java.lang.String getPreviousName(android.accounts.Account);
-    method public java.util.Map<java.lang.Integer, java.lang.Integer> getUidsAndVisibilityForAccount(android.accounts.Account);
     method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
     method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public void invalidateAuthToken(java.lang.String, java.lang.String);
@@ -3065,7 +3080,7 @@
     method public boolean removeAccountExplicitly(android.accounts.Account);
     method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
     method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
-    method public boolean setAccountVisibility(android.accounts.Account, int, int);
+    method public boolean setAccountVisibility(android.accounts.Account, java.lang.String, int);
     method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
     method public void setPassword(android.accounts.Account, java.lang.String);
     method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String);
@@ -3105,8 +3120,8 @@
     field public static final java.lang.String KEY_PASSWORD = "password";
     field public static final java.lang.String KEY_USERDATA = "userdata";
     field public static final deprecated java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
-    field public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; // 0xfffffffd
-    field public static final int UID_KEY_DEFAULT_VISIBILITY = -2; // 0xfffffffe
+    field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = "android.accounts.key_legacy_not_visible";
+    field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_VISIBLE = "android.accounts.key_legacy_visible";
     field public static final int VISIBILITY_NOT_VISIBLE = 3; // 0x3
     field public static final int VISIBILITY_UNDEFINED = 0; // 0x0
     field public static final int VISIBILITY_USER_MANAGED_NOT_VISIBLE = 4; // 0x4
@@ -4964,6 +4979,7 @@
     method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
     method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
     method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
+    method public void addResults(android.os.Bundle);
     method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
     method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
     method public void callActivityOnDestroy(android.app.Activity);
@@ -4988,6 +5004,7 @@
     method public android.os.Bundle getBinderCounts();
     method public android.content.ComponentName getComponentName();
     method public android.content.Context getContext();
+    method public java.lang.String getProcessName();
     method public android.content.Context getTargetContext();
     method public android.app.UiAutomation getUiAutomation();
     method public android.app.UiAutomation getUiAutomation(int);
@@ -5204,15 +5221,20 @@
     ctor public Notification(android.os.Parcel);
     method public android.app.Notification clone();
     method public int describeContents();
+    method public int getBadgeIcon();
     method public java.lang.String getChannel();
     method public java.lang.String getGroup();
     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.String getShortcutId();
     method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
     method public long getTimeout();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
+    field public static final int BADGE_ICON_LARGE = 2; // 0x2
+    field public static final int BADGE_ICON_NONE = 0; // 0x0
+    field public static final int BADGE_ICON_SMALL = 1; // 0x1
     field public static final java.lang.String CATEGORY_ALARM = "alarm";
     field public static final java.lang.String CATEGORY_CALL = "call";
     field public static final java.lang.String CATEGORY_EMAIL = "email";
@@ -5306,7 +5328,7 @@
     field public deprecated int ledARGB;
     field public deprecated int ledOffMS;
     field public deprecated int ledOnMS;
-    field public deprecated int number;
+    field public int number;
     field public deprecated int priority;
     field public android.app.Notification publicVersion;
     field public deprecated android.net.Uri sound;
@@ -5394,6 +5416,7 @@
     method public android.app.Notification.Builder addExtras(android.os.Bundle);
     method public android.app.Notification.Builder addPerson(java.lang.String);
     method public android.app.Notification build();
+    method public android.app.Notification.Builder chooseBadgeIcon(int);
     method public android.widget.RemoteViews createBigContentView();
     method public android.widget.RemoteViews createContentView();
     method public android.widget.RemoteViews createHeadsUpContentView();
@@ -5426,13 +5449,14 @@
     method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
     method public deprecated android.app.Notification.Builder setLights(int, int, int);
     method public android.app.Notification.Builder setLocalOnly(boolean);
-    method public deprecated android.app.Notification.Builder setNumber(int);
+    method public android.app.Notification.Builder setNumber(int);
     method public android.app.Notification.Builder setOngoing(boolean);
     method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
     method public deprecated android.app.Notification.Builder setPriority(int);
     method public android.app.Notification.Builder setProgress(int, int, boolean);
     method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
     method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+    method public android.app.Notification.Builder setShortcutId(java.lang.String);
     method public android.app.Notification.Builder setShowWhen(boolean);
     method public android.app.Notification.Builder setSmallIcon(int);
     method public android.app.Notification.Builder setSmallIcon(int, int);
@@ -6202,6 +6226,10 @@
     method public void onDetached();
   }
 
+  public class VrManager {
+    method public void setPersistentVrModeEnabled(boolean);
+  }
+
   public final class WallpaperInfo implements android.os.Parcelable {
     ctor public WallpaperInfo(android.content.Context, android.content.pm.ResolveInfo) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public int describeContents();
@@ -8327,6 +8355,65 @@
 
 }
 
+package android.companion {
+
+  public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
+  }
+
+  public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
+    method public android.companion.AssociationRequest<F> build();
+    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
+    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
+    method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
+    method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
+  }
+
+  public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.BluetoothDeviceFilter> CREATOR;
+  }
+
+  public static final class BluetoothDeviceFilter.Builder {
+    ctor public BluetoothDeviceFilter.Builder();
+    method public android.companion.BluetoothDeviceFilter.Builder addServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
+    method public android.companion.BluetoothDeviceFilter build();
+    method public android.companion.BluetoothDeviceFilter.Builder setAddress(java.lang.String);
+    method public android.companion.BluetoothDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+  }
+
+  public final class BluetoothLEDeviceFilter implements android.companion.DeviceFilter {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
+  }
+
+  public static final class BluetoothLEDeviceFilter.Builder {
+    ctor public BluetoothLEDeviceFilter.Builder();
+    method public android.companion.BluetoothLEDeviceFilter build();
+    method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+    method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
+  }
+
+  public final class CompanionDeviceManager {
+    method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+    field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
+  }
+
+  public static abstract class CompanionDeviceManager.Callback {
+    ctor public CompanionDeviceManager.Callback();
+    method public abstract void onDeviceFound(android.content.IntentSender);
+    method public abstract void onFailure(java.lang.CharSequence);
+  }
+
+  public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
+  }
+
+}
+
 package android.content {
 
   public abstract class AbstractThreadedSyncAdapter {
@@ -8946,6 +9033,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 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";
@@ -9004,6 +9092,7 @@
     field public static final java.lang.String USB_SERVICE = "usb";
     field public static final java.lang.String USER_SERVICE = "user";
     field public static final java.lang.String VIBRATOR_SERVICE = "vibrator";
+    field public static final java.lang.String VR_SERVICE = "vrmanager";
     field public static final java.lang.String WALLPAPER_SERVICE = "wallpaper";
     field public static final java.lang.String WIFI_AWARE_SERVICE = "wifiaware";
     field public static final java.lang.String WIFI_P2P_SERVICE = "wifip2p";
@@ -9502,6 +9591,10 @@
     field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
     field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
+    field public static final java.lang.String EXTRA_AUTO_FILL_ASSIST_STRUCTURE = "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
+    field public static final java.lang.String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
+    field public static final java.lang.String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
+    field public static final java.lang.String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
     field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
     field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -10358,6 +10451,7 @@
     field public java.lang.String[] splitPublicSourceDirs;
     field public java.lang.String[] splitSourceDirs;
     field public java.lang.String targetPackage;
+    field public java.lang.String targetProcess;
   }
 
   public final class IntentFilterVerificationInfo implements android.os.Parcelable {
@@ -10812,6 +10906,7 @@
     field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
     field public static final java.lang.String FEATURE_VR_MODE = "android.software.vr.mode";
     field public static final java.lang.String FEATURE_VR_MODE_HIGH_PERFORMANCE = "android.hardware.vr.high_performance";
+    field public static final java.lang.String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
     field public static final java.lang.String FEATURE_VULKAN_HARDWARE_LEVEL = "android.hardware.vulkan.level";
     field public static final java.lang.String FEATURE_VULKAN_HARDWARE_VERSION = "android.hardware.vulkan.version";
     field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch";
@@ -21996,6 +22091,7 @@
     method public int getContentType();
     method public int getFlags();
     method public int getUsage();
+    method public static int getVolumeControlStream(android.media.AudioAttributes);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
     field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
@@ -23768,6 +23864,7 @@
   }
 
   public static final class MediaMuxer.OutputFormat {
+    field public static final int MUXER_OUTPUT_3GPP = 2; // 0x2
     field public static final int MUXER_OUTPUT_MPEG_4 = 0; // 0x0
     field public static final int MUXER_OUTPUT_WEBM = 1; // 0x1
   }
@@ -25271,6 +25368,8 @@
 
   public final class MediaController {
     ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
+    method public void addQueueItem(android.media.MediaDescription);
+    method public void addQueueItem(android.media.MediaDescription, int);
     method public void adjustVolume(int, int);
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
     method public android.os.Bundle getExtras();
@@ -25289,6 +25388,8 @@
     method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.media.session.MediaController.Callback);
     method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
+    method public void removeQueueItem(android.media.MediaDescription);
+    method public void removeQueueItemAt(int);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void setVolumeTo(int, int);
     method public void unregisterCallback(android.media.session.MediaController.Callback);
@@ -25366,11 +25467,14 @@
     method public void setSessionActivity(android.app.PendingIntent);
     method public void setShuffleModeEnabled(boolean);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+    field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
   public static abstract class MediaSession.Callback {
     ctor public MediaSession.Callback();
+    method public void onAddQueueItem(android.media.MediaDescription);
+    method public void onAddQueueItem(android.media.MediaDescription, int);
     method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void onCustomAction(java.lang.String, android.os.Bundle);
     method public void onFastForward();
@@ -25384,6 +25488,8 @@
     method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
     method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
     method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
+    method public void onRemoveQueueItem(android.media.MediaDescription);
+    method public void onRemoveQueueItemAt(int);
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
@@ -25627,6 +25733,7 @@
     field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
     field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
     field public static final java.lang.String COLUMN_SERVICE_TYPE = "service_type";
+    field public static final java.lang.String COLUMN_SYSTEM_APPROVED = "system_approved";
     field public static final java.lang.String COLUMN_TRANSIENT = "transient";
     field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
     field public static final java.lang.String COLUMN_TYPE = "type";
@@ -25693,6 +25800,7 @@
     field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
     field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
     field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
     field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
     field public static final java.lang.String COLUMN_AUTHOR = "author";
     field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
@@ -25700,6 +25808,7 @@
     field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
     field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
     field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
@@ -25713,17 +25822,14 @@
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
     field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
     field public static final java.lang.String COLUMN_LIVE = "live";
-    field public static final java.lang.String COLUMN_LOGO = "logo";
+    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
     field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
     field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
     field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
     field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
-    field public static final java.lang.String COLUMN_PREVIEW_DURATION = "preview_duration";
-    field public static final java.lang.String COLUMN_PREVIEW_INTENT_URI = "preview_intent_uri";
-    field public static final java.lang.String COLUMN_PREVIEW_LAST_PLAYBACK_POSITION = "preview_last_playback_position";
     field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
-    field public static final java.lang.String COLUMN_PREVIEW_WEIGHT = "preview_weight";
     field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
     field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
     field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
@@ -25744,6 +25850,7 @@
     field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
     field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+    field public static final java.lang.String COLUMN_WEIGHT = "weight";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
     field public static final android.net.Uri CONTENT_URI;
@@ -28252,6 +28359,7 @@
 
   public class WifiManager {
     method public int addNetwork(android.net.wifi.WifiConfiguration);
+    method public boolean addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
     method public static int calculateSignalLevel(int, int);
     method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
     method public static int compareSignalLevel(int, int);
@@ -28267,6 +28375,7 @@
     method public android.net.wifi.WifiInfo getConnectionInfo();
     method public android.net.wifi.WifiConnectionStatistics getConnectionStatistics();
     method public android.net.DhcpInfo getDhcpInfo();
+    method public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
     method public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
     method public java.util.List<android.net.wifi.ScanResult> getScanResults();
     method public android.net.wifi.WifiConfiguration getWifiApConfiguration();
@@ -28290,6 +28399,7 @@
     method public boolean reassociate();
     method public boolean reconnect();
     method public boolean removeNetwork(int);
+    method public boolean removePasspointConfiguration(java.lang.String);
     method public boolean saveConfiguration();
     method public void setTdlsEnabled(java.net.InetAddress, boolean);
     method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
@@ -28673,6 +28783,241 @@
 
 }
 
+package android.net.wifi.hotspot2 {
+
+  public final class ConfigParser {
+    method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(java.lang.String, byte[]);
+  }
+
+  public final class PasspointConfiguration implements android.os.Parcelable {
+    ctor public PasspointConfiguration();
+    ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+    method public int describeContents();
+    method public android.net.wifi.hotspot2.pps.Credential getCredential();
+    method public int getCredentialPriority();
+    method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
+    method public android.net.wifi.hotspot2.pps.Policy getPolicy();
+    method public long getSubscriptionCreationTimeInMs();
+    method public long getSubscriptionExpirationTimeInMs();
+    method public java.lang.String getSubscriptionType();
+    method public android.net.wifi.hotspot2.pps.UpdateParameter getSubscriptionUpdate();
+    method public java.util.Map<java.lang.String, byte[]> getTrustRootCertList();
+    method public int getUpdateIdentififer();
+    method public long getUsageLimitDataLimit();
+    method public long getUsageLimitStartTimeInMs();
+    method public long getUsageLimitTimeLimitInMinutes();
+    method public long getUsageLimitUsageTimePeriodInMinutes();
+    method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
+    method public void setCredentialPriority(int);
+    method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+    method public void setPolicy(android.net.wifi.hotspot2.pps.Policy);
+    method public void setSubscriptionCreationTimeInMs(long);
+    method public void setSubscriptionExpirationTimeInMs(long);
+    method public void setSubscriptionType(java.lang.String);
+    method public void setSubscriptionUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+    method public void setTrustRootCertList(java.util.Map<java.lang.String, byte[]>);
+    method public void setUpdateIdentifier(int);
+    method public void setUsageLimitDataLimit(long);
+    method public void setUsageLimitStartTimeInMs(long);
+    method public void setUsageLimitTimeLimitInMinutes(long);
+    method public void setUsageLimitUsageTimePeriodInMinutes(long);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
+  }
+
+}
+
+package android.net.wifi.hotspot2.omadm {
+
+  public final class PpsMoParser {
+    method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(java.lang.String);
+  }
+
+}
+
+package android.net.wifi.hotspot2.pps {
+
+  public final class Credential implements android.os.Parcelable {
+    ctor public Credential();
+    ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
+    method public int describeContents();
+    method public java.security.cert.X509Certificate getCaCertificate();
+    method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
+    method public boolean getCheckAaaServerStatus();
+    method public java.security.cert.X509Certificate[] getClientCertificateChain();
+    method public java.security.PrivateKey getClientPrivateKey();
+    method public long getCreationTimeInMs();
+    method public long getExpirationTimeInMs();
+    method public java.lang.String getRealm();
+    method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
+    method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
+    method public void setCaCertificate(java.security.cert.X509Certificate);
+    method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+    method public void setCheckAaaServerCertStatus(boolean);
+    method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
+    method public void setClientPrivateKey(java.security.PrivateKey);
+    method public void setCreationTimeInMs(long);
+    method public void setExpirationTimeInMs(long);
+    method public void setRealm(java.lang.String);
+    method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+    method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
+  }
+
+  public static final class Credential.CertificateCredential implements android.os.Parcelable {
+    ctor public Credential.CertificateCredential();
+    ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+    method public int describeContents();
+    method public byte[] getCertSha256Fingerprint();
+    method public java.lang.String getCertType();
+    method public void setCertSha256Fingerprint(byte[]);
+    method public void setCertType(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
+  }
+
+  public static final class Credential.SimCredential implements android.os.Parcelable {
+    ctor public Credential.SimCredential();
+    ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+    method public int describeContents();
+    method public int getEapType();
+    method public java.lang.String getImsi();
+    method public void setEapType(int);
+    method public void setImsi(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
+  }
+
+  public static final class Credential.UserCredential implements android.os.Parcelable {
+    ctor public Credential.UserCredential();
+    ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+    method public int describeContents();
+    method public boolean getAbleToShare();
+    method public int getEapType();
+    method public boolean getMachineManaged();
+    method public java.lang.String getNonEapInnerMethod();
+    method public java.lang.String getPassword();
+    method public java.lang.String getSoftTokenApp();
+    method public java.lang.String getUsername();
+    method public void setAbleToShare(boolean);
+    method public void setEapType(int);
+    method public void setMachineManaged(boolean);
+    method public void setNonEapInnerMethod(java.lang.String);
+    method public void setPassword(java.lang.String);
+    method public void setSoftTokenApp(java.lang.String);
+    method public void setUsername(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
+  }
+
+  public final class HomeSp implements android.os.Parcelable {
+    ctor public HomeSp();
+    ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+    method public int describeContents();
+    method public java.lang.String getFqdn();
+    method public java.lang.String getFriendlyName();
+    method public java.util.Map<java.lang.String, java.lang.Long> getHomeNetworkIds();
+    method public java.lang.String getIconUrl();
+    method public long[] getMatchAllOis();
+    method public long[] getMatchAnysOis();
+    method public java.lang.String[] getOtherHomePartners();
+    method public long[] getRoamingConsortiumOis();
+    method public void setFqdn(java.lang.String);
+    method public void setFriendlyName(java.lang.String);
+    method public void setHomeNetworkIds(java.util.Map<java.lang.String, java.lang.Long>);
+    method public void setIconUrl(java.lang.String);
+    method public void setMatchAllOis(long[]);
+    method public void setMatchAnyOis(long[]);
+    method public void setOtherHomePartners(java.lang.String[]);
+    method public void setRoamingConsortiumOis(long[]);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
+  }
+
+  public final class Policy implements android.os.Parcelable {
+    ctor public Policy();
+    ctor public Policy(android.net.wifi.hotspot2.pps.Policy);
+    method public int describeContents();
+    method public java.lang.String[] getExcludedSsidList();
+    method public int getMaximumBssLoadValue();
+    method public long getMinHomeDownlinkBandWidht();
+    method public long getMinHomeUplinkBandwidth();
+    method public long getMinRoamingDownlinkBandwidth();
+    method public long getMinRoamingUplinkBandwidth();
+    method public android.net.wifi.hotspot2.pps.UpdateParameter getPolicyUpdate();
+    method public java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> getPreferredRoamingPartnerList();
+    method public java.util.Map<java.lang.Integer, java.lang.String> getRequiredProtoPortMap();
+    method public void setExcludedSsidList(java.lang.String[]);
+    method public void setMaximumBssLoadValue(int);
+    method public void setMinHomeDownlinkBandwidth(long);
+    method public void setMinHomeUplinkBandwidth(long);
+    method public void setMinRoamingDownlinkBandwidth(long);
+    method public void setMinRoamingUplinkBandwidth(long);
+    method public void setPolicyUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+    method public void setPreferredRoamingPartnerList(java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner>);
+    method public void setRequiredProtoPortMap(java.util.Map<java.lang.Integer, java.lang.String>);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy> CREATOR;
+  }
+
+  public static final class Policy.RoamingPartner implements android.os.Parcelable {
+    ctor public Policy.RoamingPartner();
+    ctor public Policy.RoamingPartner(android.net.wifi.hotspot2.pps.Policy.RoamingPartner);
+    method public int describeContents();
+    method public java.lang.String getCountries();
+    method public java.lang.String getFqdn();
+    method public boolean getFqdnExactMatch();
+    method public int getPriority();
+    method public void setCountries(java.lang.String);
+    method public void setFqdn(java.lang.String);
+    method public void setFqdnExactMatch(boolean);
+    method public void setPriority(int);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> CREATOR;
+  }
+
+  public final class UpdateParameter implements android.os.Parcelable {
+    ctor public UpdateParameter();
+    ctor public UpdateParameter(android.net.wifi.hotspot2.pps.UpdateParameter);
+    method public int describeContents();
+    method public java.lang.String getBase64EncodedPassword();
+    method public java.lang.String getRestriction();
+    method public java.lang.String getServerUri();
+    method public byte[] getTrustRootCertSha256Fingerprint();
+    method public java.lang.String getTrustRootCertUrl();
+    method public long getUpdateIntervalInMinutes();
+    method public java.lang.String getUpdateMethod();
+    method public java.lang.String getUsername();
+    method public void setBase64EncodedPassword(java.lang.String);
+    method public void setRestriction(java.lang.String);
+    method public void setServerUri(java.lang.String);
+    method public void setTrustRootCertSha256Fingerprint(byte[]);
+    method public void setTrustRootCertUrl(java.lang.String);
+    method public void setUpdateIntervalInMinutes(long);
+    method public void setUpdateMethod(java.lang.String);
+    method public void setUsername(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.UpdateParameter> CREATOR;
+    field public static final long UPDATE_CHECK_INTERVAL_NEVER = 4294967295L; // 0xffffffffL
+    field public static final java.lang.String UPDATE_METHOD_OMADM = "OMA-DM-ClientInitiated";
+    field public static final java.lang.String UPDATE_METHOD_SSP = "SSP-ClientInitiated";
+    field public static final java.lang.String UPDATE_RESTRICTION_HOMESP = "HomeSP";
+    field public static final java.lang.String UPDATE_RESTRICTION_ROAMING_PARTNER = "RoamingPartner";
+    field public static final java.lang.String UPDATE_RESTRICTION_UNRESTRICTED = "Unrestricted";
+  }
+
+}
+
 package android.net.wifi.p2p {
 
   public class WifiP2pConfig implements android.os.Parcelable {
@@ -38885,26 +39230,19 @@
     ctor public AutoFillService();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
-    method public void onDatasetAuthenticationRequest(android.os.Bundle, int);
     method public void onDisconnected();
     method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public void onFillResponseAuthenticationRequest(android.os.Bundle, int);
     method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
-    field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS";
-    field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS";
-    field public static final int FLAG_AUTHENTICATION_ERROR = 4; // 0x4
-    field public static final int FLAG_AUTHENTICATION_REQUESTED = 1; // 0x1
-    field public static final int FLAG_AUTHENTICATION_SUCCESS = 2; // 0x2
-    field public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 8; // 0x8
     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";
   }
 
-  public final class FillCallback {
-    method public void onDatasetAuthentication(android.view.autofill.Dataset, int);
+  public final class FillCallback implements android.os.Parcelable {
+    method public int describeContents();
     method public void onFailure(java.lang.CharSequence);
-    method public void onFillResponseAuthentication(int);
     method public void onSuccess(android.view.autofill.FillResponse);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.autofill.FillCallback> CREATOR;
   }
 
   public final class SaveCallback {
@@ -42378,11 +42716,6 @@
     field public static final int PHONE_TYPE_GSM = 1; // 0x1
     field public static final int PHONE_TYPE_NONE = 0; // 0x0
     field public static final int PHONE_TYPE_SIP = 3; // 0x3
-    field public static final int SIM_ACTIVATION_RESULT_CANCELED = 4; // 0x4
-    field public static final int SIM_ACTIVATION_RESULT_COMPLETE = 0; // 0x0
-    field public static final int SIM_ACTIVATION_RESULT_FAILED = 3; // 0x3
-    field public static final int SIM_ACTIVATION_RESULT_IN_PROGRESS = 2; // 0x2
-    field public static final int SIM_ACTIVATION_RESULT_NOT_SUPPORTED = 1; // 0x1
     field public static final int SIM_STATE_ABSENT = 1; // 0x1
     field public static final int SIM_STATE_CARD_IO_ERROR = 8; // 0x8
     field public static final int SIM_STATE_CARD_RESTRICTED = 9; // 0x9
@@ -45115,6 +45448,15 @@
     method public android.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
   }
 
+  public abstract class TransitionListenerAdapter implements android.transition.Transition.TransitionListener {
+    ctor public TransitionListenerAdapter();
+    method public void onTransitionCancel(android.transition.Transition);
+    method public void onTransitionEnd(android.transition.Transition);
+    method public void onTransitionPause(android.transition.Transition);
+    method public void onTransitionResume(android.transition.Transition);
+    method public void onTransitionStart(android.transition.Transition);
+  }
+
   public class TransitionManager {
     ctor public TransitionManager();
     method public static void beginDelayedTransition(android.view.ViewGroup);
@@ -47514,8 +47856,8 @@
     method public void drawableHotspotChanged(float, float);
     method protected void drawableStateChanged();
     method public android.view.View findFocus();
-    method public final <T extends android.view.View> T findViewById(int);
-    method public final <T extends android.view.View> T findViewWithTag(java.lang.Object);
+    method public final android.view.View findViewById(int);
+    method public final android.view.View findViewWithTag(java.lang.Object);
     method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
     method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
     method public android.view.View focusSearch(int);
@@ -49093,6 +49435,7 @@
     field public static final int TYPE_APPLICATION = 2; // 0x2
     field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
     field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
+    field public static final int TYPE_APPLICATION_OVERLAY = 2038; // 0x7f6
     field public static final int TYPE_APPLICATION_PANEL = 1000; // 0x3e8
     field public static final int TYPE_APPLICATION_STARTING = 3; // 0x3
     field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea
@@ -49102,17 +49445,17 @@
     field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
     field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
     field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
-    field public static final int TYPE_PHONE = 2002; // 0x7d2
-    field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+    field public static final deprecated int TYPE_PHONE = 2002; // 0x7d2
+    field public static final deprecated int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
     field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
     field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
     field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
     field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
-    field public static final int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
+    field public static final deprecated int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
     field public static final int TYPE_SYSTEM_DIALOG = 2008; // 0x7d8
-    field public static final int TYPE_SYSTEM_ERROR = 2010; // 0x7da
-    field public static final int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
-    field public static final int TYPE_TOAST = 2005; // 0x7d5
+    field public static final deprecated int TYPE_SYSTEM_ERROR = 2010; // 0x7da
+    field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
+    field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
     field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
     field public float alpha;
     field public float buttonBrightness;
@@ -49921,10 +50264,9 @@
   }
 
   public static final class Dataset.Builder {
-    ctor public Dataset.Builder(java.lang.CharSequence);
+    ctor public Dataset.Builder(java.lang.String, java.lang.CharSequence);
     method public android.view.autofill.Dataset build();
-    method public android.view.autofill.Dataset.Builder requiresCustomAuthentication(android.os.Bundle, int);
-    method public android.view.autofill.Dataset.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+    method public android.view.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
     method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
     method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
   }
@@ -49936,12 +50278,11 @@
   }
 
   public static final class FillResponse.Builder {
-    ctor public FillResponse.Builder();
+    ctor public FillResponse.Builder(java.lang.String);
     method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
     method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
     method public android.view.autofill.FillResponse build();
-    method public android.view.autofill.FillResponse.Builder requiresCustomAuthentication(android.os.Bundle, int);
-    method public android.view.autofill.FillResponse.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+    method public android.view.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
     method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
   }
 
@@ -50367,7 +50708,7 @@
 
   public final class TextClassificationManager {
     method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
-    method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+    method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier();
   }
 
   public final class TextClassificationResult {
@@ -54059,6 +54400,7 @@
     method public void setIs24HourView(java.lang.Boolean);
     method public void setMinute(int);
     method public void setOnTimeChangedListener(android.widget.TimePicker.OnTimeChangedListener);
+    method public boolean validateInput();
   }
 
   public static abstract interface TimePicker.OnTimeChangedListener {
@@ -54457,6 +54799,8 @@
     field public static final int OP_INVOKE_INTERFACE = 114; // 0x72
     field public static final int OP_INVOKE_INTERFACE_JUMBO = 9983; // 0x26ff
     field public static final int OP_INVOKE_INTERFACE_RANGE = 120; // 0x78
+    field public static final int OP_INVOKE_POLYMORPHIC = 250; // 0xfa
+    field public static final int OP_INVOKE_POLYMORPHIC_RANGE = 251; // 0xfb
     field public static final int OP_INVOKE_STATIC = 113; // 0x71
     field public static final int OP_INVOKE_STATIC_JUMBO = 9727; // 0x25ff
     field public static final int OP_INVOKE_STATIC_RANGE = 119; // 0x77
@@ -57751,12 +58095,15 @@
   }
 
   public abstract class MethodHandle {
+    method public java.lang.invoke.MethodHandle asCollector(java.lang.Class<?>, int);
     method public java.lang.invoke.MethodHandle asFixedArity();
+    method public java.lang.invoke.MethodHandle asSpreader(java.lang.Class<?>, int);
     method public java.lang.invoke.MethodHandle asType(java.lang.invoke.MethodType);
     method public java.lang.invoke.MethodHandle asVarargsCollector(java.lang.Class<?>);
     method public java.lang.invoke.MethodHandle bindTo(java.lang.Object);
     method public final java.lang.Object invoke(java.lang.Object...) throws java.lang.Throwable;
     method public final java.lang.Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
+    method public java.lang.Object invokeWithArguments(java.lang.Object...) throws java.lang.Throwable;
     method public java.lang.Object invokeWithArguments(java.util.List<?>) throws java.lang.Throwable;
     method public boolean isVarargsCollector();
     method public java.lang.invoke.MethodType type();
@@ -57790,17 +58137,23 @@
     method public static java.lang.invoke.MethodHandle arrayElementGetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
     method public static java.lang.invoke.MethodHandle arrayElementSetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
     method public static java.lang.invoke.MethodHandle catchException(java.lang.invoke.MethodHandle, java.lang.Class<? extends java.lang.Throwable>, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle collectArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle constant(java.lang.Class<?>, java.lang.Object);
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.lang.Class<?>...);
     method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+    method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
     method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle guardWithTest(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle identity(java.lang.Class<?>);
+    method public static java.lang.invoke.MethodHandle insertArguments(java.lang.invoke.MethodHandle, int, java.lang.Object...);
     method public static java.lang.invoke.MethodHandle invoker(java.lang.invoke.MethodType);
     method public static java.lang.invoke.MethodHandles.Lookup lookup();
     method public static java.lang.invoke.MethodHandle permuteArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, int...);
     method public static java.lang.invoke.MethodHandles.Lookup publicLookup();
+    method public static <T extends java.lang.reflect.Member> T reflectAs(java.lang.Class<T>, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle spreadInvoker(java.lang.invoke.MethodType, int);
     method public static java.lang.invoke.MethodHandle throwException(java.lang.Class<?>, java.lang.Class<? extends java.lang.Throwable>);
   }
 
@@ -57817,6 +58170,7 @@
     method public java.lang.invoke.MethodHandles.Lookup in(java.lang.Class<?>);
     method public java.lang.Class<?> lookupClass();
     method public int lookupModes();
+    method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
     method public void throwMakeAccessException(java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException;
     method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
     method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 29d152a..bbb7f89 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -203,7 +203,6 @@
 
   public static final class R.attr {
     ctor public R.attr();
-    field public static final int __removed0 = 16844097; // 0x1010541
     field public static final int __removed1 = 16844099; // 0x1010543
     field public static final int absListViewStyle = 16842858; // 0x101006a
     field public static final int accessibilityEventTypes = 16843648; // 0x1010380
@@ -1270,6 +1269,7 @@
     field public static final int targetId = 16843740; // 0x10103dc
     field public static final int targetName = 16843853; // 0x101044d
     field public static final int targetPackage = 16842785; // 0x1010021
+    field public static final int targetProcess = 16844097; // 0x1010541
     field public static final int targetSandboxVersion = 16844110; // 0x101054e
     field public static final int targetSdkVersion = 16843376; // 0x1010270
     field public static final int taskAffinity = 16842770; // 0x1010012
@@ -2688,11 +2688,25 @@
 
 package android.accessibilityservice {
 
+  public final class AccessibilityButtonController {
+    method public boolean isAccessibilityButtonAvailable();
+    method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+    method public void registerAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback, android.os.Handler);
+    method public void unregisterAccessibilityButtonCallback(android.accessibilityservice.AccessibilityButtonController.AccessibilityButtonCallback);
+  }
+
+  public static abstract class AccessibilityButtonController.AccessibilityButtonCallback {
+    ctor public AccessibilityButtonController.AccessibilityButtonCallback();
+    method public void onAvailabilityChanged(android.accessibilityservice.AccessibilityButtonController, boolean);
+    method public void onClicked(android.accessibilityservice.AccessibilityButtonController);
+  }
+
   public abstract class AccessibilityService extends android.app.Service {
     ctor public AccessibilityService();
     method public final void disableSelf();
     method public final boolean dispatchGesture(android.accessibilityservice.GestureDescription, android.accessibilityservice.AccessibilityService.GestureResultCallback, android.os.Handler);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
+    method public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController();
     method public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
     method public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
@@ -2805,6 +2819,7 @@
     field public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 128; // 0x80
     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 int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
@@ -2909,7 +2924,7 @@
   public class AccountManager {
     method public android.accounts.AccountManagerFuture<android.os.Bundle> addAccount(java.lang.String, java.lang.String, java.lang.String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle);
-    method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.Integer, java.lang.Integer>);
+    method public boolean addAccountExplicitly(android.accounts.Account, java.lang.String, android.os.Bundle, java.util.Map<java.lang.String, java.lang.Integer>);
     method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean);
     method public void addOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener, android.os.Handler, boolean, java.lang.String[]);
     method public java.lang.String blockingGetAuthToken(android.accounts.Account, java.lang.String, boolean) throws android.accounts.AuthenticatorException, java.io.IOException, android.accounts.OperationCanceledException;
@@ -2918,7 +2933,7 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> editProperties(java.lang.String, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> finishSession(android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public static android.accounts.AccountManager get(android.content.Context);
-    method public int getAccountVisibility(android.accounts.Account, int);
+    method public int getAccountVisibility(android.accounts.Account, java.lang.String);
     method public android.accounts.Account[] getAccounts();
     method public java.util.Map<android.accounts.Account, java.lang.Integer> getAccountsAndVisibilityForPackage(java.lang.String, java.lang.String);
     method public android.accounts.Account[] getAccountsByType(java.lang.String);
@@ -2929,9 +2944,9 @@
     method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthToken(android.accounts.Account, java.lang.String, android.os.Bundle, boolean, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AccountManagerFuture<android.os.Bundle> getAuthTokenByFeatures(java.lang.String, java.lang.String, java.lang.String[], android.app.Activity, android.os.Bundle, android.os.Bundle, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler);
     method public android.accounts.AuthenticatorDescription[] getAuthenticatorTypes();
+    method public java.util.Map<java.lang.String, java.lang.Integer> getPackagesAndVisibilityForAccount(android.accounts.Account);
     method public java.lang.String getPassword(android.accounts.Account);
     method public java.lang.String getPreviousName(android.accounts.Account);
-    method public java.util.Map<java.lang.Integer, java.lang.Integer> getUidsAndVisibilityForAccount(android.accounts.Account);
     method public java.lang.String getUserData(android.accounts.Account, java.lang.String);
     method public android.accounts.AccountManagerFuture<java.lang.Boolean> hasFeatures(android.accounts.Account, java.lang.String[], android.accounts.AccountManagerCallback<java.lang.Boolean>, android.os.Handler);
     method public void invalidateAuthToken(java.lang.String, java.lang.String);
@@ -2945,7 +2960,7 @@
     method public boolean removeAccountExplicitly(android.accounts.Account);
     method public void removeOnAccountsUpdatedListener(android.accounts.OnAccountsUpdateListener);
     method public android.accounts.AccountManagerFuture<android.accounts.Account> renameAccount(android.accounts.Account, java.lang.String, android.accounts.AccountManagerCallback<android.accounts.Account>, android.os.Handler);
-    method public boolean setAccountVisibility(android.accounts.Account, int, int);
+    method public boolean setAccountVisibility(android.accounts.Account, java.lang.String, int);
     method public void setAuthToken(android.accounts.Account, java.lang.String, java.lang.String);
     method public void setPassword(android.accounts.Account, java.lang.String);
     method public void setUserData(android.accounts.Account, java.lang.String, java.lang.String);
@@ -2985,8 +3000,8 @@
     field public static final java.lang.String KEY_PASSWORD = "password";
     field public static final java.lang.String KEY_USERDATA = "userdata";
     field public static final deprecated java.lang.String LOGIN_ACCOUNTS_CHANGED_ACTION = "android.accounts.LOGIN_ACCOUNTS_CHANGED";
-    field public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3; // 0xfffffffd
-    field public static final int UID_KEY_DEFAULT_VISIBILITY = -2; // 0xfffffffe
+    field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE = "android.accounts.key_legacy_not_visible";
+    field public static final java.lang.String PACKAGE_NAME_KEY_LEGACY_VISIBLE = "android.accounts.key_legacy_visible";
     field public static final int VISIBILITY_NOT_VISIBLE = 3; // 0x3
     field public static final int VISIBILITY_UNDEFINED = 0; // 0x0
     field public static final int VISIBILITY_USER_MANAGED_NOT_VISIBLE = 4; // 0x4
@@ -4814,6 +4829,7 @@
     method public void addMonitor(android.app.Instrumentation.ActivityMonitor);
     method public android.app.Instrumentation.ActivityMonitor addMonitor(android.content.IntentFilter, android.app.Instrumentation.ActivityResult, boolean);
     method public android.app.Instrumentation.ActivityMonitor addMonitor(java.lang.String, android.app.Instrumentation.ActivityResult, boolean);
+    method public void addResults(android.os.Bundle);
     method public void callActivityOnCreate(android.app.Activity, android.os.Bundle);
     method public void callActivityOnCreate(android.app.Activity, android.os.Bundle, android.os.PersistableBundle);
     method public void callActivityOnDestroy(android.app.Activity);
@@ -4838,6 +4854,7 @@
     method public android.os.Bundle getBinderCounts();
     method public android.content.ComponentName getComponentName();
     method public android.content.Context getContext();
+    method public java.lang.String getProcessName();
     method public android.content.Context getTargetContext();
     method public android.app.UiAutomation getUiAutomation();
     method public android.app.UiAutomation getUiAutomation(int);
@@ -5054,14 +5071,19 @@
     ctor public Notification(android.os.Parcel);
     method public android.app.Notification clone();
     method public int describeContents();
+    method public int getBadgeIcon();
     method public java.lang.String getChannel();
     method public java.lang.String getGroup();
     method public android.graphics.drawable.Icon getLargeIcon();
+    method public java.lang.String getShortcutId();
     method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
     method public long getTimeout();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.media.AudioAttributes AUDIO_ATTRIBUTES_DEFAULT;
+    field public static final int BADGE_ICON_LARGE = 2; // 0x2
+    field public static final int BADGE_ICON_NONE = 0; // 0x0
+    field public static final int BADGE_ICON_SMALL = 1; // 0x1
     field public static final java.lang.String CATEGORY_ALARM = "alarm";
     field public static final java.lang.String CATEGORY_CALL = "call";
     field public static final java.lang.String CATEGORY_EMAIL = "email";
@@ -5153,7 +5175,7 @@
     field public deprecated int ledARGB;
     field public deprecated int ledOffMS;
     field public deprecated int ledOnMS;
-    field public deprecated int number;
+    field public int number;
     field public deprecated int priority;
     field public android.app.Notification publicVersion;
     field public deprecated android.net.Uri sound;
@@ -5241,6 +5263,7 @@
     method public android.app.Notification.Builder addExtras(android.os.Bundle);
     method public android.app.Notification.Builder addPerson(java.lang.String);
     method public android.app.Notification build();
+    method public android.app.Notification.Builder chooseBadgeIcon(int);
     method public android.widget.RemoteViews createBigContentView();
     method public android.widget.RemoteViews createContentView();
     method public android.widget.RemoteViews createHeadsUpContentView();
@@ -5273,13 +5296,14 @@
     method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
     method public deprecated android.app.Notification.Builder setLights(int, int, int);
     method public android.app.Notification.Builder setLocalOnly(boolean);
-    method public deprecated android.app.Notification.Builder setNumber(int);
+    method public android.app.Notification.Builder setNumber(int);
     method public android.app.Notification.Builder setOngoing(boolean);
     method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
     method public deprecated android.app.Notification.Builder setPriority(int);
     method public android.app.Notification.Builder setProgress(int, int, boolean);
     method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
     method public android.app.Notification.Builder setRemoteInputHistory(java.lang.CharSequence[]);
+    method public android.app.Notification.Builder setShortcutId(java.lang.String);
     method public android.app.Notification.Builder setShowWhen(boolean);
     method public android.app.Notification.Builder setSmallIcon(int);
     method public android.app.Notification.Builder setSmallIcon(int, int);
@@ -7964,6 +7988,65 @@
 
 }
 
+package android.companion {
+
+  public final class AssociationRequest<F extends android.companion.DeviceFilter> implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.AssociationRequest> CREATOR;
+  }
+
+  public static final class AssociationRequest.Builder<F extends android.companion.DeviceFilter> {
+    method public android.companion.AssociationRequest<F> build();
+    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothDeviceFilter> createForBluetoothDevice();
+    method public static android.companion.AssociationRequest.Builder<android.companion.BluetoothLEDeviceFilter> createForBluetoothLEDevice();
+    method public android.companion.AssociationRequest.Builder<F> setDeviceFilter(F);
+    method public android.companion.AssociationRequest.Builder<F> setSingleDevice(boolean);
+  }
+
+  public final class BluetoothDeviceFilter implements android.companion.DeviceFilter {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.BluetoothDeviceFilter> CREATOR;
+  }
+
+  public static final class BluetoothDeviceFilter.Builder {
+    ctor public BluetoothDeviceFilter.Builder();
+    method public android.companion.BluetoothDeviceFilter.Builder addServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
+    method public android.companion.BluetoothDeviceFilter build();
+    method public android.companion.BluetoothDeviceFilter.Builder setAddress(java.lang.String);
+    method public android.companion.BluetoothDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+  }
+
+  public final class BluetoothLEDeviceFilter implements android.companion.DeviceFilter {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.companion.BluetoothLEDeviceFilter> CREATOR;
+  }
+
+  public static final class BluetoothLEDeviceFilter.Builder {
+    ctor public BluetoothLEDeviceFilter.Builder();
+    method public android.companion.BluetoothLEDeviceFilter build();
+    method public android.companion.BluetoothLEDeviceFilter.Builder setNamePattern(java.util.regex.Pattern);
+    method public android.companion.BluetoothLEDeviceFilter.Builder setScanFilter(android.bluetooth.le.ScanFilter);
+  }
+
+  public final class CompanionDeviceManager {
+    method public void associate(android.companion.AssociationRequest<?>, android.companion.CompanionDeviceManager.Callback, android.os.Handler);
+    field public static final java.lang.String EXTRA_DEVICE = "android.companion.extra.DEVICE";
+  }
+
+  public static abstract class CompanionDeviceManager.Callback {
+    ctor public CompanionDeviceManager.Callback();
+    method public abstract void onDeviceFound(android.content.IntentSender);
+    method public abstract void onFailure(java.lang.CharSequence);
+  }
+
+  public abstract interface DeviceFilter<D extends android.os.Parcelable> implements android.os.Parcelable {
+  }
+
+}
+
 package android.content {
 
   public abstract class AbstractThreadedSyncAdapter {
@@ -8578,6 +8661,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 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
@@ -9116,6 +9200,10 @@
     field public static final java.lang.String EXTRA_ASSIST_INPUT_HINT_KEYBOARD = "android.intent.extra.ASSIST_INPUT_HINT_KEYBOARD";
     field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
     field public static final java.lang.String EXTRA_ASSIST_UID = "android.intent.extra.ASSIST_UID";
+    field public static final java.lang.String EXTRA_AUTO_FILL_ASSIST_STRUCTURE = "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
+    field public static final java.lang.String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
+    field public static final java.lang.String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
+    field public static final java.lang.String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
     field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
     field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -9931,6 +10019,7 @@
     field public java.lang.String[] splitPublicSourceDirs;
     field public java.lang.String[] splitSourceDirs;
     field public java.lang.String targetPackage;
+    field public java.lang.String targetProcess;
   }
 
   public class LabeledIntent extends android.content.Intent {
@@ -10356,6 +10445,7 @@
     field public static final java.lang.String FEATURE_VERIFIED_BOOT = "android.software.verified_boot";
     field public static final java.lang.String FEATURE_VR_MODE = "android.software.vr.mode";
     field public static final java.lang.String FEATURE_VR_MODE_HIGH_PERFORMANCE = "android.hardware.vr.high_performance";
+    field public static final java.lang.String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
     field public static final java.lang.String FEATURE_VULKAN_HARDWARE_LEVEL = "android.hardware.vulkan.level";
     field public static final java.lang.String FEATURE_VULKAN_HARDWARE_VERSION = "android.hardware.vulkan.version";
     field public static final java.lang.String FEATURE_WATCH = "android.hardware.type.watch";
@@ -20532,6 +20622,7 @@
     method public int getContentType();
     method public int getFlags();
     method public int getUsage();
+    method public static int getVolumeControlStream(android.media.AudioAttributes);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
     field public static final int CONTENT_TYPE_MUSIC = 2; // 0x2
@@ -22254,6 +22345,7 @@
   }
 
   public static final class MediaMuxer.OutputFormat {
+    field public static final int MUXER_OUTPUT_3GPP = 2; // 0x2
     field public static final int MUXER_OUTPUT_MPEG_4 = 0; // 0x0
     field public static final int MUXER_OUTPUT_WEBM = 1; // 0x1
   }
@@ -23674,6 +23766,8 @@
 
   public final class MediaController {
     ctor public MediaController(android.content.Context, android.media.session.MediaSession.Token);
+    method public void addQueueItem(android.media.MediaDescription);
+    method public void addQueueItem(android.media.MediaDescription, int);
     method public void adjustVolume(int, int);
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
     method public android.os.Bundle getExtras();
@@ -23692,6 +23786,8 @@
     method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.media.session.MediaController.Callback);
     method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
+    method public void removeQueueItem(android.media.MediaDescription);
+    method public void removeQueueItemAt(int);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void setVolumeTo(int, int);
     method public void unregisterCallback(android.media.session.MediaController.Callback);
@@ -23769,11 +23865,14 @@
     method public void setSessionActivity(android.app.PendingIntent);
     method public void setShuffleModeEnabled(boolean);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+    field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
   public static abstract class MediaSession.Callback {
     ctor public MediaSession.Callback();
+    method public void onAddQueueItem(android.media.MediaDescription);
+    method public void onAddQueueItem(android.media.MediaDescription, int);
     method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void onCustomAction(java.lang.String, android.os.Bundle);
     method public void onFastForward();
@@ -23787,6 +23886,8 @@
     method public void onPrepareFromMediaId(java.lang.String, android.os.Bundle);
     method public void onPrepareFromSearch(java.lang.String, android.os.Bundle);
     method public void onPrepareFromUri(android.net.Uri, android.os.Bundle);
+    method public void onRemoveQueueItem(android.media.MediaDescription);
+    method public void onRemoveQueueItemAt(int);
     method public void onRewind();
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
@@ -24034,6 +24135,7 @@
     field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
     field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
     field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
     field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
     field public static final java.lang.String COLUMN_AUTHOR = "author";
     field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
@@ -24041,6 +24143,7 @@
     field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
     field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
     field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
@@ -24054,17 +24157,14 @@
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
     field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
     field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
     field public static final java.lang.String COLUMN_LIVE = "live";
-    field public static final java.lang.String COLUMN_LOGO = "logo";
+    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
     field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
     field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
     field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
     field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
-    field public static final java.lang.String COLUMN_PREVIEW_DURATION = "preview_duration";
-    field public static final java.lang.String COLUMN_PREVIEW_INTENT_URI = "preview_intent_uri";
-    field public static final java.lang.String COLUMN_PREVIEW_LAST_PLAYBACK_POSITION = "preview_last_playback_position";
     field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
-    field public static final java.lang.String COLUMN_PREVIEW_WEIGHT = "preview_weight";
     field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
     field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
     field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
@@ -24084,6 +24184,7 @@
     field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
     field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+    field public static final java.lang.String COLUMN_WEIGHT = "weight";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
     field public static final android.net.Uri CONTENT_URI;
@@ -25829,6 +25930,7 @@
 
   public class WifiManager {
     method public int addNetwork(android.net.wifi.WifiConfiguration);
+    method public boolean addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
     method public static int calculateSignalLevel(int, int);
     method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
     method public static int compareSignalLevel(int, int);
@@ -25841,6 +25943,7 @@
     method public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
     method public android.net.wifi.WifiInfo getConnectionInfo();
     method public android.net.DhcpInfo getDhcpInfo();
+    method public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
     method public java.util.List<android.net.wifi.ScanResult> getScanResults();
     method public int getWifiState();
     method public boolean is5GHzBandSupported();
@@ -25856,6 +25959,7 @@
     method public boolean reassociate();
     method public boolean reconnect();
     method public boolean removeNetwork(int);
+    method public boolean removePasspointConfiguration(java.lang.String);
     method public boolean saveConfiguration();
     method public void setTdlsEnabled(java.net.InetAddress, boolean);
     method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
@@ -26070,6 +26174,241 @@
 
 }
 
+package android.net.wifi.hotspot2 {
+
+  public final class ConfigParser {
+    method public static android.net.wifi.hotspot2.PasspointConfiguration parsePasspointConfig(java.lang.String, byte[]);
+  }
+
+  public final class PasspointConfiguration implements android.os.Parcelable {
+    ctor public PasspointConfiguration();
+    ctor public PasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+    method public int describeContents();
+    method public android.net.wifi.hotspot2.pps.Credential getCredential();
+    method public int getCredentialPriority();
+    method public android.net.wifi.hotspot2.pps.HomeSp getHomeSp();
+    method public android.net.wifi.hotspot2.pps.Policy getPolicy();
+    method public long getSubscriptionCreationTimeInMs();
+    method public long getSubscriptionExpirationTimeInMs();
+    method public java.lang.String getSubscriptionType();
+    method public android.net.wifi.hotspot2.pps.UpdateParameter getSubscriptionUpdate();
+    method public java.util.Map<java.lang.String, byte[]> getTrustRootCertList();
+    method public int getUpdateIdentififer();
+    method public long getUsageLimitDataLimit();
+    method public long getUsageLimitStartTimeInMs();
+    method public long getUsageLimitTimeLimitInMinutes();
+    method public long getUsageLimitUsageTimePeriodInMinutes();
+    method public void setCredential(android.net.wifi.hotspot2.pps.Credential);
+    method public void setCredentialPriority(int);
+    method public void setHomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+    method public void setPolicy(android.net.wifi.hotspot2.pps.Policy);
+    method public void setSubscriptionCreationTimeInMs(long);
+    method public void setSubscriptionExpirationTimeInMs(long);
+    method public void setSubscriptionType(java.lang.String);
+    method public void setSubscriptionUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+    method public void setTrustRootCertList(java.util.Map<java.lang.String, byte[]>);
+    method public void setUpdateIdentifier(int);
+    method public void setUsageLimitDataLimit(long);
+    method public void setUsageLimitStartTimeInMs(long);
+    method public void setUsageLimitTimeLimitInMinutes(long);
+    method public void setUsageLimitUsageTimePeriodInMinutes(long);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
+  }
+
+}
+
+package android.net.wifi.hotspot2.omadm {
+
+  public final class PpsMoParser {
+    method public static android.net.wifi.hotspot2.PasspointConfiguration parseMoText(java.lang.String);
+  }
+
+}
+
+package android.net.wifi.hotspot2.pps {
+
+  public final class Credential implements android.os.Parcelable {
+    ctor public Credential();
+    ctor public Credential(android.net.wifi.hotspot2.pps.Credential);
+    method public int describeContents();
+    method public java.security.cert.X509Certificate getCaCertificate();
+    method public android.net.wifi.hotspot2.pps.Credential.CertificateCredential getCertCredential();
+    method public boolean getCheckAaaServerStatus();
+    method public java.security.cert.X509Certificate[] getClientCertificateChain();
+    method public java.security.PrivateKey getClientPrivateKey();
+    method public long getCreationTimeInMs();
+    method public long getExpirationTimeInMs();
+    method public java.lang.String getRealm();
+    method public android.net.wifi.hotspot2.pps.Credential.SimCredential getSimCredential();
+    method public android.net.wifi.hotspot2.pps.Credential.UserCredential getUserCredential();
+    method public void setCaCertificate(java.security.cert.X509Certificate);
+    method public void setCertCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+    method public void setCheckAaaServerCertStatus(boolean);
+    method public void setClientCertificateChain(java.security.cert.X509Certificate[]);
+    method public void setClientPrivateKey(java.security.PrivateKey);
+    method public void setCreationTimeInMs(long);
+    method public void setExpirationTimeInMs(long);
+    method public void setRealm(java.lang.String);
+    method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+    method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
+  }
+
+  public static final class Credential.CertificateCredential implements android.os.Parcelable {
+    ctor public Credential.CertificateCredential();
+    ctor public Credential.CertificateCredential(android.net.wifi.hotspot2.pps.Credential.CertificateCredential);
+    method public int describeContents();
+    method public byte[] getCertSha256Fingerprint();
+    method public java.lang.String getCertType();
+    method public void setCertSha256Fingerprint(byte[]);
+    method public void setCertType(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
+  }
+
+  public static final class Credential.SimCredential implements android.os.Parcelable {
+    ctor public Credential.SimCredential();
+    ctor public Credential.SimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
+    method public int describeContents();
+    method public int getEapType();
+    method public java.lang.String getImsi();
+    method public void setEapType(int);
+    method public void setImsi(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
+  }
+
+  public static final class Credential.UserCredential implements android.os.Parcelable {
+    ctor public Credential.UserCredential();
+    ctor public Credential.UserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
+    method public int describeContents();
+    method public boolean getAbleToShare();
+    method public int getEapType();
+    method public boolean getMachineManaged();
+    method public java.lang.String getNonEapInnerMethod();
+    method public java.lang.String getPassword();
+    method public java.lang.String getSoftTokenApp();
+    method public java.lang.String getUsername();
+    method public void setAbleToShare(boolean);
+    method public void setEapType(int);
+    method public void setMachineManaged(boolean);
+    method public void setNonEapInnerMethod(java.lang.String);
+    method public void setPassword(java.lang.String);
+    method public void setSoftTokenApp(java.lang.String);
+    method public void setUsername(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
+  }
+
+  public final class HomeSp implements android.os.Parcelable {
+    ctor public HomeSp();
+    ctor public HomeSp(android.net.wifi.hotspot2.pps.HomeSp);
+    method public int describeContents();
+    method public java.lang.String getFqdn();
+    method public java.lang.String getFriendlyName();
+    method public java.util.Map<java.lang.String, java.lang.Long> getHomeNetworkIds();
+    method public java.lang.String getIconUrl();
+    method public long[] getMatchAllOis();
+    method public long[] getMatchAnysOis();
+    method public java.lang.String[] getOtherHomePartners();
+    method public long[] getRoamingConsortiumOis();
+    method public void setFqdn(java.lang.String);
+    method public void setFriendlyName(java.lang.String);
+    method public void setHomeNetworkIds(java.util.Map<java.lang.String, java.lang.Long>);
+    method public void setIconUrl(java.lang.String);
+    method public void setMatchAllOis(long[]);
+    method public void setMatchAnyOis(long[]);
+    method public void setOtherHomePartners(java.lang.String[]);
+    method public void setRoamingConsortiumOis(long[]);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
+  }
+
+  public final class Policy implements android.os.Parcelable {
+    ctor public Policy();
+    ctor public Policy(android.net.wifi.hotspot2.pps.Policy);
+    method public int describeContents();
+    method public java.lang.String[] getExcludedSsidList();
+    method public int getMaximumBssLoadValue();
+    method public long getMinHomeDownlinkBandWidht();
+    method public long getMinHomeUplinkBandwidth();
+    method public long getMinRoamingDownlinkBandwidth();
+    method public long getMinRoamingUplinkBandwidth();
+    method public android.net.wifi.hotspot2.pps.UpdateParameter getPolicyUpdate();
+    method public java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> getPreferredRoamingPartnerList();
+    method public java.util.Map<java.lang.Integer, java.lang.String> getRequiredProtoPortMap();
+    method public void setExcludedSsidList(java.lang.String[]);
+    method public void setMaximumBssLoadValue(int);
+    method public void setMinHomeDownlinkBandwidth(long);
+    method public void setMinHomeUplinkBandwidth(long);
+    method public void setMinRoamingDownlinkBandwidth(long);
+    method public void setMinRoamingUplinkBandwidth(long);
+    method public void setPolicyUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
+    method public void setPreferredRoamingPartnerList(java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner>);
+    method public void setRequiredProtoPortMap(java.util.Map<java.lang.Integer, java.lang.String>);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy> CREATOR;
+  }
+
+  public static final class Policy.RoamingPartner implements android.os.Parcelable {
+    ctor public Policy.RoamingPartner();
+    ctor public Policy.RoamingPartner(android.net.wifi.hotspot2.pps.Policy.RoamingPartner);
+    method public int describeContents();
+    method public java.lang.String getCountries();
+    method public java.lang.String getFqdn();
+    method public boolean getFqdnExactMatch();
+    method public int getPriority();
+    method public void setCountries(java.lang.String);
+    method public void setFqdn(java.lang.String);
+    method public void setFqdnExactMatch(boolean);
+    method public void setPriority(int);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> CREATOR;
+  }
+
+  public final class UpdateParameter implements android.os.Parcelable {
+    ctor public UpdateParameter();
+    ctor public UpdateParameter(android.net.wifi.hotspot2.pps.UpdateParameter);
+    method public int describeContents();
+    method public java.lang.String getBase64EncodedPassword();
+    method public java.lang.String getRestriction();
+    method public java.lang.String getServerUri();
+    method public byte[] getTrustRootCertSha256Fingerprint();
+    method public java.lang.String getTrustRootCertUrl();
+    method public long getUpdateIntervalInMinutes();
+    method public java.lang.String getUpdateMethod();
+    method public java.lang.String getUsername();
+    method public void setBase64EncodedPassword(java.lang.String);
+    method public void setRestriction(java.lang.String);
+    method public void setServerUri(java.lang.String);
+    method public void setTrustRootCertSha256Fingerprint(byte[]);
+    method public void setTrustRootCertUrl(java.lang.String);
+    method public void setUpdateIntervalInMinutes(long);
+    method public void setUpdateMethod(java.lang.String);
+    method public void setUsername(java.lang.String);
+    method public boolean validate();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.UpdateParameter> CREATOR;
+    field public static final long UPDATE_CHECK_INTERVAL_NEVER = 4294967295L; // 0xffffffffL
+    field public static final java.lang.String UPDATE_METHOD_OMADM = "OMA-DM-ClientInitiated";
+    field public static final java.lang.String UPDATE_METHOD_SSP = "SSP-ClientInitiated";
+    field public static final java.lang.String UPDATE_RESTRICTION_HOMESP = "HomeSP";
+    field public static final java.lang.String UPDATE_RESTRICTION_ROAMING_PARTNER = "RoamingPartner";
+    field public static final java.lang.String UPDATE_RESTRICTION_UNRESTRICTED = "Unrestricted";
+  }
+
+}
+
 package android.net.wifi.p2p {
 
   public class WifiP2pConfig implements android.os.Parcelable {
@@ -35989,26 +36328,19 @@
     ctor public AutoFillService();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public void onConnected();
-    method public void onDatasetAuthenticationRequest(android.os.Bundle, int);
     method public void onDisconnected();
     method public abstract void onFillRequest(android.app.assist.AssistStructure, android.os.Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback);
-    method public void onFillResponseAuthenticationRequest(android.os.Bundle, int);
     method public abstract void onSaveRequest(android.app.assist.AssistStructure, android.os.Bundle, android.service.autofill.SaveCallback);
-    field public static final java.lang.String EXTRA_DATASET_EXTRAS = "android.service.autofill.extra.DATASET_EXTRAS";
-    field public static final java.lang.String EXTRA_RESPONSE_EXTRAS = "android.service.autofill.extra.RESPONSE_EXTRAS";
-    field public static final int FLAG_AUTHENTICATION_ERROR = 4; // 0x4
-    field public static final int FLAG_AUTHENTICATION_REQUESTED = 1; // 0x1
-    field public static final int FLAG_AUTHENTICATION_SUCCESS = 2; // 0x2
-    field public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE = 8; // 0x8
     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";
   }
 
-  public final class FillCallback {
-    method public void onDatasetAuthentication(android.view.autofill.Dataset, int);
+  public final class FillCallback implements android.os.Parcelable {
+    method public int describeContents();
     method public void onFailure(java.lang.CharSequence);
-    method public void onFillResponseAuthentication(int);
     method public void onSuccess(android.view.autofill.FillResponse);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.autofill.FillCallback> CREATOR;
   }
 
   public final class SaveCallback {
@@ -41849,6 +42181,15 @@
     method public android.transition.TransitionManager inflateTransitionManager(int, android.view.ViewGroup);
   }
 
+  public abstract class TransitionListenerAdapter implements android.transition.Transition.TransitionListener {
+    ctor public TransitionListenerAdapter();
+    method public void onTransitionCancel(android.transition.Transition);
+    method public void onTransitionEnd(android.transition.Transition);
+    method public void onTransitionPause(android.transition.Transition);
+    method public void onTransitionResume(android.transition.Transition);
+    method public void onTransitionStart(android.transition.Transition);
+  }
+
   public class TransitionManager {
     ctor public TransitionManager();
     method public static void beginDelayedTransition(android.view.ViewGroup);
@@ -44414,8 +44755,8 @@
     method public void drawableHotspotChanged(float, float);
     method protected void drawableStateChanged();
     method public android.view.View findFocus();
-    method public final <T extends android.view.View> T findViewById(int);
-    method public final <T extends android.view.View> T findViewWithTag(java.lang.Object);
+    method public final android.view.View findViewById(int);
+    method public final android.view.View findViewWithTag(java.lang.Object);
     method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
     method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
     method public android.view.View focusSearch(int);
@@ -45995,6 +46336,7 @@
     field public static final int TYPE_APPLICATION = 2; // 0x2
     field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb
     field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9
+    field public static final int TYPE_APPLICATION_OVERLAY = 2038; // 0x7f6
     field public static final int TYPE_APPLICATION_PANEL = 1000; // 0x3e8
     field public static final int TYPE_APPLICATION_STARTING = 3; // 0x3
     field public static final int TYPE_APPLICATION_SUB_PANEL = 1002; // 0x3ea
@@ -46004,17 +46346,17 @@
     field public static final int TYPE_INPUT_METHOD = 2011; // 0x7db
     field public static final int TYPE_INPUT_METHOD_DIALOG = 2012; // 0x7dc
     field public static final int TYPE_KEYGUARD_DIALOG = 2009; // 0x7d9
-    field public static final int TYPE_PHONE = 2002; // 0x7d2
-    field public static final int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
+    field public static final deprecated int TYPE_PHONE = 2002; // 0x7d2
+    field public static final deprecated int TYPE_PRIORITY_PHONE = 2007; // 0x7d7
     field public static final int TYPE_PRIVATE_PRESENTATION = 2030; // 0x7ee
     field public static final int TYPE_SEARCH_BAR = 2001; // 0x7d1
     field public static final int TYPE_STATUS_BAR = 2000; // 0x7d0
     field public static final int TYPE_STATUS_BAR_PANEL = 2014; // 0x7de
-    field public static final int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
+    field public static final deprecated int TYPE_SYSTEM_ALERT = 2003; // 0x7d3
     field public static final int TYPE_SYSTEM_DIALOG = 2008; // 0x7d8
-    field public static final int TYPE_SYSTEM_ERROR = 2010; // 0x7da
-    field public static final int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
-    field public static final int TYPE_TOAST = 2005; // 0x7d5
+    field public static final deprecated int TYPE_SYSTEM_ERROR = 2010; // 0x7da
+    field public static final deprecated int TYPE_SYSTEM_OVERLAY = 2006; // 0x7d6
+    field public static final deprecated int TYPE_TOAST = 2005; // 0x7d5
     field public static final int TYPE_WALLPAPER = 2013; // 0x7dd
     field public float alpha;
     field public float buttonBrightness;
@@ -46825,10 +47167,9 @@
   }
 
   public static final class Dataset.Builder {
-    ctor public Dataset.Builder(java.lang.CharSequence);
+    ctor public Dataset.Builder(java.lang.String, java.lang.CharSequence);
     method public android.view.autofill.Dataset build();
-    method public android.view.autofill.Dataset.Builder requiresCustomAuthentication(android.os.Bundle, int);
-    method public android.view.autofill.Dataset.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+    method public android.view.autofill.Dataset.Builder setAuthentication(android.content.IntentSender);
     method public android.view.autofill.Dataset.Builder setExtras(android.os.Bundle);
     method public android.view.autofill.Dataset.Builder setValue(android.view.autofill.AutoFillId, android.view.autofill.AutoFillValue);
   }
@@ -46840,12 +47181,11 @@
   }
 
   public static final class FillResponse.Builder {
-    ctor public FillResponse.Builder();
+    ctor public FillResponse.Builder(java.lang.String);
     method public android.view.autofill.FillResponse.Builder addDataset(android.view.autofill.Dataset);
     method public android.view.autofill.FillResponse.Builder addSavableFields(android.view.autofill.AutoFillId...);
     method public android.view.autofill.FillResponse build();
-    method public android.view.autofill.FillResponse.Builder requiresCustomAuthentication(android.os.Bundle, int);
-    method public android.view.autofill.FillResponse.Builder requiresFingerprintAuthentication(android.hardware.fingerprint.FingerprintManager.CryptoObject, android.os.Bundle, int);
+    method public android.view.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender);
     method public android.view.autofill.FillResponse.Builder setExtras(android.os.Bundle);
   }
 
@@ -47271,7 +47611,7 @@
 
   public final class TextClassificationManager {
     method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
-    method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+    method public synchronized android.view.textclassifier.TextClassifier getDefaultTextClassifier();
   }
 
   public final class TextClassificationResult {
@@ -50614,6 +50954,7 @@
     method public void setIs24HourView(java.lang.Boolean);
     method public void setMinute(int);
     method public void setOnTimeChangedListener(android.widget.TimePicker.OnTimeChangedListener);
+    method public boolean validateInput();
     field public static final int MODE_CLOCK = 2; // 0x2
     field public static final int MODE_SPINNER = 1; // 0x1
   }
@@ -51015,6 +51356,8 @@
     field public static final int OP_INVOKE_INTERFACE = 114; // 0x72
     field public static final int OP_INVOKE_INTERFACE_JUMBO = 9983; // 0x26ff
     field public static final int OP_INVOKE_INTERFACE_RANGE = 120; // 0x78
+    field public static final int OP_INVOKE_POLYMORPHIC = 250; // 0xfa
+    field public static final int OP_INVOKE_POLYMORPHIC_RANGE = 251; // 0xfb
     field public static final int OP_INVOKE_STATIC = 113; // 0x71
     field public static final int OP_INVOKE_STATIC_JUMBO = 9727; // 0x25ff
     field public static final int OP_INVOKE_STATIC_RANGE = 119; // 0x77
@@ -54309,12 +54652,15 @@
   }
 
   public abstract class MethodHandle {
+    method public java.lang.invoke.MethodHandle asCollector(java.lang.Class<?>, int);
     method public java.lang.invoke.MethodHandle asFixedArity();
+    method public java.lang.invoke.MethodHandle asSpreader(java.lang.Class<?>, int);
     method public java.lang.invoke.MethodHandle asType(java.lang.invoke.MethodType);
     method public java.lang.invoke.MethodHandle asVarargsCollector(java.lang.Class<?>);
     method public java.lang.invoke.MethodHandle bindTo(java.lang.Object);
     method public final java.lang.Object invoke(java.lang.Object...) throws java.lang.Throwable;
     method public final java.lang.Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
+    method public java.lang.Object invokeWithArguments(java.lang.Object...) throws java.lang.Throwable;
     method public java.lang.Object invokeWithArguments(java.util.List<?>) throws java.lang.Throwable;
     method public boolean isVarargsCollector();
     method public java.lang.invoke.MethodType type();
@@ -54348,17 +54694,23 @@
     method public static java.lang.invoke.MethodHandle arrayElementGetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
     method public static java.lang.invoke.MethodHandle arrayElementSetter(java.lang.Class<?>) throws java.lang.IllegalArgumentException;
     method public static java.lang.invoke.MethodHandle catchException(java.lang.invoke.MethodHandle, java.lang.Class<? extends java.lang.Throwable>, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle collectArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle constant(java.lang.Class<?>, java.lang.Object);
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
     method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.lang.Class<?>...);
     method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+    method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
     method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle guardWithTest(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
     method public static java.lang.invoke.MethodHandle identity(java.lang.Class<?>);
+    method public static java.lang.invoke.MethodHandle insertArguments(java.lang.invoke.MethodHandle, int, java.lang.Object...);
     method public static java.lang.invoke.MethodHandle invoker(java.lang.invoke.MethodType);
     method public static java.lang.invoke.MethodHandles.Lookup lookup();
     method public static java.lang.invoke.MethodHandle permuteArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, int...);
     method public static java.lang.invoke.MethodHandles.Lookup publicLookup();
+    method public static <T extends java.lang.reflect.Member> T reflectAs(java.lang.Class<T>, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle spreadInvoker(java.lang.invoke.MethodType, int);
     method public static java.lang.invoke.MethodHandle throwException(java.lang.Class<?>, java.lang.Class<? extends java.lang.Throwable>);
   }
 
@@ -54375,6 +54727,7 @@
     method public java.lang.invoke.MethodHandles.Lookup in(java.lang.Class<?>);
     method public java.lang.Class<?> lookupClass();
     method public int lookupModes();
+    method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
     method public void throwMakeAccessException(java.lang.String, java.lang.Object) throws java.lang.IllegalAccessException;
     method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
     method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index c773275..7901737 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "BootAnimation"
 
 #include <stdint.h>
+#include <inttypes.h>
 #include <sys/inotify.h>
 #include <sys/poll.h>
 #include <sys/stat.h>
@@ -35,6 +36,7 @@
 #include <utils/Atomic.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
+#include <utils/SystemClock.h>
 
 #include <ui/PixelFormat.h>
 #include <ui/Rect.h>
@@ -350,6 +352,7 @@
 
 bool BootAnimation::android()
 {
+    ALOGD("BootAnimationShownTiming: BootAnimation start time: %" PRId64 "ms", elapsedRealtime());
     initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
     initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
 
@@ -854,8 +857,8 @@
         mTimeCheckThread = nullptr;
     }
 
+    // We should have joined mInitAudioThread thread in playAnimation
     if (mInitAudioThread != nullptr) {
-        mInitAudioThread->requestExit();
         mInitAudioThread = nullptr;
     }
 
@@ -875,6 +878,7 @@
     const int animationX = (mWidth - animation.width) / 2;
     const int animationY = (mHeight - animation.height) / 2;
 
+    ALOGD("BootAnimationShownTiming: BootAnimation start time: %" PRId64 "ms", elapsedRealtime());
     for (size_t i=0 ; i<pcount ; i++) {
         const Animation::Part& part(animation.parts[i]);
         const size_t fcount = part.frames.size();
diff --git a/compiled-classes-phone b/compiled-classes-phone
index e4ffaa3..ea8f4a4 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -1,5 +1,5 @@
 #
-# Copyright (C) 2016 The Android Open Source Project
+# Copyright (C) 2017 The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -31,7 +31,6 @@
 android.R$styleable
 android.accessibilityservice.AccessibilityServiceInfo
 android.accessibilityservice.AccessibilityServiceInfo$1
-android.accessibilityservice.AccessibilityServiceInfo$CapabilityInfo
 android.accessibilityservice.IAccessibilityServiceClient
 android.accessibilityservice.IAccessibilityServiceConnection
 android.accessibilityservice.IAccessibilityServiceConnection$Stub
@@ -58,6 +57,8 @@
 android.accounts.AccountManager$Future2Task$1
 android.accounts.AccountManagerCallback
 android.accounts.AccountManagerFuture
+android.accounts.AccountManagerInternal
+android.accounts.AccountManagerInternal$OnAppPermissionChangeListener
 android.accounts.AccountsException
 android.accounts.AuthenticatorDescription
 android.accounts.AuthenticatorDescription$1
@@ -78,7 +79,6 @@
 android.accounts.OperationCanceledException
 android.animation.AnimationHandler
 android.animation.AnimationHandler$1
-android.animation.AnimationHandler$2
 android.animation.AnimationHandler$AnimationFrameCallback
 android.animation.AnimationHandler$AnimationFrameCallbackProvider
 android.animation.AnimationHandler$MyFrameCallbackProvider
@@ -90,9 +90,13 @@
 android.animation.AnimatorInflater$PathDataEvaluator
 android.animation.AnimatorListenerAdapter
 android.animation.AnimatorSet
-android.animation.AnimatorSet$AnimatorSetListener
+android.animation.AnimatorSet$1
+android.animation.AnimatorSet$2
+android.animation.AnimatorSet$3
+android.animation.AnimatorSet$AnimationEvent
 android.animation.AnimatorSet$Builder
 android.animation.AnimatorSet$Node
+android.animation.AnimatorSet$SeekState
 android.animation.ArgbEvaluator
 android.animation.FloatArrayEvaluator
 android.animation.FloatEvaluator
@@ -119,14 +123,15 @@
 android.animation.PathKeyframes
 android.animation.PathKeyframes$1
 android.animation.PathKeyframes$2
-android.animation.PathKeyframes$3
-android.animation.PathKeyframes$4
 android.animation.PathKeyframes$FloatKeyframesBase
 android.animation.PathKeyframes$IntKeyframesBase
 android.animation.PathKeyframes$SimpleKeyframes
 android.animation.PropertyValuesHolder
+android.animation.PropertyValuesHolder$1
 android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
 android.animation.PropertyValuesHolder$IntPropertyValuesHolder
+android.animation.PropertyValuesHolder$PropertyValues
+android.animation.PropertyValuesHolder$PropertyValues$DataSource
 android.animation.RectEvaluator
 android.animation.RevealAnimator
 android.animation.StateListAnimator
@@ -139,22 +144,25 @@
 android.animation.TypeEvaluator
 android.animation.ValueAnimator
 android.animation.ValueAnimator$AnimatorUpdateListener
-android.annotation.TargetApi
+android.app.-$Lambda$36$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$39$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$57$vZ1qb742P9hE4drBY-TrOZB_qKo
+android.app.-$Lambda$7$u_rp3dnwvfyMTggc6hVftcuYJ3E
+android.app.-$Lambda$71$3eJ3p8XnIxdVOnT82Ns3R0V5ZQE
+android.app.-$Lambda$76$3eJ3p8XnIxdVOnT82Ns3R0V5ZQE
 android.app.ActionBar
 android.app.ActionBar$LayoutParams
 android.app.ActionBar$OnMenuVisibilityListener
-android.app.ActionBar$OnNavigationListener
 android.app.ActionBar$Tab
 android.app.ActionBar$TabListener
 android.app.Activity
 android.app.Activity$HostCallbacks
-android.app.Activity$NonConfigurationInstances
 android.app.ActivityManager
+android.app.ActivityManager$1
 android.app.ActivityManager$AppTask
 android.app.ActivityManager$MemoryInfo
 android.app.ActivityManager$MemoryInfo$1
-android.app.ActivityManager$ProcessErrorStateInfo
-android.app.ActivityManager$ProcessErrorStateInfo$1
+android.app.ActivityManager$OnUidImportanceListener
 android.app.ActivityManager$RecentTaskInfo
 android.app.ActivityManager$RecentTaskInfo$1
 android.app.ActivityManager$RunningAppProcessInfo
@@ -168,10 +176,12 @@
 android.app.ActivityManager$StackInfo$1
 android.app.ActivityManager$TaskDescription
 android.app.ActivityManager$TaskDescription$1
+android.app.ActivityManager$TaskSnapshot
+android.app.ActivityManager$TaskSnapshot$1
 android.app.ActivityManager$TaskThumbnail
-android.app.ActivityManager$TaskThumbnail$1
 android.app.ActivityManager$TaskThumbnailInfo
 android.app.ActivityManager$TaskThumbnailInfo$1
+android.app.ActivityManager$UidObserver
 android.app.ActivityManagerInternal
 android.app.ActivityManagerInternal$SleepToken
 android.app.ActivityOptions
@@ -189,6 +199,7 @@
 android.app.ActivityThread$ContextCleanupInfo
 android.app.ActivityThread$CreateServiceData
 android.app.ActivityThread$DropBoxReporter
+android.app.ActivityThread$DumpComponentInfo
 android.app.ActivityThread$EventLoggingReporter
 android.app.ActivityThread$GcIdler
 android.app.ActivityThread$H
@@ -199,18 +210,13 @@
 android.app.ActivityThread$ProviderKey
 android.app.ActivityThread$ProviderRefCount
 android.app.ActivityThread$ReceiverData
+android.app.ActivityThread$RequestAssistContextExtras
 android.app.ActivityThread$ResultData
 android.app.ActivityThread$ServiceArgsData
 android.app.ActivityThread$StopInfo
-android.app.ActivityTransitionCoordinator
-android.app.ActivityTransitionCoordinator$1
-android.app.ActivityTransitionCoordinator$2
-android.app.ActivityTransitionCoordinator$ContinueTransitionListener
-android.app.ActivityTransitionCoordinator$FixedEpicenterCallback
-android.app.ActivityTransitionCoordinator$SharedElementOriginalState
 android.app.ActivityTransitionState
+android.app.AlarmManager
 android.app.AlarmManager$AlarmClockInfo
-android.app.AlarmManager$AlarmClockInfo$1
 android.app.AlarmManager$ListenerWrapper
 android.app.AlarmManager$OnAlarmListener
 android.app.AlertDialog
@@ -227,71 +233,59 @@
 android.app.Application
 android.app.Application$ActivityLifecycleCallbacks
 android.app.ApplicationErrorReport
-android.app.ApplicationErrorReport$1
 android.app.ApplicationErrorReport$CrashInfo
+android.app.ApplicationErrorReport$ParcelableCrashInfo
 android.app.ApplicationLoaders
 android.app.ApplicationPackageManager
 android.app.ApplicationPackageManager$MoveCallbackDelegate
 android.app.ApplicationPackageManager$OnPermissionsChangeListenerDelegate
 android.app.ApplicationPackageManager$ResourceName
-android.app.ApplicationThreadProxy
 android.app.AutomaticZenRule
 android.app.BackStackRecord
 android.app.BackStackRecord$Op
-android.app.BackStackRecord$TransitionState
-android.app.BackStackState
-android.app.BackStackState$1
 android.app.BroadcastOptions
 android.app.ContentProviderHolder
 android.app.ContentProviderHolder$1
 android.app.ContextImpl
-android.app.ContextImpl$1
 android.app.ContextImpl$ApplicationContentResolver
 android.app.DatePickerDialog
 android.app.DatePickerDialog$OnDateSetListener
 android.app.Dialog
-android.app.Dialog$-void__init__android_content_Context_context_int_themeResId_boolean_createContextThemeWrapper_LambdaImpl0
 android.app.Dialog$ListenersHandler
 android.app.DialogFragment
 android.app.DownloadManager
 android.app.DownloadManager$CursorTranslator
 android.app.DownloadManager$Query
 android.app.DownloadManager$Request
-android.app.EnterTransitionCoordinator
-android.app.EnterTransitionCoordinator$1
-android.app.EnterTransitionCoordinator$4
-android.app.EnterTransitionCoordinator$5
-android.app.EnterTransitionCoordinator$5$1
-android.app.EnterTransitionCoordinator$5$1$1
-android.app.EnterTransitionCoordinator$6
-android.app.EnterTransitionCoordinator$7
-android.app.EnterTransitionCoordinator$8
-android.app.ExitTransitionCoordinator
-android.app.ExitTransitionCoordinator$10
-android.app.ExitTransitionCoordinator$11
-android.app.ExitTransitionCoordinator$4
 android.app.Fragment
 android.app.Fragment$1
+android.app.Fragment$AnimationInfo
+android.app.Fragment$OnStartEnterTransitionListener
 android.app.Fragment$SavedState
-android.app.FragmentBreadCrumbs
 android.app.FragmentContainer
 android.app.FragmentController
 android.app.FragmentHostCallback
 android.app.FragmentManager
 android.app.FragmentManager$BackStackEntry
+android.app.FragmentManager$FragmentLifecycleCallbacks
 android.app.FragmentManager$OnBackStackChangedListener
 android.app.FragmentManagerImpl
 android.app.FragmentManagerImpl$1
 android.app.FragmentManagerImpl$2
-android.app.FragmentManagerImpl$3
-android.app.FragmentManagerImpl$4
-android.app.FragmentManagerImpl$5
 android.app.FragmentManagerImpl$AnimateOnHWLayerIfNeededListener
+android.app.FragmentManagerImpl$OpGenerator
+android.app.FragmentManagerImpl$PopBackStackState
+android.app.FragmentManagerImpl$StartEnterTransitionListener
 android.app.FragmentManagerState
 android.app.FragmentManagerState$1
 android.app.FragmentState
 android.app.FragmentState$1
 android.app.FragmentTransaction
+android.app.FragmentTransition
+android.app.FragmentTransition$3
+android.app.FragmentTransition$4
+android.app.FragmentTransition$5
+android.app.FragmentTransition$FragmentContainerTransition
 android.app.IActivityContainer
 android.app.IActivityContainer$Stub
 android.app.IActivityContainerCallback
@@ -356,12 +350,11 @@
 android.app.JobSchedulerImpl
 android.app.KeyguardManager
 android.app.ListActivity
-android.app.ListActivity$1
-android.app.ListActivity$2
 android.app.ListFragment
 android.app.ListFragment$1
 android.app.ListFragment$2
 android.app.LoadedApk
+android.app.LoadedApk$DexLoadReporter
 android.app.LoadedApk$ReceiverDispatcher
 android.app.LoadedApk$ReceiverDispatcher$Args
 android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
@@ -391,26 +384,34 @@
 android.app.Notification$InboxStyle
 android.app.Notification$MediaStyle
 android.app.Notification$MessagingStyle
+android.app.Notification$MessagingStyle$Message
+android.app.Notification$StandardTemplateParams
 android.app.Notification$Style
 android.app.Notification$WearableExtender
+android.app.NotificationChannel
+android.app.NotificationChannel$1
 android.app.NotificationManager
 android.app.NotificationManager$Policy
 android.app.NotificationManager$Policy$1
 android.app.OnActivityPausedListener
-android.app.PackageDeleteObserver
-android.app.PackageDeleteObserver$1
-android.app.PackageInstallObserver
-android.app.PackageInstallObserver$1
 android.app.PendingIntent
 android.app.PendingIntent$1
 android.app.PendingIntent$CanceledException
 android.app.PendingIntent$FinishedDispatcher
 android.app.PendingIntent$OnFinished
+android.app.PendingIntent$OnMarshaledListener
+android.app.PictureInPictureArgs
+android.app.PictureInPictureArgs$1
 android.app.Presentation
 android.app.ProfilerInfo
 android.app.ProgressDialog
 android.app.QueuedWork
+android.app.QueuedWork$QueuedWorkHandler
 android.app.ReceiverRestrictedContext
+android.app.RemoteAction
+android.app.RemoteAction$1
+android.app.RemoteAction$2
+android.app.RemoteAction$OnActionListener
 android.app.RemoteInput
 android.app.RemoteInput$1
 android.app.RemoteInput$Builder
@@ -419,13 +420,14 @@
 android.app.ResourcesManager$ActivityResources
 android.app.ResultInfo
 android.app.ResultInfo$1
+android.app.RetailDemoModeServiceInternal
+android.app.SearchManager
 android.app.SearchableInfo
 android.app.SearchableInfo$1
 android.app.Service
 android.app.ServiceConnectionLeaked
 android.app.SharedElementCallback
 android.app.SharedElementCallback$1
-android.app.SharedElementCallback$OnSharedElementsReadyListener
 android.app.SharedPreferencesImpl
 android.app.SharedPreferencesImpl$1
 android.app.SharedPreferencesImpl$2
@@ -509,6 +511,11 @@
 android.app.SystemServiceRegistry$72
 android.app.SystemServiceRegistry$73
 android.app.SystemServiceRegistry$74
+android.app.SystemServiceRegistry$75
+android.app.SystemServiceRegistry$76
+android.app.SystemServiceRegistry$77
+android.app.SystemServiceRegistry$78
+android.app.SystemServiceRegistry$79
 android.app.SystemServiceRegistry$8
 android.app.SystemServiceRegistry$9
 android.app.SystemServiceRegistry$CachedServiceFetcher
@@ -516,29 +523,43 @@
 android.app.SystemServiceRegistry$StaticApplicationContextServiceFetcher
 android.app.SystemServiceRegistry$StaticServiceFetcher
 android.app.TaskStackBuilder
-android.app.TimePickerDialog
+android.app.TaskStackListener
 android.app.TimePickerDialog$OnTimeSetListener
 android.app.UiModeManager
-android.app.WaitResult;
+android.app.UserSwitchObserver
+android.app.VoiceInteractor$PickOptionRequest$Option
+android.app.WaitResult
 android.app.WallpaperInfo
+android.app.WallpaperInfo$1
 android.app.WallpaperManager
 android.app.WallpaperManager$Globals
-android.app.admin.DeviceAdminInfo
-android.app.admin.DeviceAdminInfo$1
-android.app.admin.DeviceAdminInfo$PolicyInfo
 android.app.admin.DevicePolicyManager
 android.app.admin.DevicePolicyManagerInternal
 android.app.admin.DevicePolicyManagerInternal$OnCrossProfileWidgetProvidersChangeListener
 android.app.admin.IDevicePolicyManager
 android.app.admin.IDevicePolicyManager$Stub
 android.app.admin.IDevicePolicyManager$Stub$Proxy
+android.app.admin.PasswordMetrics
+android.app.admin.PasswordMetrics$1
 android.app.admin.SecurityLog
 android.app.admin.SecurityLog$SecurityEvent
 android.app.admin.SecurityLog$SecurityEvent$1
+android.app.admin.SystemUpdateInfo
+android.app.admin.SystemUpdateInfo$1
 android.app.admin.SystemUpdatePolicy
 android.app.admin.SystemUpdatePolicy$1
 android.app.assist.AssistContent
+android.app.assist.AssistContent$1
 android.app.assist.AssistStructure
+android.app.assist.AssistStructure$1
+android.app.assist.AssistStructure$ParcelTransferReader
+android.app.assist.AssistStructure$ParcelTransferWriter
+android.app.assist.AssistStructure$SendChannel
+android.app.assist.AssistStructure$ViewNode
+android.app.assist.AssistStructure$ViewNodeBuilder
+android.app.assist.AssistStructure$ViewNodeText
+android.app.assist.AssistStructure$ViewStackEntry
+android.app.assist.AssistStructure$WindowNode
 android.app.backup.BackupAgent
 android.app.backup.BackupAgentHelper
 android.app.backup.BackupDataInput
@@ -559,6 +580,7 @@
 android.app.backup.IBackupObserver
 android.app.backup.IFullBackupRestoreObserver
 android.app.backup.IRestoreSession
+android.app.backup.ISelectBackupTransportCallback
 android.app.backup.RestoreDescription
 android.app.backup.RestoreSet
 android.app.backup.SharedPreferencesBackupHelper
@@ -597,10 +619,15 @@
 android.app.trust.TrustManager$TrustListener
 android.app.usage.ConfigurationStats
 android.app.usage.ConfigurationStats$1
+android.app.usage.ExternalStorageStats
+android.app.usage.IStorageStatsManager
+android.app.usage.IStorageStatsManager$Stub
 android.app.usage.IUsageStatsManager
 android.app.usage.IUsageStatsManager$Stub
 android.app.usage.IUsageStatsManager$Stub$Proxy
 android.app.usage.NetworkStatsManager
+android.app.usage.StorageStats
+android.app.usage.StorageStatsManager
 android.app.usage.TimeSparseArray
 android.app.usage.UsageEvents
 android.app.usage.UsageEvents$1
@@ -626,18 +653,15 @@
 android.bluetooth.BluetoothActivityEnergyInfo$1
 android.bluetooth.BluetoothAdapter
 android.bluetooth.BluetoothAdapter$1
-android.bluetooth.BluetoothAdapter$2
-android.bluetooth.BluetoothAdapter$BluetoothStateChangeCallback
-android.bluetooth.BluetoothAdapter$LeScanCallback
-android.bluetooth.BluetoothAudioConfig
 android.bluetooth.BluetoothClass
 android.bluetooth.BluetoothClass$1
 android.bluetooth.BluetoothCodecConfig
+android.bluetooth.BluetoothCodecConfig$1
 android.bluetooth.BluetoothCodecStatus
+android.bluetooth.BluetoothCodecStatus$1
 android.bluetooth.BluetoothDevice
 android.bluetooth.BluetoothDevice$1
 android.bluetooth.BluetoothDevice$2
-android.bluetooth.BluetoothGattCallbackWrapper
 android.bluetooth.BluetoothGattCharacteristic
 android.bluetooth.BluetoothGattDescriptor
 android.bluetooth.BluetoothGattService
@@ -674,8 +698,6 @@
 android.bluetooth.IBluetoothA2dp
 android.bluetooth.IBluetoothA2dp$Stub
 android.bluetooth.IBluetoothA2dp$Stub$Proxy
-android.bluetooth.IBluetoothA2dpSink
-android.bluetooth.IBluetoothA2dpSink$Stub
 android.bluetooth.IBluetoothCallback
 android.bluetooth.IBluetoothCallback$Stub
 android.bluetooth.IBluetoothCallback$Stub$Proxy
@@ -683,14 +705,10 @@
 android.bluetooth.IBluetoothGatt$Stub
 android.bluetooth.IBluetoothGatt$Stub$Proxy
 android.bluetooth.IBluetoothGattCallback
-android.bluetooth.IBluetoothGattCallback$Stub
-android.bluetooth.IBluetoothGattCallback$Stub$Proxy
 android.bluetooth.IBluetoothGattServerCallback
 android.bluetooth.IBluetoothHeadset
 android.bluetooth.IBluetoothHeadset$Stub
 android.bluetooth.IBluetoothHeadset$Stub$Proxy
-android.bluetooth.IBluetoothHeadsetClient
-android.bluetooth.IBluetoothHeadsetClient$Stub
 android.bluetooth.IBluetoothHeadsetPhone
 android.bluetooth.IBluetoothHeadsetPhone$Stub
 android.bluetooth.IBluetoothHeadsetPhone$Stub$Proxy
@@ -715,8 +733,6 @@
 android.bluetooth.IBluetoothPbap
 android.bluetooth.IBluetoothPbap$Stub
 android.bluetooth.IBluetoothPbap$Stub$Proxy
-android.bluetooth.IBluetoothPbapClient
-android.bluetooth.IBluetoothPbapClient$Stub
 android.bluetooth.IBluetoothProfileServiceConnection
 android.bluetooth.IBluetoothProfileServiceConnection$Stub
 android.bluetooth.IBluetoothProfileServiceConnection$Stub$Proxy
@@ -736,11 +752,15 @@
 android.bluetooth.UidTraffic$1
 android.bluetooth.le.AdvertiseData
 android.bluetooth.le.AdvertiseSettings
-android.bluetooth.le.BluetoothLeAdvertiser
 android.bluetooth.le.BluetoothLeScanner
 android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper
 android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1
+android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$2
 android.bluetooth.le.BluetoothLeUtils
+android.bluetooth.le.IAdvertiserCallback
+android.bluetooth.le.IScannerCallback
+android.bluetooth.le.IScannerCallback$Stub
+android.bluetooth.le.IScannerCallback$Stub$Proxy
 android.bluetooth.le.ScanCallback
 android.bluetooth.le.ScanFilter
 android.bluetooth.le.ScanFilter$1
@@ -826,6 +846,7 @@
 android.content.IIntentSender$Stub$Proxy
 android.content.IOnPrimaryClipChangedListener
 android.content.IOnPrimaryClipChangedListener$Stub
+android.content.IOnPrimaryClipChangedListener$Stub$Proxy
 android.content.IRestrictionsManager
 android.content.IRestrictionsManager$Stub
 android.content.IRestrictionsManager$Stub$Proxy
@@ -841,14 +862,11 @@
 android.content.Intent
 android.content.Intent$1
 android.content.Intent$FilterComparison
-android.content.Intent$ShortcutIconResource
-android.content.Intent$ShortcutIconResource$1
 android.content.IntentFilter
 android.content.IntentFilter$1
 android.content.IntentFilter$AuthorityEntry
 android.content.IntentFilter$MalformedMimeTypeException
 android.content.IntentSender
-android.content.IntentSender$1
 android.content.IntentSender$SendIntentException
 android.content.Loader
 android.content.Loader$ForceLoadContentObserver
@@ -893,11 +911,14 @@
 android.content.UriPermission
 android.content.pm.ActivityInfo
 android.content.pm.ActivityInfo$1
+android.content.pm.ActivityInfo$WindowLayout
 android.content.pm.ApplicationInfo
 android.content.pm.ApplicationInfo$1
 android.content.pm.ComponentInfo
 android.content.pm.ConfigurationInfo
 android.content.pm.ConfigurationInfo$1
+android.content.pm.EphemeralResponse
+android.content.pm.FallbackCategoryProvider
 android.content.pm.FeatureGroupInfo
 android.content.pm.FeatureGroupInfo$1
 android.content.pm.FeatureInfo
@@ -914,16 +935,9 @@
 android.content.pm.IOtaDexopt
 android.content.pm.IOtaDexopt$Stub
 android.content.pm.IPackageDataObserver
-android.content.pm.IPackageDataObserver$Stub
-android.content.pm.IPackageDataObserver$Stub$Proxy
 android.content.pm.IPackageDeleteObserver
-android.content.pm.IPackageDeleteObserver$Stub
 android.content.pm.IPackageDeleteObserver2
-android.content.pm.IPackageDeleteObserver2$Stub
-android.content.pm.IPackageInstallObserver
-android.content.pm.IPackageInstallObserver$Stub
 android.content.pm.IPackageInstallObserver2
-android.content.pm.IPackageInstallObserver2$Stub
 android.content.pm.IPackageInstaller
 android.content.pm.IPackageInstaller$Stub
 android.content.pm.IPackageInstaller$Stub$Proxy
@@ -931,8 +945,6 @@
 android.content.pm.IPackageInstallerCallback$Stub
 android.content.pm.IPackageInstallerCallback$Stub$Proxy
 android.content.pm.IPackageInstallerSession
-android.content.pm.IPackageInstallerSession$Stub
-android.content.pm.IPackageInstallerSession$Stub$Proxy
 android.content.pm.IPackageManager
 android.content.pm.IPackageManager$Stub
 android.content.pm.IPackageManager$Stub$Proxy
@@ -944,6 +956,7 @@
 android.content.pm.IPackageStatsObserver$Stub$Proxy
 android.content.pm.IShortcutService
 android.content.pm.IShortcutService$Stub
+android.content.pm.IShortcutService$Stub$Proxy
 android.content.pm.InstrumentationInfo
 android.content.pm.InstrumentationInfo$1
 android.content.pm.IntentFilterVerificationInfo
@@ -956,46 +969,49 @@
 android.content.pm.LauncherApps$Callback
 android.content.pm.LauncherApps$CallbackMessageHandler
 android.content.pm.LauncherApps$CallbackMessageHandler$CallbackInfo
+android.content.pm.LauncherApps$ShortcutQuery
 android.content.pm.PackageCleanItem
-android.content.pm.PackageCleanItem$1
 android.content.pm.PackageInfo
 android.content.pm.PackageInfo$1
 android.content.pm.PackageInfoLite
-android.content.pm.PackageInfoLite$1
 android.content.pm.PackageInstaller
 android.content.pm.PackageInstaller$Session
 android.content.pm.PackageInstaller$SessionCallback
 android.content.pm.PackageInstaller$SessionCallbackDelegate
 android.content.pm.PackageInstaller$SessionInfo
-android.content.pm.PackageInstaller$SessionInfo$1
 android.content.pm.PackageInstaller$SessionParams
-android.content.pm.PackageInstaller$SessionParams$1
 android.content.pm.PackageItemInfo
 android.content.pm.PackageManager
-android.content.pm.PackageManager$LegacyPackageDeleteObserver
 android.content.pm.PackageManager$MoveCallback
 android.content.pm.PackageManager$NameNotFoundException
 android.content.pm.PackageManager$OnPermissionsChangedListener
 android.content.pm.PackageManagerInternal
+android.content.pm.PackageManagerInternal$ExternalSourcesPolicy
 android.content.pm.PackageManagerInternal$PackagesProvider
 android.content.pm.PackageManagerInternal$SyncAdapterPackagesProvider
 android.content.pm.PackageParser
 android.content.pm.PackageParser$Activity
+android.content.pm.PackageParser$Activity$1
 android.content.pm.PackageParser$ActivityIntentInfo
 android.content.pm.PackageParser$ApkLite
 android.content.pm.PackageParser$Component
 android.content.pm.PackageParser$IntentInfo
 android.content.pm.PackageParser$NewPermissionInfo
 android.content.pm.PackageParser$Package
+android.content.pm.PackageParser$Package$1
 android.content.pm.PackageParser$PackageLite
 android.content.pm.PackageParser$PackageParserException
 android.content.pm.PackageParser$ParseComponentArgs
 android.content.pm.PackageParser$ParsePackageItemArgs
 android.content.pm.PackageParser$Permission
+android.content.pm.PackageParser$Permission$1
 android.content.pm.PackageParser$PermissionGroup
+android.content.pm.PackageParser$PermissionGroup$1
 android.content.pm.PackageParser$Provider
+android.content.pm.PackageParser$Provider$1
 android.content.pm.PackageParser$ProviderIntentInfo
 android.content.pm.PackageParser$Service
+android.content.pm.PackageParser$Service$1
 android.content.pm.PackageParser$ServiceIntentInfo
 android.content.pm.PackageParser$SplitNameComparator
 android.content.pm.PackageParser$SplitPermissionInfo
@@ -1024,6 +1040,11 @@
 android.content.pm.ResolveInfo$1
 android.content.pm.ServiceInfo
 android.content.pm.ServiceInfo$1
+android.content.pm.SharedLibraryInfo
+android.content.pm.SharedLibraryInfo$1
+android.content.pm.ShortcutInfo
+android.content.pm.ShortcutInfo$1
+android.content.pm.ShortcutInfo$Builder
 android.content.pm.ShortcutManager
 android.content.pm.ShortcutServiceInternal
 android.content.pm.ShortcutServiceInternal$ShortcutChangeListener
@@ -1033,7 +1054,18 @@
 android.content.pm.UserInfo$1
 android.content.pm.VerifierDeviceIdentity
 android.content.pm.VerifierInfo
+android.content.pm.VersionedPackage
+android.content.pm.VersionedPackage$1
 android.content.pm.XmlSerializerAndParser
+android.content.pm.permission.IRuntimePermissionPresenter
+android.content.pm.permission.IRuntimePermissionPresenter$Stub
+android.content.pm.permission.IRuntimePermissionPresenter$Stub$Proxy
+android.content.pm.permission.RuntimePermissionPresentationInfo
+android.content.pm.permission.RuntimePermissionPresentationInfo$1
+android.content.pm.permission.RuntimePermissionPresenter
+android.content.pm.permission.RuntimePermissionPresenter$OnResultCallback
+android.content.pm.permission.RuntimePermissionPresenter$RemoteService
+android.content.pm.permission.RuntimePermissionPresenter$RemoteService$1
 android.content.res.AssetFileDescriptor
 android.content.res.AssetFileDescriptor$1
 android.content.res.AssetFileDescriptor$AutoCloseInputStream
@@ -1109,6 +1141,7 @@
 android.database.SQLException
 android.database.sqlite.DatabaseObjectNotClosedException
 android.database.sqlite.SQLiteAbortException
+android.database.sqlite.SQLiteAccessPermException
 android.database.sqlite.SQLiteCantOpenDatabaseException
 android.database.sqlite.SQLiteClosable
 android.database.sqlite.SQLiteConnection
@@ -1144,6 +1177,7 @@
 android.database.sqlite.SQLiteProgram
 android.database.sqlite.SQLiteQuery
 android.database.sqlite.SQLiteQueryBuilder
+android.database.sqlite.SQLiteReadOnlyDatabaseException
 android.database.sqlite.SQLiteSession
 android.database.sqlite.SQLiteSession$Transaction
 android.database.sqlite.SQLiteStatement
@@ -1170,6 +1204,7 @@
 android.drm.DrmManagerClient$OnInfoListener
 android.drm.DrmOutputStream
 android.drm.DrmSupportInfo
+android.graphics.BaseCanvas
 android.graphics.Bitmap
 android.graphics.Bitmap$1
 android.graphics.Bitmap$CompressFormat
@@ -1196,23 +1231,20 @@
 android.graphics.DiscretePathEffect
 android.graphics.DrawFilter
 android.graphics.EmbossMaskFilter
-android.graphics.FontConfig
-android.graphics.FontConfig$Alias
-android.graphics.FontConfig$Axis
-android.graphics.FontConfig$Family
-android.graphics.FontConfig$Font
 android.graphics.FontFamily
 android.graphics.FontListParser
+android.graphics.GraphicBuffer
+android.graphics.GraphicBuffer$1
 android.graphics.ImageFormat
 android.graphics.Insets
 android.graphics.Interpolator
 android.graphics.Interpolator$Result
-android.graphics.LayerRasterizer
 android.graphics.LightingColorFilter
 android.graphics.LinearGradient
 android.graphics.MaskFilter
 android.graphics.Matrix
 android.graphics.Matrix$1
+android.graphics.Matrix$NoImagePreloadHolder
 android.graphics.Matrix$ScaleToFit
 android.graphics.Movie
 android.graphics.NinePatch
@@ -1246,7 +1278,6 @@
 android.graphics.PorterDuffColorFilter
 android.graphics.PorterDuffXfermode
 android.graphics.RadialGradient
-android.graphics.Rasterizer
 android.graphics.Rect
 android.graphics.Rect$1
 android.graphics.Rect$UnflattenHelper
@@ -1270,7 +1301,6 @@
 android.graphics.YuvImage
 android.graphics.drawable.Animatable
 android.graphics.drawable.Animatable2
-android.graphics.drawable.Animatable2$AnimationCallback
 android.graphics.drawable.AnimatedRotateDrawable
 android.graphics.drawable.AnimatedRotateDrawable$1
 android.graphics.drawable.AnimatedRotateDrawable$AnimatedRotateState
@@ -1282,7 +1312,6 @@
 android.graphics.drawable.AnimatedStateListDrawable$Transition
 android.graphics.drawable.AnimatedVectorDrawable
 android.graphics.drawable.AnimatedVectorDrawable$1
-android.graphics.drawable.AnimatedVectorDrawable$2
 android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState
 android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator
 android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimator
@@ -1301,6 +1330,7 @@
 android.graphics.drawable.Drawable$ConstantState
 android.graphics.drawable.DrawableContainer
 android.graphics.drawable.DrawableContainer$1
+android.graphics.drawable.DrawableContainer$BlockInvalidateCallback
 android.graphics.drawable.DrawableContainer$DrawableContainerState
 android.graphics.drawable.DrawableInflater
 android.graphics.drawable.DrawableWrapper
@@ -1349,13 +1379,31 @@
 android.graphics.drawable.VectorDrawable$VClipPath
 android.graphics.drawable.VectorDrawable$VFullPath
 android.graphics.drawable.VectorDrawable$VFullPath$1
+android.graphics.drawable.VectorDrawable$VFullPath$10
+android.graphics.drawable.VectorDrawable$VFullPath$2
+android.graphics.drawable.VectorDrawable$VFullPath$3
+android.graphics.drawable.VectorDrawable$VFullPath$4
+android.graphics.drawable.VectorDrawable$VFullPath$5
+android.graphics.drawable.VectorDrawable$VFullPath$6
+android.graphics.drawable.VectorDrawable$VFullPath$7
+android.graphics.drawable.VectorDrawable$VFullPath$8
+android.graphics.drawable.VectorDrawable$VFullPath$9
 android.graphics.drawable.VectorDrawable$VGroup
 android.graphics.drawable.VectorDrawable$VGroup$1
+android.graphics.drawable.VectorDrawable$VGroup$2
+android.graphics.drawable.VectorDrawable$VGroup$3
+android.graphics.drawable.VectorDrawable$VGroup$4
+android.graphics.drawable.VectorDrawable$VGroup$5
+android.graphics.drawable.VectorDrawable$VGroup$6
+android.graphics.drawable.VectorDrawable$VGroup$7
+android.graphics.drawable.VectorDrawable$VGroup$8
+android.graphics.drawable.VectorDrawable$VGroup$9
 android.graphics.drawable.VectorDrawable$VObject
 android.graphics.drawable.VectorDrawable$VPath
+android.graphics.drawable.VectorDrawable$VPath$1
 android.graphics.drawable.VectorDrawable$VectorDrawableState
+android.graphics.drawable.VectorDrawable$VectorDrawableState$1
 android.graphics.drawable.shapes.OvalShape
-android.graphics.drawable.shapes.PathShape
 android.graphics.drawable.shapes.RectShape
 android.graphics.drawable.shapes.RoundRectShape
 android.graphics.drawable.shapes.Shape
@@ -1363,7 +1411,6 @@
 android.graphics.pdf.PdfEditor
 android.graphics.pdf.PdfRenderer
 android.hardware.Camera
-android.hardware.Camera$Area
 android.hardware.Camera$AutoFocusCallback
 android.hardware.Camera$AutoFocusMoveCallback
 android.hardware.Camera$CameraInfo
@@ -1377,9 +1424,13 @@
 android.hardware.Camera$PreviewCallback
 android.hardware.Camera$ShutterCallback
 android.hardware.Camera$Size
+android.hardware.CameraStatus
+android.hardware.CameraStatus$1
 android.hardware.ConsumerIrManager
 android.hardware.GeomagneticField
 android.hardware.GeomagneticField$LegendreTable
+android.hardware.HardwareBuffer
+android.hardware.HardwareBuffer$1
 android.hardware.ICameraService
 android.hardware.ICameraService$Stub
 android.hardware.ICameraService$Stub$Proxy
@@ -1419,8 +1470,11 @@
 android.hardware.camera2.CameraManager
 android.hardware.camera2.CameraManager$AvailabilityCallback
 android.hardware.camera2.CameraManager$CameraManagerGlobal
+android.hardware.camera2.CameraManager$CameraManagerGlobal$1
+android.hardware.camera2.CameraManager$CameraManagerGlobal$2
 android.hardware.camera2.CameraManager$CameraManagerGlobal$3
 android.hardware.camera2.CameraManager$CameraManagerGlobal$4
+android.hardware.camera2.CameraManager$CameraManagerGlobal$5
 android.hardware.camera2.CameraManager$TorchCallback
 android.hardware.camera2.CameraMetadata
 android.hardware.camera2.CaptureFailure
@@ -1461,6 +1515,7 @@
 android.hardware.camera2.impl.CameraDeviceImpl
 android.hardware.camera2.impl.CameraDeviceImpl$1
 android.hardware.camera2.impl.CameraDeviceImpl$10
+android.hardware.camera2.impl.CameraDeviceImpl$11
 android.hardware.camera2.impl.CameraDeviceImpl$2
 android.hardware.camera2.impl.CameraDeviceImpl$3
 android.hardware.camera2.impl.CameraDeviceImpl$4
@@ -1472,7 +1527,6 @@
 android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$2
 android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$3
 android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$4
-android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$5
 android.hardware.camera2.impl.CameraDeviceImpl$CameraDeviceCallbacks$6
 android.hardware.camera2.impl.CameraDeviceImpl$CaptureCallback
 android.hardware.camera2.impl.CameraDeviceImpl$CaptureCallbackHolder
@@ -1565,7 +1619,6 @@
 android.hardware.camera2.params.StreamConfigurationDuration
 android.hardware.camera2.params.StreamConfigurationMap
 android.hardware.camera2.params.TonemapCurve
-android.hardware.camera2.utils.ArrayUtils
 android.hardware.camera2.utils.HashCodeHelpers
 android.hardware.camera2.utils.SubmitInfo
 android.hardware.camera2.utils.SubmitInfo$1
@@ -1605,21 +1658,11 @@
 android.hardware.fingerprint.FingerprintManager
 android.hardware.fingerprint.FingerprintManager$1
 android.hardware.fingerprint.FingerprintManager$2
-android.hardware.fingerprint.FingerprintManager$2$1
 android.hardware.fingerprint.FingerprintManager$AuthenticationCallback
 android.hardware.fingerprint.FingerprintManager$AuthenticationResult
-android.hardware.fingerprint.FingerprintManager$CryptoObject
-android.hardware.fingerprint.FingerprintManager$EnrollmentCallback
 android.hardware.fingerprint.FingerprintManager$LockoutResetCallback
 android.hardware.fingerprint.FingerprintManager$MyHandler
-android.hardware.fingerprint.FingerprintManager$OnAuthenticationCancelListener
-android.hardware.fingerprint.FingerprintManager$OnEnrollCancelListener
-android.hardware.fingerprint.FingerprintManager$RemovalCallback
-android.hardware.fingerprint.IFingerprintDaemon
-android.hardware.fingerprint.IFingerprintDaemon$Stub
-android.hardware.fingerprint.IFingerprintDaemon$Stub$Proxy
-android.hardware.fingerprint.IFingerprintDaemonCallback
-android.hardware.fingerprint.IFingerprintDaemonCallback$Stub
+android.hardware.fingerprint.IFingerprintClientActiveCallback
 android.hardware.fingerprint.IFingerprintService
 android.hardware.fingerprint.IFingerprintService$Stub
 android.hardware.fingerprint.IFingerprintService$Stub$Proxy
@@ -1628,14 +1671,8 @@
 android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback$Stub$Proxy
 android.hardware.fingerprint.IFingerprintServiceReceiver
 android.hardware.fingerprint.IFingerprintServiceReceiver$Stub
-android.hardware.fingerprint.IFingerprintServiceReceiver$Stub$Proxy
-android.hardware.hdmi.HdmiClient
 android.hardware.hdmi.HdmiControlManager
-android.hardware.hdmi.HdmiPlaybackClient
 android.hardware.hdmi.HdmiPlaybackClient$DisplayStatusCallback
-android.hardware.hdmi.HdmiTvClient
-android.hardware.hdmi.IHdmiControlService
-android.hardware.hdmi.IHdmiControlService$Stub
 android.hardware.input.IInputDevicesChangedListener
 android.hardware.input.IInputDevicesChangedListener$Stub
 android.hardware.input.IInputDevicesChangedListener$Stub$Proxy
@@ -1655,13 +1692,15 @@
 android.hardware.input.KeyboardLayout$1
 android.hardware.input.TouchCalibration
 android.hardware.input.TouchCalibration$1
-android.hardware.location.ActivityChangedEvent
 android.hardware.location.ActivityRecognitionHardware
-android.hardware.location.ActivityRecognitionHardware$SinkList
 android.hardware.location.ContextHubInfo
 android.hardware.location.ContextHubInfo$1
 android.hardware.location.ContextHubManager
-android.hardware.location.ContextHubService
+android.hardware.location.ContextHubManager$1
+android.hardware.location.ContextHubManager$Callback
+android.hardware.location.ContextHubManager$ICallback
+android.hardware.location.ContextHubMessage
+android.hardware.location.ContextHubMessage$1
 android.hardware.location.GeofenceHardware
 android.hardware.location.GeofenceHardware$GeofenceHardwareMonitorCallbackWrapper
 android.hardware.location.GeofenceHardwareCallback
@@ -1671,27 +1710,21 @@
 android.hardware.location.GeofenceHardwareImpl$3
 android.hardware.location.GeofenceHardwareImpl$Reaper
 android.hardware.location.GeofenceHardwareMonitorCallback
-android.hardware.location.GeofenceHardwareRequestParcelable
 android.hardware.location.GeofenceHardwareService
 android.hardware.location.GeofenceHardwareService$1
 android.hardware.location.IActivityRecognitionHardware
 android.hardware.location.IActivityRecognitionHardware$Stub
-android.hardware.location.IActivityRecognitionHardware$Stub$Proxy
 android.hardware.location.IActivityRecognitionHardwareClient
 android.hardware.location.IActivityRecognitionHardwareClient$Stub
 android.hardware.location.IActivityRecognitionHardwareClient$Stub$Proxy
-android.hardware.location.IActivityRecognitionHardwareSink
-android.hardware.location.IActivityRecognitionHardwareSink$Stub
-android.hardware.location.IActivityRecognitionHardwareSink$Stub$Proxy
 android.hardware.location.IActivityRecognitionHardwareWatcher
+android.hardware.location.IContextHubCallback
+android.hardware.location.IContextHubCallback$Stub
+android.hardware.location.IContextHubCallback$Stub$Proxy
 android.hardware.location.IContextHubService
 android.hardware.location.IContextHubService$Stub
+android.hardware.location.IContextHubService$Stub$Proxy
 android.hardware.location.IFusedLocationHardware
-android.hardware.location.IFusedLocationHardware$Stub
-android.hardware.location.IFusedLocationHardware$Stub$Proxy
-android.hardware.location.IFusedLocationHardwareSink
-android.hardware.location.IFusedLocationHardwareSink$Stub
-android.hardware.location.IFusedLocationHardwareSink$Stub$Proxy
 android.hardware.location.IGeofenceHardware
 android.hardware.location.IGeofenceHardware$Stub
 android.hardware.location.IGeofenceHardware$Stub$Proxy
@@ -1699,6 +1732,10 @@
 android.hardware.location.IGeofenceHardwareMonitorCallback$Stub
 android.hardware.location.IGeofenceHardwareMonitorCallback$Stub$Proxy
 android.hardware.location.MemoryRegion
+android.hardware.location.MemoryRegion$1
+android.hardware.location.NanoApp
+android.hardware.location.NanoAppFilter
+android.hardware.location.NanoAppFilter$1
 android.hardware.location.NanoAppInstanceInfo
 android.hardware.location.NanoAppInstanceInfo$1
 android.hardware.radio.RadioManager
@@ -1722,6 +1759,21 @@
 android.hardware.radio.RadioMetadata$1
 android.hardware.radio.RadioModule
 android.hardware.radio.RadioTuner
+android.hardware.radio.V1_0.Call
+android.hardware.radio.V1_0.CardStatus
+android.hardware.radio.V1_0.CdmaSignalStrength
+android.hardware.radio.V1_0.EvdoSignalStrength
+android.hardware.radio.V1_0.GsmSignalStrength
+android.hardware.radio.V1_0.IRadio
+android.hardware.radio.V1_0.IRadio$Proxy
+android.hardware.radio.V1_0.IRadioIndication
+android.hardware.radio.V1_0.IRadioIndication$Stub
+android.hardware.radio.V1_0.IRadioResponse
+android.hardware.radio.V1_0.IRadioResponse$Stub
+android.hardware.radio.V1_0.LteSignalStrength
+android.hardware.radio.V1_0.RadioResponseInfo
+android.hardware.radio.V1_0.SignalStrength
+android.hardware.radio.V1_0.TdScdmaSignalStrength
 android.hardware.soundtrigger.IRecognitionStatusCallback
 android.hardware.soundtrigger.IRecognitionStatusCallback$Stub
 android.hardware.soundtrigger.KeyphraseEnrollmentInfo
@@ -1757,21 +1809,28 @@
 android.hardware.usb.UsbAccessory
 android.hardware.usb.UsbDevice
 android.hardware.usb.UsbDeviceConnection
-android.hardware.usb.UsbInterface
 android.hardware.usb.UsbManager
 android.hardware.usb.UsbPort
 android.hardware.usb.UsbPort$1
 android.hardware.usb.UsbPortStatus
 android.hardware.usb.UsbPortStatus$1
 android.hardware.usb.UsbRequest
+android.hidl.base.V1_0.IBase
 android.icu.impl.BMPSet
 android.icu.impl.CacheBase
 android.icu.impl.CacheValue
 android.icu.impl.CacheValue$NullValue
 android.icu.impl.CacheValue$SoftValue
 android.icu.impl.CacheValue$Strength
-android.icu.impl.CalendarData
+android.icu.impl.CalendarAstronomer
+android.icu.impl.CalendarAstronomer$2
+android.icu.impl.CalendarAstronomer$CoordFunc
+android.icu.impl.CalendarAstronomer$Equatorial
+android.icu.impl.CalendarAstronomer$MoonAge
+android.icu.impl.CalendarAstronomer$SolarLongitude
 android.icu.impl.CalendarUtil
+android.icu.impl.CalendarUtil$CalendarPreferences
+android.icu.impl.CaseMap$StringContextIterator
 android.icu.impl.CharTrie
 android.icu.impl.CharacterIteration
 android.icu.impl.ClassLoaderUtil
@@ -1779,6 +1838,8 @@
 android.icu.impl.CurrencyData$CurrencyDisplayInfo
 android.icu.impl.CurrencyData$CurrencyDisplayInfoProvider
 android.icu.impl.CurrencyData$CurrencySpacingInfo
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType
 android.icu.impl.DateNumberFormat
 android.icu.impl.DontCareFieldPosition
 android.icu.impl.Grego
@@ -1792,6 +1853,7 @@
 android.icu.impl.ICUConfig
 android.icu.impl.ICUCurrencyDisplayInfoProvider
 android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo
+android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo$SpacingInfoSink
 android.icu.impl.ICUCurrencyMetaInfo
 android.icu.impl.ICUCurrencyMetaInfo$Collector
 android.icu.impl.ICUCurrencyMetaInfo$CurrencyCollector
@@ -1809,8 +1871,11 @@
 android.icu.impl.ICUResourceBundle
 android.icu.impl.ICUResourceBundle$1
 android.icu.impl.ICUResourceBundle$2
-android.icu.impl.ICUResourceBundle$2$1
+android.icu.impl.ICUResourceBundle$3
+android.icu.impl.ICUResourceBundle$3$1
+android.icu.impl.ICUResourceBundle$4
 android.icu.impl.ICUResourceBundle$AvailEntry
+android.icu.impl.ICUResourceBundle$Loader
 android.icu.impl.ICUResourceBundle$OpenType
 android.icu.impl.ICUResourceBundle$WholeBundle
 android.icu.impl.ICUResourceBundleImpl
@@ -1844,6 +1909,7 @@
 android.icu.impl.JavaTimeZone
 android.icu.impl.LocaleDisplayNamesImpl
 android.icu.impl.LocaleDisplayNamesImpl$Cache
+android.icu.impl.LocaleDisplayNamesImpl$CapitalizationContextSink
 android.icu.impl.LocaleDisplayNamesImpl$CapitalizationContextUsage
 android.icu.impl.LocaleDisplayNamesImpl$DataTable
 android.icu.impl.LocaleDisplayNamesImpl$DataTables
@@ -1875,21 +1941,10 @@
 android.icu.impl.ReplaceableUCharacterIterator
 android.icu.impl.RuleCharacterIterator
 android.icu.impl.SimpleCache
-android.icu.impl.SimplePatternFormatter
+android.icu.impl.SimpleFormatterImpl
 android.icu.impl.SoftCache
 android.icu.impl.StandardPlural
 android.icu.impl.StringPrepDataReader
-android.icu.impl.TextTrieMap
-android.icu.impl.TextTrieMap$CharIterator
-android.icu.impl.TextTrieMap$Node
-android.icu.impl.TimeZoneNamesFactoryImpl
-android.icu.impl.TimeZoneNamesImpl
-android.icu.impl.TimeZoneNamesImpl$MZ2TZsCache
-android.icu.impl.TimeZoneNamesImpl$MZMapEntry
-android.icu.impl.TimeZoneNamesImpl$NameInfo
-android.icu.impl.TimeZoneNamesImpl$TZ2MZsCache
-android.icu.impl.TimeZoneNamesImpl$ZNames
-android.icu.impl.TimeZoneNamesImpl$ZNamesLoader
 android.icu.impl.Trie
 android.icu.impl.Trie$DataManipulate
 android.icu.impl.Trie$DefaultGetFoldingOffset
@@ -1942,8 +1997,10 @@
 android.icu.impl.UPropertyAliases
 android.icu.impl.UPropertyAliases$IsAcceptable
 android.icu.impl.URLHandler$URLVisitor
+android.icu.impl.UResource$Array
 android.icu.impl.UResource$Key
-android.icu.impl.UResource$TableSink
+android.icu.impl.UResource$Sink
+android.icu.impl.UResource$Table
 android.icu.impl.UResource$Value
 android.icu.impl.USerializedSet
 android.icu.impl.Utility
@@ -1979,7 +2036,6 @@
 android.icu.impl.locale.LocaleObjectCache$CacheEntry
 android.icu.impl.locale.LocaleSyntaxException
 android.icu.lang.UCharacter
-android.icu.lang.UCharacter$StringContextIterator
 android.icu.lang.UCharacterEnums$ECharacterCategory
 android.icu.lang.UCharacterEnums$ECharacterDirection
 android.icu.lang.UScript
@@ -2014,26 +2070,36 @@
 android.icu.text.DateFormat$BooleanAttribute
 android.icu.text.DateFormat$Field
 android.icu.text.DateFormatSymbols
+android.icu.text.DateFormatSymbols$1
+android.icu.text.DateFormatSymbols$CalendarDataSink
+android.icu.text.DateFormatSymbols$CalendarDataSink$AliasType
 android.icu.text.DateFormatSymbols$CapitalizationContextUsage
 android.icu.text.DateIntervalFormat
 android.icu.text.DateIntervalFormat$BestMatchInfo
 android.icu.text.DateIntervalFormat$SkeletonAndItsBestMatch
 android.icu.text.DateIntervalInfo
+android.icu.text.DateIntervalInfo$DateIntervalSink
 android.icu.text.DateIntervalInfo$PatternInfo
 android.icu.text.DateTimePatternGenerator
+android.icu.text.DateTimePatternGenerator$AppendItemFormatsSink
+android.icu.text.DateTimePatternGenerator$AppendItemNamesSink
+android.icu.text.DateTimePatternGenerator$AvailableFormatsSink
 android.icu.text.DateTimePatternGenerator$DTPGflags
 android.icu.text.DateTimePatternGenerator$DateTimeMatcher
+android.icu.text.DateTimePatternGenerator$DayPeriodAllowedHoursSink
 android.icu.text.DateTimePatternGenerator$DistanceInfo
 android.icu.text.DateTimePatternGenerator$FormatParser
 android.icu.text.DateTimePatternGenerator$PatternInfo
 android.icu.text.DateTimePatternGenerator$PatternWithMatcher
 android.icu.text.DateTimePatternGenerator$PatternWithSkeletonFlag
+android.icu.text.DateTimePatternGenerator$SkeletonFields
 android.icu.text.DateTimePatternGenerator$VariableField
 android.icu.text.DecimalFormat
 android.icu.text.DecimalFormat$Unit
 android.icu.text.DecimalFormatSymbols
 android.icu.text.DecimalFormatSymbols$1
 android.icu.text.DecimalFormatSymbols$CacheData
+android.icu.text.DecimalFormatSymbols$DecFmtDataSink
 android.icu.text.DigitList
 android.icu.text.DisplayContext
 android.icu.text.DisplayContext$Type
@@ -2045,14 +2111,6 @@
 android.icu.text.ListFormatter$Style
 android.icu.text.LocaleDisplayNames
 android.icu.text.LocaleDisplayNames$DialectHandling
-android.icu.text.MessageFormat
-android.icu.text.MessageFormat$AppendableWrapper
-android.icu.text.MessageFormat$Field
-android.icu.text.MessagePattern
-android.icu.text.MessagePattern$ApostropheMode
-android.icu.text.MessagePattern$ArgType
-android.icu.text.MessagePattern$Part
-android.icu.text.MessagePattern$Part$Type
 android.icu.text.Normalizer
 android.icu.text.Normalizer$FCDMode
 android.icu.text.Normalizer$Mode
@@ -2074,6 +2132,9 @@
 android.icu.text.NumberFormatServiceShim$NFService
 android.icu.text.NumberFormatServiceShim$NFService$1RBNumberFormatFactory
 android.icu.text.NumberingSystem
+android.icu.text.NumberingSystem$1
+android.icu.text.NumberingSystem$2
+android.icu.text.NumberingSystem$LocaleLookupData
 android.icu.text.PluralRanges
 android.icu.text.PluralRanges$Matrix
 android.icu.text.PluralRules
@@ -2101,20 +2162,18 @@
 android.icu.text.RelativeDateTimeFormatter
 android.icu.text.RelativeDateTimeFormatter$AbsoluteUnit
 android.icu.text.RelativeDateTimeFormatter$Cache
+android.icu.text.RelativeDateTimeFormatter$Cache$1
 android.icu.text.RelativeDateTimeFormatter$Direction
 android.icu.text.RelativeDateTimeFormatter$Loader
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$DateTimeUnit
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$RelativeSink
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$RelativeTimeDetailSink
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$RelativeTimeSink
-android.icu.text.RelativeDateTimeFormatter$RelDateTimeFmtDataSink$UnitSink
+android.icu.text.RelativeDateTimeFormatter$RelDateTimeDataSink
+android.icu.text.RelativeDateTimeFormatter$RelDateTimeDataSink$DateTimeUnit
 android.icu.text.RelativeDateTimeFormatter$RelativeDateTimeFormatterData
 android.icu.text.RelativeDateTimeFormatter$RelativeUnit
 android.icu.text.RelativeDateTimeFormatter$Style
 android.icu.text.Replaceable
 android.icu.text.ReplaceableString
 android.icu.text.RuleBasedBreakIterator
+android.icu.text.RuleBasedBreakIterator$LookAheadResults
 android.icu.text.RuleBasedCollator
 android.icu.text.RuleBasedCollator$CollationBuffer
 android.icu.text.RuleBasedCollator$CollationKeyByteSink
@@ -2125,9 +2184,6 @@
 android.icu.text.SimpleDateFormat$PatternItem
 android.icu.text.StringPrep
 android.icu.text.StringPrepParseException
-android.icu.text.TimeZoneNames
-android.icu.text.TimeZoneNames$Cache
-android.icu.text.TimeZoneNames$Factory
 android.icu.text.TimeZoneNames$NameType
 android.icu.text.UCharacterIterator
 android.icu.text.UFieldPosition
@@ -2156,12 +2212,19 @@
 android.icu.util.CharsTrie
 android.icu.util.CharsTrie$Entry
 android.icu.util.CharsTrie$Iterator
+android.icu.util.ChineseCalendar
 android.icu.util.Currency
+android.icu.util.Currency$1
 android.icu.util.Currency$CurrencyUsage
 android.icu.util.Currency$EquivalenceRelation
 android.icu.util.CurrencyAmount
 android.icu.util.Freezable
 android.icu.util.GregorianCalendar
+android.icu.util.HebrewCalendar
+android.icu.util.ICUException
+android.icu.util.IndianCalendar
+android.icu.util.IslamicCalendar
+android.icu.util.IslamicCalendar$CalculationType
 android.icu.util.LocaleData
 android.icu.util.Measure
 android.icu.util.MeasureUnit
@@ -2175,11 +2238,13 @@
 android.icu.util.TimeZone
 android.icu.util.TimeZone$ConstantZone
 android.icu.util.ULocale
+android.icu.util.ULocale$1
+android.icu.util.ULocale$2
 android.icu.util.ULocale$Category
 android.icu.util.ULocale$JDKLocaleHelper
 android.icu.util.ULocale$Type
 android.icu.util.UResourceBundle
-android.icu.util.UResourceBundle$ResourceCacheKey
+android.icu.util.UResourceBundle$RootType
 android.icu.util.UResourceBundleIterator
 android.icu.util.UResourceTypeMismatchException
 android.icu.util.VersionInfo
@@ -2197,26 +2262,17 @@
 android.inputmethodservice.InputMethodService$InputMethodSessionImpl
 android.inputmethodservice.InputMethodService$Insets
 android.inputmethodservice.InputMethodService$SettingsObserver
-android.inputmethodservice.Keyboard
-android.inputmethodservice.Keyboard$Key
-android.inputmethodservice.Keyboard$Row
-android.inputmethodservice.KeyboardView
-android.inputmethodservice.KeyboardView$1
-android.inputmethodservice.KeyboardView$2
-android.inputmethodservice.KeyboardView$OnKeyboardActionListener
-android.inputmethodservice.KeyboardView$SwipeTracker
 android.inputmethodservice.SoftInputWindow
+android.inputmethodservice.SoftInputWindow$Callback
 android.location.Address
 android.location.Address$1
 android.location.Country
 android.location.Country$1
 android.location.CountryDetector
 android.location.CountryDetector$ListenerTransport
+android.location.CountryDetector$ListenerTransport$1
 android.location.CountryListener
 android.location.Criteria
-android.location.Criteria$1
-android.location.FusedBatchOptions
-android.location.FusedBatchOptions$1
 android.location.Geocoder
 android.location.GeocoderParams
 android.location.GeocoderParams$1
@@ -2238,11 +2294,8 @@
 android.location.ICountryListener
 android.location.ICountryListener$Stub
 android.location.ICountryListener$Stub$Proxy
-android.location.IFusedGeofenceHardware
-android.location.IFusedGeofenceHardware$Stub
 android.location.IFusedProvider
 android.location.IFusedProvider$Stub
-android.location.IFusedProvider$Stub$Proxy
 android.location.IGeocodeProvider
 android.location.IGeocodeProvider$Stub
 android.location.IGeocodeProvider$Stub$Proxy
@@ -2284,7 +2337,6 @@
 android.location.LocationProvider
 android.location.LocationRequest
 android.location.LocationRequest$1
-android.media.AmrInputStream
 android.media.AudioAttributes
 android.media.AudioAttributes$1
 android.media.AudioAttributes$Builder
@@ -2303,6 +2355,7 @@
 android.media.AudioManager
 android.media.AudioManager$1
 android.media.AudioManager$2
+android.media.AudioManager$3
 android.media.AudioManager$NativeEventHandlerDelegate
 android.media.AudioManager$NativeEventHandlerDelegate$1
 android.media.AudioManager$OnAmPortUpdateListener
@@ -2315,6 +2368,10 @@
 android.media.AudioMixPort
 android.media.AudioMixPortConfig
 android.media.AudioPatch
+android.media.AudioPlaybackConfiguration
+android.media.AudioPlaybackConfiguration$1
+android.media.AudioPlaybackConfiguration$IPlayerShell
+android.media.AudioPlaybackConfiguration$PlayerDeathMonitor
 android.media.AudioPort
 android.media.AudioPortConfig
 android.media.AudioPortEventHandler
@@ -2331,6 +2388,8 @@
 android.media.AudioSystem$ErrorCallback
 android.media.AudioTimestamp
 android.media.AudioTrack
+android.media.BufferingParams
+android.media.BufferingParams$1
 android.media.CamcorderProfile
 android.media.CameraProfile
 android.media.Cea708CaptionRenderer
@@ -2339,11 +2398,9 @@
 android.media.DeniedByServerException
 android.media.EncoderCapabilities
 android.media.ExifInterface
-android.media.ExifInterface$ByteOrderAwarenessDataInputStream
-android.media.ExifInterface$ByteOrderAwarenessDataOutputStream
+android.media.ExifInterface$ByteOrderedDataInputStream
 android.media.ExifInterface$ExifAttribute
 android.media.ExifInterface$ExifTag
-android.media.ExifInterface$Rational
 android.media.IAudioFocusDispatcher
 android.media.IAudioFocusDispatcher$Stub
 android.media.IAudioFocusDispatcher$Stub$Proxy
@@ -2357,12 +2414,23 @@
 android.media.IMediaHTTPConnection$Stub
 android.media.IMediaHTTPService
 android.media.IMediaHTTPService$Stub
+android.media.IMediaResourceMonitor
+android.media.IMediaResourceMonitor$Stub
 android.media.IMediaRouterClient
 android.media.IMediaRouterClient$Stub
 android.media.IMediaRouterClient$Stub$Proxy
 android.media.IMediaRouterService
 android.media.IMediaRouterService$Stub
 android.media.IMediaRouterService$Stub$Proxy
+android.media.IMediaScannerListener
+android.media.IMediaScannerListener$Stub
+android.media.IMediaScannerService
+android.media.IMediaScannerService$Stub
+android.media.IPlaybackConfigDispatcher
+android.media.IPlaybackConfigDispatcher$Stub
+android.media.IPlayer
+android.media.IPlayer$Stub
+android.media.IPlayer$Stub$Proxy
 android.media.IRecordingConfigDispatcher
 android.media.IRecordingConfigDispatcher$Stub
 android.media.IRemoteVolumeController
@@ -2390,14 +2458,10 @@
 android.media.ImageWriter$WriterSurfaceImage
 android.media.ImageWriter$WriterSurfaceImage$SurfacePlane
 android.media.JetPlayer
-android.media.MediaActionSound
-android.media.MediaActionSound$1
-android.media.MediaActionSound$SoundState
 android.media.MediaCodec
 android.media.MediaCodec$BufferInfo
 android.media.MediaCodec$BufferMap
 android.media.MediaCodec$BufferMap$CodecBuffer
-android.media.MediaCodec$Callback
 android.media.MediaCodec$CodecException
 android.media.MediaCodec$CryptoException
 android.media.MediaCodec$CryptoInfo
@@ -2413,7 +2477,6 @@
 android.media.MediaCodecInfo$VideoCapabilities
 android.media.MediaCodecList
 android.media.MediaCrypto
-android.media.MediaCryptoException
 android.media.MediaDescription
 android.media.MediaDescription$1
 android.media.MediaDescription$Builder
@@ -2423,7 +2486,6 @@
 android.media.MediaDrm$EventHandler
 android.media.MediaDrm$KeyRequest
 android.media.MediaDrm$MediaDrmStateException
-android.media.MediaDrm$OnEventListener
 android.media.MediaDrm$ProvisionRequest
 android.media.MediaDrmException
 android.media.MediaExtractor
@@ -2441,7 +2503,8 @@
 android.media.MediaPlayer
 android.media.MediaPlayer$1
 android.media.MediaPlayer$2
-android.media.MediaPlayer$2$1
+android.media.MediaPlayer$3
+android.media.MediaPlayer$3$1
 android.media.MediaPlayer$EventHandler
 android.media.MediaPlayer$OnBufferingUpdateListener
 android.media.MediaPlayer$OnCompletionListener
@@ -2473,6 +2536,7 @@
 android.media.MediaRouter$Static$Client$1
 android.media.MediaRouter$UserRouteInfo
 android.media.MediaRouter$VolumeCallback
+android.media.MediaRouter$VolumeCallbackInfo
 android.media.MediaRouter$VolumeChangeReceiver
 android.media.MediaRouter$WifiDisplayStatusChangedReceiver
 android.media.MediaRouterClientState
@@ -2480,7 +2544,13 @@
 android.media.MediaRouterClientState$RouteInfo
 android.media.MediaRouterClientState$RouteInfo$1
 android.media.MediaScanner
+android.media.MediaScanner$FileEntry
+android.media.MediaScanner$MediaBulkDeleter
+android.media.MediaScanner$MyMediaScannerClient
+android.media.MediaScannerClient
 android.media.MediaScannerConnection
+android.media.MediaScannerConnection$1
+android.media.MediaScannerConnection$ClientProxy
 android.media.MediaScannerConnection$MediaScannerConnectionClient
 android.media.MediaScannerConnection$OnScanCompletedListener
 android.media.MediaSync
@@ -2493,6 +2563,9 @@
 android.media.PlaybackParams$1
 android.media.PlayerBase
 android.media.PlayerBase$1
+android.media.PlayerBase$2
+android.media.PlayerBase$PlayerIdCard
+android.media.PlayerBase$PlayerIdCard$1
 android.media.Rating
 android.media.Rating$1
 android.media.RemoteControlClient
@@ -2504,7 +2577,6 @@
 android.media.Ringtone$MyOnCompletionListener
 android.media.RingtoneManager
 android.media.SoundPool
-android.media.SoundPool$1
 android.media.SoundPool$Builder
 android.media.SoundPool$EventHandler
 android.media.SoundPool$OnLoadCompleteListener
@@ -2520,7 +2592,6 @@
 android.media.ThumbnailUtils$SizedThumbnailBitmap
 android.media.ToneGenerator
 android.media.TtmlRenderer
-android.media.UnsupportedSchemeException
 android.media.Utils
 android.media.Utils$1
 android.media.Utils$2
@@ -2528,10 +2599,8 @@
 android.media.VolumePolicy$1
 android.media.VolumeProvider
 android.media.WebVttRenderer
-android.media.audiofx.AcousticEchoCanceler
 android.media.audiofx.AudioEffect
 android.media.audiofx.AudioEffect$Descriptor
-android.media.audiofx.AutomaticGainControl
 android.media.audiofx.BassBoost
 android.media.audiofx.BassBoost$Settings
 android.media.audiofx.Equalizer
@@ -2541,12 +2610,20 @@
 android.media.audiofx.Virtualizer
 android.media.audiofx.Virtualizer$Settings
 android.media.audiofx.Visualizer
+android.media.audiofx.Visualizer$OnDataCaptureListener
 android.media.audiopolicy.AudioMix
 android.media.audiopolicy.AudioMixingRule
 android.media.audiopolicy.AudioMixingRule$AudioMixMatchCriterion
 android.media.audiopolicy.AudioPolicyConfig
 android.media.audiopolicy.IAudioPolicyCallback
 android.media.audiopolicy.IAudioPolicyCallback$Stub
+android.media.browse.MediaBrowser
+android.media.browse.MediaBrowser$10
+android.media.browse.MediaBrowser$ConnectionCallback
+android.media.browse.MediaBrowser$MediaItem
+android.media.browse.MediaBrowser$MediaServiceConnection
+android.media.browse.MediaBrowser$MediaServiceConnection$1
+android.media.browse.MediaBrowser$ServiceCallbacks
 android.media.midi.IMidiDeviceListener
 android.media.midi.IMidiDeviceOpenCallback
 android.media.midi.IMidiDeviceServer
@@ -2569,6 +2646,8 @@
 android.media.session.IActiveSessionsListener
 android.media.session.IActiveSessionsListener$Stub
 android.media.session.IActiveSessionsListener$Stub$Proxy
+android.media.session.IOnMediaKeyListener
+android.media.session.IOnVolumeKeyLongPressListener
 android.media.session.ISession
 android.media.session.ISession$Stub
 android.media.session.ISession$Stub$Proxy
@@ -2617,12 +2696,12 @@
 android.media.tv.TvInputManager
 android.media.tv.TvStreamConfig
 android.media.tv.TvStreamConfig$Builder
+android.metrics.LogMaker
 android.mtp.MtpDatabase
 android.mtp.MtpDevice
 android.mtp.MtpDeviceInfo
 android.mtp.MtpEvent
 android.mtp.MtpObjectInfo
-android.mtp.MtpObjectInfo$Builder
 android.mtp.MtpPropertyGroup
 android.mtp.MtpPropertyList
 android.mtp.MtpServer
@@ -2632,14 +2711,13 @@
 android.net.ConnectivityManager$CallbackHandler
 android.net.ConnectivityManager$NetworkCallback
 android.net.ConnectivityManager$OnNetworkActiveListener
-android.net.ConnectivityManager$OnStartTetheringCallback
 android.net.ConnectivityManager$PacketKeepalive
 android.net.ConnectivityManager$PacketKeepaliveCallback
 android.net.ConnectivityMetricsEvent
 android.net.ConnectivityMetricsEvent$1
 android.net.ConnectivityMetricsEvent$Reference
-android.net.ConnectivityMetricsLogger
 android.net.ConnectivityThread
+android.net.ConnectivityThread$Singleton
 android.net.Credentials
 android.net.DataUsageRequest
 android.net.DhcpInfo
@@ -2649,16 +2727,22 @@
 android.net.EthernetManager
 android.net.EthernetManager$1
 android.net.EthernetManager$2
+android.net.EventLogTags
 android.net.IConnectivityManager
 android.net.IConnectivityManager$Stub
 android.net.IConnectivityManager$Stub$Proxy
 android.net.IConnectivityMetricsLogger
 android.net.IConnectivityMetricsLogger$Stub
-android.net.IConnectivityMetricsLogger$Stub$Proxy
 android.net.IEthernetManager
 android.net.IEthernetManager$Stub
 android.net.IEthernetServiceListener
 android.net.IEthernetServiceListener$Stub
+android.net.IIpConnectivityMetrics
+android.net.IIpConnectivityMetrics$Stub
+android.net.INetd
+android.net.INetd$Stub
+android.net.INetd$Stub$Proxy
+android.net.INetdEventCallback
 android.net.INetworkManagementEventObserver
 android.net.INetworkManagementEventObserver$Stub
 android.net.INetworkPolicyListener
@@ -2669,6 +2753,7 @@
 android.net.INetworkPolicyManager$Stub$Proxy
 android.net.INetworkScoreCache
 android.net.INetworkScoreCache$Stub
+android.net.INetworkScoreCache$Stub$Proxy
 android.net.INetworkScoreService
 android.net.INetworkScoreService$Stub
 android.net.INetworkScoreService$Stub$Proxy
@@ -2704,6 +2789,7 @@
 android.net.Network$2
 android.net.Network$NetworkBoundSocketFactory
 android.net.NetworkAgent
+android.net.NetworkBadging
 android.net.NetworkCapabilities
 android.net.NetworkCapabilities$1
 android.net.NetworkConfig
@@ -2725,6 +2811,7 @@
 android.net.NetworkRequest
 android.net.NetworkRequest$1
 android.net.NetworkRequest$Builder
+android.net.NetworkRequest$Type
 android.net.NetworkScoreManager
 android.net.NetworkScorerAppManager
 android.net.NetworkState
@@ -2745,13 +2832,17 @@
 android.net.Proxy
 android.net.ProxyInfo
 android.net.ProxyInfo$1
+android.net.RecommendationRequest
+android.net.RecommendationResult
 android.net.RouteInfo
 android.net.RouteInfo$1
 android.net.RssiCurve
+android.net.RssiCurve$1
 android.net.SSLCertificateSocketFactory
 android.net.SSLCertificateSocketFactory$1
 android.net.SSLSessionCache
 android.net.ScoredNetwork
+android.net.ScoredNetwork$1
 android.net.SntpClient
 android.net.StaticIpConfiguration
 android.net.StaticIpConfiguration$1
@@ -2771,7 +2862,7 @@
 android.net.Uri$PathSegmentsBuilder
 android.net.Uri$StringUri
 android.net.UrlQuerySanitizer
-android.net.UrlQuerySanitizer$ValueSanitizer
+android.net.VpnService
 android.net.WebAddress
 android.net.WifiKey
 android.net.WifiKey$1
@@ -2784,19 +2875,23 @@
 android.net.http.SslCertificate
 android.net.http.SslError
 android.net.http.X509TrustManagerExtensions
+android.net.metrics.ApfProgramEvent
+android.net.metrics.ApfProgramEvent$1
+android.net.metrics.ConnectStats
 android.net.metrics.DefaultNetworkEvent
 android.net.metrics.DefaultNetworkEvent$1
 android.net.metrics.DhcpClientEvent
 android.net.metrics.DhcpClientEvent$1
 android.net.metrics.DnsEvent
 android.net.metrics.DnsEvent$1
-android.net.metrics.IpConnectivityEvent
+android.net.metrics.IpConnectivityLog
 android.net.metrics.IpManagerEvent
 android.net.metrics.IpManagerEvent$1
-android.net.metrics.IpReachabilityEvent
-android.net.metrics.IpReachabilityEvent$1
 android.net.metrics.NetworkEvent
 android.net.metrics.NetworkEvent$1
+android.net.metrics.RaEvent
+android.net.metrics.RaEvent$1
+android.net.metrics.RaEvent$Builder
 android.net.metrics.ValidationProbeEvent
 android.net.metrics.ValidationProbeEvent$1
 android.net.metrics.ValidationProbeEvent$Decoder
@@ -2806,8 +2901,6 @@
 android.net.sip.ISipService
 android.net.sip.ISipService$Stub
 android.net.sip.SipManager
-android.net.sip.SipProfile
-android.net.sip.SipProfile$Builder
 android.net.wifi.IRttManager
 android.net.wifi.IRttManager$Stub
 android.net.wifi.IRttManager$Stub$Proxy
@@ -2817,9 +2910,10 @@
 android.net.wifi.IWifiScanner
 android.net.wifi.IWifiScanner$Stub
 android.net.wifi.IWifiScanner$Stub$Proxy
+android.net.wifi.ParcelUtil
+android.net.wifi.RssiPacketCountInfo
 android.net.wifi.RttManager
 android.net.wifi.RttManager$RttCapabilities
-android.net.wifi.RttManager$RttCapabilities$1
 android.net.wifi.RttManager$RttListener
 android.net.wifi.RttManager$RttResult
 android.net.wifi.RttManager$ServiceHandler
@@ -2831,6 +2925,7 @@
 android.net.wifi.SupplicantState$1
 android.net.wifi.WifiActivityEnergyInfo
 android.net.wifi.WifiActivityEnergyInfo$1
+android.net.wifi.WifiChannel
 android.net.wifi.WifiConfiguration
 android.net.wifi.WifiConfiguration$1
 android.net.wifi.WifiConfiguration$AuthAlgorithm
@@ -2844,9 +2939,6 @@
 android.net.wifi.WifiConnectionStatistics$1
 android.net.wifi.WifiEnterpriseConfig
 android.net.wifi.WifiEnterpriseConfig$1
-android.net.wifi.WifiEnterpriseConfig$Eap
-android.net.wifi.WifiEnterpriseConfig$Phase2
-android.net.wifi.WifiEnterpriseConfig$SupplicantLoader
 android.net.wifi.WifiInfo
 android.net.wifi.WifiInfo$1
 android.net.wifi.WifiLinkLayerStats
@@ -2855,25 +2947,30 @@
 android.net.wifi.WifiManager$ActionListener
 android.net.wifi.WifiManager$MulticastLock
 android.net.wifi.WifiManager$WifiLock
+android.net.wifi.WifiNetworkScoreCache
+android.net.wifi.WifiNetworkScoreCache$CacheListener
 android.net.wifi.WifiScanner
 android.net.wifi.WifiScanner$ActionListener
 android.net.wifi.WifiScanner$ChannelSpec
-android.net.wifi.WifiScanner$OperationResult
-android.net.wifi.WifiScanner$OperationResult$1
 android.net.wifi.WifiScanner$ParcelableScanData
 android.net.wifi.WifiScanner$ParcelableScanData$1
+android.net.wifi.WifiScanner$ParcelableScanResults
+android.net.wifi.WifiScanner$ParcelableScanResults$1
 android.net.wifi.WifiScanner$PnoScanListener
 android.net.wifi.WifiScanner$ScanData
 android.net.wifi.WifiScanner$ScanData$1
 android.net.wifi.WifiScanner$ScanListener
 android.net.wifi.WifiScanner$ScanSettings
 android.net.wifi.WifiScanner$ScanSettings$1
+android.net.wifi.WifiScanner$ScanSettings$HiddenNetwork
 android.net.wifi.WifiScanner$ServiceHandler
 android.net.wifi.WifiSsid
 android.net.wifi.WifiSsid$1
+android.net.wifi.WifiWakeReasonAndCounts
 android.net.wifi.WpsInfo
 android.net.wifi.WpsInfo$1
-android.net.wifi.nan.WifiNanManager
+android.net.wifi.aware.WifiAwareManager
+android.net.wifi.hotspot2.PasspointConfiguration
 android.net.wifi.p2p.IWifiP2pManager
 android.net.wifi.p2p.IWifiP2pManager$Stub
 android.net.wifi.p2p.WifiP2pConfig
@@ -2925,7 +3022,6 @@
 android.nfc.NfcAdapter$1
 android.nfc.NfcAdapter$CreateBeamUrisCallback
 android.nfc.NfcAdapter$CreateNdefMessageCallback
-android.nfc.NfcAdapter$NfcUnlockHandler
 android.nfc.NfcAdapter$OnNdefPushCompleteCallback
 android.nfc.NfcEvent
 android.nfc.NfcManager
@@ -2976,11 +3072,17 @@
 android.opengl.GLSurfaceView$GLThread
 android.opengl.GLSurfaceView$GLThreadManager
 android.opengl.GLSurfaceView$Renderer
+android.opengl.GLSurfaceView$SimpleEGLConfigChooser
 android.opengl.GLU
 android.opengl.GLUtils
 android.opengl.Matrix
 android.opengl.Visibility
+android.os.-$Lambda$0$-dncxFEc2F2bgG2fsIoC6FC6WNE
+android.os.-$Lambda$1$-dncxFEc2F2bgG2fsIoC6FC6WNE
+android.os.-$Lambda$5$6x30vPJhBKUfNY8tswxuZo3DCe0
+android.os.-$Lambda$67$OsaxDBgigpqjZN1F4C6nYRYm1YQ
 android.os.AsyncResult
+android.os.AsyncTask
 android.os.AsyncTask$1
 android.os.AsyncTask$2
 android.os.AsyncTask$3
@@ -3000,12 +3102,14 @@
 android.os.BatteryStats
 android.os.BatteryStats$BitDescription
 android.os.BatteryStats$ControllerActivityCounter
+android.os.BatteryStats$Counter
 android.os.BatteryStats$DailyItem
 android.os.BatteryStats$HistoryEventTracker
 android.os.BatteryStats$HistoryItem
 android.os.BatteryStats$HistoryPrinter
 android.os.BatteryStats$HistoryStepDetails
 android.os.BatteryStats$HistoryTag
+android.os.BatteryStats$IntToString
 android.os.BatteryStats$LevelStepTracker
 android.os.BatteryStats$LongCounter
 android.os.BatteryStats$PackageChange
@@ -3014,6 +3118,7 @@
 android.os.BatteryStats$Uid$Pid
 android.os.BatteryStats$Uid$Pkg
 android.os.BatteryStats$Uid$Pkg$Serv
+android.os.BatteryStats$Uid$Proc
 android.os.BatteryStats$Uid$Sensor
 android.os.BatteryStats$Uid$Wakelock
 android.os.Binder
@@ -3042,16 +3147,20 @@
 android.os.Environment
 android.os.Environment$UserEnvironment
 android.os.FactoryTest
-android.os.FileBridge
-android.os.FileBridge$FileBridgeOutputStream
+android.os.FileObserver
 android.os.FileObserver$ObserverThread
 android.os.FileUtils
+android.os.GraphicsEnvironment
 android.os.Handler
 android.os.Handler$BlockingRunnable
 android.os.Handler$Callback
 android.os.Handler$MessengerImpl
 android.os.HandlerThread
 android.os.HardwarePropertiesManager
+android.os.HwBinder
+android.os.HwBlob
+android.os.HwParcel
+android.os.HwRemoteBinder
 android.os.IBatteryPropertiesListener
 android.os.IBatteryPropertiesListener$Stub
 android.os.IBatteryPropertiesRegistrar
@@ -3062,11 +3171,22 @@
 android.os.ICancellationSignal
 android.os.ICancellationSignal$Stub
 android.os.ICancellationSignal$Stub$Proxy
+android.os.IDeviceIdentifiersPolicyService
+android.os.IDeviceIdentifiersPolicyService$Stub
 android.os.IDeviceIdleController
 android.os.IDeviceIdleController$Stub
 android.os.IDeviceIdleController$Stub$Proxy
 android.os.IHardwarePropertiesManager
 android.os.IHardwarePropertiesManager$Stub
+android.os.IHardwarePropertiesManager$Stub$Proxy
+android.os.IHwBinder
+android.os.IHwBinder$DeathRecipient
+android.os.IHwInterface
+android.os.IIncidentManager
+android.os.IIncidentManager$Stub
+android.os.IInstalld
+android.os.IInstalld$Stub
+android.os.IInstalld$Stub$Proxy
 android.os.IInterface
 android.os.IMaintenanceActivityListener
 android.os.IMessenger
@@ -3084,10 +3204,8 @@
 android.os.IProcessInfoService
 android.os.IProcessInfoService$Stub
 android.os.IProgressListener
-android.os.IProgressListener$Stub
 android.os.IRecoverySystem
 android.os.IRecoverySystem$Stub
-android.os.IRecoverySystem$Stub$Proxy
 android.os.IRecoverySystemProgressListener
 android.os.IRemoteCallback
 android.os.IRemoteCallback$Stub
@@ -3103,6 +3221,7 @@
 android.os.IVibratorService
 android.os.IVibratorService$Stub
 android.os.IVibratorService$Stub$Proxy
+android.os.IncidentManager
 android.os.LocaleList
 android.os.LocaleList$1
 android.os.Looper
@@ -3115,7 +3234,6 @@
 android.os.MessageQueue$OnFileDescriptorEventListener
 android.os.Messenger
 android.os.Messenger$1
-android.os.NetworkOnMainThreadException
 android.os.NullVibrator
 android.os.OperationCanceledException
 android.os.Parcel
@@ -3141,6 +3259,8 @@
 android.os.PersistableBundle
 android.os.PersistableBundle$1
 android.os.PersistableBundle$MyReadMapCallback
+android.os.PooledStringReader
+android.os.PooledStringWriter
 android.os.PowerManager
 android.os.PowerManager$WakeLock
 android.os.PowerManager$WakeLock$1
@@ -3148,12 +3268,14 @@
 android.os.PowerManagerInternal$LowPowerModeListener
 android.os.Process
 android.os.Process$ProcessStartResult
-android.os.Process$ZygoteState
 android.os.RecoverySystem
-android.os.RecoverySystem$ProgressListener
 android.os.Registrant
 android.os.RegistrantList
 android.os.RemoteCallback
+android.os.RemoteCallback$1
+android.os.RemoteCallback$2
+android.os.RemoteCallback$3
+android.os.RemoteCallback$OnResultListener
 android.os.RemoteCallbackList
 android.os.RemoteCallbackList$Callback
 android.os.RemoteException
@@ -3163,9 +3285,13 @@
 android.os.ResultReceiver$MyRunnable
 android.os.SELinux
 android.os.ServiceManager
+android.os.ServiceManager$ServiceNotFoundException
 android.os.ServiceManagerNative
 android.os.ServiceManagerProxy
 android.os.ServiceSpecificException
+android.os.ShellCallback
+android.os.ShellCallback$1
+android.os.ShellCommand
 android.os.StatFs
 android.os.StrictMode
 android.os.StrictMode$1
@@ -3191,6 +3317,7 @@
 android.os.StrictMode$ThreadPolicy$Builder
 android.os.StrictMode$ThreadSpanState
 android.os.StrictMode$ViolationInfo
+android.os.StrictMode$ViolationInfo$1
 android.os.StrictMode$VmPolicy
 android.os.StrictMode$VmPolicy$Builder
 android.os.SynchronousResultReceiver
@@ -3203,11 +3330,9 @@
 android.os.SystemVibrator
 android.os.TokenWatcher
 android.os.TokenWatcher$1
-android.os.TokenWatcher$Death
 android.os.Trace
 android.os.Trace$1
 android.os.TransactionTooLargeException
-android.os.TransactionTracker
 android.os.UEventObserver
 android.os.UEventObserver$UEvent
 android.os.UEventObserver$UEventThread
@@ -3220,26 +3345,30 @@
 android.os.Vibrator
 android.os.WorkSource
 android.os.WorkSource$1
+android.os.ZygoteProcess
+android.os.ZygoteProcess$ZygoteState
 android.os.ZygoteStartFailedEx
+android.os.health.HealthStats
 android.os.health.HealthStatsParceler
 android.os.health.SystemHealthManager
+android.os.health.TimerStat
 android.os.storage.DiskInfo
 android.os.storage.DiskInfo$1
-android.os.storage.IStorageManager
-android.os.storage.IStorageManager$Stub
-android.os.storage.IStorageManager$Stub$Proxy
+android.os.storage.IObbActionListener
+android.os.storage.IObbActionListener$Stub
 android.os.storage.IStorageEventListener
 android.os.storage.IStorageEventListener$Stub
 android.os.storage.IStorageEventListener$Stub$Proxy
+android.os.storage.IStorageManager
+android.os.storage.IStorageManager$Stub
+android.os.storage.IStorageManager$Stub$Proxy
 android.os.storage.IStorageShutdownObserver
-android.os.storage.IObbActionListener
-android.os.storage.IObbActionListener$Stub
-android.os.storage.StorageManagerInternal
-android.os.storage.StorageManagerInternal$ExternalStorageMountPolicy
 android.os.storage.StorageEventListener
 android.os.storage.StorageManager
 android.os.storage.StorageManager$ObbActionListener
 android.os.storage.StorageManager$StorageEventListenerDelegate
+android.os.storage.StorageManagerInternal
+android.os.storage.StorageManagerInternal$ExternalStorageMountPolicy
 android.os.storage.StorageVolume
 android.os.storage.StorageVolume$1
 android.os.storage.VolumeInfo
@@ -3247,30 +3376,30 @@
 android.os.storage.VolumeInfo$2
 android.os.storage.VolumeRecord
 android.os.storage.VolumeRecord$1
+android.permissionpresenterservice.RuntimePermissionPresenterService
+android.permissionpresenterservice.RuntimePermissionPresenterService$1
+android.permissionpresenterservice.RuntimePermissionPresenterService$MyHandler
+android.preference.CheckBoxPreference
 android.preference.DialogPreference
-android.preference.GenericInflater
 android.preference.GenericInflater$Parent
 android.preference.ListPreference
 android.preference.Preference
+android.preference.Preference$BaseSavedState
+android.preference.Preference$BaseSavedState$1
 android.preference.Preference$OnPreferenceChangeInternalListener
 android.preference.Preference$OnPreferenceChangeListener
 android.preference.Preference$OnPreferenceClickListener
 android.preference.PreferenceActivity
-android.preference.PreferenceActivity$1
-android.preference.PreferenceActivity$Header
-android.preference.PreferenceActivity$Header$1
 android.preference.PreferenceFragment
 android.preference.PreferenceFragment$1
 android.preference.PreferenceFragment$2
 android.preference.PreferenceFragment$3
 android.preference.PreferenceFragment$OnPreferenceStartFragmentCallback
 android.preference.PreferenceFrameLayout
-android.preference.PreferenceFrameLayout$LayoutParams
 android.preference.PreferenceGroup
 android.preference.PreferenceGroupAdapter
 android.preference.PreferenceGroupAdapter$1
 android.preference.PreferenceGroupAdapter$PreferenceLayout
-android.preference.PreferenceInflater
 android.preference.PreferenceManager
 android.preference.PreferenceManager$OnActivityDestroyListener
 android.preference.PreferenceManager$OnPreferenceTreeClickListener
@@ -3285,8 +3414,6 @@
 android.preference.TwoStatePreference
 android.print.IPrintDocumentAdapter
 android.print.IPrintJobStateChangeListener
-android.print.IPrintJobStateChangeListener$Stub
-android.print.IPrintJobStateChangeListener$Stub$Proxy
 android.print.IPrintManager
 android.print.IPrintManager$Stub
 android.print.IPrintManager$Stub$Proxy
@@ -3298,7 +3425,6 @@
 android.print.IPrintSpooler$Stub$Proxy
 android.print.IPrintSpoolerCallbacks
 android.print.IPrintSpoolerCallbacks$Stub
-android.print.IPrintSpoolerCallbacks$Stub$Proxy
 android.print.IPrintSpoolerClient
 android.print.IPrintSpoolerClient$Stub
 android.print.IPrintSpoolerClient$Stub$Proxy
@@ -3314,31 +3440,25 @@
 android.print.PrintDocumentAdapter$WriteResultCallback
 android.print.PrintDocumentInfo
 android.print.PrintDocumentInfo$Builder
-android.print.PrintJob
 android.print.PrintJobId
 android.print.PrintJobInfo
-android.print.PrintJobInfo$1
 android.print.PrintManager
 android.print.PrintManager$1
-android.print.PrintManager$PrintJobStateChangeListener
-android.print.PrintManager$PrintJobStateChangeListenerWrapper
 android.print.PrintManager$PrintServicesChangeListener
 android.print.PrintManager$PrintServicesChangeListenerWrapper
 android.print.PrintServicesLoader
 android.print.PrintServicesLoader$1
 android.print.PrintServicesLoader$MyHandler
 android.print.PrinterId
-android.print.pdf.PrintedPdfDocument
 android.printservice.IPrintServiceClient
 android.printservice.IPrintServiceClient$Stub
 android.printservice.PrintServiceInfo
 android.printservice.PrintServiceInfo$1
 android.printservice.recommendation.IRecommendationsChangeListener
+android.provider.-$Lambda$46$87WmhkvObehVg0OMBzwa_MTVV8g
 android.provider.BaseColumns
 android.provider.BlockedNumberContract
 android.provider.BlockedNumberContract$BlockedNumbers
-android.provider.BlockedNumberContract$SystemContract
-android.provider.BlockedNumberContract$SystemContract$BlockSuppressionStatus
 android.provider.CalendarContract
 android.provider.CalendarContract$Attendees
 android.provider.CalendarContract$AttendeesColumns
@@ -3367,12 +3487,16 @@
 android.provider.CallLog
 android.provider.CallLog$Calls
 android.provider.Contacts
+android.provider.Contacts$ContactMethods
+android.provider.Contacts$ContactMethodsColumns
+android.provider.Contacts$PeopleColumns
 android.provider.ContactsContract
 android.provider.ContactsContract$AggregationExceptions
 android.provider.ContactsContract$BaseSyncColumns
 android.provider.ContactsContract$CommonDataKinds$BaseTypes
 android.provider.ContactsContract$CommonDataKinds$Callable
 android.provider.ContactsContract$CommonDataKinds$CommonColumns
+android.provider.ContactsContract$CommonDataKinds$Contactables
 android.provider.ContactsContract$CommonDataKinds$Email
 android.provider.ContactsContract$CommonDataKinds$Event
 android.provider.ContactsContract$CommonDataKinds$Im
@@ -3385,7 +3509,6 @@
 android.provider.ContactsContract$ContactOptionsColumns
 android.provider.ContactsContract$ContactStatusColumns
 android.provider.ContactsContract$Contacts
-android.provider.ContactsContract$Contacts$AggregationSuggestions$Builder
 android.provider.ContactsContract$ContactsColumns
 android.provider.ContactsContract$Data
 android.provider.ContactsContract$DataColumns
@@ -3397,7 +3520,6 @@
 android.provider.ContactsContract$Directory
 android.provider.ContactsContract$DisplayPhoto
 android.provider.ContactsContract$Groups
-android.provider.ContactsContract$Groups$EntityIteratorImpl
 android.provider.ContactsContract$GroupsColumns
 android.provider.ContactsContract$MetadataSync
 android.provider.ContactsContract$MetadataSyncColumns
@@ -3408,7 +3530,6 @@
 android.provider.ContactsContract$ProviderStatus
 android.provider.ContactsContract$QuickContact
 android.provider.ContactsContract$RawContacts
-android.provider.ContactsContract$RawContacts$EntityIteratorImpl
 android.provider.ContactsContract$RawContactsColumns
 android.provider.ContactsContract$RawContactsEntity
 android.provider.ContactsContract$Settings
@@ -3418,8 +3539,8 @@
 android.provider.ContactsContract$StreamItemsColumns
 android.provider.ContactsContract$SyncColumns
 android.provider.ContactsContract$SyncState
+android.provider.ContactsInternal
 android.provider.DocumentsContract
-android.provider.DocumentsContract$Root
 android.provider.DocumentsProvider
 android.provider.Downloads
 android.provider.Downloads$Impl
@@ -3450,12 +3571,11 @@
 android.provider.SearchIndexablesContract
 android.provider.SearchIndexablesProvider
 android.provider.SearchRecentSuggestions
-android.provider.SearchRecentSuggestions$1
 android.provider.Settings
+android.provider.Settings$ContentProviderHolder
 android.provider.Settings$GenerationTracker
 android.provider.Settings$Global
 android.provider.Settings$NameValueCache
-android.provider.Settings$NameValueCache$-java_lang_String_getStringForUser_android_content_ContentResolver_cr_java_lang_String_name_int_userHandle_LambdaImpl0
 android.provider.Settings$NameValueTable
 android.provider.Settings$Secure
 android.provider.Settings$SettingNotFoundException
@@ -3492,18 +3612,21 @@
 android.provider.VoicemailContract$Status
 android.provider.VoicemailContract$Voicemails
 android.renderscript.Allocation
+android.renderscript.Allocation$MipmapControl
 android.renderscript.BaseObj
 android.renderscript.Element
-android.renderscript.Matrix4f
-android.renderscript.RSRuntimeException
+android.renderscript.Element$DataKind
+android.renderscript.Element$DataType
 android.renderscript.RenderScript
+android.renderscript.RenderScript$ContextType
+android.renderscript.RenderScript$MessageThread
 android.renderscript.RenderScriptCacheDir
 android.renderscript.Script
 android.renderscript.ScriptIntrinsic
 android.renderscript.ScriptIntrinsicBlur
 android.renderscript.Type
-android.security.Credentials
-android.security.FrameworkNetworkSecurityPolicy
+android.renderscript.Type$Builder
+android.renderscript.Type$CubemapFace
 android.security.GateKeeper
 android.security.IKeyChainService
 android.security.IKeyChainService$Stub
@@ -3514,10 +3637,11 @@
 android.security.KeyChain
 android.security.KeyChain$1
 android.security.KeyChain$KeyChainConnection
-android.security.KeyChainAliasCallback
 android.security.KeyStore
-android.security.KeyStore$State
 android.security.NetworkSecurityPolicy
+android.security.keymaster.IKeyAttestationApplicationIdProvider
+android.security.keymaster.IKeyAttestationApplicationIdProvider$Stub
+android.security.keymaster.KeyAttestationApplicationId
 android.security.keymaster.KeymasterArguments
 android.security.keymaster.KeymasterArguments$1
 android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
@@ -3559,12 +3683,20 @@
 android.security.net.config.RootTrustManager
 android.security.net.config.RootTrustManagerFactorySpi
 android.security.net.config.SystemCertificateSource
-android.security.net.config.TrustAnchor
+android.security.net.config.SystemCertificateSource$NoPreloadHolder
 android.security.net.config.TrustedCertificateStoreAdapter
 android.security.net.config.UserCertificateSource
+android.security.net.config.UserCertificateSource$NoPreloadHolder
+android.security.net.config.XmlConfigSource
+android.security.net.config.XmlConfigSource$ParserException
+android.service.autofill.IAutoFillManagerService
+android.service.autofill.IAutoFillManagerService$Stub
+android.service.autofill.IAutoFillManagerService$Stub$Proxy
 android.service.carrier.CarrierIdentifier
+android.service.carrier.CarrierIdentifier$1
 android.service.carrier.ICarrierService
 android.service.carrier.ICarrierService$Stub
+android.service.carrier.ICarrierService$Stub$Proxy
 android.service.chooser.ChooserTarget
 android.service.chooser.ChooserTargetService
 android.service.dreams.DreamManagerInternal
@@ -3580,13 +3712,22 @@
 android.service.dreams.IDreamService
 android.service.dreams.IDreamService$Stub
 android.service.dreams.IDreamService$Stub$Proxy
-android.service.gatekeeper.GateKeeperResponse
-android.service.gatekeeper.GateKeeperResponse$1
 android.service.gatekeeper.IGateKeeperService
 android.service.gatekeeper.IGateKeeperService$Stub
 android.service.gatekeeper.IGateKeeperService$Stub$Proxy
-android.service.media.CameraPrewarmService
+android.service.media.IMediaBrowserService
+android.service.media.IMediaBrowserService$Stub
+android.service.media.IMediaBrowserService$Stub$Proxy
+android.service.media.IMediaBrowserServiceCallbacks
+android.service.media.IMediaBrowserServiceCallbacks$Stub
+android.service.media.IMediaBrowserServiceCallbacks$Stub$Proxy
 android.service.media.MediaBrowserService
+android.service.media.MediaBrowserService$1
+android.service.media.MediaBrowserService$BrowserRoot
+android.service.media.MediaBrowserService$ConnectionRecord
+android.service.media.MediaBrowserService$Result
+android.service.media.MediaBrowserService$ServiceBinder
+android.service.media.MediaBrowserService$ServiceBinder$1
 android.service.notification.Adjustment
 android.service.notification.Condition
 android.service.notification.Condition$1
@@ -3597,6 +3738,7 @@
 android.service.notification.IConditionListener$Stub
 android.service.notification.IConditionProvider
 android.service.notification.IConditionProvider$Stub
+android.service.notification.IConditionProvider$Stub$Proxy
 android.service.notification.INotificationListener
 android.service.notification.INotificationListener$Stub
 android.service.notification.INotificationListener$Stub$Proxy
@@ -3609,9 +3751,6 @@
 android.service.notification.NotificationListenerService$Ranking
 android.service.notification.NotificationListenerService$RankingMap
 android.service.notification.NotificationListenerService$RankingMap$1
-android.service.notification.NotificationAssistantService
-android.service.notification.NotificationAssistantService$MyHandler
-android.service.notification.NotificationAssistantService$NotificationRankingServiceWrapper
 android.service.notification.NotificationRankingUpdate
 android.service.notification.NotificationRankingUpdate$1
 android.service.notification.StatusBarNotification
@@ -3620,9 +3759,7 @@
 android.service.notification.ZenModeConfig$1
 android.service.notification.ZenModeConfig$Diff
 android.service.notification.ZenModeConfig$EventInfo
-android.service.notification.ZenModeConfig$Migration
 android.service.notification.ZenModeConfig$ScheduleInfo
-android.service.notification.ZenModeConfig$XmlV1
 android.service.notification.ZenModeConfig$ZenRule
 android.service.notification.ZenModeConfig$ZenRule$1
 android.service.persistentdata.IPersistentDataBlockService
@@ -3633,6 +3770,7 @@
 android.service.quicksettings.IQSService$Stub
 android.service.quicksettings.IQSTileService
 android.service.quicksettings.Tile
+android.service.quicksettings.Tile$1
 android.service.quicksettings.TileService
 android.service.textservice.SpellCheckerService
 android.service.textservice.SpellCheckerService$InternalISpellCheckerSession
@@ -3641,16 +3779,6 @@
 android.service.textservice.SpellCheckerService$SentenceLevelAdapter$SentenceWordItem
 android.service.textservice.SpellCheckerService$Session
 android.service.textservice.SpellCheckerService$SpellCheckerServiceBinder
-android.service.trust.ITrustAgentService
-android.service.trust.ITrustAgentService$Stub
-android.service.trust.ITrustAgentService$Stub$Proxy
-android.service.trust.ITrustAgentServiceCallback
-android.service.trust.ITrustAgentServiceCallback$Stub
-android.service.trust.ITrustAgentServiceCallback$Stub$Proxy
-android.service.trust.TrustAgentService
-android.service.trust.TrustAgentService$1
-android.service.trust.TrustAgentService$ConfigurationData
-android.service.trust.TrustAgentService$TrustAgentServiceWrapper
 android.service.voice.AlwaysOnHotwordDetector
 android.service.voice.AlwaysOnHotwordDetector$Callback
 android.service.voice.AlwaysOnHotwordDetector$EventPayload
@@ -3661,12 +3789,33 @@
 android.service.voice.IVoiceInteractionService$Stub
 android.service.voice.IVoiceInteractionService$Stub$Proxy
 android.service.voice.IVoiceInteractionSession
+android.service.voice.IVoiceInteractionSession$Stub
+android.service.voice.IVoiceInteractionSession$Stub$Proxy
+android.service.voice.IVoiceInteractionSessionService
+android.service.voice.IVoiceInteractionSessionService$Stub
+android.service.voice.IVoiceInteractionSessionService$Stub$Proxy
 android.service.voice.VoiceInteractionManagerInternal
 android.service.voice.VoiceInteractionService
 android.service.voice.VoiceInteractionService$1
 android.service.voice.VoiceInteractionService$MyHandler
 android.service.voice.VoiceInteractionServiceInfo
 android.service.voice.VoiceInteractionSession
+android.service.voice.VoiceInteractionSession$1
+android.service.voice.VoiceInteractionSession$2
+android.service.voice.VoiceInteractionSession$2$1
+android.service.voice.VoiceInteractionSession$3
+android.service.voice.VoiceInteractionSession$4
+android.service.voice.VoiceInteractionSession$AbortVoiceRequest
+android.service.voice.VoiceInteractionSession$CommandRequest
+android.service.voice.VoiceInteractionSession$CompleteVoiceRequest
+android.service.voice.VoiceInteractionSession$ConfirmationRequest
+android.service.voice.VoiceInteractionSession$Insets
+android.service.voice.VoiceInteractionSession$MyCallbacks
+android.service.voice.VoiceInteractionSession$PickOptionRequest
+android.service.voice.VoiceInteractionSession$Request
+android.service.voice.VoiceInteractionSessionService
+android.service.voice.VoiceInteractionSessionService$1
+android.service.voice.VoiceInteractionSessionService$2
 android.service.vr.IVrManager
 android.service.vr.IVrManager$Stub
 android.service.vr.IVrManager$Stub$Proxy
@@ -3733,6 +3882,7 @@
 android.system.StructFlock
 android.system.StructGroupReq
 android.system.StructGroupSourceReq
+android.system.StructIfaddrs
 android.system.StructLinger
 android.system.StructPasswd
 android.system.StructPollfd
@@ -3742,6 +3892,7 @@
 android.system.StructUcred
 android.system.StructUtsname
 android.system.UnixSocketAddress
+android.telecom.-$Lambda$3$afyb_ODGzn3xMew6fjs8ANSIdVo
 android.telecom.AudioState
 android.telecom.AudioState$1
 android.telecom.Call
@@ -3760,8 +3911,8 @@
 android.telecom.Connection
 android.telecom.Connection$1
 android.telecom.Connection$2
+android.telecom.Connection$FailureSignalingConnection
 android.telecom.Connection$Listener
-android.telecom.Connection$VideoProvider
 android.telecom.ConnectionRequest
 android.telecom.ConnectionRequest$1
 android.telecom.ConnectionService
@@ -3783,12 +3934,29 @@
 android.telecom.InCallService$2
 android.telecom.InCallService$InCallServiceBinder
 android.telecom.InCallService$VideoCall
-android.telecom.InCallService$VideoCall$Callback
 android.telecom.Log
 android.telecom.Log$1
+android.telecom.Logging.-$Lambda$2$OwO3BlCgqcOx28O1BaOAPVPor24
+android.telecom.Logging.-$Lambda$35$OwO3BlCgqcOx28O1BaOAPVPor24
+android.telecom.Logging.-$Lambda$47$OwO3BlCgqcOx28O1BaOAPVPor24
+android.telecom.Logging.EventManager
+android.telecom.Logging.EventManager$Event
+android.telecom.Logging.EventManager$EventListener
+android.telecom.Logging.EventManager$EventRecord
+android.telecom.Logging.EventManager$Loggable
+android.telecom.Logging.EventManager$TimedEventPair
+android.telecom.Logging.Runnable
+android.telecom.Logging.Runnable$1
+android.telecom.Logging.Session
+android.telecom.Logging.Session$Info
+android.telecom.Logging.Session$Info$1
+android.telecom.Logging.SessionManager
+android.telecom.Logging.SessionManager$ICurrentThreadId
+android.telecom.Logging.SessionManager$ISessionCleanupTimeoutMs
+android.telecom.Logging.SessionManager$ISessionIdQueryHandler
+android.telecom.Logging.SessionManager$ISessionListener
 android.telecom.ParcelableCall
 android.telecom.ParcelableCall$1
-android.telecom.ParcelableCallAnalytics
 android.telecom.ParcelableConference
 android.telecom.ParcelableConnection
 android.telecom.ParcelableConnection$1
@@ -3800,40 +3968,41 @@
 android.telecom.PhoneAccountHandle
 android.telecom.PhoneAccountHandle$1
 android.telecom.RemoteConnectionManager
-android.telecom.Response
 android.telecom.StatusHints
+android.telecom.TelecomAnalytics
+android.telecom.TelecomAnalytics$SessionTiming
+android.telecom.TelecomAnalytics$SessionTiming$1
 android.telecom.TelecomManager
+android.telecom.TimedEvent
 android.telecom.VideoProfile
 android.telecom.VideoProfile$1
-android.telecom.Voicemail
-android.telecom.Voicemail$Builder
 android.telephony.CarrierConfigManager
 android.telephony.CellBroadcastMessage
 android.telephony.CellIdentityCdma
 android.telephony.CellIdentityGsm
 android.telephony.CellIdentityLte
-android.telephony.CellIdentityLte$1
 android.telephony.CellIdentityWcdma
+android.telephony.CellIdentityWcdma$1
 android.telephony.CellInfo
 android.telephony.CellInfo$1
 android.telephony.CellInfoCdma
 android.telephony.CellInfoGsm
 android.telephony.CellInfoLte
-android.telephony.CellInfoLte$1
 android.telephony.CellInfoWcdma
+android.telephony.CellInfoWcdma$1
 android.telephony.CellLocation
 android.telephony.CellSignalStrength
 android.telephony.CellSignalStrengthCdma
 android.telephony.CellSignalStrengthGsm
 android.telephony.CellSignalStrengthLte
-android.telephony.CellSignalStrengthLte$1
 android.telephony.CellSignalStrengthWcdma
+android.telephony.CellSignalStrengthWcdma$1
+android.telephony.ClientRequestStats
+android.telephony.ClientRequestStats$1
 android.telephony.DisconnectCause
 android.telephony.IccOpenLogicalChannelResponse
 android.telephony.ModemActivityInfo
 android.telephony.ModemActivityInfo$1
-android.telephony.NeighboringCellInfo
-android.telephony.NeighboringCellInfo$1
 android.telephony.PhoneNumberFormattingTextWatcher
 android.telephony.PhoneNumberUtils
 android.telephony.PhoneStateListener
@@ -3844,7 +4013,6 @@
 android.telephony.PreciseDataConnectionState
 android.telephony.PreciseDataConnectionState$1
 android.telephony.RadioAccessFamily
-android.telephony.RadioAccessFamily$1
 android.telephony.Rlog
 android.telephony.ServiceState
 android.telephony.ServiceState$1
@@ -3859,26 +4027,41 @@
 android.telephony.SubscriptionManager$OnSubscriptionsChangedListener
 android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$1
 android.telephony.SubscriptionManager$OnSubscriptionsChangedListener$2
+android.telephony.TelephonyHistogram
+android.telephony.TelephonyHistogram$1
 android.telephony.TelephonyManager
 android.telephony.TelephonyManager$MultiSimVariants
+android.telephony.VisualVoicemailSmsFilterSettings
 android.telephony.VoLteServiceState
 android.telephony.VoLteServiceState$1
 android.telephony.cdma.CdmaCellLocation
+android.telephony.cdma.CdmaSmsCbProgramData
 android.telephony.gsm.GsmCellLocation
 android.telephony.gsm.SmsMessage
 android.text.AndroidBidi
 android.text.AndroidCharacter
 android.text.Annotation
-android.text.AutoText
 android.text.BidiFormatter
 android.text.BidiFormatter$DirectionalityEstimator
 android.text.BoringLayout
 android.text.BoringLayout$Metrics
+android.text.CharSequenceCharacterIterator
 android.text.ClipboardManager
 android.text.DynamicLayout
 android.text.DynamicLayout$ChangeWatcher
 android.text.Editable
 android.text.Editable$Factory
+android.text.FontConfig
+android.text.FontConfig$1
+android.text.FontConfig$Alias
+android.text.FontConfig$Alias$1
+android.text.FontConfig$Axis
+android.text.FontConfig$Axis$1
+android.text.FontConfig$Family
+android.text.FontConfig$Family$1
+android.text.FontConfig$Font
+android.text.FontConfig$Font$1
+android.text.FontManager
 android.text.GetChars
 android.text.GraphicsOperations
 android.text.Html
@@ -3889,6 +4072,8 @@
 android.text.HtmlToSpannedConverter$Bold
 android.text.HtmlToSpannedConverter$Href
 android.text.Hyphenator
+android.text.ITextClassificationService
+android.text.ITextClassificationService$Stub
 android.text.InputFilter
 android.text.InputFilter$LengthFilter
 android.text.InputType
@@ -3948,16 +4133,12 @@
 android.text.method.BaseKeyListener
 android.text.method.BaseMovementMethod
 android.text.method.DialerKeyListener
-android.text.method.DigitsKeyListener
 android.text.method.KeyListener
 android.text.method.LinkMovementMethod
 android.text.method.MetaKeyKeyListener
 android.text.method.MovementMethod
 android.text.method.NumberKeyListener
 android.text.method.PasswordTransformationMethod
-android.text.method.PasswordTransformationMethod$PasswordCharSequence
-android.text.method.PasswordTransformationMethod$ViewReference
-android.text.method.PasswordTransformationMethod$Visible
 android.text.method.QwertyKeyListener
 android.text.method.QwertyKeyListener$Replaced
 android.text.method.ReplacementTransformationMethod
@@ -3975,7 +4156,6 @@
 android.text.method.WordIterator
 android.text.style.AbsoluteSizeSpan
 android.text.style.AlignmentSpan
-android.text.style.AlignmentSpan$Standard
 android.text.style.BackgroundColorSpan
 android.text.style.BulletSpan
 android.text.style.CharacterStyle
@@ -3994,7 +4174,6 @@
 android.text.style.MetricAffectingSpan
 android.text.style.MetricAffectingSpan$Passthrough
 android.text.style.ParagraphStyle
-android.text.style.QuoteSpan
 android.text.style.RelativeSizeSpan
 android.text.style.ReplacementSpan
 android.text.style.SpellCheckSpan
@@ -4002,7 +4181,6 @@
 android.text.style.StyleSpan
 android.text.style.SubscriptSpan
 android.text.style.SuggestionSpan
-android.text.style.SuggestionSpan$1
 android.text.style.SuperscriptSpan
 android.text.style.TabStopSpan
 android.text.style.TextAppearanceSpan
@@ -4012,7 +4190,6 @@
 android.text.style.TtsSpan$SemioticClassBuilder
 android.text.style.TtsSpan$TelephoneBuilder
 android.text.style.TtsSpan$TextBuilder
-android.text.style.TtsSpan$VerbatimBuilder
 android.text.style.TypefaceSpan
 android.text.style.URLSpan
 android.text.style.UnderlineSpan
@@ -4028,7 +4205,6 @@
 android.text.util.Linkify$TransformFilter
 android.text.util.Rfc822Token
 android.text.util.Rfc822Tokenizer
-android.transition.ArcMotion
 android.transition.AutoTransition
 android.transition.ChangeBounds
 android.transition.ChangeBounds$1
@@ -4051,8 +4227,6 @@
 android.transition.ChangeTransform$GhostListener
 android.transition.ChangeTransform$PathAnimatorMatrix
 android.transition.ChangeTransform$Transforms
-android.transition.CircularPropagation
-android.transition.Explode
 android.transition.Fade
 android.transition.Fade$1
 android.transition.Fade$FadeAnimatorListener
@@ -4074,7 +4248,6 @@
 android.transition.Transition$2
 android.transition.Transition$3
 android.transition.Transition$AnimationInfo
-android.transition.Transition$ArrayListManager
 android.transition.Transition$EpicenterCallback
 android.transition.Transition$TransitionListener
 android.transition.Transition$TransitionListenerAdapter
@@ -4087,7 +4260,6 @@
 android.transition.TransitionSet$1
 android.transition.TransitionSet$TransitionSetListener
 android.transition.TransitionUtils
-android.transition.TransitionUtils$MatrixEvaluator
 android.transition.TransitionValues
 android.transition.TransitionValuesMaps
 android.transition.TranslationAnimationCreator
@@ -4109,7 +4281,7 @@
 android.util.Base64$Coder
 android.util.Base64$Decoder
 android.util.Base64$Encoder
-android.util.Base64DataException
+android.util.BootTimingsTraceLog
 android.util.ContainerHelpers
 android.util.DebugUtils
 android.util.DisplayMetrics
@@ -4130,12 +4302,14 @@
 android.util.Log
 android.util.Log$1
 android.util.Log$ImmediateLogWriter
-android.util.Log$TerribleFailure
+android.util.Log$NoPreloadHolder
 android.util.Log$TerribleFailureHandler
 android.util.LogPrinter
+android.util.LongArray
 android.util.LongSparseArray
 android.util.LongSparseLongArray
 android.util.LruCache
+android.util.MalformedJsonException
 android.util.MapCollections
 android.util.MapCollections$ArrayIterator
 android.util.MapCollections$EntrySet
@@ -4161,6 +4335,7 @@
 android.util.Property
 android.util.Range
 android.util.Rational
+android.util.ReflectiveProperty
 android.util.Singleton
 android.util.Size
 android.util.SizeF
@@ -4172,7 +4347,6 @@
 android.util.Spline
 android.util.Spline$MonotoneCubicSpline
 android.util.StateSet
-android.util.StringBuilderPrinter
 android.util.SuperNotCalledException
 android.util.TimeFormatException
 android.util.TimeUtils
@@ -4184,18 +4358,17 @@
 android.util.Xml$Encoding
 android.util.Xml$XmlSerializerFactory
 android.util.apk.ApkSignatureSchemeV2Verifier
+android.util.apk.ApkSignatureSchemeV2Verifier$ByteBufferDataSource
+android.util.apk.ApkSignatureSchemeV2Verifier$DataSource
+android.util.apk.ApkSignatureSchemeV2Verifier$MemoryMappedFileDataSource
+android.util.apk.ApkSignatureSchemeV2Verifier$SignatureInfo
 android.util.apk.ApkSignatureSchemeV2Verifier$SignatureNotFoundException
+android.util.apk.ApkSignatureSchemeV2Verifier$VerbatimX509Certificate
+android.util.apk.ApkSignatureSchemeV2Verifier$WrappedX509Certificate
 android.util.apk.ZipUtils
 android.util.jar.StrictJarFile
-android.util.jar.StrictJarFile$EntryIterator
-android.util.jar.StrictJarFile$JarFileInputStream
-android.util.jar.StrictJarFile$RAFStream
-android.util.jar.StrictJarFile$ZipInflaterInputStream
-android.util.jar.StrictJarManifest
-android.util.jar.StrictJarManifest$Chunk
-android.util.jar.StrictJarManifestReader
-android.util.jar.StrictJarVerifier
-android.util.jar.StrictJarVerifier$VerifierEntry
+android.view.-$Lambda$48$iU_USrtPm1XIm5H9QYQvXfBGDE4
+android.view.-$Lambda$49$iU_USrtPm1XIm5H9QYQvXfBGDE4
 android.view.AbsSavedState
 android.view.AbsSavedState$1
 android.view.AbsSavedState$2
@@ -4219,8 +4392,6 @@
 android.view.ContextMenu$ContextMenuInfo
 android.view.ContextThemeWrapper
 android.view.Display
-android.view.Display$ColorTransform
-android.view.Display$ColorTransform$1
 android.view.Display$HdrCapabilities
 android.view.Display$HdrCapabilities$1
 android.view.Display$Mode
@@ -4247,8 +4418,6 @@
 android.view.GestureDetector$OnGestureListener
 android.view.GestureDetector$SimpleOnGestureListener
 android.view.GhostView
-android.view.GraphicBuffer
-android.view.GraphicBuffer$1
 android.view.Gravity
 android.view.HandlerActionQueue
 android.view.HandlerActionQueue$HandlerAction
@@ -4266,8 +4435,15 @@
 android.view.IGraphicsStats$Stub$Proxy
 android.view.IInputFilter
 android.view.IOnKeyguardExitResult
+android.view.IPinnedStackController
+android.view.IPinnedStackController$Stub
+android.view.IPinnedStackController$Stub$Proxy
+android.view.IPinnedStackListener
+android.view.IPinnedStackListener$Stub
+android.view.IPinnedStackListener$Stub$Proxy
 android.view.IRotationWatcher
 android.view.IRotationWatcher$Stub
+android.view.IRotationWatcher$Stub$Proxy
 android.view.IWindow
 android.view.IWindow$Stub
 android.view.IWindow$Stub$Proxy
@@ -4307,8 +4483,6 @@
 android.view.KeyEvent$1
 android.view.KeyEvent$Callback
 android.view.KeyEvent$DispatcherState
-android.view.KeyboardShortcutGroup
-android.view.KeyboardShortcutInfo
 android.view.LayoutInflater
 android.view.LayoutInflater$Factory
 android.view.LayoutInflater$Factory2
@@ -4327,16 +4501,20 @@
 android.view.MotionEvent$PointerProperties
 android.view.NotificationHeaderView
 android.view.NotificationHeaderView$1
+android.view.NotificationHeaderView$2
 android.view.NotificationHeaderView$HeaderTouchListener
 android.view.OrientationEventListener
 android.view.OrientationEventListener$SensorEventListenerImpl
 android.view.PointerIcon
 android.view.PointerIcon$1
+android.view.RecordingCanvas
 android.view.RemotableViewMethod
 android.view.RenderNode
+android.view.RenderNode$NoImagePreloadHolder
 android.view.RenderNodeAnimator
 android.view.RenderNodeAnimator$1
 android.view.RenderNodeAnimator$DelayedAnimationHelper
+android.view.RenderNodeAnimatorSetHelper
 android.view.ScaleGestureDetector
 android.view.ScaleGestureDetector$1
 android.view.ScaleGestureDetector$OnScaleGestureListener
@@ -4347,6 +4525,7 @@
 android.view.Surface
 android.view.Surface$1
 android.view.Surface$CompatibleCanvas
+android.view.Surface$HwuiContext
 android.view.Surface$OutOfResourcesException
 android.view.SurfaceControl
 android.view.SurfaceControl$PhysicalDisplayInfo
@@ -4364,7 +4543,7 @@
 android.view.TextureView$1
 android.view.TextureView$SurfaceTextureListener
 android.view.ThreadedRenderer
-android.view.ThreadedRenderer$HardwareDrawCallbacks
+android.view.ThreadedRenderer$DrawCallbacks
 android.view.ThreadedRenderer$ProcessInitializer
 android.view.TouchDelegate
 android.view.VelocityTracker
@@ -4412,21 +4591,24 @@
 android.view.View$PerformClick
 android.view.View$ScrollabilityCache
 android.view.View$TintInfo
+android.view.View$TooltipInfo
 android.view.View$TransformationInfo
 android.view.View$UnsetPressedState
 android.view.ViewAnimationUtils
 android.view.ViewConfiguration
+android.view.ViewDebug$CapturedViewProperty
+android.view.ViewDebug$ExportedProperty
 android.view.ViewDebug$HierarchyHandler
 android.view.ViewGroup
 android.view.ViewGroup$1
 android.view.ViewGroup$2
 android.view.ViewGroup$3
+android.view.ViewGroup$4
 android.view.ViewGroup$LayoutParams
 android.view.ViewGroup$MarginLayoutParams
 android.view.ViewGroup$OnHierarchyChangeListener
 android.view.ViewGroup$TouchTarget
 android.view.ViewGroupOverlay
-android.view.ViewHierarchyEncoder
 android.view.ViewManager
 android.view.ViewOutlineProvider
 android.view.ViewOutlineProvider$1
@@ -4489,6 +4671,7 @@
 android.view.Window
 android.view.Window$Callback
 android.view.Window$OnWindowDismissedCallback
+android.view.Window$OnWindowSwipeDismissedCallback
 android.view.Window$WindowControllerCallback
 android.view.WindowAnimationFrameStats
 android.view.WindowAnimationFrameStats$1
@@ -4520,18 +4703,20 @@
 android.view.WindowManagerPolicy$OnKeyguardExitResult
 android.view.WindowManagerPolicy$PointerEventListener
 android.view.WindowManagerPolicy$ScreenOnListener
+android.view.WindowManagerPolicy$StartingSurface
 android.view.WindowManagerPolicy$WindowManagerFuncs
 android.view.WindowManagerPolicy$WindowState
 android.view.accessibility.AccessibilityEvent
-android.view.accessibility.AccessibilityEvent$1
 android.view.accessibility.AccessibilityEventSource
 android.view.accessibility.AccessibilityManager
 android.view.accessibility.AccessibilityManager$1
+android.view.accessibility.AccessibilityManager$AccessibilityServicesStateChangeListener
 android.view.accessibility.AccessibilityManager$AccessibilityStateChangeListener
 android.view.accessibility.AccessibilityManager$HighTextContrastChangeListener
 android.view.accessibility.AccessibilityManager$MyHandler
 android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
 android.view.accessibility.AccessibilityNodeInfo
+android.view.accessibility.AccessibilityNodeInfo$1
 android.view.accessibility.AccessibilityNodeInfo$AccessibilityAction
 android.view.accessibility.AccessibilityNodeInfo$CollectionInfo
 android.view.accessibility.AccessibilityNodeInfo$CollectionItemInfo
@@ -4561,6 +4746,8 @@
 android.view.animation.Animation$NoImagePreloadHolder
 android.view.animation.AnimationSet
 android.view.animation.AnimationUtils
+android.view.animation.AnimationUtils$1
+android.view.animation.AnimationUtils$AnimationState
 android.view.animation.BaseInterpolator
 android.view.animation.ClipRectAnimation
 android.view.animation.CycleInterpolator
@@ -4576,12 +4763,16 @@
 android.view.animation.ScaleAnimation
 android.view.animation.Transformation
 android.view.animation.TranslateAnimation
+android.view.autofill.AutoFillId
+android.view.autofill.AutoFillId$1
+android.view.autofill.AutoFillManager
+android.view.autofill.AutoFillType
+android.view.autofill.AutoFillType$1
 android.view.inputmethod.BaseInputConnection
 android.view.inputmethod.CompletionInfo
 android.view.inputmethod.CompletionInfo$1
 android.view.inputmethod.ComposingText
 android.view.inputmethod.CorrectionInfo
-android.view.inputmethod.CorrectionInfo$1
 android.view.inputmethod.CursorAnchorInfo
 android.view.inputmethod.CursorAnchorInfo$Builder
 android.view.inputmethod.EditorInfo
@@ -4595,6 +4786,7 @@
 android.view.inputmethod.InputConnection
 android.view.inputmethod.InputConnectionInspector
 android.view.inputmethod.InputConnectionWrapper
+android.view.inputmethod.InputContentInfo
 android.view.inputmethod.InputMethod
 android.view.inputmethod.InputMethod$SessionCallback
 android.view.inputmethod.InputMethodInfo
@@ -4614,6 +4806,8 @@
 android.view.inputmethod.InputMethodSubtype$1
 android.view.inputmethod.InputMethodSubtype$InputMethodSubtypeBuilder
 android.view.inputmethod.InputMethodSubtypeArray
+android.view.textclassifier.TextClassificationManager
+android.view.textclassifier.TextLanguage
 android.view.textservice.SentenceSuggestionsInfo
 android.view.textservice.SentenceSuggestionsInfo$1
 android.view.textservice.SpellCheckerInfo
@@ -4645,10 +4839,13 @@
 android.webkit.JsPromptResult
 android.webkit.JsResult
 android.webkit.MimeTypeMap
+android.webkit.ServiceWorkerClient
 android.webkit.ServiceWorkerController
+android.webkit.ServiceWorkerWebSettings
 android.webkit.SslErrorHandler
 android.webkit.TokenBindingService
 android.webkit.URLUtil
+android.webkit.UserPackage
 android.webkit.ValueCallback
 android.webkit.WebBackForwardList
 android.webkit.WebChromeClient
@@ -4657,7 +4854,6 @@
 android.webkit.WebIconDatabase
 android.webkit.WebMessage
 android.webkit.WebMessagePort
-android.webkit.WebResourceError
 android.webkit.WebResourceRequest
 android.webkit.WebResourceResponse
 android.webkit.WebSettings
@@ -4693,12 +4889,13 @@
 android.webkit.WebViewProviderInfo$1
 android.webkit.WebViewProviderResponse
 android.webkit.WebViewProviderResponse$1
+android.webkit.WebViewZygote
+android.widget.-$Lambda$50$tfOQKOmkDz_xLYaBQX_cysn8vbE
 android.widget.AbsListView
 android.widget.AbsListView$3
 android.widget.AbsListView$4
 android.widget.AbsListView$AbsPositionScroller
 android.widget.AbsListView$AdapterDataSetObserver
-android.widget.AbsListView$CheckForLongPress
 android.widget.AbsListView$CheckForTap
 android.widget.AbsListView$FlingRunnable
 android.widget.AbsListView$FlingRunnable$1
@@ -4709,6 +4906,7 @@
 android.widget.AbsListView$OnScrollListener
 android.widget.AbsListView$PerformClick
 android.widget.AbsListView$PositionScroller
+android.widget.AbsListView$PositionScroller$1
 android.widget.AbsListView$RecycleBin
 android.widget.AbsListView$RecyclerListener
 android.widget.AbsListView$SavedState
@@ -4746,7 +4944,6 @@
 android.widget.AdapterView$OnItemLongClickListener
 android.widget.AdapterView$OnItemSelectedListener
 android.widget.AdapterView$SelectionNotifier
-android.widget.Advanceable
 android.widget.ArrayAdapter
 android.widget.AutoCompleteTextView
 android.widget.AutoCompleteTextView$DropDownItemClickListener
@@ -4768,7 +4965,6 @@
 android.widget.CompoundButton$SavedState$1
 android.widget.CursorAdapter
 android.widget.CursorFilter$CursorFilterClient
-android.widget.DatePicker
 android.widget.DatePicker$OnDateChangedListener
 android.widget.DateTimeView
 android.widget.DateTimeView$ReceiverInfo
@@ -4781,7 +4977,6 @@
 android.widget.Editor$1
 android.widget.Editor$2
 android.widget.Editor$Blink
-android.widget.Editor$CorrectionHighlighter
 android.widget.Editor$CursorAnchorInfoNotifier
 android.widget.Editor$CursorController
 android.widget.Editor$EditOperation
@@ -4794,6 +4989,7 @@
 android.widget.Editor$InsertionPointCursorController
 android.widget.Editor$PositionListener
 android.widget.Editor$ProcessTextIntentActionsHandler
+android.widget.Editor$SelectionHandleView
 android.widget.Editor$SelectionModifierCursorController
 android.widget.Editor$SpanController
 android.widget.Editor$SuggestionHelper
@@ -4802,7 +4998,6 @@
 android.widget.Editor$TextViewPositionListener
 android.widget.Editor$UndoInputFilter
 android.widget.ExpandableListConnector
-android.widget.ExpandableListView
 android.widget.FastScroller
 android.widget.FastScroller$1
 android.widget.FastScroller$2
@@ -4896,7 +5091,6 @@
 android.widget.PopupWindow$1
 android.widget.PopupWindow$2
 android.widget.PopupWindow$3
-android.widget.PopupWindow$4
 android.widget.PopupWindow$OnDismissListener
 android.widget.PopupWindow$PopupBackgroundView
 android.widget.PopupWindow$PopupDecorView
@@ -4904,6 +5098,7 @@
 android.widget.PopupWindow$PopupDecorView$2
 android.widget.PopupWindow$PopupDecorView$2$1
 android.widget.PopupWindow$PopupDecorView$3
+android.widget.PopupWindow$PopupDecorView$4
 android.widget.ProgressBar
 android.widget.ProgressBar$1
 android.widget.ProgressBar$ProgressTintInfo
@@ -4943,10 +5138,7 @@
 android.widget.RemoteViews$SetDrawableParameters
 android.widget.RemoteViews$SetOnClickPendingIntent
 android.widget.RemoteViews$SetOnClickPendingIntent$1
-android.widget.RemoteViews$SetRemoteInputsAction
-android.widget.RemoteViews$TextViewDrawableAction
 android.widget.RemoteViews$ViewGroupAction
-android.widget.RemoteViews$ViewPaddingAction
 android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
 android.widget.RemoteViewsService
 android.widget.RemoteViewsService$RemoteViewsFactory
@@ -4973,11 +5165,10 @@
 android.widget.SearchView$OnCloseListener
 android.widget.SearchView$OnQueryTextListener
 android.widget.SearchView$SearchAutoComplete
+android.widget.SearchView$UpdatableTouchDelegate
 android.widget.SectionIndexer
 android.widget.SeekBar
 android.widget.SeekBar$OnSeekBarChangeListener
-android.widget.SimpleAdapter
-android.widget.SimpleAdapter$ViewBinder
 android.widget.SimpleCursorAdapter
 android.widget.Space
 android.widget.SpellChecker
@@ -4985,7 +5176,6 @@
 android.widget.SpellChecker$SpellParser
 android.widget.Spinner
 android.widget.Spinner$1
-android.widget.Spinner$DialogPopup
 android.widget.Spinner$DropDownAdapter
 android.widget.Spinner$DropdownPopup
 android.widget.Spinner$DropdownPopup$1
@@ -5035,7 +5225,6 @@
 android.widget.Toast
 android.widget.Toast$TN
 android.widget.Toast$TN$1
-android.widget.Toast$TN$2
 android.widget.ToggleButton
 android.widget.Toolbar
 android.widget.Toolbar$1
@@ -5059,6 +5248,7 @@
 android.widget.ViewFlipper$2
 android.widget.ViewSwitcher
 android.widget.WrapperListAdapter
+android.widget.ZoomButtonsController
 com.android.dex.ClassData
 com.android.dex.ClassData$Method
 com.android.dex.ClassDef
@@ -5085,9 +5275,19 @@
 com.android.dex.util.ByteOutput
 com.android.dex.util.ExceptionWithContext
 com.android.dex.util.FileUtils
+com.android.framework.protobuf.nano.CodedInputByteBufferNano
+com.android.framework.protobuf.nano.CodedOutputByteBufferNano
+com.android.framework.protobuf.nano.ExtendableMessageNano
+com.android.framework.protobuf.nano.InternalNano
+com.android.framework.protobuf.nano.InvalidProtocolBufferNanoException
+com.android.framework.protobuf.nano.MessageNano
+com.android.framework.protobuf.nano.WireFormatNano
+com.android.i18n.phonenumbers.AlternateFormatsCountryCodeSet
 com.android.i18n.phonenumbers.AsYouTypeFormatter
 com.android.i18n.phonenumbers.CountryCodeToRegionCodeMap
 com.android.i18n.phonenumbers.MetadataLoader
+com.android.i18n.phonenumbers.MetadataManager
+com.android.i18n.phonenumbers.MetadataManager$1
 com.android.i18n.phonenumbers.MetadataSource
 com.android.i18n.phonenumbers.MultiFileMetadataSourceImpl
 com.android.i18n.phonenumbers.NumberParseException
@@ -5096,7 +5296,6 @@
 com.android.i18n.phonenumbers.PhoneNumberMatcher$State
 com.android.i18n.phonenumbers.PhoneNumberUtil
 com.android.i18n.phonenumbers.PhoneNumberUtil$1
-com.android.i18n.phonenumbers.PhoneNumberUtil$2
 com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency
 com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$1
 com.android.i18n.phonenumbers.PhoneNumberUtil$Leniency$2
@@ -5114,19 +5313,13 @@
 com.android.i18n.phonenumbers.RegexCache
 com.android.i18n.phonenumbers.RegexCache$LRUCache
 com.android.i18n.phonenumbers.RegexCache$LRUCache$1
+com.android.i18n.phonenumbers.ShortNumbersRegionCodeSet
 com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder
-com.android.i18n.phonenumbers.prefixmapper.DefaultMapStorage
 com.android.i18n.phonenumbers.prefixmapper.MappingFileProvider
-com.android.i18n.phonenumbers.prefixmapper.PhonePrefixMap
-com.android.i18n.phonenumbers.prefixmapper.PhonePrefixMapStorageStrategy
 com.android.i18n.phonenumbers.prefixmapper.PrefixFileReader
-com.android.ims.ImsCall
-com.android.ims.ImsCall$ImsCallSessionListenerProxy
 com.android.ims.ImsCall$Listener
 com.android.ims.ImsCallForwardInfo
 com.android.ims.ImsCallProfile
-com.android.ims.ImsCallProfile$1
-com.android.ims.ImsConferenceState
 com.android.ims.ImsConfig
 com.android.ims.ImsConfigListener
 com.android.ims.ImsConfigListener$Stub
@@ -5141,37 +5334,77 @@
 com.android.ims.ImsManager$2
 com.android.ims.ImsManager$ImsRegistrationListenerProxy
 com.android.ims.ImsManager$ImsServiceDeathRecipient
+com.android.ims.ImsMultiEndpoint
+com.android.ims.ImsMultiEndpoint$ImsExternalCallStateListenerProxy
 com.android.ims.ImsReasonInfo
 com.android.ims.ImsReasonInfo$1
 com.android.ims.ImsSsInfo
-com.android.ims.ImsStreamMediaProfile
-com.android.ims.ImsStreamMediaProfile$1
-com.android.ims.ImsSuppServiceNotification
-com.android.ims.internal.ICall
 com.android.ims.internal.IImsCallSession
-com.android.ims.internal.IImsCallSession$Stub
 com.android.ims.internal.IImsCallSessionListener
-com.android.ims.internal.IImsCallSessionListener$Stub
 com.android.ims.internal.IImsConfig
 com.android.ims.internal.IImsConfig$Stub
+com.android.ims.internal.IImsConfig$Stub$Proxy
 com.android.ims.internal.IImsEcbm
 com.android.ims.internal.IImsEcbm$Stub
 com.android.ims.internal.IImsEcbmListener
 com.android.ims.internal.IImsEcbmListener$Stub
+com.android.ims.internal.IImsExternalCallStateListener
+com.android.ims.internal.IImsExternalCallStateListener$Stub
 com.android.ims.internal.IImsMultiEndpoint
+com.android.ims.internal.IImsMultiEndpoint$Stub
 com.android.ims.internal.IImsRegistrationListener
 com.android.ims.internal.IImsRegistrationListener$Stub
+com.android.ims.internal.IImsRegistrationListener$Stub$Proxy
 com.android.ims.internal.IImsService
 com.android.ims.internal.IImsService$Stub
+com.android.ims.internal.IImsService$Stub$Proxy
+com.android.ims.internal.IImsServiceController
+com.android.ims.internal.IImsServiceFeatureListener
 com.android.ims.internal.IImsUt
 com.android.ims.internal.IImsUt$Stub
 com.android.ims.internal.IImsUtListener
 com.android.ims.internal.IImsUtListener$Stub
-com.android.ims.internal.IImsVideoCallProvider
-com.android.ims.internal.ImsCallSession
-com.android.ims.internal.ImsCallSession$IImsCallSessionListenerProxy
-com.android.ims.internal.ImsCallSession$Listener
-com.android.ims.internal.ImsCallSession$State
+com.android.ims.internal.uce.common.CapInfo
+com.android.ims.internal.uce.common.CapInfo$1
+com.android.ims.internal.uce.common.StatusCode
+com.android.ims.internal.uce.common.StatusCode$1
+com.android.ims.internal.uce.common.UceLong
+com.android.ims.internal.uce.common.UceLong$1
+com.android.ims.internal.uce.options.IOptionsListener
+com.android.ims.internal.uce.options.IOptionsService
+com.android.ims.internal.uce.presence.IPresenceListener
+com.android.ims.internal.uce.presence.IPresenceListener$Stub
+com.android.ims.internal.uce.presence.IPresenceListener$Stub$Proxy
+com.android.ims.internal.uce.presence.IPresenceService
+com.android.ims.internal.uce.presence.IPresenceService$Stub
+com.android.ims.internal.uce.presence.IPresenceService$Stub$Proxy
+com.android.ims.internal.uce.presence.PresCapInfo
+com.android.ims.internal.uce.presence.PresCmdId
+com.android.ims.internal.uce.presence.PresCmdId$1
+com.android.ims.internal.uce.presence.PresCmdStatus
+com.android.ims.internal.uce.presence.PresCmdStatus$1
+com.android.ims.internal.uce.presence.PresPublishTriggerType
+com.android.ims.internal.uce.presence.PresPublishTriggerType$1
+com.android.ims.internal.uce.presence.PresResInfo
+com.android.ims.internal.uce.presence.PresResInfo$1
+com.android.ims.internal.uce.presence.PresResInstanceInfo
+com.android.ims.internal.uce.presence.PresResInstanceInfo$1
+com.android.ims.internal.uce.presence.PresRlmiInfo
+com.android.ims.internal.uce.presence.PresRlmiInfo$1
+com.android.ims.internal.uce.presence.PresServiceInfo
+com.android.ims.internal.uce.presence.PresSipResponse
+com.android.ims.internal.uce.presence.PresSipResponse$1
+com.android.ims.internal.uce.presence.PresSubscriptionState
+com.android.ims.internal.uce.presence.PresSubscriptionState$1
+com.android.ims.internal.uce.presence.PresTupleInfo
+com.android.ims.internal.uce.presence.PresTupleInfo$1
+com.android.ims.internal.uce.uceservice.IUceListener
+com.android.ims.internal.uce.uceservice.IUceListener$Stub
+com.android.ims.internal.uce.uceservice.IUceService
+com.android.ims.internal.uce.uceservice.IUceService$Stub
+com.android.ims.internal.uce.uceservice.IUceService$Stub$Proxy
+com.android.ims.internal.uce.uceservice.ImsUceManager
+com.android.ims.internal.uce.uceservice.ImsUceManager$UceServiceDeathRecipient
 com.android.internal.R$styleable
 com.android.internal.alsa.AlsaCardsParser
 com.android.internal.alsa.AlsaCardsParser$AlsaCardRecord
@@ -5186,17 +5419,6 @@
 com.android.internal.app.AlertController$CheckedItemAdapter
 com.android.internal.app.AlertController$RecycleListView
 com.android.internal.app.AssistUtils
-com.android.internal.app.ChooserActivity
-com.android.internal.app.ChooserActivity$1
-com.android.internal.app.ChooserActivity$BaseChooserTargetComparator
-com.android.internal.app.ChooserActivity$ChooserListAdapter
-com.android.internal.app.ChooserActivity$ChooserRowAdapter
-com.android.internal.app.ChooserActivity$ChooserRowAdapter$1
-com.android.internal.app.ChooserActivity$ChooserRowAdapter$2
-com.android.internal.app.ChooserActivity$ChooserRowAdapter$3
-com.android.internal.app.ChooserActivity$OffsetDataSetObserver
-com.android.internal.app.ChooserActivity$RowScale
-com.android.internal.app.ChooserActivity$RowViewHolder
 com.android.internal.app.IAppOpsCallback
 com.android.internal.app.IAppOpsCallback$Stub
 com.android.internal.app.IAppOpsCallback$Stub$Proxy
@@ -5204,6 +5426,7 @@
 com.android.internal.app.IAppOpsService$Stub
 com.android.internal.app.IAppOpsService$Stub$Proxy
 com.android.internal.app.IAssistScreenshotReceiver
+com.android.internal.app.IAssistScreenshotReceiver$Stub
 com.android.internal.app.IBatteryStats
 com.android.internal.app.IBatteryStats$Stub
 com.android.internal.app.IBatteryStats$Stub$Proxy
@@ -5215,41 +5438,34 @@
 com.android.internal.app.IVoiceInteractionManagerService
 com.android.internal.app.IVoiceInteractionManagerService$Stub
 com.android.internal.app.IVoiceInteractionManagerService$Stub$Proxy
+com.android.internal.app.IVoiceInteractionSessionListener
+com.android.internal.app.IVoiceInteractionSessionListener$Stub
+com.android.internal.app.IVoiceInteractionSessionListener$Stub$Proxy
 com.android.internal.app.IVoiceInteractionSessionShowCallback
 com.android.internal.app.IVoiceInteractionSessionShowCallback$Stub
+com.android.internal.app.IVoiceInteractionSessionShowCallback$Stub$Proxy
 com.android.internal.app.IVoiceInteractor
 com.android.internal.app.IVoiceInteractor$Stub
-com.android.internal.app.IntentForwarderActivity
+com.android.internal.app.IVoiceInteractor$Stub$Proxy
 com.android.internal.app.LocaleHelper
 com.android.internal.app.LocalePicker
 com.android.internal.app.LocalePickerWithRegion$LocaleSelectedListener
-com.android.internal.app.PlatLogoActivity
+com.android.internal.app.NightDisplayController
+com.android.internal.app.NightDisplayController$1
+com.android.internal.app.NightDisplayController$Callback
+com.android.internal.app.NightDisplayController$LocalTime
 com.android.internal.app.ProcessMap
 com.android.internal.app.ResolverActivity
-com.android.internal.app.ResolverActivity$1
-com.android.internal.app.ResolverActivity$2
-com.android.internal.app.ResolverActivity$3
-com.android.internal.app.ResolverActivity$DisplayResolveInfo
-com.android.internal.app.ResolverActivity$LoadAdapterIconTask
-com.android.internal.app.ResolverActivity$LoadIconTask
-com.android.internal.app.ResolverActivity$ResolveListAdapter
-com.android.internal.app.ResolverActivity$ResolvedComponentInfo
-com.android.internal.app.ResolverActivity$TargetInfo
-com.android.internal.app.ResolverActivity$ViewHolder
-com.android.internal.app.ResolverComparator
-com.android.internal.app.ResolverComparator$ScoredTarget
 com.android.internal.app.ToolbarActionBar
 com.android.internal.app.ToolbarActionBar$1
 com.android.internal.app.ToolbarActionBar$2
 com.android.internal.app.ToolbarActionBar$ActionMenuPresenterCallback
 com.android.internal.app.ToolbarActionBar$MenuBuilderCallback
 com.android.internal.app.ToolbarActionBar$ToolbarCallbackWrapper
-com.android.internal.app.UnlaunchableAppActivity
 com.android.internal.app.WindowDecorActionBar
 com.android.internal.app.WindowDecorActionBar$1
 com.android.internal.app.WindowDecorActionBar$2
 com.android.internal.app.WindowDecorActionBar$3
-com.android.internal.app.WindowDecorActionBar$ActionModeImpl
 com.android.internal.app.procstats.DumpUtils
 com.android.internal.app.procstats.DurationsTable
 com.android.internal.app.procstats.IProcessStats
@@ -5281,11 +5497,16 @@
 com.android.internal.backup.LocalTransport
 com.android.internal.backup.LocalTransportService
 com.android.internal.content.NativeLibraryHelper
-com.android.internal.content.NativeLibraryHelper$Handle
 com.android.internal.content.PackageHelper
 com.android.internal.content.PackageMonitor
 com.android.internal.content.ReferrerIntent
 com.android.internal.content.ReferrerIntent$1
+com.android.internal.font.IFontManager
+com.android.internal.font.IFontManager$Stub
+com.android.internal.graphics.drawable.AnimationScaleListDrawable
+com.android.internal.graphics.drawable.AnimationScaleListDrawable$AnimationScaleListState
+com.android.internal.hardware.AmbientDisplayConfiguration
+com.android.internal.inputmethod.IInputContentUriToken
 com.android.internal.inputmethod.InputMethodSubtypeHandle
 com.android.internal.inputmethod.InputMethodSubtypeSwitchingController
 com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$ControllerImpl
@@ -5296,6 +5517,7 @@
 com.android.internal.inputmethod.InputMethodSubtypeSwitchingController$StaticRotationList
 com.android.internal.inputmethod.InputMethodUtils
 com.android.internal.inputmethod.InputMethodUtils$1
+com.android.internal.inputmethod.InputMethodUtils$InputMethodListBuilder
 com.android.internal.inputmethod.InputMethodUtils$InputMethodSettings
 com.android.internal.inputmethod.LocaleUtils
 com.android.internal.inputmethod.LocaleUtils$LocaleExtractor
@@ -5321,6 +5543,7 @@
 com.android.internal.net.VpnInfo
 com.android.internal.net.VpnProfile
 com.android.internal.os.AndroidPrintStream
+com.android.internal.os.AppFuseMount
 com.android.internal.os.AtomicFile
 com.android.internal.os.BackgroundThread
 com.android.internal.os.BatterySipper
@@ -5334,6 +5557,8 @@
 com.android.internal.os.BatteryStatsImpl$BatteryCallback
 com.android.internal.os.BatteryStatsImpl$Clocks
 com.android.internal.os.BatteryStatsImpl$ControllerActivityCounterImpl
+com.android.internal.os.BatteryStatsImpl$Counter
+com.android.internal.os.BatteryStatsImpl$DurationTimer
 com.android.internal.os.BatteryStatsImpl$ExternalStatsSync
 com.android.internal.os.BatteryStatsImpl$LongSamplingCounter
 com.android.internal.os.BatteryStatsImpl$MyHandler
@@ -5351,6 +5576,7 @@
 com.android.internal.os.BatteryStatsImpl$Uid$3
 com.android.internal.os.BatteryStatsImpl$Uid$Pkg
 com.android.internal.os.BatteryStatsImpl$Uid$Pkg$Serv
+com.android.internal.os.BatteryStatsImpl$Uid$Proc
 com.android.internal.os.BatteryStatsImpl$Uid$Sensor
 com.android.internal.os.BatteryStatsImpl$Uid$Wakelock
 com.android.internal.os.BinderInternal
@@ -5359,6 +5585,9 @@
 com.android.internal.os.CameraPowerCalculator
 com.android.internal.os.CpuPowerCalculator
 com.android.internal.os.FlashlightPowerCalculator
+com.android.internal.os.FuseAppLoop
+com.android.internal.os.FuseAppLoop$1
+com.android.internal.os.FuseAppLoop$UnmountedException
 com.android.internal.os.HandlerCaller
 com.android.internal.os.HandlerCaller$Callback
 com.android.internal.os.HandlerCaller$MyHandler
@@ -5369,15 +5598,18 @@
 com.android.internal.os.IResultReceiver
 com.android.internal.os.IResultReceiver$Stub
 com.android.internal.os.IResultReceiver$Stub$Proxy
-com.android.internal.os.InstallerConnection
-com.android.internal.os.InstallerConnection$InstallerException
+com.android.internal.os.IShellCallback
+com.android.internal.os.IShellCallback$Stub
+com.android.internal.os.IShellCallback$Stub$Proxy
 com.android.internal.os.KernelCpuSpeedReader
+com.android.internal.os.KernelMemoryBandwidthStats
 com.android.internal.os.KernelUidCpuTimeReader
 com.android.internal.os.KernelWakelockReader
 com.android.internal.os.KernelWakelockStats
 com.android.internal.os.KernelWakelockStats$Entry
 com.android.internal.os.LoggingPrintStream
 com.android.internal.os.LoggingPrintStream$1
+com.android.internal.os.MemoryPowerCalculator
 com.android.internal.os.MobileRadioPowerCalculator
 com.android.internal.os.PathClassLoaderFactory
 com.android.internal.os.PowerCalculator
@@ -5385,31 +5617,35 @@
 com.android.internal.os.PowerProfile$CpuClusterKey
 com.android.internal.os.ProcessCpuTracker
 com.android.internal.os.ProcessCpuTracker$1
+com.android.internal.os.ProcessCpuTracker$FilterStats
 com.android.internal.os.ProcessCpuTracker$Stats
+com.android.internal.os.RoSystemProperties
 com.android.internal.os.RuntimeInit
 com.android.internal.os.RuntimeInit$1
 com.android.internal.os.RuntimeInit$Arguments
-com.android.internal.os.RuntimeInit$UncaughtHandler
+com.android.internal.os.RuntimeInit$KillApplicationHandler
+com.android.internal.os.RuntimeInit$LoggingHandler
 com.android.internal.os.SamplingProfilerIntegration
 com.android.internal.os.SensorPowerCalculator
 com.android.internal.os.SomeArgs
+com.android.internal.os.TransferPipe
 com.android.internal.os.WakelockPowerCalculator
-com.android.internal.os.WifiPowerEstimator
+com.android.internal.os.WifiPowerCalculator
 com.android.internal.os.Zygote
+com.android.internal.os.Zygote$MethodAndArgsCaller
 com.android.internal.os.ZygoteConnection
 com.android.internal.os.ZygoteConnection$Arguments
 com.android.internal.os.ZygoteInit
-com.android.internal.os.ZygoteInit$MethodAndArgsCaller
 com.android.internal.os.ZygoteSecurityException
+com.android.internal.os.ZygoteServer
 com.android.internal.policy.DecorContext
 com.android.internal.policy.DecorView
 com.android.internal.policy.DecorView$1
-com.android.internal.policy.DecorView$4
-com.android.internal.policy.DecorView$ActionModeCallback2Wrapper
 com.android.internal.policy.DecorView$ColorViewState
 com.android.internal.policy.DividerSnapAlgorithm
 com.android.internal.policy.DividerSnapAlgorithm$SnapTarget
 com.android.internal.policy.DockedDividerUtils
+com.android.internal.policy.IKeyguardDismissCallback
 com.android.internal.policy.IKeyguardDrawnCallback
 com.android.internal.policy.IKeyguardDrawnCallback$Stub
 com.android.internal.policy.IKeyguardDrawnCallback$Stub$Proxy
@@ -5434,6 +5670,8 @@
 com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback
 com.android.internal.policy.PhoneWindow$RotationWatcher
 com.android.internal.policy.PhoneWindow$RotationWatcher$1
+com.android.internal.policy.PipMotionHelper
+com.android.internal.policy.PipSnapAlgorithm
 com.android.internal.statusbar.IStatusBar
 com.android.internal.statusbar.IStatusBar$Stub
 com.android.internal.statusbar.IStatusBar$Stub$Proxy
@@ -5464,10 +5702,8 @@
 com.android.internal.telecom.RemoteServiceCallback
 com.android.internal.telecom.RemoteServiceCallback$Stub
 com.android.internal.telecom.RemoteServiceCallback$Stub$Proxy
-com.android.internal.telephony.ATParseEx
-com.android.internal.telephony.AsyncEmergencyContactNotifier
+com.android.internal.telephony.AppSmsManager
 com.android.internal.telephony.BaseCommands
-com.android.internal.telephony.BlockChecker
 com.android.internal.telephony.Call
 com.android.internal.telephony.Call$SrvccState
 com.android.internal.telephony.Call$State
@@ -5481,28 +5717,30 @@
 com.android.internal.telephony.CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler$CallerInfoWorkerHandler
 com.android.internal.telephony.CallerInfoAsyncQuery$CookieWrapper
 com.android.internal.telephony.CallerInfoAsyncQuery$OnQueryCompleteListener
+com.android.internal.telephony.CarrierActionAgent
 com.android.internal.telephony.CarrierAppUtils
 com.android.internal.telephony.CarrierServiceBindHelper
 com.android.internal.telephony.CarrierServiceBindHelper$1
 com.android.internal.telephony.CarrierServiceBindHelper$2
 com.android.internal.telephony.CarrierServiceBindHelper$AppBinding
 com.android.internal.telephony.CarrierServiceBindHelper$CarrierServicePackageMonitor
+com.android.internal.telephony.CarrierServiceStateTracker
+com.android.internal.telephony.CarrierServiceStateTracker$1
+com.android.internal.telephony.CarrierSignalAgent
+com.android.internal.telephony.CarrierSignalAgent$1
 com.android.internal.telephony.CellBroadcastHandler
 com.android.internal.telephony.CellNetworkScanResult
+com.android.internal.telephony.ClientWakelockAccountant
+com.android.internal.telephony.ClientWakelockTracker
 com.android.internal.telephony.CommandException
 com.android.internal.telephony.CommandException$Error
 com.android.internal.telephony.CommandsInterface
 com.android.internal.telephony.CommandsInterface$RadioState
 com.android.internal.telephony.Connection
-com.android.internal.telephony.Connection$Listener
-com.android.internal.telephony.Connection$ListenerBase
-com.android.internal.telephony.Connection$PostDialListener
-com.android.internal.telephony.Connection$PostDialState
 com.android.internal.telephony.DctConstants$Activity
 com.android.internal.telephony.DctConstants$State
 com.android.internal.telephony.DebugService
 com.android.internal.telephony.DefaultPhoneNotifier
-com.android.internal.telephony.DriverCall
 com.android.internal.telephony.EncodeException
 com.android.internal.telephony.GsmAlphabet
 com.android.internal.telephony.GsmAlphabet$TextEncodingDetails
@@ -5514,6 +5752,7 @@
 com.android.internal.telephony.GsmCdmaPhone$1
 com.android.internal.telephony.GsmCdmaPhone$2
 com.android.internal.telephony.HardwareConfig
+com.android.internal.telephony.HbpcdUtils
 com.android.internal.telephony.ICarrierConfigLoader
 com.android.internal.telephony.ICarrierConfigLoader$Stub
 com.android.internal.telephony.ICarrierConfigLoader$Stub$Proxy
@@ -5521,7 +5760,6 @@
 com.android.internal.telephony.IIccPhoneBook$Stub
 com.android.internal.telephony.IMms
 com.android.internal.telephony.IMms$Stub
-com.android.internal.telephony.IMms$Stub$Proxy
 com.android.internal.telephony.IOnSubscriptionsChangedListener
 com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub
 com.android.internal.telephony.IOnSubscriptionsChangedListener$Stub$Proxy
@@ -5555,20 +5793,16 @@
 com.android.internal.telephony.IccSmsInterfaceManager$CellBroadcastRangeManager
 com.android.internal.telephony.ImsSMSDispatcher
 com.android.internal.telephony.InboundSmsHandler
+com.android.internal.telephony.InboundSmsHandler$1
 com.android.internal.telephony.InboundSmsHandler$DefaultState
 com.android.internal.telephony.InboundSmsHandler$DeliveringState
 com.android.internal.telephony.InboundSmsHandler$IdleState
-com.android.internal.telephony.InboundSmsHandler$SmsBroadcastReceiver
+com.android.internal.telephony.InboundSmsHandler$NewMessageNotificationActionReceiver
 com.android.internal.telephony.InboundSmsHandler$StartupState
 com.android.internal.telephony.InboundSmsHandler$WaitingState
-com.android.internal.telephony.InboundSmsTracker
 com.android.internal.telephony.IntRangeManager
-com.android.internal.telephony.IntRangeManager$ClientRange
-com.android.internal.telephony.IntRangeManager$IntRange
 com.android.internal.telephony.MccTable
 com.android.internal.telephony.MccTable$MccEntry
-com.android.internal.telephony.MmiCode
-com.android.internal.telephony.MmiCode$State
 com.android.internal.telephony.OperatorInfo
 com.android.internal.telephony.Phone
 com.android.internal.telephony.Phone$1
@@ -5577,7 +5811,6 @@
 com.android.internal.telephony.PhoneFactory
 com.android.internal.telephony.PhoneInternalInterface
 com.android.internal.telephony.PhoneInternalInterface$DataActivityState
-com.android.internal.telephony.PhoneInternalInterface$SuppService
 com.android.internal.telephony.PhoneNotifier
 com.android.internal.telephony.PhoneStateIntentReceiver
 com.android.internal.telephony.PhoneSubInfoController
@@ -5593,43 +5826,39 @@
 com.android.internal.telephony.RIL$2
 com.android.internal.telephony.RIL$RILReceiver
 com.android.internal.telephony.RIL$RILSender
+com.android.internal.telephony.RIL$RadioProxyDeathRecipient
+com.android.internal.telephony.RIL$RilHandler
 com.android.internal.telephony.RILConstants
 com.android.internal.telephony.RILRequest
 com.android.internal.telephony.RadioCapability
+com.android.internal.telephony.RadioIndication
+com.android.internal.telephony.RadioResponse
+com.android.internal.telephony.RatRatcheter
+com.android.internal.telephony.RatRatcheter$1
 com.android.internal.telephony.RestrictedState
 com.android.internal.telephony.RetryManager
-com.android.internal.telephony.RetryManager$RetryRec
+com.android.internal.telephony.RilWakelockInfo
 com.android.internal.telephony.SMSDispatcher
 com.android.internal.telephony.SMSDispatcher$SettingsObserver
-com.android.internal.telephony.SMSDispatcher$SmsTracker
 com.android.internal.telephony.ServiceStateTracker
 com.android.internal.telephony.ServiceStateTracker$1
 com.android.internal.telephony.ServiceStateTracker$2
 com.android.internal.telephony.ServiceStateTracker$3
 com.android.internal.telephony.ServiceStateTracker$CellInfoResult
 com.android.internal.telephony.ServiceStateTracker$SstSubscriptionsChangedListener
-com.android.internal.telephony.SmsAddress
 com.android.internal.telephony.SmsApplication
 com.android.internal.telephony.SmsApplication$SmsApplicationData
 com.android.internal.telephony.SmsApplication$SmsPackageMonitor
 com.android.internal.telephony.SmsBroadcastUndelivered
 com.android.internal.telephony.SmsBroadcastUndelivered$1
 com.android.internal.telephony.SmsBroadcastUndelivered$ScanRawTableThread
-com.android.internal.telephony.SmsConstants$MessageClass
-com.android.internal.telephony.SmsHeader
-com.android.internal.telephony.SmsHeader$PortAddrs
 com.android.internal.telephony.SmsMessageBase
-com.android.internal.telephony.SmsMessageBase$SubmitPduBase
-com.android.internal.telephony.SmsNumberUtils
-com.android.internal.telephony.SmsResponse
 com.android.internal.telephony.SmsStorageMonitor
 com.android.internal.telephony.SmsStorageMonitor$1
 com.android.internal.telephony.SmsUsageMonitor
 com.android.internal.telephony.SmsUsageMonitor$SettingsObserver
 com.android.internal.telephony.SmsUsageMonitor$SettingsObserverHandler
-com.android.internal.telephony.SmsUsageMonitor$ShortCodePatternMatcher
 com.android.internal.telephony.SubscriptionController
-com.android.internal.telephony.SubscriptionController$1
 com.android.internal.telephony.SubscriptionController$ScLocalLog
 com.android.internal.telephony.SubscriptionInfoUpdater
 com.android.internal.telephony.SubscriptionInfoUpdater$1
@@ -5640,10 +5869,8 @@
 com.android.internal.telephony.TelephonyCapabilities
 com.android.internal.telephony.TelephonyComponentFactory
 com.android.internal.telephony.TelephonyDevController
-com.android.internal.telephony.TelephonyEventLog
 com.android.internal.telephony.TelephonyTester
 com.android.internal.telephony.TelephonyTester$1
-com.android.internal.telephony.UUSInfo
 com.android.internal.telephony.UiccPhoneBookController
 com.android.internal.telephony.UiccSmsController
 com.android.internal.telephony.WakeLockStateMachine
@@ -5652,45 +5879,36 @@
 com.android.internal.telephony.WakeLockStateMachine$IdleState
 com.android.internal.telephony.WakeLockStateMachine$WaitingState
 com.android.internal.telephony.WapPushOverSms
+com.android.internal.telephony.WapPushOverSms$1
+com.android.internal.telephony.WapPushOverSms$BindServiceThread
 com.android.internal.telephony.cat.AppInterface
-com.android.internal.telephony.cat.CatException
+com.android.internal.telephony.cat.AppInterface$CommandType
+com.android.internal.telephony.cat.CatCmdMessage
+com.android.internal.telephony.cat.CatCmdMessage$BrowserSettings
+com.android.internal.telephony.cat.CatCmdMessage$CallSettings
+com.android.internal.telephony.cat.CatCmdMessage$SetupEventListSettings
 com.android.internal.telephony.cat.CatLog
+com.android.internal.telephony.cat.CatResponseMessage
 com.android.internal.telephony.cat.CatService
-com.android.internal.telephony.cat.CommandParamsFactory
-com.android.internal.telephony.cat.IconLoader
-com.android.internal.telephony.cat.ResultException
-com.android.internal.telephony.cat.RilMessageDecoder
-com.android.internal.telephony.cat.RilMessageDecoder$StateCmdParamsReady
-com.android.internal.telephony.cat.RilMessageDecoder$StateStart
-com.android.internal.telephony.cdma.CdmaCallWaitingNotification
+com.android.internal.telephony.cat.Input
+com.android.internal.telephony.cat.Item
+com.android.internal.telephony.cat.LaunchBrowserMode
+com.android.internal.telephony.cat.Menu
+com.android.internal.telephony.cat.ResultCode
+com.android.internal.telephony.cat.TextMessage
+com.android.internal.telephony.cat.ToneSettings
 com.android.internal.telephony.cdma.CdmaInboundSmsHandler
-com.android.internal.telephony.cdma.CdmaInformationRecords$CdmaDisplayInfoRec
-com.android.internal.telephony.cdma.CdmaInformationRecords$CdmaSignalInfoRec
 com.android.internal.telephony.cdma.CdmaSMSDispatcher
 com.android.internal.telephony.cdma.CdmaServiceCategoryProgramHandler
 com.android.internal.telephony.cdma.CdmaServiceCategoryProgramHandler$1
-com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo
 com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager
 com.android.internal.telephony.cdma.EriInfo
 com.android.internal.telephony.cdma.EriManager
+com.android.internal.telephony.cdma.EriManager$EriDisplayInformation
 com.android.internal.telephony.cdma.EriManager$EriFile
-com.android.internal.telephony.cdma.SignalToneUtil
 com.android.internal.telephony.dataconnection.ApnContext
-com.android.internal.telephony.dataconnection.ApnSetting
-com.android.internal.telephony.dataconnection.DataCallResponse
-com.android.internal.telephony.dataconnection.DataCallResponse$SetupResult
 com.android.internal.telephony.dataconnection.DataConnection
-com.android.internal.telephony.dataconnection.DataConnection$ConnectionParams
-com.android.internal.telephony.dataconnection.DataConnection$DcActivatingState
-com.android.internal.telephony.dataconnection.DataConnection$DcActiveState
-com.android.internal.telephony.dataconnection.DataConnection$DcDefaultState
-com.android.internal.telephony.dataconnection.DataConnection$DcDisconnectingState
-com.android.internal.telephony.dataconnection.DataConnection$DcDisconnectionErrorCreatingConnection
-com.android.internal.telephony.dataconnection.DataConnection$DcInactiveState
-com.android.internal.telephony.dataconnection.DataConnection$DcNetworkAgent
-com.android.internal.telephony.dataconnection.DataConnection$DisconnectParams
-com.android.internal.telephony.dataconnection.DataConnection$UpdateLinkPropertyResult
-com.android.internal.telephony.dataconnection.DcAsyncChannel
+com.android.internal.telephony.dataconnection.DataEnabledSettings
 com.android.internal.telephony.dataconnection.DcController
 com.android.internal.telephony.dataconnection.DcController$1
 com.android.internal.telephony.dataconnection.DcController$DccDefaultState
@@ -5717,19 +5935,24 @@
 com.android.internal.telephony.gsm.GsmCellBroadcastHandler
 com.android.internal.telephony.gsm.GsmInboundSmsHandler
 com.android.internal.telephony.gsm.GsmSMSDispatcher
-com.android.internal.telephony.gsm.GsmSmsAddress
-com.android.internal.telephony.gsm.SimTlv
-com.android.internal.telephony.gsm.SmsBroadcastConfigInfo
 com.android.internal.telephony.gsm.SmsMessage
-com.android.internal.telephony.gsm.SmsMessage$PduParser
-com.android.internal.telephony.gsm.SmsMessage$SubmitPdu
-com.android.internal.telephony.gsm.SuppServiceNotification
 com.android.internal.telephony.gsm.UsimDataDownloadHandler
-com.android.internal.telephony.gsm.UsimPhoneBookManager
+com.android.internal.telephony.ims.-$Lambda$2$6hDwuvYxqWrzW_Ex5wc53XnUOpg
+com.android.internal.telephony.ims.-$Lambda$3$6hDwuvYxqWrzW_Ex5wc53XnUOpg
+com.android.internal.telephony.ims.-$Lambda$4$6hDwuvYxqWrzW_Ex5wc53XnUOpg
+com.android.internal.telephony.ims.ImsResolver
+com.android.internal.telephony.ims.ImsResolver$1
+com.android.internal.telephony.ims.ImsResolver$2
+com.android.internal.telephony.ims.ImsResolver$3
+com.android.internal.telephony.ims.ImsResolver$ImsServiceControllerFactory
+com.android.internal.telephony.ims.ImsResolver$SubscriptionManagerProxy
+com.android.internal.telephony.ims.ImsServiceController$ImsServiceControllerCallbacks
 com.android.internal.telephony.imsphone.ImsExternalCallTracker
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$1
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$2
 com.android.internal.telephony.imsphone.ImsExternalCallTracker$ExternalCallStateListener
 com.android.internal.telephony.imsphone.ImsExternalCallTracker$ExternalConnectionListener
-com.android.internal.telephony.imsphone.ImsExternalConnection
+com.android.internal.telephony.imsphone.ImsExternalCallTracker$ImsCallNotify
 com.android.internal.telephony.imsphone.ImsExternalConnection$Listener
 com.android.internal.telephony.imsphone.ImsPhone
 com.android.internal.telephony.imsphone.ImsPhone$1
@@ -5743,64 +5966,43 @@
 com.android.internal.telephony.imsphone.ImsPhoneCallTracker$3
 com.android.internal.telephony.imsphone.ImsPhoneCallTracker$4
 com.android.internal.telephony.imsphone.ImsPhoneCallTracker$5
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker$6
+com.android.internal.telephony.imsphone.ImsPhoneCallTracker$PhoneStateListener
 com.android.internal.telephony.imsphone.ImsPhoneCommandInterface
-com.android.internal.telephony.imsphone.ImsPhoneConnection
-com.android.internal.telephony.imsphone.ImsPhoneConnection$MyHandler
 com.android.internal.telephony.imsphone.ImsPhoneFactory
-com.android.internal.telephony.imsphone.ImsPhoneMmiCode
 com.android.internal.telephony.imsphone.ImsPullCall
-com.android.internal.telephony.sip.SipPhone
-com.android.internal.telephony.sip.SipPhoneBase
+com.android.internal.telephony.metrics.CallSessionEventBuilder
+com.android.internal.telephony.metrics.InProgressCallSession
+com.android.internal.telephony.metrics.InProgressSmsSession
+com.android.internal.telephony.metrics.SmsSessionEventBuilder
+com.android.internal.telephony.metrics.TelephonyEventBuilder
+com.android.internal.telephony.metrics.TelephonyMetrics
+com.android.internal.telephony.nano.TelephonyProto$ImsCapabilities
+com.android.internal.telephony.nano.TelephonyProto$ImsConnectionState
+com.android.internal.telephony.nano.TelephonyProto$ImsReasonInfo
+com.android.internal.telephony.nano.TelephonyProto$RilDataCall
+com.android.internal.telephony.nano.TelephonyProto$SmsSession$Event
+com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event
+com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event$RilCall
+com.android.internal.telephony.nano.TelephonyProto$TelephonyEvent
+com.android.internal.telephony.nano.TelephonyProto$TelephonyServiceState
+com.android.internal.telephony.nano.TelephonyProto$TelephonyServiceState$TelephonyOperator
+com.android.internal.telephony.nano.TelephonyProto$TelephonySettings
 com.android.internal.telephony.test.SimulatedRadioControl
-com.android.internal.telephony.uicc.AdnRecord
-com.android.internal.telephony.uicc.AdnRecord$1
-com.android.internal.telephony.uicc.AdnRecordCache
-com.android.internal.telephony.uicc.AdnRecordLoader
 com.android.internal.telephony.uicc.IccCardApplicationStatus
-com.android.internal.telephony.uicc.IccCardApplicationStatus$AppState
 com.android.internal.telephony.uicc.IccCardApplicationStatus$AppType
-com.android.internal.telephony.uicc.IccCardApplicationStatus$PersoSubState
 com.android.internal.telephony.uicc.IccCardProxy
 com.android.internal.telephony.uicc.IccCardStatus
 com.android.internal.telephony.uicc.IccCardStatus$CardState
 com.android.internal.telephony.uicc.IccCardStatus$PinState
 com.android.internal.telephony.uicc.IccConstants
-com.android.internal.telephony.uicc.IccFileHandler
-com.android.internal.telephony.uicc.IccFileHandler$LoadLinearFixedContext
-com.android.internal.telephony.uicc.IccIoResult
 com.android.internal.telephony.uicc.IccRecords
-com.android.internal.telephony.uicc.IccRecords$IccRecordLoaded
-com.android.internal.telephony.uicc.IccServiceTable
+com.android.internal.telephony.uicc.IccRefreshResponse
 com.android.internal.telephony.uicc.IccUtils
-com.android.internal.telephony.uicc.IsimFileHandler
-com.android.internal.telephony.uicc.IsimRecords
-com.android.internal.telephony.uicc.IsimUiccRecords
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimDomainLoaded
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimImpiLoaded
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimImpuLoaded
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimIstLoaded
-com.android.internal.telephony.uicc.IsimUiccRecords$EfIsimPcscfLoaded
-com.android.internal.telephony.uicc.SIMRecords
-com.android.internal.telephony.uicc.SIMRecords$1
-com.android.internal.telephony.uicc.SIMRecords$EfPlLoaded
-com.android.internal.telephony.uicc.SIMRecords$EfUsimLiLoaded
-com.android.internal.telephony.uicc.SIMRecords$GetSpnFsmState
-com.android.internal.telephony.uicc.SpnOverride
 com.android.internal.telephony.uicc.UiccCard
 com.android.internal.telephony.uicc.UiccCard$1
 com.android.internal.telephony.uicc.UiccCardApplication
-com.android.internal.telephony.uicc.UiccCardApplication$1
-com.android.internal.telephony.uicc.UiccCarrierPrivilegeRules
-com.android.internal.telephony.uicc.UiccCarrierPrivilegeRules$1
 com.android.internal.telephony.uicc.UiccController
-com.android.internal.telephony.uicc.UiccPkcs15
-com.android.internal.telephony.uicc.UiccPkcs15$FileHandler
-com.android.internal.telephony.uicc.UiccPkcs15$Pkcs15Selector
-com.android.internal.telephony.uicc.UsimFileHandler
-com.android.internal.telephony.uicc.UsimServiceTable
-com.android.internal.telephony.uicc.UsimServiceTable$UsimService
-com.android.internal.telephony.uicc.VoiceMailConstants
+com.android.internal.telephony.uicc.UiccStateChangedLauncher
 com.android.internal.textservice.ISpellCheckerService
 com.android.internal.textservice.ISpellCheckerService$Stub
 com.android.internal.textservice.ISpellCheckerService$Stub$Proxy
@@ -5828,6 +6030,9 @@
 com.android.internal.util.AsyncChannel$DeathMonitor
 com.android.internal.util.AsyncChannel$SyncMessenger
 com.android.internal.util.AsyncChannel$SyncMessenger$SyncHandler
+com.android.internal.util.ConcurrentUtils
+com.android.internal.util.ConcurrentUtils$1
+com.android.internal.util.ConcurrentUtils$1$1
 com.android.internal.util.DumpUtils$Dump
 com.android.internal.util.FastMath
 com.android.internal.util.FastPrintWriter
@@ -5850,7 +6055,6 @@
 com.android.internal.util.MessageUtils
 com.android.internal.util.NotificationColorUtil
 com.android.internal.util.NotificationColorUtil$ColorUtilsFromCompat
-com.android.internal.util.ParcelableString
 com.android.internal.util.Preconditions
 com.android.internal.util.Predicate
 com.android.internal.util.ProcFileReader
@@ -5865,7 +6069,8 @@
 com.android.internal.util.StateMachine$SmHandler$HaltingState
 com.android.internal.util.StateMachine$SmHandler$QuittingState
 com.android.internal.util.StateMachine$SmHandler$StateInfo
-com.android.internal.util.UserIcons
+com.android.internal.util.ToBooleanFunction
+com.android.internal.util.TokenBucket
 com.android.internal.util.VirtualRefBasePtr
 com.android.internal.util.WakeupMessage
 com.android.internal.util.XmlUtils
@@ -5874,12 +6079,6 @@
 com.android.internal.view.ActionBarPolicy
 com.android.internal.view.BaseIWindow
 com.android.internal.view.BaseSurfaceHolder
-com.android.internal.view.FloatingActionMode
-com.android.internal.view.FloatingActionMode$1
-com.android.internal.view.FloatingActionMode$2
-com.android.internal.view.FloatingActionMode$3
-com.android.internal.view.FloatingActionMode$4
-com.android.internal.view.FloatingActionMode$FloatingToolbarVisibilityHelper
 com.android.internal.view.IInputConnectionWrapper
 com.android.internal.view.IInputConnectionWrapper$MyHandler
 com.android.internal.view.IInputConnectionWrapper$SomeArgs
@@ -5908,11 +6107,13 @@
 com.android.internal.view.InputBindResult$1
 com.android.internal.view.InputConnectionWrapper
 com.android.internal.view.InputConnectionWrapper$InputContextCallback
+com.android.internal.view.OneShotPreDrawListener
 com.android.internal.view.RootViewSurfaceTaker
 com.android.internal.view.RotationPolicy
-com.android.internal.view.RotationPolicy$1
 com.android.internal.view.RotationPolicy$RotationPolicyListener
 com.android.internal.view.RotationPolicy$RotationPolicyListener$1
+com.android.internal.view.SurfaceCallbackHelper
+com.android.internal.view.SurfaceCallbackHelper$1
 com.android.internal.view.WindowManagerPolicyThread
 com.android.internal.view.animation.FallbackLUTInterpolator
 com.android.internal.view.animation.HasNativeInterpolator
@@ -5922,7 +6123,6 @@
 com.android.internal.view.menu.ActionMenuItemView
 com.android.internal.view.menu.ActionMenuItemView$PopupCallback
 com.android.internal.view.menu.BaseMenuPresenter
-com.android.internal.view.menu.ContextMenuBuilder
 com.android.internal.view.menu.ListMenuItemView
 com.android.internal.view.menu.MenuAdapter
 com.android.internal.view.menu.MenuBuilder
@@ -5942,12 +6142,12 @@
 com.android.internal.view.menu.StandardMenuPopup$1
 com.android.internal.view.menu.StandardMenuPopup$2
 com.android.internal.view.menu.SubMenuBuilder
+com.android.internal.widget.-$Lambda$6$LaTFiUorkqfcqmu-zMQbCLeO77c
 com.android.internal.widget.AbsActionBarView
 com.android.internal.widget.AbsActionBarView$VisibilityAnimListener
 com.android.internal.widget.ActionBarContainer
 com.android.internal.widget.ActionBarContainer$ActionBarBackgroundDrawable
 com.android.internal.widget.ActionBarContextView
-com.android.internal.widget.ActionBarContextView$1
 com.android.internal.widget.ActionBarOverlayLayout
 com.android.internal.widget.ActionBarOverlayLayout$1
 com.android.internal.widget.ActionBarOverlayLayout$2
@@ -5959,60 +6159,29 @@
 com.android.internal.widget.AlertDialogLayout
 com.android.internal.widget.BackgroundFallback
 com.android.internal.widget.ButtonBarLayout
+com.android.internal.widget.CachingIconView
 com.android.internal.widget.DecorContentParent
 com.android.internal.widget.DecorToolbar
 com.android.internal.widget.DialogTitle
 com.android.internal.widget.EditableInputConnection
-com.android.internal.widget.FloatingToolbar
-com.android.internal.widget.FloatingToolbar$1
-com.android.internal.widget.FloatingToolbar$2
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$1
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$12
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$13
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$14
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$15
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$16
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$2
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$3
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$4
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$5
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$LogAccelerateInterpolator
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$OverflowPanel
-com.android.internal.widget.FloatingToolbar$FloatingToolbarPopup$OverflowPanelViewHelper
+com.android.internal.widget.ICheckCredentialProgressCallback
 com.android.internal.widget.ILockSettings
 com.android.internal.widget.ILockSettings$Stub
 com.android.internal.widget.ILockSettings$Stub$Proxy
 com.android.internal.widget.ImageFloatingTextView
-com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
-com.android.internal.widget.LockPatternChecker
-com.android.internal.widget.LockPatternChecker$3
-com.android.internal.widget.LockPatternChecker$5
-com.android.internal.widget.LockPatternChecker$OnCheckCallback
-com.android.internal.widget.LockPatternChecker$OnVerifyCallback
 com.android.internal.widget.LockPatternUtils
-com.android.internal.widget.LockPatternUtils$1
 com.android.internal.widget.LockPatternUtils$RequestThrottledException
 com.android.internal.widget.LockPatternUtils$StrongAuthTracker
 com.android.internal.widget.LockPatternUtils$StrongAuthTracker$1
 com.android.internal.widget.LockPatternUtils$StrongAuthTracker$H
 com.android.internal.widget.MediaNotificationView
 com.android.internal.widget.NotificationActionListLayout
-com.android.internal.widget.NotificationActionListLayout$-void__clinit___LambdaImpl0
+com.android.internal.widget.NotificationExpandButton
 com.android.internal.widget.PreferenceImageView
-com.android.internal.widget.ResolverDrawerLayout
-com.android.internal.widget.ResolverDrawerLayout$1
-com.android.internal.widget.ResolverDrawerLayout$LayoutParams
-com.android.internal.widget.ResolverDrawerLayout$OnDismissedListener
 com.android.internal.widget.ScrollBarUtils
-com.android.internal.widget.TextViewInputDisabler
-com.android.internal.widget.TextViewInputDisabler$1
 com.android.internal.widget.ToolbarWidgetWrapper
 com.android.internal.widget.ToolbarWidgetWrapper$1
-com.android.internal.widget.ToolbarWidgetWrapper$2
-com.android.internal.widget.ToolbarWidgetWrapper$3
 com.android.internal.widget.VerifyCredentialResponse
-com.android.internal.widget.VerifyCredentialResponse$1
 com.android.okhttp.Address
 com.android.okhttp.AndroidInternal
 com.android.okhttp.AndroidShimResponseCache
@@ -6032,6 +6201,8 @@
 com.android.okhttp.ConnectionSpec
 com.android.okhttp.ConnectionSpec$Builder
 com.android.okhttp.Dispatcher
+com.android.okhttp.Dns
+com.android.okhttp.Dns$1
 com.android.okhttp.Handshake
 com.android.okhttp.Headers
 com.android.okhttp.Headers$Builder
@@ -6060,12 +6231,11 @@
 com.android.okhttp.internal.DiskLruCache$1
 com.android.okhttp.internal.DiskLruCache$2
 com.android.okhttp.internal.DiskLruCache$3
+com.android.okhttp.internal.DiskLruCache$Editor
 com.android.okhttp.internal.DiskLruCache$Entry
 com.android.okhttp.internal.FaultHidingSink
 com.android.okhttp.internal.Internal
 com.android.okhttp.internal.InternalCache
-com.android.okhttp.internal.Network
-com.android.okhttp.internal.Network$1
 com.android.okhttp.internal.OptionalMethod
 com.android.okhttp.internal.Platform
 com.android.okhttp.internal.RouteDatabase
@@ -6076,17 +6246,17 @@
 com.android.okhttp.internal.http.CacheStrategy
 com.android.okhttp.internal.http.CacheStrategy$Factory
 com.android.okhttp.internal.http.HeaderParser
-com.android.okhttp.internal.http.HttpConnection
-com.android.okhttp.internal.http.HttpConnection$AbstractSource
-com.android.okhttp.internal.http.HttpConnection$ChunkedSink
-com.android.okhttp.internal.http.HttpConnection$ChunkedSource
-com.android.okhttp.internal.http.HttpConnection$FixedLengthSink
-com.android.okhttp.internal.http.HttpConnection$FixedLengthSource
-com.android.okhttp.internal.http.HttpConnection$UnknownLengthSource
+com.android.okhttp.internal.http.Http1xStream
+com.android.okhttp.internal.http.Http1xStream$AbstractSource
+com.android.okhttp.internal.http.Http1xStream$ChunkedSink
+com.android.okhttp.internal.http.Http1xStream$ChunkedSource
+com.android.okhttp.internal.http.Http1xStream$FixedLengthSink
+com.android.okhttp.internal.http.Http1xStream$FixedLengthSource
+com.android.okhttp.internal.http.Http1xStream$UnknownLengthSource
 com.android.okhttp.internal.http.HttpEngine
 com.android.okhttp.internal.http.HttpEngine$1
 com.android.okhttp.internal.http.HttpMethod
-com.android.okhttp.internal.http.HttpTransport
+com.android.okhttp.internal.http.HttpStream
 com.android.okhttp.internal.http.OkHeaders
 com.android.okhttp.internal.http.OkHeaders$1
 com.android.okhttp.internal.http.RealResponseBody
@@ -6096,12 +6266,13 @@
 com.android.okhttp.internal.http.RouteException
 com.android.okhttp.internal.http.RouteSelector
 com.android.okhttp.internal.http.StatusLine
-com.android.okhttp.internal.http.Transport
+com.android.okhttp.internal.http.StreamAllocation
 com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
 com.android.okhttp.internal.huc.HttpURLConnectionImpl
 com.android.okhttp.internal.huc.HttpsURLConnectionImpl
 com.android.okhttp.internal.io.FileSystem
 com.android.okhttp.internal.io.FileSystem$1
+com.android.okhttp.internal.io.RealConnection
 com.android.okhttp.internal.tls.OkHostnameVerifier
 com.android.okhttp.okio.AsyncTimeout
 com.android.okhttp.okio.AsyncTimeout$1
@@ -6145,20 +6316,34 @@
 com.android.org.bouncycastle.asn1.x509.X509ObjectIdentifiers
 com.android.org.bouncycastle.asn1.x9.X9ObjectIdentifiers
 com.android.org.bouncycastle.crypto.AsymmetricBlockCipher
+com.android.org.bouncycastle.crypto.BlockCipher
+com.android.org.bouncycastle.crypto.BufferedBlockCipher
 com.android.org.bouncycastle.crypto.CipherKeyGenerator
+com.android.org.bouncycastle.crypto.CipherParameters
 com.android.org.bouncycastle.crypto.CryptoException
+com.android.org.bouncycastle.crypto.DataLengthException
 com.android.org.bouncycastle.crypto.Digest
 com.android.org.bouncycastle.crypto.ExtendedDigest
 com.android.org.bouncycastle.crypto.InvalidCipherTextException
 com.android.org.bouncycastle.crypto.KeyGenerationParameters
+com.android.org.bouncycastle.crypto.OutputLengthException
+com.android.org.bouncycastle.crypto.RuntimeCryptoException
 com.android.org.bouncycastle.crypto.digests.AndroidDigestFactory
 com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryInterface
 com.android.org.bouncycastle.crypto.digests.AndroidDigestFactoryOpenSSL
 com.android.org.bouncycastle.crypto.digests.OpenSSLDigest
 com.android.org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
 com.android.org.bouncycastle.crypto.encodings.OAEPEncoding
+com.android.org.bouncycastle.crypto.engines.AESEngine
 com.android.org.bouncycastle.crypto.engines.RSABlindedEngine
 com.android.org.bouncycastle.crypto.engines.RSACoreEngine
+com.android.org.bouncycastle.crypto.paddings.BlockCipherPadding
+com.android.org.bouncycastle.crypto.paddings.PKCS7Padding
+com.android.org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher
+com.android.org.bouncycastle.crypto.params.KeyParameter
+com.android.org.bouncycastle.crypto.params.ParametersWithRandom
+com.android.org.bouncycastle.jcajce.PBKDFKey
+com.android.org.bouncycastle.jcajce.PKCS12Key
 com.android.org.bouncycastle.jcajce.provider.asymmetric.DH$Mappings
 com.android.org.bouncycastle.jcajce.provider.asymmetric.DSA$Mappings
 com.android.org.bouncycastle.jcajce.provider.asymmetric.EC$Mappings
@@ -6196,6 +6381,8 @@
 com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi
 com.android.org.bouncycastle.jcajce.provider.keystore.bc.BcKeyStoreSpi$Std
 com.android.org.bouncycastle.jcajce.provider.symmetric.AES
+com.android.org.bouncycastle.jcajce.provider.symmetric.AES$ECB
+com.android.org.bouncycastle.jcajce.provider.symmetric.AES$ECB$1
 com.android.org.bouncycastle.jcajce.provider.symmetric.AES$KeyGen
 com.android.org.bouncycastle.jcajce.provider.symmetric.AES$Mappings
 com.android.org.bouncycastle.jcajce.provider.symmetric.ARC4
@@ -6206,18 +6393,31 @@
 com.android.org.bouncycastle.jcajce.provider.symmetric.DES$Mappings
 com.android.org.bouncycastle.jcajce.provider.symmetric.DESede
 com.android.org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings
 com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12
 com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters$Mappings
 com.android.org.bouncycastle.jcajce.provider.symmetric.RC2
 com.android.org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings
 com.android.org.bouncycastle.jcajce.provider.symmetric.SymmetricAlgorithmProvider
 com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish
 com.android.org.bouncycastle.jcajce.provider.symmetric.Twofish$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BCPBEKey
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$GenericBlockCipher
 com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseKeyGenerator
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseWrapCipher
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.BlockCipherProvider
+com.android.org.bouncycastle.jcajce.provider.symmetric.util.PBE
 com.android.org.bouncycastle.jcajce.provider.util.AlgorithmProvider
 com.android.org.bouncycastle.jcajce.provider.util.AsymmetricAlgorithmProvider
 com.android.org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter
 com.android.org.bouncycastle.jcajce.provider.util.DigestFactory
+com.android.org.bouncycastle.jcajce.spec.AEADParameterSpec
 com.android.org.bouncycastle.jcajce.util.BCJcaJceHelper
 com.android.org.bouncycastle.jcajce.util.JcaJceHelper
 com.android.org.bouncycastle.jcajce.util.ProviderJcaJceHelper
@@ -6227,19 +6427,25 @@
 com.android.org.bouncycastle.jce.provider.BouncyCastleProviderConfiguration
 com.android.org.bouncycastle.util.Arrays
 com.android.org.bouncycastle.util.Encodable
+com.android.org.bouncycastle.util.Pack
 com.android.org.bouncycastle.util.Strings
 com.android.org.bouncycastle.util.Strings$1
+com.android.org.conscrypt.AbstractOpenSSLSession
 com.android.org.conscrypt.AbstractSessionContext
 com.android.org.conscrypt.AbstractSessionContext$1
 com.android.org.conscrypt.AddressUtils
 com.android.org.conscrypt.ByteArray
-com.android.org.conscrypt.CertPinManager
+com.android.org.conscrypt.CertBlacklist
 com.android.org.conscrypt.CertificatePriorityComparator
 com.android.org.conscrypt.ChainStrengthAnalyzer
 com.android.org.conscrypt.ClientSessionContext
 com.android.org.conscrypt.ClientSessionContext$HostAndPort
 com.android.org.conscrypt.CryptoUpcalls
+com.android.org.conscrypt.EvpMdRef$MD5
+com.android.org.conscrypt.EvpMdRef$SHA1
+com.android.org.conscrypt.EvpMdRef$SHA256
 com.android.org.conscrypt.FileClientSessionCache
+com.android.org.conscrypt.FileClientSessionCache$CacheFile
 com.android.org.conscrypt.FileClientSessionCache$Impl
 com.android.org.conscrypt.Hex
 com.android.org.conscrypt.JSSEProvider
@@ -6278,7 +6484,6 @@
 com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
 com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
 com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
-com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA512
 com.android.org.conscrypt.OpenSSLProvider
 com.android.org.conscrypt.OpenSSLRSAKeyFactory
 com.android.org.conscrypt.OpenSSLRSAKeyPairGenerator
@@ -6305,10 +6510,8 @@
 com.android.org.conscrypt.OpenSSLX509CertificateFactory$2
 com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
 com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException
-com.android.org.conscrypt.PinEntryException
-com.android.org.conscrypt.PinListEntry
-com.android.org.conscrypt.PinManagerException
 com.android.org.conscrypt.Platform
+com.android.org.conscrypt.Platform$NoPreloadHolder
 com.android.org.conscrypt.SSLClientSessionCache
 com.android.org.conscrypt.SSLParametersImpl
 com.android.org.conscrypt.SSLParametersImpl$AliasChooser
@@ -6326,12 +6529,20 @@
 com.android.org.conscrypt.TrustedCertificateStore$4
 com.android.org.conscrypt.TrustedCertificateStore$5
 com.android.org.conscrypt.TrustedCertificateStore$CertSelector
+com.android.org.conscrypt.ct.CTLogInfo
+com.android.org.conscrypt.ct.CTLogStore
+com.android.org.conscrypt.ct.CTLogStoreImpl
+com.android.org.conscrypt.ct.CTLogStoreImpl$InvalidLogFileException
+com.android.org.conscrypt.ct.CTPolicy
+com.android.org.conscrypt.ct.CTPolicyImpl
+com.android.org.conscrypt.ct.CTVerifier
+com.android.org.conscrypt.ct.KnownLogs
+com.android.org.conscrypt.ct.SerializationException
 com.android.org.conscrypt.util.ArrayUtils
 com.android.org.conscrypt.util.EmptyArray
 com.android.server.AppWidgetBackupBridge
 com.android.server.BootReceiver
 com.android.server.BootReceiver$1
-com.android.server.BootReceiver$2
 com.android.server.LocalServices
 com.android.server.NetworkManagementSocketTagger
 com.android.server.NetworkManagementSocketTagger$1
@@ -6341,6 +6552,7 @@
 com.android.server.WidgetBackupProvider
 com.android.server.backup.AccountSyncSettingsBackupHelper
 com.android.server.net.BaseNetworkObserver
+com.android.server.net.DnsServerEntry
 com.android.server.net.DnsServerRepository
 com.android.server.net.NetlinkTracker
 com.android.server.net.NetlinkTracker$Callback
@@ -6350,6 +6562,17 @@
 com.android.server.sip.SipWakeLock
 com.android.server.sip.SipWakeupTimer
 com.android.server.sip.SipWakeupTimer$MyEventComparator
+com.android.server.wifi.nano.WifiMetricsProto$AlertReasonCount
+com.android.server.wifi.nano.WifiMetricsProto$ConnectionEvent
+com.android.server.wifi.nano.WifiMetricsProto$RouterFingerPrint
+com.android.server.wifi.nano.WifiMetricsProto$RssiPollCount
+com.android.server.wifi.nano.WifiMetricsProto$SoftApDurationBucket
+com.android.server.wifi.nano.WifiMetricsProto$SoftApReturnCodeCount
+com.android.server.wifi.nano.WifiMetricsProto$WifiLog
+com.android.server.wifi.nano.WifiMetricsProto$WifiLog$ScanReturnEntry
+com.android.server.wifi.nano.WifiMetricsProto$WifiLog$WifiSystemStateEntry
+com.android.server.wifi.nano.WifiMetricsProto$WifiScoreCount
+com.android.server.wm.nano.WindowManagerProtos$TaskSnapshotProto
 com.google.android.collect.Lists
 com.google.android.collect.Maps
 com.google.android.collect.Sets
@@ -6363,15 +6586,21 @@
 com.google.android.mms.pdu.GenericPdu
 com.google.android.mms.pdu.PduComposer
 com.google.android.mms.pdu.PduPersister
+dalvik.annotation.optimization.CriticalNative
+dalvik.annotation.optimization.FastNative
 dalvik.system.BaseDexClassLoader
+dalvik.system.BaseDexClassLoader$Reporter
 dalvik.system.BlockGuard
 dalvik.system.BlockGuard$1
 dalvik.system.BlockGuard$2
 dalvik.system.BlockGuard$BlockGuardPolicyException
 dalvik.system.BlockGuard$Policy
+dalvik.system.ClassExt
 dalvik.system.CloseGuard
 dalvik.system.CloseGuard$DefaultReporter
+dalvik.system.CloseGuard$DefaultTracker
 dalvik.system.CloseGuard$Reporter
+dalvik.system.CloseGuard$Tracker
 dalvik.system.DalvikLogHandler
 dalvik.system.DalvikLogging
 dalvik.system.DexClassLoader
@@ -6379,6 +6608,10 @@
 dalvik.system.DexFile$DFEnum
 dalvik.system.DexPathList
 dalvik.system.DexPathList$Element
+dalvik.system.DexPathList$NativeLibraryElement
+dalvik.system.EmulatedStackFrame
+dalvik.system.EmulatedStackFrame$Range
+dalvik.system.InMemoryDexClassLoader$DexData
 dalvik.system.PathClassLoader
 dalvik.system.SocketTagger
 dalvik.system.SocketTagger$1
@@ -6386,11 +6619,6 @@
 dalvik.system.VMRuntime
 dalvik.system.VMStack
 dalvik.system.ZygoteHooks
-java.beans.ChangeListenerMap
-java.beans.PropertyChangeEvent
-java.beans.PropertyChangeListener
-java.beans.PropertyChangeSupport
-java.beans.PropertyChangeSupport$PropertyChangeListenerMap
 java.io.Bits
 java.io.BufferedInputStream
 java.io.BufferedOutputStream
@@ -6407,6 +6635,7 @@
 java.io.DataInputStream
 java.io.DataOutput
 java.io.DataOutputStream
+java.io.DefaultFileSystem
 java.io.EOFException
 java.io.ExpiringCache
 java.io.ExpiringCache$1
@@ -6414,7 +6643,9 @@
 java.io.Externalizable
 java.io.File
 java.io.File$PathStatus
+java.io.File$TempDirectory
 java.io.FileDescriptor
+java.io.FileDescriptor$1
 java.io.FileFilter
 java.io.FileInputStream
 java.io.FileInputStream$UseManualSkipException
@@ -6434,6 +6665,7 @@
 java.io.InterruptedIOException
 java.io.InvalidClassException
 java.io.InvalidObjectException
+java.io.NotSerializableException
 java.io.ObjectInput
 java.io.ObjectInputStream
 java.io.ObjectInputStream$BlockDataInputStream
@@ -6445,6 +6677,7 @@
 java.io.ObjectOutputStream
 java.io.ObjectOutputStream$BlockDataOutputStream
 java.io.ObjectOutputStream$HandleTable
+java.io.ObjectOutputStream$PutField
 java.io.ObjectOutputStream$ReplaceTable
 java.io.ObjectStreamClass
 java.io.ObjectStreamClass$1
@@ -6475,13 +6708,17 @@
 java.io.SerialCallbackContext
 java.io.Serializable
 java.io.SerializablePermission
+java.io.StreamCorruptedException
 java.io.StringBufferInputStream
 java.io.StringReader
 java.io.StringWriter
+java.io.SyncFailedException
 java.io.UTFDataFormatException
 java.io.UnixFileSystem
 java.io.UnsupportedEncodingException
 java.io.Writer
+java.lang.-$Lambda$250$S9HjrJh0nDg7IyU6wZdPArnZWRQ
+java.lang.-$Lambda$251$S9HjrJh0nDg7IyU6wZdPArnZWRQ
 java.lang.AbstractMethodError
 java.lang.AbstractStringBuilder
 java.lang.AndroidHardcodedSystemProperties
@@ -6498,8 +6735,6 @@
 java.lang.CaseMapper
 java.lang.CaseMapper$1
 java.lang.CharSequence
-java.lang.CharSequence$-java_util_stream_IntStream_chars__LambdaImpl0
-java.lang.CharSequence$-java_util_stream_IntStream_codePoints__LambdaImpl0
 java.lang.CharSequence$1CharIterator
 java.lang.CharSequence$1CodePointIterator
 java.lang.Character
@@ -6531,9 +6766,6 @@
 java.lang.Exception
 java.lang.ExceptionInInitializerError
 java.lang.Float
-java.lang.FloatingDecimal
-java.lang.FloatingDecimal$1
-java.lang.FloatingDecimal$2
 java.lang.IllegalAccessError
 java.lang.IllegalAccessException
 java.lang.IllegalArgumentException
@@ -6543,6 +6775,7 @@
 java.lang.IncompatibleClassChangeError
 java.lang.IndexOutOfBoundsException
 java.lang.InheritableThreadLocal
+java.lang.InstantiationError
 java.lang.InstantiationException
 java.lang.Integer
 java.lang.Integer$IntegerCache
@@ -6554,7 +6787,8 @@
 java.lang.Long
 java.lang.Long$LongCache
 java.lang.Math
-java.lang.Math$NoImagePreloadHolder
+java.lang.Math$RandomNumberGeneratorHolder
+java.lang.NegativeArraySizeException
 java.lang.NoClassDefFoundError
 java.lang.NoSuchFieldError
 java.lang.NoSuchFieldException
@@ -6586,7 +6820,6 @@
 java.lang.SecurityManager
 java.lang.Short
 java.lang.Short$ShortCache
-java.lang.Shutdown
 java.lang.StackOverflowError
 java.lang.StackTraceElement
 java.lang.StrictMath
@@ -6594,7 +6827,6 @@
 java.lang.String$CaseInsensitiveComparator
 java.lang.StringBuffer
 java.lang.StringBuilder
-java.lang.StringCoding
 java.lang.StringFactory
 java.lang.StringIndexOutOfBoundsException
 java.lang.System
@@ -6636,6 +6868,22 @@
 java.lang.annotation.Inherited
 java.lang.annotation.Retention
 java.lang.annotation.Target
+java.lang.invoke.MethodHandle
+java.lang.invoke.MethodHandleImpl
+java.lang.invoke.MethodHandleImpl$HandleInfo
+java.lang.invoke.MethodHandleInfo
+java.lang.invoke.MethodHandleStatics
+java.lang.invoke.MethodHandles
+java.lang.invoke.MethodType
+java.lang.invoke.MethodType$ConcurrentWeakInternSet
+java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
+java.lang.invoke.MethodTypeForm
+java.lang.invoke.Transformers$BindTo
+java.lang.invoke.Transformers$Collector
+java.lang.invoke.Transformers$Spreader
+java.lang.invoke.Transformers$Transformer
+java.lang.invoke.Transformers$VarargsCollector
+java.lang.invoke.WrongMethodTypeException
 java.lang.ref.FinalizerReference
 java.lang.ref.FinalizerReference$Sentinel
 java.lang.ref.PhantomReference
@@ -6643,27 +6891,40 @@
 java.lang.ref.ReferenceQueue
 java.lang.ref.SoftReference
 java.lang.ref.WeakReference
-java.lang.reflect.AbstractMethod
-java.lang.reflect.AbstractMethod$GenericInfo
 java.lang.reflect.AccessibleObject
 java.lang.reflect.AnnotatedElement
 java.lang.reflect.Array
 java.lang.reflect.Constructor
+java.lang.reflect.Executable
+java.lang.reflect.Executable$GenericInfo
 java.lang.reflect.Field
 java.lang.reflect.GenericArrayType
 java.lang.reflect.GenericDeclaration
 java.lang.reflect.InvocationHandler
 java.lang.reflect.InvocationTargetException
+java.lang.reflect.MalformedParametersException
 java.lang.reflect.Member
 java.lang.reflect.Method
 java.lang.reflect.Method$1
 java.lang.reflect.Modifier
+java.lang.reflect.Parameter
 java.lang.reflect.ParameterizedType
 java.lang.reflect.Proxy
 java.lang.reflect.Proxy$1
+java.lang.reflect.Proxy$Key1
+java.lang.reflect.Proxy$Key2
+java.lang.reflect.Proxy$KeyFactory
+java.lang.reflect.Proxy$KeyX
+java.lang.reflect.Proxy$ProxyClassFactory
 java.lang.reflect.Type
 java.lang.reflect.TypeVariable
 java.lang.reflect.UndeclaredThrowableException
+java.lang.reflect.WeakCache
+java.lang.reflect.WeakCache$CacheKey
+java.lang.reflect.WeakCache$CacheValue
+java.lang.reflect.WeakCache$Factory
+java.lang.reflect.WeakCache$LookupValue
+java.lang.reflect.WeakCache$Value
 java.lang.reflect.WildcardType
 java.math.BigDecimal
 java.math.BigInt
@@ -6671,7 +6932,6 @@
 java.math.BitLevel
 java.math.Conversion
 java.math.Division
-java.math.Logical
 java.math.MathContext
 java.math.Multiplication
 java.math.NativeBN
@@ -6718,6 +6978,7 @@
 java.net.InMemoryCookieStore
 java.net.Inet4Address
 java.net.Inet6Address
+java.net.Inet6Address$Inet6AddressHolder
 java.net.Inet6AddressImpl
 java.net.InetAddress
 java.net.InetAddress$1
@@ -6730,7 +6991,6 @@
 java.net.MalformedURLException
 java.net.MulticastSocket
 java.net.NetworkInterface
-java.net.NetworkInterface$1
 java.net.NetworkInterface$1checkedAddresses
 java.net.NoRouteToHostException
 java.net.Parts
@@ -6739,14 +6999,12 @@
 java.net.PlainSocketImpl
 java.net.PortUnreachableException
 java.net.ProtocolException
-java.net.ProtocolFamily
 java.net.Proxy
 java.net.Proxy$Type
 java.net.ProxySelector
 java.net.ResponseCache
 java.net.ServerSocket
 java.net.Socket
-java.net.Socket$1
 java.net.Socket$2
 java.net.Socket$3
 java.net.SocketAddress
@@ -6758,8 +7016,6 @@
 java.net.SocketTimeoutException
 java.net.SocksConsts
 java.net.SocksSocketImpl
-java.net.SocksSocketImpl$3
-java.net.StandardProtocolFamily
 java.net.URI
 java.net.URI$Parser
 java.net.URISyntaxException
@@ -6805,7 +7061,6 @@
 java.nio.channels.CancelledKeyException
 java.nio.channels.Channel
 java.nio.channels.Channels
-java.nio.channels.Channels$1
 java.nio.channels.Channels$ReadableByteChannelImpl
 java.nio.channels.ClosedByInterruptException
 java.nio.channels.ClosedChannelException
@@ -6815,6 +7070,7 @@
 java.nio.channels.FileLock
 java.nio.channels.GatheringByteChannel
 java.nio.channels.InterruptibleChannel
+java.nio.channels.MulticastChannel
 java.nio.channels.NetworkChannel
 java.nio.channels.NonWritableChannelException
 java.nio.channels.OverlappingFileLockException
@@ -6822,19 +7078,12 @@
 java.nio.channels.ScatteringByteChannel
 java.nio.channels.SeekableByteChannel
 java.nio.channels.SelectableChannel
-java.nio.channels.SelectionKey
-java.nio.channels.Selector
 java.nio.channels.ServerSocketChannel
 java.nio.channels.SocketChannel
 java.nio.channels.WritableByteChannel
 java.nio.channels.spi.AbstractInterruptibleChannel
 java.nio.channels.spi.AbstractInterruptibleChannel$1
 java.nio.channels.spi.AbstractSelectableChannel
-java.nio.channels.spi.AbstractSelectionKey
-java.nio.channels.spi.AbstractSelector
-java.nio.channels.spi.AbstractSelector$1
-java.nio.channels.spi.SelectorProvider
-java.nio.channels.spi.SelectorProvider$1
 java.nio.charset.CharacterCodingException
 java.nio.charset.Charset
 java.nio.charset.CharsetDecoder
@@ -6850,6 +7099,21 @@
 java.nio.charset.IllegalCharsetNameException
 java.nio.charset.StandardCharsets
 java.nio.charset.UnsupportedCharsetException
+java.nio.file.FileAlreadyExistsException
+java.nio.file.FileSystem
+java.nio.file.FileSystemException
+java.nio.file.FileSystems
+java.nio.file.FileSystems$DefaultFileSystemHolder
+java.nio.file.FileSystems$DefaultFileSystemHolder$1
+java.nio.file.Files
+java.nio.file.NoSuchFileException
+java.nio.file.OpenOption
+java.nio.file.Path
+java.nio.file.Watchable
+java.nio.file.attribute.BasicFileAttributes
+java.nio.file.attribute.FileAttribute
+java.nio.file.attribute.PosixFileAttributes
+java.nio.file.spi.FileSystemProvider
 java.security.AccessControlContext
 java.security.AccessControlException
 java.security.AccessController
@@ -6912,6 +7176,7 @@
 java.security.cert.CRL
 java.security.cert.CRLException
 java.security.cert.CertPath
+java.security.cert.CertPathBuilderException
 java.security.cert.CertPathChecker
 java.security.cert.CertPathHelperImpl
 java.security.cert.CertPathParameters
@@ -6950,7 +7215,6 @@
 java.security.interfaces.RSAPublicKey
 java.security.spec.AlgorithmParameterSpec
 java.security.spec.ECField
-java.security.spec.ECFieldF2m
 java.security.spec.ECFieldFp
 java.security.spec.ECGenParameterSpec
 java.security.spec.ECParameterSpec
@@ -6964,6 +7228,8 @@
 java.security.spec.KeySpec
 java.security.spec.MGF1ParameterSpec
 java.security.spec.PKCS8EncodedKeySpec
+java.security.spec.RSAPrivateCrtKeySpec
+java.security.spec.RSAPrivateKeySpec
 java.security.spec.RSAPublicKeySpec
 java.security.spec.X509EncodedKeySpec
 java.sql.Date
@@ -6999,17 +7265,23 @@
 java.text.RuleBasedCollator
 java.text.SimpleDateFormat
 java.text.StringCharacterIterator
-java.text.spi.DateFormatProvider
-java.text.spi.DateFormatSymbolsProvider
-java.text.spi.DecimalFormatSymbolsProvider
-java.text.spi.NumberFormatProvider
+java.time.DateTimeException
+java.util.-$Lambda$181$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$182$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$183$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$184$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$267$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$268$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$291$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$292$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$293$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$294$aUGKT4ItCOku5-JSG-x8Aqj2pJw
 java.util.AbstractCollection
 java.util.AbstractList
 java.util.AbstractList$Itr
 java.util.AbstractList$ListItr
 java.util.AbstractMap
 java.util.AbstractMap$1
-java.util.AbstractMap$1$1
 java.util.AbstractMap$2
 java.util.AbstractMap$2$1
 java.util.AbstractMap$SimpleEntry
@@ -7019,14 +7291,31 @@
 java.util.AbstractSet
 java.util.ArrayDeque
 java.util.ArrayDeque$DeqIterator
+java.util.ArrayDeque$DescendingIterator
 java.util.ArrayList
 java.util.ArrayList$ArrayListSpliterator
 java.util.ArrayList$Itr
 java.util.ArrayList$ListItr
 java.util.ArrayList$SubList
 java.util.ArrayList$SubList$1
+java.util.ArrayPrefixHelpers$CumulateTask
+java.util.ArrayPrefixHelpers$DoubleCumulateTask
+java.util.ArrayPrefixHelpers$IntCumulateTask
+java.util.ArrayPrefixHelpers$LongCumulateTask
 java.util.Arrays
 java.util.Arrays$ArrayList
+java.util.Arrays$NaturalOrder
+java.util.ArraysParallelSortHelpers$FJByte$Sorter
+java.util.ArraysParallelSortHelpers$FJChar$Sorter
+java.util.ArraysParallelSortHelpers$FJDouble$Sorter
+java.util.ArraysParallelSortHelpers$FJFloat$Sorter
+java.util.ArraysParallelSortHelpers$FJInt$Sorter
+java.util.ArraysParallelSortHelpers$FJLong$Sorter
+java.util.ArraysParallelSortHelpers$FJObject$Sorter
+java.util.ArraysParallelSortHelpers$FJShort$Sorter
+java.util.Base64
+java.util.Base64$Decoder
+java.util.Base64$Encoder
 java.util.BitSet
 java.util.Calendar
 java.util.Collection
@@ -7038,6 +7327,9 @@
 java.util.Collections$CheckedCollection
 java.util.Collections$CheckedList
 java.util.Collections$CheckedMap
+java.util.Collections$CheckedNavigableMap
+java.util.Collections$CheckedNavigableSet
+java.util.Collections$CheckedQueue
 java.util.Collections$CheckedRandomAccessList
 java.util.Collections$CheckedSet
 java.util.Collections$CheckedSortedMap
@@ -7058,6 +7350,8 @@
 java.util.Collections$SynchronizedCollection
 java.util.Collections$SynchronizedList
 java.util.Collections$SynchronizedMap
+java.util.Collections$SynchronizedNavigableMap
+java.util.Collections$SynchronizedNavigableSet
 java.util.Collections$SynchronizedRandomAccessList
 java.util.Collections$SynchronizedSet
 java.util.Collections$SynchronizedSortedMap
@@ -7070,18 +7364,16 @@
 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet
 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1
 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
+java.util.Collections$UnmodifiableNavigableMap
+java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap
+java.util.Collections$UnmodifiableNavigableSet
+java.util.Collections$UnmodifiableNavigableSet$EmptyNavigableSet
 java.util.Collections$UnmodifiableRandomAccessList
 java.util.Collections$UnmodifiableSet
 java.util.Collections$UnmodifiableSortedMap
 java.util.Collections$UnmodifiableSortedSet
 java.util.ComparableTimSort
 java.util.Comparator
-java.util.Comparator$-java_util_Comparator_comparingDouble_java_util_function_ToDoubleFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparingInt_java_util_function_ToIntFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparingLong_java_util_function_ToLongFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparing_java_util_function_Function_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparing_java_util_function_Function_keyExtractor_java_util_Comparator_keyComparator_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_thenComparing_java_util_Comparator_other_LambdaImpl0
 java.util.Comparators$NaturalOrderComparator
 java.util.Comparators$NullComparator
 java.util.ConcurrentModificationException
@@ -7105,8 +7397,6 @@
 java.util.EnumSet$SerializationProxy
 java.util.Enumeration
 java.util.EventListener
-java.util.EventObject
-java.util.FormatFlagsConversionMismatchException
 java.util.Formattable
 java.util.Formatter
 java.util.Formatter$Conversion
@@ -7121,9 +7411,10 @@
 java.util.HashMap$EntryIterator
 java.util.HashMap$EntrySet
 java.util.HashMap$HashIterator
-java.util.HashMap$HashMapEntry
 java.util.HashMap$KeyIterator
 java.util.HashMap$KeySet
+java.util.HashMap$Node
+java.util.HashMap$TreeNode
 java.util.HashMap$ValueIterator
 java.util.HashMap$Values
 java.util.HashSet
@@ -7148,11 +7439,14 @@
 java.util.JumboEnumSet
 java.util.JumboEnumSet$EnumSetIterator
 java.util.LinkedHashMap
-java.util.LinkedHashMap$EntryIterator
-java.util.LinkedHashMap$KeyIterator
+java.util.LinkedHashMap$LinkedEntryIterator
+java.util.LinkedHashMap$LinkedEntrySet
 java.util.LinkedHashMap$LinkedHashIterator
 java.util.LinkedHashMap$LinkedHashMapEntry
-java.util.LinkedHashMap$ValueIterator
+java.util.LinkedHashMap$LinkedKeyIterator
+java.util.LinkedHashMap$LinkedKeySet
+java.util.LinkedHashMap$LinkedValueIterator
+java.util.LinkedHashMap$LinkedValues
 java.util.LinkedHashSet
 java.util.LinkedList
 java.util.LinkedList$DescendingIterator
@@ -7160,10 +7454,13 @@
 java.util.LinkedList$Node
 java.util.List
 java.util.ListIterator
+java.util.ListResourceBundle
 java.util.Locale
 java.util.Locale$Builder
 java.util.Locale$Cache
 java.util.Locale$Category
+java.util.Locale$FilteringMode
+java.util.Locale$LanguageRange
 java.util.Locale$LocaleKey
 java.util.Map
 java.util.Map$Entry
@@ -7197,14 +7494,8 @@
 java.util.ResourceBundle$Control$1
 java.util.ResourceBundle$Control$CandidateListCache
 java.util.ResourceBundle$LoaderReference
-java.util.ResourceBundle$RBClassLoader
-java.util.ResourceBundle$RBClassLoader$1
 java.util.Scanner
 java.util.Scanner$1
-java.util.ServiceConfigurationError
-java.util.ServiceLoader
-java.util.ServiceLoader$1
-java.util.ServiceLoader$LazyIterator
 java.util.Set
 java.util.SimpleTimeZone
 java.util.SortedMap
@@ -7220,6 +7511,7 @@
 java.util.Spliterators$EmptySpliterator$OfInt
 java.util.Spliterators$EmptySpliterator$OfLong
 java.util.Spliterators$EmptySpliterator$OfRef
+java.util.Spliterators$IteratorSpliterator
 java.util.Stack
 java.util.StringJoiner
 java.util.StringTokenizer
@@ -7264,6 +7556,7 @@
 java.util.WeakHashMap$KeySet
 java.util.WeakHashMap$ValueIterator
 java.util.WeakHashMap$Values
+java.util.concurrent.-$Lambda$269$xR9BLpu6SifNikvFgr4lEiECBsk
 java.util.concurrent.AbstractExecutorService
 java.util.concurrent.ArrayBlockingQueue
 java.util.concurrent.BlockingDeque
@@ -7279,15 +7572,48 @@
 java.util.concurrent.CompletionStage
 java.util.concurrent.ConcurrentHashMap
 java.util.concurrent.ConcurrentHashMap$BaseIterator
+java.util.concurrent.ConcurrentHashMap$BulkTask
 java.util.concurrent.ConcurrentHashMap$CollectionView
 java.util.concurrent.ConcurrentHashMap$CounterCell
 java.util.concurrent.ConcurrentHashMap$EntryIterator
 java.util.concurrent.ConcurrentHashMap$EntrySetView
+java.util.concurrent.ConcurrentHashMap$ForEachEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedValueTask
+java.util.concurrent.ConcurrentHashMap$ForEachValueTask
 java.util.concurrent.ConcurrentHashMap$ForwardingNode
 java.util.concurrent.ConcurrentHashMap$KeyIterator
 java.util.concurrent.ConcurrentHashMap$KeySetView
 java.util.concurrent.ConcurrentHashMap$MapEntry
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToLongTask
 java.util.concurrent.ConcurrentHashMap$Node
+java.util.concurrent.ConcurrentHashMap$ReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$ReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$ReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$ReservationNode
+java.util.concurrent.ConcurrentHashMap$SearchEntriesTask
+java.util.concurrent.ConcurrentHashMap$SearchKeysTask
+java.util.concurrent.ConcurrentHashMap$SearchMappingsTask
+java.util.concurrent.ConcurrentHashMap$SearchValuesTask
 java.util.concurrent.ConcurrentHashMap$Segment
 java.util.concurrent.ConcurrentHashMap$Traverser
 java.util.concurrent.ConcurrentHashMap$TreeBin
@@ -7306,15 +7632,15 @@
 java.util.concurrent.ConcurrentSkipListMap$KeyIterator
 java.util.concurrent.ConcurrentSkipListMap$KeySet
 java.util.concurrent.ConcurrentSkipListMap$Node
-java.util.concurrent.ConcurrentSkipListMap$SubMap
 java.util.concurrent.ConcurrentSkipListMap$ValueIterator
 java.util.concurrent.ConcurrentSkipListMap$Values
 java.util.concurrent.ConcurrentSkipListSet
 java.util.concurrent.CopyOnWriteArrayList
-java.util.concurrent.CopyOnWriteArrayList$CowIterator
+java.util.concurrent.CopyOnWriteArrayList$COWIterator
 java.util.concurrent.CopyOnWriteArraySet
 java.util.concurrent.CountDownLatch
 java.util.concurrent.CountDownLatch$Sync
+java.util.concurrent.CountedCompleter
 java.util.concurrent.DelayQueue
 java.util.concurrent.Delayed
 java.util.concurrent.ExecutionException
@@ -7346,6 +7672,8 @@
 java.util.concurrent.LinkedBlockingQueue
 java.util.concurrent.LinkedBlockingQueue$Itr
 java.util.concurrent.LinkedBlockingQueue$Node
+java.util.concurrent.Phaser
+java.util.concurrent.Phaser$QNode
 java.util.concurrent.PriorityBlockingQueue
 java.util.concurrent.RejectedExecutionException
 java.util.concurrent.RejectedExecutionHandler
@@ -7368,6 +7696,7 @@
 java.util.concurrent.ThreadLocalRandom$1
 java.util.concurrent.ThreadPoolExecutor
 java.util.concurrent.ThreadPoolExecutor$AbortPolicy
+java.util.concurrent.ThreadPoolExecutor$DiscardOldestPolicy
 java.util.concurrent.ThreadPoolExecutor$DiscardPolicy
 java.util.concurrent.ThreadPoolExecutor$Worker
 java.util.concurrent.TimeUnit
@@ -7412,21 +7741,35 @@
 java.util.concurrent.locks.ReentrantReadWriteLock$Sync$HoldCounter
 java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
 java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
+java.util.function.-$Lambda$276$1MZdIZ-DL_fjy9l0o8IMJk57T2g
 java.util.function.BiConsumer
 java.util.function.BiFunction
+java.util.function.BinaryOperator
 java.util.function.Consumer
+java.util.function.DoubleBinaryOperator
 java.util.function.Function
+java.util.function.IntBinaryOperator
+java.util.function.IntConsumer
+java.util.function.IntFunction
+java.util.function.IntToDoubleFunction
+java.util.function.IntToLongFunction
+java.util.function.IntUnaryOperator
+java.util.function.LongBinaryOperator
+java.util.function.LongUnaryOperator
 java.util.function.Predicate
 java.util.function.Supplier
+java.util.function.ToDoubleBiFunction
 java.util.function.ToDoubleFunction
+java.util.function.ToIntBiFunction
 java.util.function.ToIntFunction
+java.util.function.ToLongBiFunction
 java.util.function.ToLongFunction
 java.util.function.UnaryOperator
 java.util.jar.Attributes
 java.util.jar.Attributes$Name
 java.util.jar.JarEntry
 java.util.jar.JarFile
-java.util.jar.JarFile$1
+java.util.jar.JarFile$JarEntryIterator
 java.util.jar.JarFile$JarFileEntry
 java.util.jar.JarVerifier
 java.util.jar.JarVerifier$1
@@ -7434,9 +7777,6 @@
 java.util.jar.Manifest
 java.util.jar.Manifest$FastInputStream
 java.util.logging.ErrorManager
-java.util.logging.FileHandler
-java.util.logging.FileHandler$InitializationErrorManager
-java.util.logging.FileHandler$MeteredStream
 java.util.logging.Filter
 java.util.logging.Formatter
 java.util.logging.Handler
@@ -7445,7 +7785,8 @@
 java.util.logging.LogManager
 java.util.logging.LogManager$1
 java.util.logging.LogManager$2
-java.util.logging.LogManager$4
+java.util.logging.LogManager$3
+java.util.logging.LogManager$5
 java.util.logging.LogManager$Cleaner
 java.util.logging.LogManager$LogNode
 java.util.logging.LogManager$LoggerContext
@@ -7456,31 +7797,71 @@
 java.util.logging.LogRecord
 java.util.logging.Logger
 java.util.logging.Logger$1
+java.util.logging.Logger$LoggerBundle
 java.util.logging.LoggingPermission
 java.util.logging.LoggingProxyImpl
-java.util.logging.SimpleFormatter
-java.util.logging.StreamHandler
-java.util.logging.XMLFormatter
 java.util.prefs.AbstractPreferences
 java.util.prefs.FileSystemPreferences
 java.util.prefs.Preferences
 java.util.regex.MatchResult
 java.util.regex.Matcher
+java.util.regex.Matcher$OffsetBasedMatchResult
 java.util.regex.Pattern
 java.util.regex.PatternSyntaxException
-java.util.spi.LocaleServiceProvider
+java.util.stream.-$Lambda$155$qTstLJg88fs2C3g6LH-R51vCVP0
+java.util.stream.-$Lambda$41$qTstLJg88fs2C3g6LH-R51vCVP0
+java.util.stream.-$Lambda$67$qTstLJg88fs2C3g6LH-R51vCVP0
+java.util.stream.-$Lambda$89$qTstLJg88fs2C3g6LH-R51vCVP0
+java.util.stream.AbstractPipeline
 java.util.stream.BaseStream
+java.util.stream.Collector
+java.util.stream.Collector$Characteristics
+java.util.stream.Collectors
+java.util.stream.Collectors$CollectorImpl
+java.util.stream.DoubleStream
+java.util.stream.ForEachOps
+java.util.stream.ForEachOps$ForEachOp
+java.util.stream.ForEachOps$ForEachOp$OfRef
 java.util.stream.IntStream
+java.util.stream.LongStream
+java.util.stream.PipelineHelper
+java.util.stream.ReduceOps
+java.util.stream.ReduceOps$3
+java.util.stream.ReduceOps$3ReducingSink
+java.util.stream.ReduceOps$AccumulatingSink
+java.util.stream.ReduceOps$Box
+java.util.stream.ReduceOps$ReduceOp
+java.util.stream.ReferencePipeline
+java.util.stream.ReferencePipeline$2
+java.util.stream.ReferencePipeline$2$1
+java.util.stream.ReferencePipeline$Head
+java.util.stream.ReferencePipeline$StatefulOp
+java.util.stream.ReferencePipeline$StatelessOp
+java.util.stream.Sink
+java.util.stream.Sink$ChainedReference
+java.util.stream.SliceOps
+java.util.stream.SliceOps$1
+java.util.stream.SliceOps$1$1
 java.util.stream.Stream
+java.util.stream.StreamOpFlag
+java.util.stream.StreamOpFlag$MaskBuilder
+java.util.stream.StreamOpFlag$Type
+java.util.stream.StreamShape
+java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator
+java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef
 java.util.stream.StreamSupport
+java.util.stream.TerminalOp
+java.util.stream.TerminalSink
 java.util.zip.Adler32
 java.util.zip.CRC32
 java.util.zip.CheckedInputStream
+java.util.zip.CheckedOutputStream
 java.util.zip.Checksum
 java.util.zip.DataFormatException
 java.util.zip.Deflater
 java.util.zip.DeflaterOutputStream
 java.util.zip.GZIPInputStream
+java.util.zip.GZIPInputStream$1
 java.util.zip.GZIPOutputStream
 java.util.zip.Inflater
 java.util.zip.InflaterInputStream
@@ -7488,13 +7869,15 @@
 java.util.zip.ZipCoder
 java.util.zip.ZipConstants
 java.util.zip.ZipEntry
+java.util.zip.ZipError
 java.util.zip.ZipException
 java.util.zip.ZipFile
-java.util.zip.ZipFile$1
+java.util.zip.ZipFile$ZipEntryIterator
 java.util.zip.ZipFile$ZipFileInflaterInputStream
 java.util.zip.ZipFile$ZipFileInputStream
 java.util.zip.ZipInputStream
 java.util.zip.ZipOutputStream
+java.util.zip.ZipUtils
 javax.crypto.BadPaddingException
 javax.crypto.Cipher
 javax.crypto.Cipher$CipherSpiAndProvider
@@ -7506,7 +7889,6 @@
 javax.crypto.CipherInputStream
 javax.crypto.CipherOutputStream
 javax.crypto.CipherSpi
-javax.crypto.EncryptedPrivateKeyInfo
 javax.crypto.IllegalBlockSizeException
 javax.crypto.JarVerifier
 javax.crypto.JceSecurity
@@ -7518,11 +7900,11 @@
 javax.crypto.NoSuchPaddingException
 javax.crypto.NullCipher
 javax.crypto.SecretKey
-javax.crypto.SecretKeyFactory
 javax.crypto.ShortBufferException
+javax.crypto.interfaces.PBEKey
+javax.crypto.spec.GCMParameterSpec
 javax.crypto.spec.IvParameterSpec
 javax.crypto.spec.OAEPParameterSpec
-javax.crypto.spec.PBEKeySpec
 javax.crypto.spec.PBEParameterSpec
 javax.crypto.spec.PSource
 javax.crypto.spec.PSource$PSpecified
@@ -7546,6 +7928,7 @@
 javax.net.ssl.HandshakeCompletedListener
 javax.net.ssl.HostnameVerifier
 javax.net.ssl.HttpsURLConnection
+javax.net.ssl.HttpsURLConnection$NoPreloadHolder
 javax.net.ssl.KeyManager
 javax.net.ssl.KeyManagerFactory
 javax.net.ssl.KeyManagerFactory$1
@@ -7574,9 +7957,11 @@
 javax.net.ssl.X509ExtendedTrustManager
 javax.net.ssl.X509KeyManager
 javax.net.ssl.X509TrustManager
+javax.security.auth.Destroyable
 javax.security.auth.callback.UnsupportedCallbackException
 javax.security.auth.x500.X500Principal
 javax.security.cert.Certificate
+javax.security.cert.CertificateEncodingException
 javax.security.cert.CertificateException
 javax.security.cert.X509Certificate
 javax.sip.SipException
@@ -7607,8 +7992,6 @@
 libcore.icu.TimeZoneNames$ZoneStringsCache
 libcore.internal.StringPool
 libcore.io.AsynchronousCloseMonitor
-libcore.io.Base64
-libcore.io.Base64$InvalidBase64ByteException
 libcore.io.BlockGuardOs
 libcore.io.BufferIterator
 libcore.io.ClassPathURLStreamHandler
@@ -7622,6 +8005,8 @@
 libcore.io.EventLogger$Reporter
 libcore.io.ForwardingOs
 libcore.io.IoBridge
+libcore.io.IoTracker
+libcore.io.IoTracker$Mode
 libcore.io.IoUtils
 libcore.io.IoUtils$FileReader
 libcore.io.Libcore
@@ -7638,6 +8023,8 @@
 libcore.net.UriCodec
 libcore.net.event.NetworkEventDispatcher
 libcore.net.event.NetworkEventListener
+libcore.net.http.HttpDate
+libcore.net.http.HttpDate$1
 libcore.reflect.AnnotatedElements
 libcore.reflect.AnnotationFactory
 libcore.reflect.AnnotationMember
@@ -7683,21 +8070,16 @@
 org.apache.harmony.xml.ExpatParser$ExpatLocator
 org.apache.harmony.xml.ExpatReader
 org.apache.harmony.xml.dom.AttrImpl
-org.apache.harmony.xml.dom.CDATASectionImpl
 org.apache.harmony.xml.dom.CharacterDataImpl
-org.apache.harmony.xml.dom.CommentImpl
 org.apache.harmony.xml.dom.DOMImplementationImpl
 org.apache.harmony.xml.dom.DocumentImpl
-org.apache.harmony.xml.dom.DocumentTypeImpl
 org.apache.harmony.xml.dom.ElementImpl
 org.apache.harmony.xml.dom.ElementImpl$ElementAttrNamedNodeMapImpl
-org.apache.harmony.xml.dom.EntityReferenceImpl
 org.apache.harmony.xml.dom.InnerNodeImpl
 org.apache.harmony.xml.dom.LeafNodeImpl
 org.apache.harmony.xml.dom.NodeImpl
 org.apache.harmony.xml.dom.NodeImpl$1
 org.apache.harmony.xml.dom.NodeListImpl
-org.apache.harmony.xml.dom.ProcessingInstructionImpl
 org.apache.harmony.xml.dom.TextImpl
 org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl
 org.apache.harmony.xml.parsers.DocumentBuilderImpl
@@ -7736,7 +8118,6 @@
 org.apache.http.ReasonPhraseCatalog
 org.apache.http.RequestLine
 org.apache.http.StatusLine
-org.apache.http.TokenIterator
 org.apache.http.auth.AuthSchemeFactory
 org.apache.http.auth.AuthSchemeRegistry
 org.apache.http.auth.AuthState
@@ -7774,7 +8155,6 @@
 org.apache.http.client.utils.URLEncodedUtils
 org.apache.http.conn.BasicManagedEntity
 org.apache.http.conn.ClientConnectionManager
-org.apache.http.conn.ClientConnectionManagerFactory
 org.apache.http.conn.ClientConnectionOperator
 org.apache.http.conn.ClientConnectionRequest
 org.apache.http.conn.ConnectTimeoutException
@@ -7829,7 +8209,6 @@
 org.apache.http.entity.BasicHttpEntity
 org.apache.http.entity.ByteArrayEntity
 org.apache.http.entity.ContentLengthStrategy
-org.apache.http.entity.FileEntity
 org.apache.http.entity.HttpEntityWrapper
 org.apache.http.entity.InputStreamEntity
 org.apache.http.entity.StringEntity
@@ -7849,7 +8228,6 @@
 org.apache.http.impl.client.AbstractHttpClient
 org.apache.http.impl.client.BasicCookieStore
 org.apache.http.impl.client.BasicCredentialsProvider
-org.apache.http.impl.client.BasicResponseHandler
 org.apache.http.impl.client.ClientParamsStack
 org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy
 org.apache.http.impl.client.DefaultHttpClient
@@ -7860,6 +8238,7 @@
 org.apache.http.impl.client.DefaultTargetAuthenticationHandler
 org.apache.http.impl.client.DefaultUserTokenHandler
 org.apache.http.impl.client.EntityEnclosingRequestWrapper
+org.apache.http.impl.client.RedirectLocations
 org.apache.http.impl.client.RequestWrapper
 org.apache.http.impl.client.RoutedRequest
 org.apache.http.impl.client.TunnelRefusedException
@@ -7872,10 +8251,6 @@
 org.apache.http.impl.conn.IdleConnectionHandler
 org.apache.http.impl.conn.IdleConnectionHandler$TimeValues
 org.apache.http.impl.conn.ProxySelectorRoutePlanner
-org.apache.http.impl.conn.SingleClientConnManager
-org.apache.http.impl.conn.SingleClientConnManager$1
-org.apache.http.impl.conn.SingleClientConnManager$ConnAdapter
-org.apache.http.impl.conn.SingleClientConnManager$PoolEntry
 org.apache.http.impl.conn.tsccm.AbstractConnPool
 org.apache.http.impl.conn.tsccm.BasicPoolEntry
 org.apache.http.impl.conn.tsccm.BasicPoolEntryRef
@@ -7951,7 +8326,6 @@
 org.apache.http.message.BasicHeaderElement
 org.apache.http.message.BasicHeaderElementIterator
 org.apache.http.message.BasicHeaderValueParser
-org.apache.http.message.BasicHttpEntityEnclosingRequest
 org.apache.http.message.BasicHttpRequest
 org.apache.http.message.BasicHttpResponse
 org.apache.http.message.BasicLineFormatter
@@ -7960,7 +8334,6 @@
 org.apache.http.message.BasicNameValuePair
 org.apache.http.message.BasicRequestLine
 org.apache.http.message.BasicStatusLine
-org.apache.http.message.BasicTokenIterator
 org.apache.http.message.BufferedHeader
 org.apache.http.message.HeaderGroup
 org.apache.http.message.HeaderValueParser
@@ -8002,7 +8375,6 @@
 org.apache.http.util.EncodingUtils
 org.apache.http.util.EntityUtils
 org.apache.http.util.LangUtils
-org.apache.http.util.VersionInfo
 org.ccil.cowan.tagsoup.AttributesImpl
 org.ccil.cowan.tagsoup.AutoDetector
 org.ccil.cowan.tagsoup.Element
@@ -8027,16 +8399,12 @@
 org.kxml2.io.KXmlParser$ValueContext
 org.kxml2.io.KXmlSerializer
 org.w3c.dom.Attr
-org.w3c.dom.CDATASection
 org.w3c.dom.CharacterData
-org.w3c.dom.Comment
-org.w3c.dom.DOMException
 org.w3c.dom.DOMImplementation
 org.w3c.dom.Document
 org.w3c.dom.DocumentFragment
 org.w3c.dom.DocumentType
 org.w3c.dom.Element
-org.w3c.dom.EntityReference
 org.w3c.dom.NamedNodeMap
 org.w3c.dom.Node
 org.w3c.dom.NodeList
@@ -8055,9 +8423,6 @@
 org.xml.sax.SAXNotSupportedException
 org.xml.sax.SAXParseException
 org.xml.sax.XMLReader
-org.xml.sax.ext.DeclHandler
-org.xml.sax.ext.DefaultHandler2
-org.xml.sax.ext.EntityResolver2
 org.xml.sax.ext.LexicalHandler
 org.xml.sax.helpers.AttributesImpl
 org.xml.sax.helpers.DefaultHandler
@@ -8065,22 +8430,28 @@
 org.xmlpull.v1.XmlPullParserException
 org.xmlpull.v1.XmlPullParserFactory
 org.xmlpull.v1.XmlSerializer
+sun.invoke.util.BytecodeDescriptor
+sun.invoke.util.Wrapper
 sun.misc.ASCIICaseInsensitiveComparator
-sun.misc.BASE64Decoder
-sun.misc.CEStreamExhausted
-sun.misc.CharacterDecoder
 sun.misc.Cleaner
 sun.misc.CompoundEnumeration
-sun.misc.FDBigInt
+sun.misc.FDBigInteger
+sun.misc.FloatingDecimal
+sun.misc.FloatingDecimal$1
+sun.misc.FloatingDecimal$ASCIIToBinaryBuffer
+sun.misc.FloatingDecimal$ASCIIToBinaryConverter
+sun.misc.FloatingDecimal$BinaryToASCIIBuffer
+sun.misc.FloatingDecimal$BinaryToASCIIConverter
+sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
+sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
 sun.misc.FormattedFloatingDecimal
 sun.misc.FormattedFloatingDecimal$1
 sun.misc.FormattedFloatingDecimal$Form
-sun.misc.FpUtils
-sun.misc.Hashing
 sun.misc.IOUtils
-sun.misc.IoTrace
+sun.misc.JavaIOFileDescriptorAccess
 sun.misc.LRUCache
 sun.misc.REException
+sun.misc.SharedSecrets
 sun.misc.Unsafe
 sun.misc.VM
 sun.misc.Version
@@ -8097,17 +8468,13 @@
 sun.net.www.ParseUtil
 sun.net.www.protocol.file.Handler
 sun.net.www.protocol.jar.Handler
-sun.nio.ch.AbstractPollArrayWrapper
-sun.nio.ch.AbstractPollSelectorImpl
-sun.nio.ch.AllocatedNativeObject
 sun.nio.ch.ChannelInputStream
 sun.nio.ch.DatagramChannelImpl
 sun.nio.ch.DatagramDispatcher
-sun.nio.ch.DefaultSelectorProvider
 sun.nio.ch.DirectBuffer
+sun.nio.ch.EPollArrayWrapper
 sun.nio.ch.FileChannelImpl
 sun.nio.ch.FileChannelImpl$Unmapper
-sun.nio.ch.FileDescriptorHolderSocketImpl
 sun.nio.ch.FileDispatcher
 sun.nio.ch.FileDispatcherImpl
 sun.nio.ch.FileKey
@@ -8115,33 +8482,18 @@
 sun.nio.ch.FileLockTable
 sun.nio.ch.IOStatus
 sun.nio.ch.IOUtil
-sun.nio.ch.InheritedChannel
 sun.nio.ch.Interruptible
 sun.nio.ch.NativeDispatcher
-sun.nio.ch.NativeObject
 sun.nio.ch.NativeThread
 sun.nio.ch.NativeThreadSet
 sun.nio.ch.Net
-sun.nio.ch.Net$1
-sun.nio.ch.PollArrayWrapper
-sun.nio.ch.PollSelectorImpl
-sun.nio.ch.PollSelectorProvider
 sun.nio.ch.SelChImpl
-sun.nio.ch.SelectionKeyImpl
-sun.nio.ch.SelectorImpl
-sun.nio.ch.SelectorProviderImpl
 sun.nio.ch.ServerSocketChannelImpl
 sun.nio.ch.SharedFileLockTable
 sun.nio.ch.SharedFileLockTable$FileLockReference
-sun.nio.ch.SocketAdaptor
-sun.nio.ch.SocketAdaptor$1
-sun.nio.ch.SocketAdaptor$2
-sun.nio.ch.SocketAdaptor$SocketInputStream
 sun.nio.ch.SocketChannelImpl
-sun.nio.ch.SocketDispatcher
 sun.nio.ch.Util
 sun.nio.ch.Util$1
-sun.nio.ch.Util$2
 sun.nio.ch.Util$BufferCache
 sun.nio.cs.ArrayDecoder
 sun.nio.cs.ArrayEncoder
@@ -8151,15 +8503,30 @@
 sun.nio.cs.ThreadLocalCoders$1
 sun.nio.cs.ThreadLocalCoders$2
 sun.nio.cs.ThreadLocalCoders$Cache
-sun.reflect.annotation.AnnotationType
+sun.nio.fs.AbstractFileSystemProvider
+sun.nio.fs.AbstractPath
+sun.nio.fs.DefaultFileSystemProvider
+sun.nio.fs.LinuxFileSystem
+sun.nio.fs.LinuxFileSystemProvider
+sun.nio.fs.NativeBuffer
+sun.nio.fs.NativeBuffer$Deallocator
+sun.nio.fs.NativeBuffers
+sun.nio.fs.UnixChannelFactory
+sun.nio.fs.UnixChannelFactory$Flags
+sun.nio.fs.UnixConstants
+sun.nio.fs.UnixException
+sun.nio.fs.UnixFileAttributes
+sun.nio.fs.UnixFileModeAttribute
+sun.nio.fs.UnixFileStoreAttributes
+sun.nio.fs.UnixFileSystem
+sun.nio.fs.UnixFileSystemProvider
+sun.nio.fs.UnixMountEntry
+sun.nio.fs.UnixNativeDispatcher
+sun.nio.fs.UnixPath
+sun.nio.fs.Util
 sun.reflect.misc.ReflectUtil
 sun.security.action.GetBooleanAction
 sun.security.action.GetPropertyAction
-sun.security.ec.ECKeyFactory
-sun.security.ec.ECKeyFactory$1
-sun.security.ec.ECKeyFactory$2
-sun.security.ec.ECParameters
-sun.security.ec.NamedCurve
 sun.security.jca.GetInstance
 sun.security.jca.GetInstance$Instance
 sun.security.jca.JCAUtil
@@ -8175,8 +8542,9 @@
 sun.security.jca.ServiceId
 sun.security.pkcs.ContentInfo
 sun.security.pkcs.PKCS7
+sun.security.pkcs.PKCS7$VerbatimX509Certificate
+sun.security.pkcs.PKCS7$WrappedX509Certificate
 sun.security.pkcs.PKCS9Attribute
-sun.security.pkcs.ParsingException
 sun.security.pkcs.SignerInfo
 sun.security.provider.CertPathProvider
 sun.security.provider.X509Factory
@@ -8192,7 +8560,9 @@
 sun.security.provider.certpath.PKIXMasterCertPathValidator
 sun.security.provider.certpath.PolicyChecker
 sun.security.provider.certpath.PolicyNodeImpl
-sun.security.provider.certpath.UntrustedChecker
+sun.security.util.-$Lambda$179$Kli5xKA4dAwmFO1sy_hpNWmbfH4
+sun.security.util.AbstractAlgorithmConstraints
+sun.security.util.AlgorithmDecomposer
 sun.security.util.BitArray
 sun.security.util.ByteArrayLexOrder
 sun.security.util.ByteArrayTagOrder
@@ -8206,7 +8576,6 @@
 sun.security.util.DerOutputStream
 sun.security.util.DerValue
 sun.security.util.DisabledAlgorithmConstraints
-sun.security.util.DisabledAlgorithmConstraints$1
 sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint
 sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint$Operator
 sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraints
@@ -8221,9 +8590,7 @@
 sun.security.util.MemoryCache$CacheEntry
 sun.security.util.MemoryCache$SoftCacheEntry
 sun.security.util.ObjectIdentifier
-sun.security.util.SecurityConstants
 sun.security.util.SignatureFileVerifier
-sun.security.util.UntrustedCertificates
 sun.security.x509.AVA
 sun.security.x509.AVAKeyword
 sun.security.x509.AccessDescription
@@ -8280,25 +8647,19 @@
 sun.security.x509.X509CertImpl
 sun.security.x509.X509CertInfo
 sun.security.x509.X509Key
-sun.util.LocaleServiceProviderPool
-sun.util.LocaleServiceProviderPool$1
 sun.util.calendar.AbstractCalendar
 sun.util.calendar.BaseCalendar
 sun.util.calendar.BaseCalendar$Date
 sun.util.calendar.CalendarDate
 sun.util.calendar.CalendarSystem
 sun.util.calendar.CalendarUtils
-sun.util.calendar.Era
 sun.util.calendar.Gregorian
 sun.util.calendar.Gregorian$Date
-sun.util.calendar.ImmutableGregorianDate
 sun.util.calendar.JulianCalendar
-sun.util.calendar.JulianCalendar$Date
 sun.util.calendar.LocalGregorianCalendar
 sun.util.locale.BaseLocale
 sun.util.locale.BaseLocale$Cache
 sun.util.locale.BaseLocale$Key
-sun.util.locale.Extension
 sun.util.locale.InternalLocaleBuilder
 sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar
 sun.util.locale.LanguageTag
@@ -8309,11 +8670,9 @@
 sun.util.locale.LocaleUtils
 sun.util.locale.ParseStatus
 sun.util.locale.StringTokenIterator
-sun.util.locale.UnicodeLocaleExtension
 sun.util.logging.LoggingProxy
 sun.util.logging.LoggingSupport
 sun.util.logging.LoggingSupport$1
-sun.util.logging.LoggingSupport$2
 sun.util.logging.PlatformLogger
 sun.util.logging.PlatformLogger$1
 sun.util.logging.PlatformLogger$JavaLoggerProxy
diff --git a/core/java/android/accessibilityservice/AccessibilityButtonController.java b/core/java/android/accessibilityservice/AccessibilityButtonController.java
new file mode 100644
index 0000000..c3a5dab
--- /dev/null
+++ b/core/java/android/accessibilityservice/AccessibilityButtonController.java
@@ -0,0 +1,223 @@
+/*
+ * 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.accessibilityservice;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Slog;
+
+/**
+ * Controller for the accessibility button within the system's navigation area
+ * <p>
+ * This class may be used to query the accessibility button's state and register
+ * callbacks for interactions with and state changes to the accessibility button when
+ * {@link AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} is set.
+ * </p>
+ * <p>
+ * <strong>Note:</strong> This class and
+ * {@link AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} should not be used as
+ * the sole means for offering functionality to users via an {@link AccessibilityService}.
+ * Some device implementations may choose not to provide a software-rendered system
+ * navigation area, making this affordance permanently unavailable.
+ * </p>
+ * <p>
+ * <strong>Note:</strong> On device implementations where the accessibility button is
+ * supported, it may not be available at all times, such as when a foreground application uses
+ * {@link android.view.View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}. A user may also choose to assign
+ * this button to another accessibility service or feature. In each of these cases, a
+ * registered {@link AccessibilityButtonCallback}'s
+ * {@link AccessibilityButtonCallback#onAvailabilityChanged(AccessibilityButtonController, boolean)}
+ * method will be invoked to provide notifications of changes in the accessibility button's
+ * availability to the registering service.
+ * </p>
+ */
+public final class AccessibilityButtonController {
+    private static final String LOG_TAG = "A11yButtonController";
+
+    private final IAccessibilityServiceConnection mServiceConnection;
+    private final Object mLock;
+    private ArrayMap<AccessibilityButtonCallback, Handler> mCallbacks;
+
+    AccessibilityButtonController(@NonNull IAccessibilityServiceConnection serviceConnection) {
+        mServiceConnection = serviceConnection;
+        mLock = new Object();
+    }
+
+    /**
+     * Retrieves whether the accessibility button in the system's navigation area is
+     * available to the calling service.
+     * <p>
+     * <strong>Note:</strong> If the service is not yet connected (e.g.
+     * {@link AccessibilityService#onServiceConnected()} has not yet been called) or the
+     * service has been disconnected, this method will have no effect and return {@code false}.
+     * </p>
+     *
+     * @return {@code true} if the accessibility button in the system's navigation area is
+     * available to the calling service, {@code false} otherwise
+     */
+    public boolean isAccessibilityButtonAvailable() {
+        try {
+            return mServiceConnection.isAccessibilityButtonAvailable();
+        } catch (RemoteException re) {
+            Slog.w(LOG_TAG, "Failed to get accessibility button availability.", re);
+            re.rethrowFromSystemServer();
+            return false;
+        }
+    }
+
+    /**
+     * Registers the provided {@link AccessibilityButtonCallback} for interaction and state
+     * changes callbacks related to the accessibility button.
+     *
+     * @param callback the callback to add, must be non-null
+     */
+    public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback) {
+        registerAccessibilityButtonCallback(callback, null);
+    }
+
+    /**
+     * Registers the provided {@link AccessibilityButtonCallback} for interaction and state
+     * change callbacks related to the accessibility button. The callback will occur on the
+     * specified {@link Handler}'s thread, or on the services's main thread if the handler is
+     * {@code null}.
+     *
+     * @param callback the callback to add, must be non-null
+     * @param handler the handler on which to callback should execute, or {@code null} to
+     *                execute on the service's main thread
+     */
+    public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback,
+            @Nullable Handler handler) {
+        synchronized (mLock) {
+            if (mCallbacks == null) {
+                mCallbacks = new ArrayMap<>();
+            }
+
+            mCallbacks.put(callback, handler);
+        }
+    }
+
+    /**
+     * Unregisters the provided {@link AccessibilityButtonCallback} for interaction and state
+     * change callbacks related to the accessibility button.
+     *
+     * @param callback the callback to remove, must be non-null
+     */
+    public void unregisterAccessibilityButtonCallback(
+            @NonNull AccessibilityButtonCallback callback) {
+        synchronized (mLock) {
+            if (mCallbacks == null) {
+                return;
+            }
+
+            final int keyIndex = mCallbacks.indexOfKey(callback);
+            final boolean hasKey = keyIndex >= 0;
+            if (hasKey) {
+                mCallbacks.removeAt(keyIndex);
+            }
+        }
+    }
+
+    /**
+     * Dispatches the accessibility button click to any registered callbacks. This should
+     * be called on the service's main thread.
+     */
+    void dispatchAccessibilityButtonClicked() {
+        final ArrayMap<AccessibilityButtonCallback, Handler> entries;
+        synchronized (mLock) {
+            if (mCallbacks == null || mCallbacks.isEmpty()) {
+                Slog.w(LOG_TAG, "Received accessibility button click with no callbacks!");
+                return;
+            }
+
+            // Callbacks may remove themselves. Perform a shallow copy to avoid concurrent
+            // modification.
+            entries = new ArrayMap<>(mCallbacks);
+        }
+
+        for (int i = 0, count = entries.size(); i < count; i++) {
+            final AccessibilityButtonCallback callback = entries.keyAt(i);
+            final Handler handler = entries.valueAt(i);
+            if (handler != null) {
+                handler.post(() -> callback.onClicked(this));
+            } else {
+                // We're already on the main thread, just run the callback.
+                callback.onClicked(this);
+            }
+        }
+    }
+
+    /**
+     * Dispatches the accessibility button availability changes to any registered callbacks.
+     * This should be called on the service's main thread.
+     */
+    void dispatchAccessibilityButtonAvailabilityChanged(boolean available) {
+        final ArrayMap<AccessibilityButtonCallback, Handler> entries;
+        synchronized (mLock) {
+            if (mCallbacks == null || mCallbacks.isEmpty()) {
+                Slog.w(LOG_TAG,
+                        "Received accessibility button availability change with no callbacks!");
+                return;
+            }
+
+            // Callbacks may remove themselves. Perform a shallow copy to avoid concurrent
+            // modification.
+            entries = new ArrayMap<>(mCallbacks);
+        }
+
+        for (int i = 0, count = entries.size(); i < count; i++) {
+            final AccessibilityButtonCallback callback = entries.keyAt(i);
+            final Handler handler = entries.valueAt(i);
+            if (handler != null) {
+                handler.post(() -> callback.onAvailabilityChanged(this, available));
+            } else {
+                // We're already on the main thread, just run the callback.
+                callback.onAvailabilityChanged(this, available);
+            }
+        }
+    }
+
+    /**
+     * Callback for interaction with and changes to state of the accessibility button
+     * within the system's navigation area.
+     */
+    public static abstract class AccessibilityButtonCallback {
+
+        /**
+         * Called when the accessibility button in the system's navigation area is clicked.
+         *
+         * @param controller the controller used to register for this callback
+         */
+        public void onClicked(AccessibilityButtonController controller) {}
+
+        /**
+         * Called when the availability of the accessibility button in the system's
+         * navigation area has changed. The accessibility button may become unavailable
+         * because the device shopped showing the button, the button was assigned to another
+         * service, or for other reasons.
+         *
+         * @param controller the controller used to register for this callback
+         * @param available {@code true} if the accessibility button is available to this
+         *                  service, {@code false} otherwise
+         */
+        public void onAvailabilityChanged(AccessibilityButtonController controller,
+                boolean available) {
+        }
+    }
+}
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index a036b6a..9e486d5 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -378,6 +378,8 @@
         void onPerformGestureResult(int sequence, boolean completedSuccessfully);
         void onFingerprintCapturingGesturesChanged(boolean active);
         void onFingerprintGesture(int gesture);
+        void onAccessibilityButtonClicked();
+        void onAccessibilityButtonAvailabilityChanged(boolean available);
     }
 
     /**
@@ -400,6 +402,7 @@
 
     private MagnificationController mMagnificationController;
     private SoftKeyboardController mSoftKeyboardController;
+    private AccessibilityButtonController mAccessibilityButtonController;
 
     private int mGestureStatusCallbackSequence;
 
@@ -431,6 +434,9 @@
         if (mMagnificationController != null) {
             mMagnificationController.onServiceConnected();
         }
+        if (mSoftKeyboardController != null) {
+            mSoftKeyboardController.onServiceConnected();
+        }
 
         // The client gets to handle service connection last, after we've set
         // up any state upon which their code may rely.
@@ -809,12 +815,10 @@
         }
 
         /**
-         * Removes all instances of the specified change listener from the list
-         * of magnification change listeners.
+         * Removes the specified change listener from the list of magnification change listeners.
          *
          * @param listener the listener to remove, must be non-null
-         * @return {@code true} if at least one instance of the listener was
-         *         removed
+         * @return {@code true} if the listener was removed, {@code false} otherwise
          */
         public boolean removeListener(@NonNull OnMagnificationChangedListener listener) {
             if (mListeners == null) {
@@ -1203,11 +1207,11 @@
         }
 
         /**
-         * Removes all instances of the specified change listener from the list of magnification
-         * change listeners.
+         * Removes the specified change listener from the list of keyboard show mode change
+         * listeners.
          *
          * @param listener the listener to remove, must be non-null
-         * @return {@code true} if at least one instance of the listener was removed
+         * @return {@code true} if the listener was removed, {@code false} otherwise
          */
         public boolean removeOnShowModeChangedListener(@NonNull OnShowModeChangedListener listener) {
             if (mListeners == null) {
@@ -1252,7 +1256,7 @@
             final ArrayMap<OnShowModeChangedListener, Handler> entries;
             synchronized (mLock) {
                 if (mListeners == null || mListeners.isEmpty()) {
-                    Slog.d(LOG_TAG, "Received soft keyboard show mode changed callback"
+                    Slog.w(LOG_TAG, "Received soft keyboard show mode changed callback"
                             + " with no listeners registered!");
                     setSoftKeyboardCallbackEnabled(false);
                     return;
@@ -1308,9 +1312,9 @@
          * The lastto this method will be honored, regardless of any previous calls (including those
          * made by other AccessibilityServices).
          * <p>
-         * <strong>Note:</strong> If the service is not yet conected (e.g.
+         * <strong>Note:</strong> If the service is not yet connected (e.g.
          * {@link AccessibilityService#onServiceConnected()} has not yet been called) or the
-         * service has been disconnected, this method will hav no effect and return {@code false}.
+         * service has been disconnected, this method will have no effect and return {@code false}.
          *
          * @param showMode the new show mode for the soft keyboard
          * @return {@code true} on success
@@ -1349,6 +1353,39 @@
     }
 
     /**
+     * Returns the controller for the accessibility button within the system's navigation area.
+     * This instance may be used to query the accessibility button's state and register listeners
+     * for interactions with and state changes for the accessibility button when
+     * {@link AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} is set.
+     * <p>
+     * <strong>Note:</strong> Not all devices are capable of displaying the accessibility button
+     * within a navigation area, and as such, use of this class should be considered only as an
+     * optional feature or shortcut on supported device implementations.
+     * </p>
+     *
+     * @return the accessibility button controller for this {@link AccessibilityService}
+     */
+    @NonNull
+    public final AccessibilityButtonController getAccessibilityButtonController() {
+        synchronized (mLock) {
+            if (mAccessibilityButtonController == null) {
+                mAccessibilityButtonController = new AccessibilityButtonController(
+                        AccessibilityInteractionClient.getInstance().getConnection(mConnectionId));
+            }
+            return mAccessibilityButtonController;
+        }
+    }
+
+    private void onAccessibilityButtonClicked() {
+        getAccessibilityButtonController().dispatchAccessibilityButtonClicked();
+    }
+
+    private void onAccessibilityButtonAvailabilityChanged(boolean available) {
+        getAccessibilityButtonController().dispatchAccessibilityButtonAvailabilityChanged(
+                available);
+    }
+
+    /**
      * Performs a global action. Such an action can be performed
      * at any moment regardless of the current application or user
      * location in that application. For example going back, going
@@ -1543,6 +1580,16 @@
             public void onFingerprintGesture(int gesture) {
                 AccessibilityService.this.onFingerprintGesture(gesture);
             }
+
+            @Override
+            public void onAccessibilityButtonClicked() {
+                AccessibilityService.this.onAccessibilityButtonClicked();
+            }
+
+            @Override
+            public void onAccessibilityButtonAvailabilityChanged(boolean available) {
+                AccessibilityService.this.onAccessibilityButtonAvailabilityChanged(available);
+            }
         });
     }
 
@@ -1565,6 +1612,8 @@
         private static final int DO_GESTURE_COMPLETE = 9;
         private static final int DO_ON_FINGERPRINT_ACTIVE_CHANGED = 10;
         private static final int DO_ON_FINGERPRINT_GESTURE = 11;
+        private static final int DO_ACCESSIBILITY_BUTTON_CLICKED = 12;
+        private static final int DO_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED = 13;
 
         private final HandlerCaller mCaller;
 
@@ -1645,6 +1694,17 @@
             mCaller.sendMessage(mCaller.obtainMessageI(DO_ON_FINGERPRINT_GESTURE, gesture));
         }
 
+        public void onAccessibilityButtonClicked() {
+            final Message message = mCaller.obtainMessage(DO_ACCESSIBILITY_BUTTON_CLICKED);
+            mCaller.sendMessage(message);
+        }
+
+        public void onAccessibilityButtonAvailabilityChanged(boolean available) {
+            final Message message = mCaller.obtainMessageI(
+                    DO_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED, (available ? 1 : 0));
+            mCaller.sendMessage(message);
+        }
+
         @Override
         public void executeMessage(Message message) {
             switch (message.what) {
@@ -1750,6 +1810,15 @@
                     mCallback.onFingerprintGesture(message.arg1);
                 } return;
 
+                case (DO_ACCESSIBILITY_BUTTON_CLICKED): {
+                    mCallback.onAccessibilityButtonClicked();
+                } return;
+
+                case (DO_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED): {
+                    final boolean available = (message.arg1 != 0);
+                    mCallback.onAccessibilityButtonAvailabilityChanged(available);
+                } return;
+
                 default :
                     Log.w(LOG_TAG, "Unknown message type " + message.what);
             }
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 18e57cb..e135ffd 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -306,6 +306,12 @@
      */
     public static final int FLAG_ENABLE_ACCESSIBILITY_VOLUME = 0x00000080;
 
+     /**
+     * This flag indicates to the system that the accessibility service requests that an
+     * accessibility button be shown within the system's navigation area, if available.
+     */
+    public static final int FLAG_REQUEST_ACCESSIBILITY_BUTTON = 0x00000100;
+
     /**
      * This flag requests that all fingerprint gestures be sent to the accessibility service.
      * It is handled in {@link FingerprintGestureController}
@@ -396,6 +402,8 @@
      * @see #FLAG_REQUEST_FILTER_KEY_EVENTS
      * @see #FLAG_REPORT_VIEW_IDS
      * @see #FLAG_RETRIEVE_INTERACTIVE_WINDOWS
+     * @see #FLAG_ENABLE_ACCESSIBILITY_VOLUME
+     * @see #FLAG_REQUEST_ACCESSIBILITY_BUTTON
      */
     public int flags;
 
@@ -631,7 +639,7 @@
      * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
      * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
      * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
-     * @see #CAPABILITY_FILTER_KEY_EVENTS
+     * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
      * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
      * @see #CAPABILITY_CAN_PERFORM_GESTURES
      */
@@ -648,7 +656,7 @@
      * @see #CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT
      * @see #CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION
      * @see #CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY
-     * @see #CAPABILITY_FILTER_KEY_EVENTS
+     * @see #CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS
      * @see #CAPABILITY_CAN_CONTROL_MAGNIFICATION
      * @see #CAPABILITY_CAN_PERFORM_GESTURES
      *
@@ -936,6 +944,8 @@
                 return "FLAG_RETRIEVE_INTERACTIVE_WINDOWS";
             case FLAG_ENABLE_ACCESSIBILITY_VOLUME:
                 return "FLAG_ENABLE_ACCESSIBILITY_VOLUME";
+            case FLAG_REQUEST_ACCESSIBILITY_BUTTON:
+                return "FLAG_REQUEST_ACCESSIBILITY_BUTTON";
             case FLAG_CAPTURE_FINGERPRINT_GESTURES:
                 return "FLAG_CAPTURE_FINGERPRINT_GESTURES";
             default:
@@ -960,7 +970,7 @@
             case CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY:
                 return "CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY";
             case CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS:
-                return "CAPABILITY_CAN_FILTER_KEY_EVENTS";
+                return "CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS";
             case CAPABILITY_CAN_CONTROL_MAGNIFICATION:
                 return "CAPABILITY_CAN_CONTROL_MAGNIFICATION";
             case CAPABILITY_CAN_PERFORM_GESTURES:
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
index 3f778ad..4e96b8f 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
@@ -50,4 +50,8 @@
     void onFingerprintCapturingGesturesChanged(boolean capturing);
 
     void onFingerprintGesture(int gesture);
+
+    void onAccessibilityButtonClicked();
+
+    void onAccessibilityButtonAvailabilityChanged(boolean available);
 }
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 5499bd5..5bd37220 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -88,6 +88,8 @@
 
     void setSoftKeyboardCallbackEnabled(boolean enabled);
 
+    boolean isAccessibilityButtonAvailable();
+
     void sendGesture(int sequence, in ParceledListSlice gestureSteps);
 
     boolean isFingerprintGestureDetectionAvailable();
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index def0ff9..0263681 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -338,21 +338,24 @@
         "android.accounts.LOGIN_ACCOUNTS_CHANGED";
 
     /**
-     * Uid key to set default visibility for applications targeting API level
+     * Key to set default visibility for applications targeting API level
      * {@link android.os.Build.VERSION_CODES#O} or above and don't have the same signature as
      * authenticator See {@link #getAccountVisibility}. If the value was not set by authenticator
-     * USER_MANAGED_NOT_VISIBLE is used.
+     * {@link #VISIBILITY_USER_MANAGED_NOT_VISIBLE} is used.
      */
-    public static final int UID_KEY_DEFAULT_VISIBILITY = -2;
+    public static final String PACKAGE_NAME_KEY_LEGACY_VISIBLE =
+            "android.accounts.key_legacy_visible";
 
     /**
-     * Uid key to set visibility for applications targeting API level below
-     * {@link android.os.Build.VERSION_CODES#O} with GET_ACCOUNS permission, or applications with
-     * any targeting API level with the same signature as authenticator. See
-     * {@link #getAccountVisibility}. If the value was not set by authenticator USER_MANAGED_VISIBLE
-     * is used.
+     * Key to set visibility for applications targeting API level below
+     * {@link android.os.Build.VERSION_CODES#O} with
+     * {@link android.Manifest.permission#GET_ACCOUNTS} permission, or applications with any
+     * targeting API level with the same signature as authenticator. See
+     * {@link #getAccountVisibility}. If the value was not set by authenticator
+     * {@link #VISIBILITY_USER_MANAGED_VISIBLE} is used.
      */
-    public static final int UID_KEY_DEFAULT_LEGACY_VISIBILITY = -3;
+    public static final String PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE =
+            "android.accounts.key_legacy_not_visible";
 
     /**
      * @hide
@@ -565,12 +568,14 @@
     }
 
     /**
-     * Returns the accounts visible to the specified package, in an environment where some apps
-     * are not authorized to view all accounts. This method can only be called by system apps.
+     * Returns the accounts visible to the specified package, in an environment where some apps are
+     * not authorized to view all accounts. This method can only be called by system apps and
+     * authenticators managing the type
+     *
      * @param type The type of accounts to return, null to retrieve all accounts
      * @param packageName The package name of the app for which the accounts are to be returned
-     * @return An array of {@link Account}, one per matching account.  Empty
-     *     (never null) if no accounts of the specified type have been added.
+     * @return An array of {@link Account}, one per matching account. Empty (never null) if no
+     *         accounts of the specified type have been added.
      */
     @NonNull
     public Account[] getAccountsByTypeForPackage(String type, String packageName) {
@@ -609,7 +614,8 @@
      *
      * <p>
      * <b>NOTE:</b> If targeting your app to work on API level
-     * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before, GET_ACCOUNTS permission is
+     * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before,
+     * {@link android.Manifest.permission#GET_ACCOUNTS} permission is
      * needed for those platforms, irrespective of uid or signature match. See docs for this
      * function in API level {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}.
      *
@@ -750,7 +756,8 @@
      * accounts managed by AbstractAccountAuthenticators whose signature matches the client.
      * <p>
      * <b>NOTE:</b> If targeting your app to work on API level
-     * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before, GET_ACCOUNTS permission is
+     * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1} and before,
+     * {@link android.Manifest.permission#GET_ACCOUNTS} permission is
      * needed for those platforms, irrespective of uid or signature match. See docs for this
      * function in API level {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}.
      *
@@ -822,9 +829,8 @@
     }
 
     /**
-     * Adds an account directly to the AccountManager. Additionally this makes the Account visible
-     * to desired UIDs of applications on the device, and sends directed broadcasts to these
-     * individual applications.
+     * Adds an account directly to the AccountManager. Additionally it specifies Account visiblity
+     * for given list of packages.
      * <p>
      * Normally used by sign-up wizards associated with authenticators, not directly by
      * applications.
@@ -841,14 +847,14 @@
      * @param account The {@link Account} to add
      * @param password The password to associate with the account, null for none
      * @param extras String values to use for the account's userdata, null for none
-     * @param visibility Map from uid to visibility values which will be set before account is
-     *        added. See getAccountVisibility for possilbe values.
+     * @param visibility Map from packageName to visibility values which will be set before account
+     *        is added. See {@link #getAccountVisibility} for possible values.
      *
      * @return True if the account was successfully added, false if the account already exists, the
      *         account is null, or another error occurs.
      */
     public boolean addAccountExplicitly(Account account, String password, Bundle extras,
-            Map<Integer, Integer> visibility) {
+            Map<String, Integer> visibility) {
         if (account == null)
             throw new IllegalArgumentException("account is null");
         try {
@@ -860,20 +866,22 @@
     }
 
     /**
-     * Returns UIDs of applications for which visibility of given account was explicitly set.
+     * Returns package names and visibility which were explicitly set for given account.
      * <p>
      * This method requires the caller to have a signature match with the authenticator that owns
      * the specified account.
      *
      * @param account The account for which visibility data should be returned.
      *
-     * @return Map from uid to visibility for given account.
+     * @return Map from package names to visibility for given account.
      */
-    public Map<Integer, Integer> getUidsAndVisibilityForAccount(Account account) {
+    public Map<String, Integer> getPackagesAndVisibilityForAccount(Account account) {
         try {
+            if (account == null)
+                throw new IllegalArgumentException("account is null");
             @SuppressWarnings("unchecked")
-            Map<Integer, Integer> result = (Map<Integer, Integer>) mService
-                    .getUidsAndVisibilityForAccount(account);
+            Map<String, Integer> result = (Map<String, Integer>) mService
+                    .getPackagesAndVisibilityForAccount(account);
             return result;
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
@@ -907,30 +915,34 @@
     }
 
     /**
-     * Set visibility value of given account to certain UID.
+     * Set visibility value of given account to certain packageName.
+     * Package name must match installed application, or be equal to
+     * {@link #PACKAGE_NAME_KEY_LEGACY_VISIBLE} or {@link #PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE}.
      * <p>
      * See {@link #getAccountVisibility} for possible values.
      * <p>
      * This method requires the caller to have a signature match with the authenticator that owns
      * the specified account.
      *
-     * @param account Account to make visible.
-     * @param uid The UID of the application to modify account visibility.
+     * @param account Account to update visibility
+     * @param packageName Package name of the application to modify account visibility.
      * @param visibility - new visibility value.
      *
      * @return True if visibility value was succesfully updated.
      */
-    public boolean setAccountVisibility(Account account, int uid,
+    public boolean setAccountVisibility(Account account, String packageName,
             @AccountVisibility int visibility) {
+        if (account == null)
+            throw new IllegalArgumentException("account is null");
         try {
-            return mService.setAccountVisibility(account, uid, visibility);
+            return mService.setAccountVisibility(account, packageName, visibility);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
     }
 
     /**
-     * Gets visibility of certain account for given UID. Possible returned values are:
+     * Get visibility of certain account for given application. Possible returned values are:
      * <ul>
      * <li>{@link #VISIBILITY_UNDEFINED}</li>
      * <li>{@link #VISIBILITY_VISIBLE}</li>
@@ -944,13 +956,15 @@
      * the specified account.
      *
      * @param account Account to get visibility.
-     * @param uid The UID of the application to get account visibility.
+     * @param packageName Package name of the application to get account visibility
      *
-     * @return int Visibility for given account and uid.
+     * @return int Visibility for given account and package.
      */
-    public @AccountVisibility int getAccountVisibility(Account account, int uid) {
+    public @AccountVisibility int getAccountVisibility(Account account, String packageName) {
+        if (account == null)
+            throw new IllegalArgumentException("account is null");
         try {
-            return mService.getAccountVisibility(account, uid);
+            return mService.getAccountVisibility(account, packageName);
         } catch (RemoteException re) {
             throw re.rethrowFromSystemServer();
         }
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 95fdfef..35011b5 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -437,7 +437,7 @@
         }
         if (oldVisibility != null
                 && oldVisibility == AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE) {
-            AccountManager.get(this).setAccountVisibility(account, mCallingUid,
+            AccountManager.get(this).setAccountVisibility(account, mCallingPackage,
                     AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
         }
         Bundle bundle = new Bundle();
diff --git a/core/java/android/accounts/IAccountManager.aidl b/core/java/android/accounts/IAccountManager.aidl
index 63a0919..e0fdac1 100644
--- a/core/java/android/accounts/IAccountManager.aidl
+++ b/core/java/android/accounts/IAccountManager.aidl
@@ -108,15 +108,12 @@
     void isCredentialsUpdateSuggested(in IAccountManagerResponse response, in Account account,
         String statusToken);
 
-    /* Returns Map<Integer, Integer> from UID to visibility with all values stored for given account*/
-    Map getUidsAndVisibilityForAccount(in Account account);
-
+    /* Returns Map<String, Integer> from package name to visibility with all values stored for given account */
+    Map getPackagesAndVisibilityForAccount(in Account account);
     boolean addAccountExplicitlyWithVisibility(in Account account, String password, in Bundle extras,
             in Map visibility);
-
-    boolean setAccountVisibility(in Account a, int uid, int newVisibility);
-    int getAccountVisibility(in Account a, int uid);
-
+    boolean setAccountVisibility(in Account a, in String packageName, int newVisibility);
+    int getAccountVisibility(in Account a, in String packageName);
     /* Type may be null returns Map <Account, Integer>*/
     Map getAccountsAndVisibilityForPackage(in String packageName, in String accountType);
 
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 55ac1f4..558fdc6 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -637,13 +637,16 @@
     public void setCurrentFraction(float fraction) {
         initAnimation();
         fraction = clampFraction(fraction);
-        long seekTime = (long) (getScaledDuration() * fraction);
-        long currentTime = AnimationUtils.currentAnimationTimeMillis();
-        mStartTime = currentTime - seekTime;
         mStartTimeCommitted = true; // do not allow start time to be compensated for jank
-        if (!isPulsingInternal()) {
-            // If the animation loop hasn't started, the startTime will be adjusted in the first
-            // frame based on seek fraction.
+        if (isPulsingInternal()) {
+            long seekTime = (long) (getScaledDuration() * fraction);
+            long currentTime = AnimationUtils.currentAnimationTimeMillis();
+            // Only modify the start time when the animation is running. Seek fraction will ensure
+            // non-running animations skip to the correct start time.
+            mStartTime = currentTime - seekTime;
+        } else {
+            // If the animation loop hasn't started, or during start delay, the startTime will be
+            // adjusted once the delay has passed based on seek fraction.
             mSeekFraction = fraction;
         }
         mOverallFraction = fraction;
@@ -1028,7 +1031,7 @@
         // started-but-not-yet-reached-the-first-frame phase.
         mLastFrameTime = -1;
         mFirstFrameTime = -1;
-        addAnimationCallback((long) (mStartDelay * sDurationScale));
+        addAnimationCallback(0);
 
         if (mStartDelay == 0 || mSeekFraction >= 0 || mReversing) {
             // If there's no start delay, init the animation and notify start listeners right away
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 04510da..0b9479d 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -33,6 +33,7 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
 import android.transition.TransitionManager;
 import android.util.Pair;
 import android.util.Slog;
@@ -1342,7 +1343,7 @@
                 + mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight;
     }
 
-    private static class HideWindowListener extends Transition.TransitionListenerAdapter
+    private static class HideWindowListener extends TransitionListenerAdapter
         implements ExitTransitionCoordinator.HideSharedElementsCallback {
         private final Window mWindow;
         private final ExitTransitionCoordinator mExit;
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 1eaf029..a512350 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -24,6 +24,7 @@
 import android.os.Parcelable;
 import android.os.ResultReceiver;
 import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
 import android.transition.TransitionSet;
 import android.transition.Visibility;
 import android.util.ArrayMap;
@@ -916,7 +917,7 @@
 
     protected void onTransitionsComplete() {}
 
-    protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter {
+    protected class ContinueTransitionListener extends TransitionListenerAdapter {
         @Override
         public void onTransitionStart(Transition transition) {
             mIsStartingTransition = false;
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 0454acb..445b687 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -26,6 +26,7 @@
 import android.os.ResultReceiver;
 import android.text.TextUtils;
 import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
 import android.transition.TransitionManager;
 import android.util.ArrayMap;
 import android.view.View;
@@ -491,7 +492,7 @@
                 sharedElementTransitionStarted();
                 sharedElementTransitionComplete();
             } else {
-                sharedElementTransition.addListener(new Transition.TransitionListenerAdapter() {
+                sharedElementTransition.addListener(new TransitionListenerAdapter() {
                     @Override
                     public void onTransitionStart(Transition transition) {
                         sharedElementTransitionStarted();
@@ -592,7 +593,7 @@
                 });
                 mBackgroundAnimator.start();
             } else if (transition != null) {
-                transition.addListener(new Transition.TransitionListenerAdapter() {
+                transition.addListener(new TransitionListenerAdapter() {
                     @Override
                     public void onTransitionEnd(Transition transition) {
                         transition.removeListener(this);
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index f04eef2..29e10d8 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -31,6 +31,7 @@
 import android.os.Message;
 import android.os.ResultReceiver;
 import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
 import android.transition.TransitionManager;
 import android.view.View;
 import android.view.ViewGroup;
@@ -161,7 +162,7 @@
 
     private void startSharedElementExit(final ViewGroup decorView) {
         Transition transition = getSharedElementExitTransition();
-        transition.addListener(new Transition.TransitionListenerAdapter() {
+        transition.addListener(new TransitionListenerAdapter() {
             @Override
             public void onTransitionEnd(Transition transition) {
                 transition.removeListener(this);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 4f68ec7..b7c0737 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -2077,8 +2077,6 @@
             } else {
                 record.trackAddedFragmentsInPop(mTmpAddedFragments);
             }
-            final int bumpAmount = isPop ? -1 : 1;
-            record.bumpBackStackNesting(bumpAmount);
             addToBackStack = addToBackStack || record.mAddToBackStack;
         }
         mTmpAddedFragments.clear();
@@ -2281,8 +2279,10 @@
             final BackStackRecord record = records.get(i);
             final boolean isPop = isRecordPop.get(i);
             if (isPop) {
+                record.bumpBackStackNesting(-1);
                 record.executePopOps();
             } else {
+                record.bumpBackStackNesting(1);
                 record.executeOps();
             }
         }
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index 2570d92..f62ab8d 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -18,6 +18,7 @@
 import android.graphics.Rect;
 import android.os.Build;
 import android.transition.Transition;
+import android.transition.TransitionListenerAdapter;
 import android.transition.TransitionManager;
 import android.transition.TransitionSet;
 import android.util.ArrayMap;
@@ -332,7 +333,7 @@
             OneShotPreDrawListener.add(exitingFragment.mContainer, () -> {
                 setViewVisibility(exitingViews, View.INVISIBLE);
             });
-            exitTransition.addListener(new Transition.TransitionListenerAdapter() {
+            exitTransition.addListener(new TransitionListenerAdapter() {
                 @Override
                 public void onTransitionEnd(Transition transition) {
                     transition.removeListener(this);
@@ -995,7 +996,7 @@
             final Transition enterTransition, final ArrayList<View> enteringViews,
             final Transition exitTransition, final ArrayList<View> exitingViews,
             final TransitionSet sharedElementTransition, final ArrayList<View> sharedElementsIn) {
-        overalTransition.addListener(new Transition.TransitionListenerAdapter() {
+        overalTransition.addListener(new TransitionListenerAdapter() {
             @Override
             public void onTransitionStart(Transition transition) {
                 if (enterTransition != null) {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 3cc6282..99ae96d 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -145,6 +145,7 @@
             int flags, in Bundle arguments, in IInstrumentationWatcher watcher,
             in IUiAutomationConnection connection, int userId,
             in String abiOverride);
+    void addInstrumentationResults(in IApplicationThread target, in Bundle results);
     void finishInstrumentation(in IApplicationThread target, int resultCode,
             in Bundle results);
     /**
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index b1bdea1..4db29fb 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -186,11 +186,25 @@
             }
         }
     }
-    
+
+    /**
+     * Report some results in the middle of instrumentation execution.  Later results (including
+     * those provided by {@link #finish}) will be combined with {@link Bundle#putAll}.
+     */
+    public void addResults(Bundle results) {
+        IActivityManager am = ActivityManager.getService();
+        try {
+            am.addInstrumentationResults(mThread.getApplicationThread(), results);
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
     /**
      * Terminate instrumentation of the application.  This will cause the
      * application process to exit, removing this instrumentation from the next
-     * time the application is started. 
+     * time the application is started.  If multiple processes are currently running
+     * for this instrumentation, all of those processes will be killed.
      *  
      * @param resultCode Overall success/failure of instrumentation. 
      * @param results Any results to send back to the code that started the 
@@ -278,6 +292,18 @@
     }
 
     /**
+     * Return the name of the process this instrumentation is running in.  Note this should
+     * only be used for testing and debugging.  If you are thinking about using this to,
+     * for example, conditionalize what is initialized in an Application class, it is strongly
+     * recommended to instead use lazy initialization (such as a getter for the state that
+     * only creates it when requested).  This can greatly reduce the work your process does
+     * when created for secondary things, such as to receive a broadcast.
+     */
+    public String getProcessName() {
+        return mThread.getProcessName();
+    }
+
+    /**
      * Check whether this instrumentation was started with profiling enabled.
      * 
      * @return Returns true if profiling was enabled when starting, else false.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index b7eda25..44e328e 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -28,6 +28,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ShortcutInfo;
 import android.content.res.ColorStateList;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -48,6 +49,7 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
 import android.text.BidiFormatter;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
@@ -222,13 +224,11 @@
      * superimposed over the icon in the status bar. Starting with
      * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, the template used by
      * {@link Notification.Builder} has displayed the number in the expanded notification view.
+     * Starting with {@link android.os.Build.VERSION_CODES#O}, the number may be displayed as a
+     * badge icon in Launchers that support badging.
      *
-     * If the number is 0 or negative, it is never shown.
-     *
-     * @deprecated this number is not shown anymore
      */
-    @Deprecated
-    public int number;
+    public int number = 1;
 
     /**
      * The intent to execute when the expanded status entry is clicked.  If
@@ -633,9 +633,10 @@
 
     /**
      * Special value of {@link #color} used as a place holder for an invalid color.
+     * @hide
      */
     @ColorInt
-    private static final int COLOR_INVALID = 1;
+    public static final int COLOR_INVALID = 1;
 
     /**
      * Sphere of visibility of this notification, which affects how and when the SystemUI reveals
@@ -1073,6 +1074,26 @@
     private String mChannelId;
     private long mTimeout;
 
+    private String mShortcutId;
+
+    /**
+     * If this notification is being shown as a badge, always show as a number.
+     */
+    public static final int BADGE_ICON_NONE = 0;
+
+    /**
+     * If this notification is being shown as a badge, use the {@link #getSmallIcon()} to
+     * represent this notification.
+     */
+    public static final int BADGE_ICON_SMALL = 1;
+
+    /**
+     * If this notification is being shown as a badge, use the {@link #getLargeIcon()} to
+     * represent this notification.
+     */
+    public static final int BADGE_ICON_LARGE = 2;
+    private int mBadgeIcon = BADGE_ICON_LARGE;
+
     /**
      * Structure to encapsulate a named action that can be shown as part of this notification.
      * It must include an icon, a label, and a {@link PendingIntent} to be fired when the action is
@@ -1817,6 +1838,12 @@
             mChannelId = parcel.readString();
         }
         mTimeout = parcel.readLong();
+
+        if (parcel.readInt() != 0) {
+            mShortcutId = parcel.readString();
+        }
+
+        mBadgeIcon = parcel.readInt();
     }
 
     @Override
@@ -2041,7 +2068,7 @@
         }
         try {
             // IMPORTANT: Add marshaling code in writeToParcelImpl as we
-            // want to intercept all pending events written to the pacel.
+            // want to intercept all pending events written to the parcel.
             writeToParcelImpl(parcel, flags);
             // Must be written last!
             parcel.writeArraySet(allPendingIntents);
@@ -2184,6 +2211,15 @@
             parcel.writeInt(0);
         }
         parcel.writeLong(mTimeout);
+
+        if (mShortcutId != null) {
+            parcel.writeInt(1);
+            parcel.writeString(mShortcutId);
+        } else {
+            parcel.writeInt(0);
+        }
+
+        parcel.writeInt(mBadgeIcon);
     }
 
     /**
@@ -2381,13 +2417,30 @@
     }
 
     /**
-     * Returns the time at which this notification should be canceled, if it's not canceled already.
+     * Returns the time at which this notification should be canceled by the system, if it's not
+     * canceled already.
      */
     public long getTimeout() {
         return mTimeout;
     }
 
     /**
+     * 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}.
+     */
+    public int getBadgeIcon() {
+        return mBadgeIcon;
+    }
+
+    /**
+     * Returns the {@link ShortcutInfo#getId() id} that this notification supersedes, if any.
+     */
+    public String getShortcutId() {
+        return mShortcutId;
+    }
+
+    /**
      * The small icon representing this notification in the status bar and content view.
      *
      * @return the small icon representing this notification.
@@ -2482,7 +2535,6 @@
         private NotificationColorUtil mColorUtil;
         private boolean mIsLegacy;
         private boolean mIsLegacyInitialized;
-        private boolean mColorUtilInited = false;
 
         /**
          * Caches a contrast-enhanced version of {@link #mCachedContrastColorIsFor}.
@@ -2600,16 +2652,42 @@
         }
 
         private NotificationColorUtil getColorUtil() {
-            if (!mColorUtilInited) {
-                mColorUtilInited = true;
-                if (isLegacy() || isColorized()) {
-                    mColorUtil = NotificationColorUtil.getInstance(mContext);
-                }
+            if (mColorUtil == null) {
+                mColorUtil = NotificationColorUtil.getInstance(mContext);
             }
             return mColorUtil;
         }
 
         /**
+         * If this notification is duplicative of a Launcher shortcut, sets the
+         * {@link ShortcutInfo#getId() id} of the shortcut, in case the Launcher wants to hide
+         * the shortcut.
+         *
+         * This field will be ignored by Launchers that don't support badging or
+         * {@link android.content.pm.ShortcutManager shortcuts}.
+         *
+         * @param shortcutId the {@link ShortcutInfo#getId() id} of the shortcut this notification
+         *                   supersedes
+         */
+        public Builder setShortcutId(String shortcutId) {
+            mN.mShortcutId = shortcutId;
+            return this;
+        }
+
+        /**
+         * Sets which icon to display as a badge for this notification.
+         *
+         * Must be one of {@link #BADGE_ICON_NONE}, {@link #BADGE_ICON_SMALL},
+         * {@link #BADGE_ICON_LARGE}.
+         *
+         * Note: This value might be ignored, for launchers that don't support badge icons.
+         */
+        public Builder chooseBadgeIcon(int icon) {
+            mN.mBadgeIcon = icon;
+            return this;
+        }
+
+        /**
          * Specifies the channel the notification should be delivered on.
          */
         public Builder setChannel(String channelId) {
@@ -2804,13 +2882,9 @@
         }
 
         /**
-         * Set the large number at the right-hand side of the notification.  This is
-         * equivalent to setContentInfo, although it might show the number in a different
-         * font size for readability.
-         *
-         * @deprecated this number is not shown anywhere anymore
+         * Sets the number of items this notification represents. May be displayed as a badge count
+         * for Launchers that support badging.
          */
-        @Deprecated
         public Builder setNumber(int number) {
             mN.number = number;
             return this;
@@ -3095,12 +3169,16 @@
          * Set whether this notification should be colorized. When set, the color set with
          * {@link #setColor(int)} will be used as the background color of this notification.
          * <p>
-         * The coloring will only be applied if the notification is ongoing.
          * This should only be used for high priority ongoing tasks like navigation, an ongoing
          * call, or other similarly high-priority events for the user.
+         * <p>
+         * For most styles, the coloring will only be applied if the notification is ongoing.
+         * However, for {@link MediaStyle} and {@link DecoratedMediaCustomViewStyle} notifications
+         * that have a media session attached there is no requirement for it to be ongoing.
          *
          * @see Builder#setOngoing(boolean)
          * @see Builder#setColor(int)
+         * @see MediaStyle#setMediaSession(MediaSession.Token)
          */
         public Builder setColorized(boolean colorize) {
             mN.extras.putBoolean(EXTRA_COLORIZED, colorize);
@@ -3681,13 +3759,21 @@
         }
 
         private void bindExpandButton(RemoteViews contentView) {
-            int color = isColorized() ? getPrimaryTextColor() : resolveContrastColor();
+            int color = getPrimaryHighlightColor();
             contentView.setDrawableParameters(R.id.expand_button, false, -1, color,
                     PorterDuff.Mode.SRC_ATOP, -1);
             contentView.setInt(R.id.notification_header, "setOriginalNotificationColor",
                     color);
         }
 
+        /**
+         * @return the color that is used as the first primary highlight color. This is applied
+         * in several places like the action buttons or the app name in the header.
+         */
+        private int getPrimaryHighlightColor() {
+            return isColorized() ? getPrimaryTextColor() : resolveContrastColor();
+        }
+
         private void bindHeaderChronometerAndTime(RemoteViews contentView) {
             if (showsTimeOrChronometer()) {
                 contentView.setViewVisibility(R.id.time_divider, View.VISIBLE);
@@ -3903,10 +3989,24 @@
          *   3. Standard template view
          */
         public RemoteViews createContentView() {
+            return createContentView(false /* increasedheight */ );
+        }
+
+        /**
+         * Construct a RemoteViews for the smaller content view.
+         *
+         *   @param increasedHeight true if this layout be created with an increased height. Some
+         *   styles may support showing more then just that basic 1U size
+         *   and the system may decide to render important notifications
+         *   slightly bigger even when collapsed.
+         *
+         *   @hide
+         */
+        public RemoteViews createContentView(boolean increasedHeight) {
             if (mN.contentView != null && (mStyle == null || !mStyle.displayCustomViewInline())) {
                 return mN.contentView;
             } else if (mStyle != null) {
-                final RemoteViews styleView = mStyle.makeContentView();
+                final RemoteViews styleView = mStyle.makeContentView(increasedHeight);
                 if (styleView != null) {
                     return styleView;
                 }
@@ -4250,7 +4350,7 @@
         }
 
         private CharSequence processLegacyText(CharSequence charSequence) {
-            if (isLegacy() || isColorized()) {
+            if (isLegacy() || textColorsNeedInversion()) {
                 return getColorUtil().invertCharSequenceColors(charSequence);
             } else {
                 return charSequence;
@@ -4263,7 +4363,7 @@
         private void processSmallIconColor(Icon smallIcon, RemoteViews contentView,
                 boolean ambient) {
             boolean colorable = !isLegacy() || getColorUtil().isGrayscaleIcon(mContext, smallIcon);
-            int color = ambient ? resolveAmbientColor() : resolveContrastColor();
+            int color = ambient ? resolveAmbientColor() : getPrimaryHighlightColor();
             if (colorable) {
                 contentView.setDrawableParameters(R.id.icon, false, -1, color,
                         PorterDuff.Mode.SRC_ATOP, -1);
@@ -4524,6 +4624,15 @@
         private boolean isColorized() {
             return mN.isColorized();
         }
+
+        private boolean textColorsNeedInversion() {
+            if (mStyle == null || !MediaStyle.class.equals(mStyle.getClass())) {
+                return false;
+            }
+            int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
+            return targetSdkVersion > Build.VERSION_CODES.M
+                    && targetSdkVersion < Build.VERSION_CODES.O;
+        }
     }
 
     /**
@@ -4536,12 +4645,44 @@
     }
 
     /**
-     * @return true if this notification is colorized. This also factors in wheather the
+     * @return whether this notification has a media session attached
+     * @hide
+     */
+    public boolean hasMediaSession() {
+        return extras.getParcelable(Notification.EXTRA_MEDIA_SESSION) != null;
+    }
+
+    /**
+     * @return the style class of this notification
+     * @hide
+     */
+    public Class<? extends Notification.Style> getNotificationStyle() {
+        String templateClass = extras.getString(Notification.EXTRA_TEMPLATE);
+
+        if (!TextUtils.isEmpty(templateClass)) {
+            return Notification.getNotificationStyleClass(templateClass);
+        }
+        return null;
+    }
+
+    /**
+     * @return true if this notification is colorized. This also factors in whether the
      * notification is ongoing.
      *
      * @hide
      */
     public boolean isColorized() {
+        Class<? extends Style> style = getNotificationStyle();
+        if (MediaStyle.class.equals(style)) {
+            Boolean colorized = (Boolean) extras.get(EXTRA_COLORIZED);
+            if ((colorized == null || colorized) && hasMediaSession()) {
+                return true;
+            }
+        } else if (DecoratedMediaCustomViewStyle.class.equals(style)) {
+            if (extras.getBoolean(EXTRA_COLORIZED) && hasMediaSession()) {
+                return true;
+            }
+        }
         return extras.getBoolean(EXTRA_COLORIZED) && isOngoing();
     }
 
@@ -4656,11 +4797,13 @@
         }
 
         /**
-         * Construct a Style-specific RemoteViews for the final 1U notification layout.
+         * Construct a Style-specific RemoteViews for the collapsed notification layout.
          * The default implementation has nothing additional to add.
+         *
+         * @param increasedHeight true if this layout be created with an increased height.
          * @hide
          */
-        public RemoteViews makeContentView() {
+        public RemoteViews makeContentView(boolean increasedHeight) {
             return null;
         }
 
@@ -5006,6 +5149,23 @@
         }
 
         /**
+         * @param increasedHeight true if this layout be created with an increased height.
+         *
+         * @hide
+         */
+        @Override
+        public RemoteViews makeContentView(boolean increasedHeight) {
+            if (increasedHeight) {
+                ArrayList<Action> actions = mBuilder.mActions;
+                mBuilder.mActions = new ArrayList<>();
+                RemoteViews remoteViews = makeBigContentView();
+                mBuilder.mActions = actions;
+                return remoteViews;
+            }
+            return super.makeContentView(increasedHeight);
+        }
+
+        /**
          * @hide
          */
         public RemoteViews makeBigContentView() {
@@ -5269,17 +5429,25 @@
          * @hide
          */
         @Override
-        public RemoteViews makeContentView() {
-            Message m = findLatestIncomingMessage();
-            CharSequence title = mConversationTitle != null
-                    ? mConversationTitle
-                    : (m == null) ? null : m.mSender;
-            CharSequence text = (m == null)
-                    ? null
-                    : mConversationTitle != null ? makeMessageLine(m, mBuilder) : m.mText;
+        public RemoteViews makeContentView(boolean increasedHeight) {
+            if (!increasedHeight) {
+                Message m = findLatestIncomingMessage();
+                CharSequence title = mConversationTitle != null
+                        ? mConversationTitle
+                        : (m == null) ? null : m.mSender;
+                CharSequence text = (m == null)
+                        ? null
+                        : mConversationTitle != null ? makeMessageLine(m, mBuilder) : m.mText;
 
-            return mBuilder.applyStandardTemplateWithActions(mBuilder.getBaseLayoutResource(),
-                    mBuilder.mParams.reset().hasProgress(false).title(title).text(text));
+                return mBuilder.applyStandardTemplate(mBuilder.getBaseLayoutResource(),
+                        mBuilder.mParams.reset().hasProgress(false).title(title).text(text));
+            } else {
+                ArrayList<Action> actions = mBuilder.mActions;
+                mBuilder.mActions = new ArrayList<>();
+                RemoteViews remoteViews = makeBigContentView();
+                mBuilder.mActions = actions;
+                return remoteViews;
+            }
         }
 
         private Message findLatestIncomingMessage() {
@@ -5760,21 +5928,27 @@
      * shown as icon-only pushbuttons, suitable for transport controls. The Bitmap given to
      * {@link Notification.Builder#setLargeIcon(android.graphics.Bitmap) setLargeIcon()} will be
      * treated as album artwork.
-     *
+     * <p>
      * Unlike the other styles provided here, MediaStyle can also modify the standard-size
      * {@link Notification#contentView}; by providing action indices to
      * {@link #setShowActionsInCompactView(int...)} you can promote up to 3 actions to be displayed
      * in the standard view alongside the usual content.
-     *
+     * <p>
      * Notifications created with MediaStyle will have their category set to
      * {@link Notification#CATEGORY_TRANSPORT CATEGORY_TRANSPORT} unless you set a different
      * category using {@link Notification.Builder#setCategory(String) setCategory()}.
-     *
+     * <p>
      * Finally, if you attach a {@link android.media.session.MediaSession.Token} using
      * {@link android.app.Notification.MediaStyle#setMediaSession(MediaSession.Token)},
      * the System UI can identify this as a notification representing an active media session
      * and respond accordingly (by showing album artwork in the lockscreen, for example).
      *
+     * <p>
+     * Starting at {@link android.os.Build.VERSION_CODES#O Android O} any notification that has a
+     * media session attached with {@link #setMediaSession(MediaSession.Token)} will be colorized.
+     * You can opt-out of this behavior by using {@link Notification.Builder#setColorized(boolean)}.
+     * <p>
+     *
      * To use this style with your Notification, feed it to
      * {@link Notification.Builder#setStyle(android.app.Notification.Style)} like so:
      * <pre class="prettyprint">
@@ -5789,6 +5963,7 @@
      * </pre>
      *
      * @see Notification#bigContentView
+     * @see Notification.Builder#setColorized(boolean)
      */
     public static class MediaStyle extends Style {
         static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;
@@ -5844,7 +6019,7 @@
          * @hide
          */
         @Override
-        public RemoteViews makeContentView() {
+        public RemoteViews makeContentView(boolean increasedHeight) {
             return makeMediaContentView();
         }
 
@@ -5926,7 +6101,7 @@
 
                     final Action action = mBuilder.mActions.get(mActionsToShowInCompact[i]);
                     final RemoteViews button = generateMediaActionButton(action,
-                            mBuilder.resolveContrastColor());
+                            getPrimaryHighlightColor());
                     view.addView(com.android.internal.R.id.media_actions, button);
                 }
             }
@@ -5940,6 +6115,10 @@
             return view;
         }
 
+        private int getPrimaryHighlightColor() {
+            return mBuilder.getPrimaryHighlightColor();
+        }
+
         private RemoteViews makeMediaBigContentView() {
             final int actionCount = Math.min(mBuilder.mActions.size(), MAX_MEDIA_BUTTONS);
             // Dont add an expanded view if there is no more content to be revealed
@@ -5957,7 +6136,7 @@
                 big.removeAllViews(com.android.internal.R.id.media_actions);
                 for (int i = 0; i < actionCount; i++) {
                     final RemoteViews button = generateMediaActionButton(mBuilder.mActions.get(i),
-                            mBuilder.resolveContrastColor());
+                            getPrimaryHighlightColor());
                     big.addView(com.android.internal.R.id.media_actions, button);
                 }
             }
@@ -6020,7 +6199,7 @@
          * @hide
          */
         @Override
-        public RemoteViews makeContentView() {
+        public RemoteViews makeContentView(boolean increasedHeight) {
             return makeStandardTemplateWithCustomContent(mBuilder.mN.contentView);
         }
 
@@ -6102,7 +6281,10 @@
      * {@link android.app.Notification.Builder#setCustomBigContentView(RemoteViews)} and
      * {@link android.app.Notification.Builder#setCustomHeadsUpContentView(RemoteViews)} to set the
      * corresponding custom views to display.
-     *
+     * <p>
+     * Contrary to {@link MediaStyle} a developer has to opt-in to the colorizing of the
+     * notification by using {@link Notification.Builder#setColorized(boolean)}.
+     * <p>
      * To use this style with your Notification, feed it to
      * {@link Notification.Builder#setStyle(android.app.Notification.Style)} like so:
      * <pre class="prettyprint">
@@ -6134,8 +6316,8 @@
          * @hide
          */
         @Override
-        public RemoteViews makeContentView() {
-            RemoteViews remoteViews = super.makeContentView();
+        public RemoteViews makeContentView(boolean increasedHeight) {
+            RemoteViews remoteViews = super.makeContentView(false /* increasedHeight */);
             return buildIntoRemoteView(remoteViews, R.id.notification_content_container,
                     mBuilder.mN.contentView);
         }
@@ -6157,7 +6339,7 @@
                 return buildIntoRemoteView(remoteViews, R.id.notification_main_column,
                         customRemoteView);
             } else if (customRemoteView != mBuilder.mN.contentView){
-                remoteViews = super.makeContentView();
+                remoteViews = super.makeContentView(false /* increasedHeight */);
                 return buildIntoRemoteView(remoteViews, R.id.notification_content_container,
                         customRemoteView);
             } else {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 5a75a67..44db326 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -30,6 +30,8 @@
 import android.app.usage.UsageStatsManager;
 import android.appwidget.AppWidgetManager;
 import android.bluetooth.BluetoothManager;
+import android.companion.CompanionDeviceManager;
+import android.companion.ICompanionDeviceManager;
 import android.content.ClipboardManager;
 import android.content.Context;
 import android.content.IRestrictionsManager;
@@ -115,6 +117,7 @@
 import android.service.autofill.IAutoFillManagerService;
 import android.service.persistentdata.IPersistentDataBlockService;
 import android.service.persistentdata.PersistentDataBlockManager;
+import android.service.vr.IVrManager;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
@@ -633,6 +636,18 @@
                         UserHandle.getAppId(Process.myUid()));
             }});
 
+        registerService(Context.COMPANION_DEVICE_SERVICE, CompanionDeviceManager.class,
+                new CachedServiceFetcher<CompanionDeviceManager>() {
+                    @Override
+                    public CompanionDeviceManager createService(ContextImpl ctx)
+                            throws ServiceNotFoundException {
+                        IBinder iBinder =
+                                ServiceManager.getServiceOrThrow(Context.COMPANION_DEVICE_SERVICE);
+                        ICompanionDeviceManager service =
+                                ICompanionDeviceManager.Stub.asInterface(iBinder);
+                        return new CompanionDeviceManager(service, ctx);
+                    }});
+
         registerService(Context.CONSUMER_IR_SERVICE, ConsumerIrManager.class,
                 new CachedServiceFetcher<ConsumerIrManager>() {
             @Override
@@ -814,6 +829,14 @@
                 IAutoFillManagerService service = IAutoFillManagerService.Stub.asInterface(b);
                 return new AutoFillManager(ctx, service);
             }});
+
+        registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() {
+            @Override
+            public VrManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+                IBinder b = ServiceManager.getServiceOrThrow(Context.VR_SERVICE);
+                return new VrManager(IVrManager.Stub.asInterface(b));
+            }
+        });
     }
 
     /**
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 3f467a0..b219f2a 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -145,14 +145,25 @@
     }
 
     @Override
+    public void show() {
+        super.show();
+        getButton(BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                if (mTimePicker.validateInput()) {
+                    if (mTimeSetListener != null) {
+                        mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
+                                mTimePicker.getCurrentMinute());
+                    }
+                    dismiss();
+                }
+            }
+        });
+    }
+
+    @Override
     public void onClick(DialogInterface dialog, int which) {
         switch (which) {
-            case BUTTON_POSITIVE:
-                if (mTimeSetListener != null) {
-                    mTimeSetListener.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
-                            mTimePicker.getCurrentMinute());
-                }
-                break;
             case BUTTON_NEGATIVE:
                 cancel();
                 break;
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 6d1d1a3..1d6f42e 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -1118,6 +1118,16 @@
                 public void onFingerprintGesture(int gesture) {
                     /* do nothing */
                 }
+
+                @Override
+                public void onAccessibilityButtonClicked() {
+                    /* do nothing */
+                }
+
+                @Override
+                public void onAccessibilityButtonAvailabilityChanged(boolean available) {
+                    /* do nothing */
+                }
             });
         }
     }
diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java
new file mode 100644
index 0000000..a0b0eea
--- /dev/null
+++ b/core/java/android/app/VrManager.java
@@ -0,0 +1,44 @@
+package android.app;
+
+
+import android.annotation.SystemApi;
+import android.content.ComponentName;
+import android.os.RemoteException;
+import android.service.vr.IVrManager;
+
+/**
+ * Used to control aspects of a devices Virtual Reality (VR) capabilities.
+ * <p>
+ * You do not instantiate this class directly; instead, retrieve it through
+ * {@link android.content.Context#getSystemService}.
+ * @hide
+ */
+@SystemApi
+public class VrManager {
+    private final IVrManager mService;
+
+    /**
+     * {@hide}
+     */
+    public VrManager(IVrManager service) {
+        mService = service;
+    }
+
+    /**
+     * 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.
+     *
+     * <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
+     *
+     * @see Activity#setVrModeEnabled(boolean, ComponentName)
+     * @param enabled true if the device should be placed in persistent VR mode.
+     */
+    public void setPersistentVrModeEnabled(boolean enabled) {
+        try {
+            mService.setPersistentVrModeEnabled(enabled);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java
index 2858991..91b87d7 100644
--- a/core/java/android/app/admin/SecurityLog.java
+++ b/core/java/android/app/admin/SecurityLog.java
@@ -144,8 +144,7 @@
         }
 
         /**
-         * Returns the payload contained in this log. Each call to this method will
-         * retrieve the next payload item. If no more payload exists, it returns {@code null}.
+         * Returns the payload contained in this log entry or {@code null} if there is no payload.
          */
         public Object getData() {
             return mEvent.getData();
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 17a802d..b89c64a 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -67,7 +67,9 @@
     private final byte[] mManufacturerData;
     @Nullable
     private final byte[] mManufacturerDataMask;
-    private static final ScanFilter EMPTY = new ScanFilter.Builder().build() ;
+
+    /** @hide */
+    public static final ScanFilter EMPTY = new ScanFilter.Builder().build() ;
 
 
     private ScanFilter(String name, String deviceAddress, ParcelUuid uuid,
@@ -318,8 +320,12 @@
         return true;
     }
 
-    // Check if the uuid pattern is contained in a list of parcel uuids.
-    private boolean matchesServiceUuids(ParcelUuid uuid, ParcelUuid parcelUuidMask,
+    /**
+     * Check if the uuid pattern is contained in a list of parcel uuids.
+     *
+     * @hide
+     */
+    public static boolean matchesServiceUuids(ParcelUuid uuid, ParcelUuid parcelUuidMask,
             List<ParcelUuid> uuids) {
         if (uuid == null) {
             return true;
@@ -338,7 +344,7 @@
     }
 
     // Check if the uuid pattern matches the particular service uuid.
-    private boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
+    private static boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
         if (mask == null) {
             return uuid.equals(data);
         }
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/core/java/android/companion/AssociationRequest.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
copy to core/java/android/companion/AssociationRequest.aidl
index 62d5603..6c91062 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
+++ b/core/java/android/companion/AssociationRequest.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,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.hotspot2.pps;
+package android.companion;
 
-parcelable HomeSP;
+parcelable AssociationRequest;
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
new file mode 100644
index 0000000..d477f43
--- /dev/null
+++ b/core/java/android/companion/AssociationRequest.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.provider.OneTimeUseBuilder;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A request for the user to select a companion device to associate with.
+ *
+ * You can optionally set a {@link Builder#setDeviceFilter filter} for which devices to show to the
+ * user to select from.
+ * The exact type and fields of the filter you can set depend on the
+ * medium type. See {@link Builder}'s static factory methods for specific protocols that are
+ * supported.
+ *
+ * You can also set {@link Builder#setSingleDevice single device} to request a popup with single
+ * device to be shown instead of a list to choose from
+ *
+ * @param <F> Device filter type
+ */
+public final class AssociationRequest<F extends DeviceFilter> implements Parcelable {
+
+    /** @hide */
+    public static final int MEDIUM_TYPE_BLUETOOTH = 0;
+    /** @hide */
+    public static final int MEDIUM_TYPE_BLUETOOTH_LE = 1;
+    /** @hide */
+    public static final int MEDIUM_TYPE_WIFI = 2;
+
+    /** @hide */
+    @IntDef({MEDIUM_TYPE_BLUETOOTH, MEDIUM_TYPE_BLUETOOTH_LE, MEDIUM_TYPE_WIFI})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MediumType {}
+
+    private final boolean mSingleDevice;
+    private final int mMediumType;
+    private final F mDeviceFilter;
+
+    private AssociationRequest(boolean singleDevice, int mMediumType, F deviceFilter) {
+        this.mSingleDevice = singleDevice;
+        this.mMediumType = mMediumType;
+        this.mDeviceFilter = deviceFilter;
+    }
+
+    private AssociationRequest(Parcel in) {
+        this(
+            in.readByte() != 0,
+            in.readInt(),
+            in.readParcelable(AssociationRequest.class.getClassLoader()));
+    }
+
+    /** @hide */
+    public boolean isSingleDevice() {
+        return mSingleDevice;
+    }
+
+    /** @hide */
+    @MediumType
+    public int getMediumType() {
+        return mMediumType;
+    }
+
+    /** @hide */
+    @Nullable
+    public F getDeviceFilter() {
+        return mDeviceFilter;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeByte((byte) (mSingleDevice ? 1 : 0));
+        dest.writeInt(mMediumType);
+        dest.writeParcelable(mDeviceFilter, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<AssociationRequest> CREATOR = new Creator<AssociationRequest>() {
+        @Override
+        public AssociationRequest createFromParcel(Parcel in) {
+            return new AssociationRequest(in);
+        }
+
+        @Override
+        public AssociationRequest[] newArray(int size) {
+            return new AssociationRequest[size];
+        }
+    };
+
+    /**
+     * A builder for {@link AssociationRequest}
+     *
+     * @param <F> the type of filter for the request.
+     */
+    public static final class Builder<F extends DeviceFilter>
+            extends OneTimeUseBuilder<AssociationRequest<F>> {
+        private boolean mSingleDevice = false;
+        @MediumType private int mMediumType;
+        @Nullable private F mDeviceFilter = null;
+
+        private Builder() {}
+
+        /**
+         * Create a new builder for an association request with a Bluetooth LE device
+         */
+        @NonNull
+        public static Builder<BluetoothLEDeviceFilter> createForBluetoothLEDevice() {
+            return new Builder<BluetoothLEDeviceFilter>()
+                    .setMediumType(MEDIUM_TYPE_BLUETOOTH_LE);
+        }
+
+        /**
+         * Create a new builder for an association request with a Bluetooth(non-LE) device
+         */
+        @NonNull
+        public static Builder<BluetoothDeviceFilter> createForBluetoothDevice() {
+            return new Builder<BluetoothDeviceFilter>()
+                    .setMediumType(MEDIUM_TYPE_BLUETOOTH);
+        }
+
+        //TODO implement, once specific filter classes are available
+//        public static Builder<> createForWiFiDevice()
+//        public static Builder<> createForNanDevice()
+
+        /**
+         * @param singleDevice if true, scanning for a device will stop as soon as at least one
+         *                     fitting device is found
+         */
+        @NonNull
+        public Builder<F> setSingleDevice(boolean singleDevice) {
+            checkNotUsed();
+            this.mSingleDevice = singleDevice;
+            return this;
+        }
+
+        /**
+         * @param deviceFilter if set, only devices matching the given filter will be shown to the
+         *                     user
+         */
+        @NonNull
+        public Builder<F> setDeviceFilter(@Nullable F deviceFilter) {
+            checkNotUsed();
+            this.mDeviceFilter = deviceFilter;
+            return this;
+        }
+
+        /**
+         * @param deviceType A type of medium over which to discover devices
+         *
+         * @see MediumType
+         */
+        @NonNull
+        private Builder<F> setMediumType(@MediumType int deviceType) {
+            mMediumType = deviceType;
+            return this;
+        }
+
+        /** @inheritDoc */
+        @NonNull
+        @Override
+        public AssociationRequest<F> build() {
+            markUsed();
+            return new AssociationRequest<>(mSingleDevice, mMediumType, mDeviceFilter);
+        }
+    }
+}
diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java
new file mode 100644
index 0000000..5a69955
--- /dev/null
+++ b/core/java/android/companion/BluetoothDeviceFilter.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+import static android.companion.BluetoothDeviceFilterUtils.matchesAddress;
+import static android.companion.BluetoothDeviceFilterUtils.matchesName;
+import static android.companion.BluetoothDeviceFilterUtils.matchesServiceUuids;
+import static android.companion.BluetoothDeviceFilterUtils.patternFromString;
+import static android.companion.BluetoothDeviceFilterUtils.patternToString;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.provider.OneTimeUseBuilder;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * A filter for Bluetooth(non-LE) devices
+ */
+public final class BluetoothDeviceFilter implements DeviceFilter<BluetoothDevice> {
+
+    private static BluetoothDeviceFilter NO_OP;
+
+    private final Pattern mNamePattern;
+    private final String mAddress;
+    private final List<ParcelUuid> mServiceUuids;
+    private final List<ParcelUuid> mServiceUuidMasks;
+
+    private BluetoothDeviceFilter(
+            Pattern namePattern,
+            String address,
+            List<ParcelUuid> serviceUuids,
+            List<ParcelUuid> serviceUuidMasks) {
+        mNamePattern = namePattern;
+        mAddress = address;
+        mServiceUuids = ArrayUtils.emptyIfNull(serviceUuids);
+        mServiceUuidMasks = ArrayUtils.emptyIfNull(serviceUuidMasks);
+    }
+
+    private BluetoothDeviceFilter(Parcel in) {
+        this(
+            patternFromString(in.readString()),
+            in.readString(),
+            readUuids(in),
+            readUuids(in));
+    }
+
+    private static List<ParcelUuid> readUuids(Parcel in) {
+        final ArrayList<ParcelUuid> list = new ArrayList<>();
+        in.readParcelableList(list, ParcelUuid.class.getClassLoader());
+        return list;
+    }
+
+    /** @hide */
+    @NonNull
+    public static BluetoothDeviceFilter nullsafe(@Nullable BluetoothDeviceFilter nullable) {
+        return nullable != null ? nullable : noOp();
+    }
+
+    /** @hide */
+    @NonNull
+    public static BluetoothDeviceFilter noOp() {
+        if (NO_OP == null) NO_OP = new Builder().build();
+        return NO_OP;
+    }
+
+    /** @hide */
+    @Override
+    public boolean matches(BluetoothDevice device) {
+        return matchesAddress(mAddress, device)
+                && matchesServiceUuids(mServiceUuids, mServiceUuidMasks, device)
+                && matchesName(getNamePattern(), device);
+    }
+
+    /** @hide */
+    @Nullable
+    public Pattern getNamePattern() {
+        return mNamePattern;
+    }
+
+    /** @hide */
+    @Nullable
+    public String getAddress() {
+        return mAddress;
+    }
+
+    /** @hide */
+    @NonNull
+    public List<ParcelUuid> getServiceUuids() {
+        return mServiceUuids;
+    }
+
+    /** @hide */
+    @NonNull
+    public List<ParcelUuid> getServiceUuidMasks() {
+        return mServiceUuidMasks;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(patternToString(getNamePattern()));
+        dest.writeString(mAddress);
+        dest.writeParcelableList(mServiceUuids, flags);
+        dest.writeParcelableList(mServiceUuidMasks, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<BluetoothDeviceFilter> CREATOR
+            = new Creator<BluetoothDeviceFilter>() {
+        @Override
+        public BluetoothDeviceFilter createFromParcel(Parcel in) {
+            return new BluetoothDeviceFilter(in);
+        }
+
+        @Override
+        public BluetoothDeviceFilter[] newArray(int size) {
+            return new BluetoothDeviceFilter[size];
+        }
+    };
+
+    /**
+     * A builder for {@link BluetoothDeviceFilter}
+     */
+    public static final class Builder extends OneTimeUseBuilder<BluetoothDeviceFilter> {
+        private Pattern mNamePattern;
+        private String mAddress;
+        private ArrayList<ParcelUuid> mServiceUuid;
+        private ArrayList<ParcelUuid> mServiceUuidMask;
+
+        /**
+         * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the
+         *              given regular expression will be shown
+         */
+        public Builder setNamePattern(@Nullable Pattern regex) {
+            checkNotUsed();
+            mNamePattern = regex;
+            return this;
+        }
+
+        /**
+         * @param address if set, only devices with MAC address exactly matching the given one will
+         *                pass the filter
+         */
+        @NonNull
+        public Builder setAddress(@Nullable String address) {
+            checkNotUsed();
+            mAddress = address;
+            return this;
+        }
+
+        /**
+         * Add filtering by certain bits of {@link BluetoothDevice#getUuids()}
+         *
+         * A device with any uuid matching the given bits is considered passing
+         *
+         * @param serviceUuid the values for the bits to match
+         * @param serviceUuidMask if provided, only those bits would have to match.
+         */
+        @NonNull
+        public Builder addServiceUuid(
+                @Nullable ParcelUuid serviceUuid, @Nullable ParcelUuid serviceUuidMask) {
+            checkNotUsed();
+            mServiceUuid = ArrayUtils.add(mServiceUuid, serviceUuid);
+            mServiceUuidMask = ArrayUtils.add(mServiceUuidMask, serviceUuidMask);
+            return this;
+        }
+
+        /** @inheritDoc */
+        @Override
+        @NonNull
+        public BluetoothDeviceFilter build() {
+            markUsed();
+            return new BluetoothDeviceFilter(
+                    mNamePattern, mAddress, mServiceUuid, mServiceUuidMask);
+        }
+    }
+}
diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java
new file mode 100644
index 0000000..289f995
--- /dev/null
+++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.companion;
+
+import static android.text.TextUtils.firstNotEmpty;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanFilter;
+import android.os.ParcelUuid;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/** @hide */
+public class BluetoothDeviceFilterUtils {
+    private BluetoothDeviceFilterUtils() {}
+
+    private static final boolean DEBUG = false;
+    private static final String LOG_TAG = "BluetoothDeviceFilterUtil";
+
+    @Nullable
+    static String patternToString(@Nullable Pattern p) {
+        return p == null ? null : p.pattern();
+    }
+
+    @Nullable
+    static Pattern patternFromString(@Nullable String s) {
+        return s == null ? null : Pattern.compile(s);
+    }
+
+    static boolean matches(ScanFilter filter, BluetoothDevice device) {
+        return matchesAddress(filter.getDeviceAddress(), device)
+                && matchesServiceUuid(filter.getServiceUuid(), filter.getServiceUuidMask(), device);
+    }
+
+    static boolean matchesAddress(String deviceAddress, BluetoothDevice device) {
+        final boolean result = deviceAddress == null
+                || (device == null || !deviceAddress.equals(device.getAddress()));
+        if (DEBUG) debugLogMatchResult(result, device, deviceAddress);
+        return result;
+    }
+
+    static boolean matchesServiceUuids(List<ParcelUuid> serviceUuids,
+            List<ParcelUuid> serviceUuidMasks, BluetoothDevice device) {
+        for (int i = 0; i < serviceUuids.size(); i++) {
+            ParcelUuid uuid = serviceUuids.get(i);
+            ParcelUuid uuidMask = serviceUuidMasks.get(i);
+            if (!matchesServiceUuid(uuid, uuidMask, device)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    static boolean matchesServiceUuid(ParcelUuid serviceUuid, ParcelUuid serviceUuidMask,
+            BluetoothDevice device) {
+        final boolean result = serviceUuid == null ||
+                ScanFilter.matchesServiceUuids(
+                        serviceUuid,
+                        serviceUuidMask,
+                        Arrays.asList(device.getUuids()));
+        if (DEBUG) debugLogMatchResult(result, device, serviceUuid);
+        return result;
+    }
+
+    static boolean matchesName(@Nullable Pattern namePattern, BluetoothDevice device) {
+        boolean result;
+        if (namePattern == null)  {
+            result = true;
+        } else if (device == null) {
+            result = false;
+        } else {
+            final String name = device.getName();
+            result = name != null && namePattern.matcher(name).find();
+        }
+        if (DEBUG) debugLogMatchResult(result, device, namePattern);
+        return result;
+    }
+
+    private static void debugLogMatchResult(
+            boolean result, BluetoothDevice device, Object criteria) {
+        Log.i(LOG_TAG, getDeviceDisplayName(device) + (result ? " ~ " : " !~ ") + criteria);
+    }
+
+    public static String getDeviceDisplayName(@NonNull BluetoothDevice device) {
+        return firstNotEmpty(device.getAliasName(), device.getAddress());
+    }
+}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/core/java/android/companion/BluetoothLEDeviceFilter.aidl
similarity index 74%
copy from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
copy to core/java/android/companion/BluetoothLEDeviceFilter.aidl
index 62d5603..628cf7b 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
+++ b/core/java/android/companion/BluetoothLEDeviceFilter.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,6 @@
  * limitations under the License.
  */
 
-package android.net.wifi.hotspot2.pps;
+package android.companion;
 
-parcelable HomeSP;
+parcelable BluetoothLEDeviceFilter;
diff --git a/core/java/android/companion/BluetoothLEDeviceFilter.java b/core/java/android/companion/BluetoothLEDeviceFilter.java
new file mode 100644
index 0000000..4a481ca
--- /dev/null
+++ b/core/java/android/companion/BluetoothLEDeviceFilter.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+import static android.companion.BluetoothDeviceFilterUtils.patternFromString;
+import static android.companion.BluetoothDeviceFilterUtils.patternToString;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanFilter;
+import android.os.Parcel;
+import android.provider.OneTimeUseBuilder;
+
+import com.android.internal.util.ObjectUtils;
+
+import java.util.regex.Pattern;
+
+/**
+ * A filter for Bluetooth LE devices
+ *
+ * @see ScanFilter
+ */
+public final class BluetoothLEDeviceFilter implements DeviceFilter<BluetoothDevice> {
+
+    private static BluetoothLEDeviceFilter NO_OP;
+
+    private final Pattern mNamePattern;
+    private final ScanFilter mScanFilter;
+
+    private BluetoothLEDeviceFilter(Pattern namePattern, ScanFilter scanFilter) {
+        mNamePattern = namePattern;
+        mScanFilter = ObjectUtils.firstNotNull(scanFilter, ScanFilter.EMPTY);
+    }
+
+    @SuppressLint("ParcelClassLoader")
+    private BluetoothLEDeviceFilter(Parcel in) {
+        this(
+            patternFromString(in.readString()),
+            in.readParcelable(null));
+    }
+
+    /** @hide */
+    @NonNull
+    public static BluetoothLEDeviceFilter nullsafe(@Nullable BluetoothLEDeviceFilter nullable) {
+        return nullable != null ? nullable : noOp();
+    }
+
+    /** @hide */
+    @NonNull
+    public static BluetoothLEDeviceFilter noOp() {
+        if (NO_OP == null) NO_OP = new Builder().build();
+        return NO_OP;
+    }
+
+    /** @hide */
+    @Nullable
+    public Pattern getNamePattern() {
+        return mNamePattern;
+    }
+
+    /** @hide */
+    @NonNull
+    public ScanFilter getScanFilter() {
+        return mScanFilter;
+    }
+
+    /** @hide */
+    @Override
+    public boolean matches(BluetoothDevice device) {
+        return BluetoothDeviceFilterUtils.matches(getScanFilter(), device)
+                && BluetoothDeviceFilterUtils.matchesName(getNamePattern(), device);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(patternToString(getNamePattern()));
+        dest.writeParcelable(mScanFilter, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Creator<BluetoothLEDeviceFilter> CREATOR
+            = new Creator<BluetoothLEDeviceFilter>() {
+        @Override
+        public BluetoothLEDeviceFilter createFromParcel(Parcel in) {
+            return new BluetoothLEDeviceFilter(in);
+        }
+
+        @Override
+        public BluetoothLEDeviceFilter[] newArray(int size) {
+            return new BluetoothLEDeviceFilter[size];
+        }
+    };
+
+    /**
+     * Builder for {@link BluetoothLEDeviceFilter}
+     */
+    public static final class Builder extends OneTimeUseBuilder<BluetoothLEDeviceFilter> {
+        private ScanFilter mScanFilter;
+        private Pattern mNamePattern;
+
+        /**
+         * @param regex if set, only devices with {@link BluetoothDevice#getName name} matching the
+         *              given regular expression will be shown
+         */
+        public Builder setNamePattern(@Nullable Pattern regex) {
+            checkNotUsed();
+            mNamePattern = regex;
+            return this;
+        }
+
+        /**
+         * @param scanFilter a {@link ScanFilter} to filter devices by
+         *
+         * @see ScanFilter for specific details on its various fields
+         */
+        @NonNull
+        public Builder setScanFilter(@Nullable ScanFilter scanFilter) {
+            checkNotUsed();
+            mScanFilter = scanFilter;
+            return this;
+        }
+
+        /** @inheritDoc */
+        @Override
+        @NonNull
+        public BluetoothLEDeviceFilter build() {
+            markUsed();
+            return new BluetoothLEDeviceFilter(mNamePattern, mScanFilter);
+        }
+    }
+}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
new file mode 100644
index 0000000..b379c7c
--- /dev/null
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.IntentSender;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+
+/**
+ * System level service for managing companion devices
+ *
+ * Usage:
+ * To obtain an instance call
+ * {@link Context#getSystemService}({@link Context#COMPANION_DEVICE_SERVICE})
+ *
+ * Then, call {@link #associate} to initiate the flow of associating current package
+ * with a device selected by user
+ *
+ * @see AssociationRequest
+ */
+public final class CompanionDeviceManager {
+
+    /**
+     * A device, returned in the activity result of the {@link IntentSender} received in
+     * {@link Callback#onDeviceFound}
+     */
+    public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE";
+
+    /**
+     * A callback to receive once at least one suitable device is found, or the search failed
+     * (e.g. timed out)
+     */
+    public abstract static class Callback {
+
+        /**
+         * Called once at least one suitable device is found
+         *
+         * @param chooserLauncher a {@link IntentSender} to launch the UI for user to select a
+         *                        device
+         */
+        public abstract void onDeviceFound(IntentSender chooserLauncher);
+
+        /**
+         * Called if there was an error looking for device(s), e.g. timeout
+         *
+         * @param error the cause of the error
+         */
+        public abstract void onFailure(CharSequence error);
+    }
+
+    private final ICompanionDeviceManager mService;
+    private final Context mContext;
+
+    /** @hide */
+    public CompanionDeviceManager(
+            @NonNull ICompanionDeviceManager service, @NonNull Context context) {
+        mService = service;
+        mContext = context;
+    }
+
+    /**
+     * Associate this app with a companion device, selected by user
+     *
+     * Once at least one appropriate device is found, {@code callback} will be called with a
+     * {@link PendingIntent} that can be used to show the list of available devices for the user
+     * to select.
+     * It should be started for result (i.e. using
+     * {@link android.app.Activity#startIntentSenderForResult}), as the resulting
+     * {@link android.content.Intent} will contain extra {@link #EXTRA_DEVICE}, with the selected
+     * device. (e.g. {@link android.bluetooth.BluetoothDevice})
+     *
+     * @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,
+     *                to deliver it on main thread
+     *
+     * @see AssociationRequest
+     */
+    public void associate(
+            @NonNull AssociationRequest<?> request,
+            @NonNull Callback callback,
+            @Nullable Handler handler) {
+        final Handler finalHandler = handler != null
+                ? handler
+                : new Handler(Looper.getMainLooper());
+        try {
+            mService.associate(
+                    request,
+                    new IOnAssociateCallback.Stub() {
+
+                        @Override
+                        public void onSuccess(PendingIntent launcher) throws RemoteException {
+                            finalHandler.post(() -> {
+                                callback.onDeviceFound(launcher.getIntentSender());
+                            });
+                        }
+
+                        @Override
+                        public void onFailure(CharSequence reason) throws RemoteException {
+                            finalHandler.post(() -> callback.onFailure(reason));
+                        }
+                    },
+                    mContext.getPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** @hide */
+    public void requestNotificationAccess() {
+        //TODO implement
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    /** @hide */
+    public boolean haveNotificationAccess() {
+        //TODO implement
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+}
diff --git a/core/java/android/companion/DeviceFilter.java b/core/java/android/companion/DeviceFilter.java
new file mode 100644
index 0000000..8362b2d
--- /dev/null
+++ b/core/java/android/companion/DeviceFilter.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.companion;
+
+import android.annotation.Nullable;
+import android.os.Parcelable;
+
+/**
+ * A filter for companion devices of type {@code D}
+ *
+ * @param <D> Type of devices, filtered by this filter,
+ *           e.g. {@link android.bluetooth.BluetoothDevice}, {@link android.net.wifi.WifiInfo}
+ */
+public interface DeviceFilter<D extends Parcelable> extends Parcelable {
+
+    /**
+     * @return whether the given device matches this filter
+     *
+     * @hide
+     */
+    boolean matches(D device);
+
+    /**
+     * A nullsafe {@link #matches(Parcelable)}, returning true if the filter is null
+     *
+     * @hide
+     */
+    static <D extends Parcelable> boolean matches(@Nullable DeviceFilter<D> filter, D device) {
+        return filter == null || filter.matches(device);
+    }
+}
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
new file mode 100644
index 0000000..065e31be
--- /dev/null
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion;
+
+import android.companion.IOnAssociateCallback;
+import android.companion.AssociationRequest;
+
+/**
+ * Interface for communication with the core companion device manager service.
+ *
+ * @hide
+ */
+interface ICompanionDeviceManager {
+    void associate(in AssociationRequest request,
+        in IOnAssociateCallback callback,
+        in String callingPackage); //TODO int userId?
+
+    //TODO add these
+//    boolean haveNotificationAccess(String packageName);
+//    oneway void requestNotificationAccess(String packageName);
+}
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/companion/ICompanionDeviceManagerService.aidl
similarity index 65%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/android/companion/ICompanionDeviceManagerService.aidl
index ded8f97..ff2a7eb 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/companion/ICompanionDeviceManagerService.aidl
@@ -13,18 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.service.autofill;
 
-import java.io.PrintWriter;
+package android.companion;
 
-final class CallbackHelper {
+import android.companion.AssociationRequest;
+import android.companion.IOnAssociateCallback;
 
-    static interface Dumpable {
-        void dump(String prefix, PrintWriter pw);
-        void setFinalizer(Finalizer f);
-    }
 
-    static interface Finalizer {
-        void gone();
-    }
+/** @hide */
+interface ICompanionDeviceManagerService {
+    void startDiscovery(
+        in AssociationRequest request,
+        in IOnAssociateCallback callback,
+        in String callingPackage);
 }
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl
similarity index 60%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl
index ded8f97..c9dd345 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/companion/ICompanionDeviceManagerServiceCallback.aidl
@@ -10,21 +10,15 @@
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
+ * See the License for the specific language governing per  missions and
  * limitations under the License.
  */
-package android.service.autofill;
 
-import java.io.PrintWriter;
+package android.companion;
 
-final class CallbackHelper {
+import android.bluetooth.BluetoothDevice;
 
-    static interface Dumpable {
-        void dump(String prefix, PrintWriter pw);
-        void setFinalizer(Finalizer f);
-    }
-
-    static interface Finalizer {
-        void gone();
-    }
+/** @hide */
+interface ICompanionDeviceManagerServiceCallback {
+    void onDeviceSelected(in BluetoothDevice device);
 }
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/companion/IOnAssociateCallback.aidl
similarity index 60%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/android/companion/IOnAssociateCallback.aidl
index ded8f97..4867eadd 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/companion/IOnAssociateCallback.aidl
@@ -10,21 +10,16 @@
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
+ * See the License for the specific language governing per  missions and
  * limitations under the License.
  */
-package android.service.autofill;
 
-import java.io.PrintWriter;
+package android.companion;
 
-final class CallbackHelper {
+import android.app.PendingIntent;
 
-    static interface Dumpable {
-        void dump(String prefix, PrintWriter pw);
-        void setFinalizer(Finalizer f);
-    }
-
-    static interface Finalizer {
-        void gone();
-    }
+/** @hide */
+interface IOnAssociateCallback {
+    void onSuccess(in PendingIntent launcher);
+    void onFailure(in CharSequence reason);
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index f610a29..06f7303 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -35,6 +35,7 @@
 import android.app.IApplicationThread;
 import android.app.IServiceConnection;
 import android.app.Notification;
+import android.app.VrManager;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -3599,6 +3600,14 @@
     public static final String PRINT_SERVICE = "print";
 
     /**
+     * {@link android.companion.CompanionDeviceManager} for managing companion devices
+     *
+     * @see #getSystemService
+     * @see android.companion.CompanionDeviceManager
+     */
+    public static final String COMPANION_DEVICE_SERVICE = "companion_device";
+
+    /**
      * Use with {@link #getSystemService} to retrieve a
      * {@link android.hardware.ConsumerIrManager} for transmitting infrared
      * signals from the device.
@@ -3764,6 +3773,16 @@
     public static final String OVERLAY_SERVICE = "overlay";
 
     /**
+     * Use with {@link #getSystemService} to retrieve a
+     * {@link VrManager} for accessing the VR service.
+     *
+     * @see #getSystemService
+     * @hide
+     */
+    @SystemApi
+    public static final String VR_SERVICE = "vrmanager";
+
+    /**
      * Determine whether the given permission is allowed for a particular
      * process and user ID running in the system.
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1130327..6a8141f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1806,6 +1806,41 @@
     @SystemApi
     public static final String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
 
+    /**
+     * Intent extra: An id if an autofill item ({@link
+     * android.view.autofill.Dataset} or {@link android.view.autofill.FillResponse}).
+     * <p>
+     * Type: String
+     * </p>
+     */
+    public static final String EXTRA_AUTO_FILL_ITEM_ID = "android.intent.extra.AUTO_FILL_ITEM_ID";
+
+    /**
+     * Intent extra: The assist structure which captures the filled screen.
+     * <p>
+     * Type: {@link android.app.assist.AssistStructure}
+     * </p>
+     */
+    public static final String EXTRA_AUTO_FILL_ASSIST_STRUCTURE =
+            "android.intent.extra.AUTO_FILL_ASSIST_STRUCTURE";
+
+    /**
+     * Intent extra: The metadata associated with the authenticated entity ({@link
+     * android.view.autofill.Dataset} or {@link android.view.autofill.FillResponse}).
+     * <p>
+     * Type: {@link android.os.Bundle}
+     * </p>
+     */
+    public static final String EXTRA_AUTO_FILL_EXTRAS = "android.intent.extra.AUTO_FILL_EXTRAS";
+
+    /**
+     * Intent extra: A callback to report an authentication result.
+     * <p>
+     * Type: {@link android.view.autofill.FillResponse}
+     * </p>
+     */
+    public static final String EXTRA_AUTO_FILL_CALLBACK = "android.intent.extra.AUTO_FILL_CALLBACK";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard intent broadcast actions (see action variable).
diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java
index dd53eac..74d2f11 100644
--- a/core/java/android/content/SyncRequest.java
+++ b/core/java/android/content/SyncRequest.java
@@ -351,7 +351,7 @@
          * @param requiresCharging true if sync requires the phone to be plugged in. Default false.
          */
         public Builder setRequiresCharging(boolean requiresCharging) {
-            mRequiresCharging = true;
+            mRequiresCharging = requiresCharging;
             return this;
         }
 
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 92cb709..9a8eff0 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -397,14 +397,6 @@
     public static final int FLAG_ALWAYS_FOCUSABLE = 0x40000;
 
     /**
-     * Bit in {@link #flags} indicating if the activity is a launcher activity which should always
-     * show up on the top of others.
-     * See android.R.attr#onTopLauncher.
-     * @hide
-     */
-    public static final int FLAG_ON_TOP_LAUNCHER = 0x80000;
-
-    /**
      * Bit in {@link #flags} indicating if the activity is visible to ephemeral applications.
      * @hide
      */
diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java
index a135d8f..59c5307 100644
--- a/core/java/android/content/pm/InstrumentationInfo.java
+++ b/core/java/android/content/pm/InstrumentationInfo.java
@@ -34,6 +34,13 @@
     public String targetPackage;
 
     /**
+     * Names of the process(es) this instrumentation will run in.  If not specified, only
+     * runs in the main process of the targetPackage.  Can either be a comma-separated list
+     * of process names or '*' for any process that launches to run targetPackage code.
+     */
+    public String targetProcess;
+
+    /**
      * Full path to the base APK for this application.
      */
     public String sourceDir;
@@ -113,6 +120,7 @@
     public InstrumentationInfo(InstrumentationInfo orig) {
         super(orig);
         targetPackage = orig.targetPackage;
+        targetProcess = orig.targetProcess;
         sourceDir = orig.sourceDir;
         publicSourceDir = orig.publicSourceDir;
         splitNames = orig.splitNames;
@@ -141,6 +149,7 @@
     public void writeToParcel(Parcel dest, int parcelableFlags) {
         super.writeToParcel(dest, parcelableFlags);
         dest.writeString(targetPackage);
+        dest.writeString(targetProcess);
         dest.writeString(sourceDir);
         dest.writeString(publicSourceDir);
         dest.writeStringArray(splitNames);
@@ -170,6 +179,7 @@
     private InstrumentationInfo(Parcel source) {
         super(source);
         targetPackage = source.readString();
+        targetProcess = source.readString();
         sourceDir = source.readString();
         publicSourceDir = source.readString();
         splitNames = source.readStringArray();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index ab641c9..b20b5e2 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1741,6 +1741,22 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature(String, int)}: If this feature is supported, the Vulkan native API
+     * will enumerate at least one {@code VkPhysicalDevice}, and the feature version will indicate
+     * what level of optional compute features are supported beyond the Vulkan 1.0 requirements.
+     * <p>
+     * Compute level 0 indicates support for:
+     * <ul>
+     * <li>Ability to use pointers to buffer data from shaders</li>
+     * <li>Ability to load/store 16-bit values from buffers</li>
+     * <li>Ability to control shader floating point rounding mode</li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_VULKAN_HARDWARE_COMPUTE = "android.hardware.vulkan.compute";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature(String, int)}: The version of this feature indicates the highest
      * {@code VkPhysicalDeviceProperties::apiVersion} supported by the physical devices that support
      * the hardware level indicated by {@link #FEATURE_VULKAN_HARDWARE_LEVEL}. The feature version
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a45a2ff..7cef781 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -17,7 +17,6 @@
 package android.content.pm;
 
 import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
-import static android.content.pm.ActivityInfo.FLAG_ON_TOP_LAUNCHER;
 import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
@@ -1623,6 +1622,7 @@
             return parseApkLite(apkPath, parser, attrs, flags, signatures, certificates);
 
         } catch (XmlPullParserException | IOException | RuntimeException e) {
+            Slog.w(TAG, "Failed to parse " + apkPath, e);
             throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
                     "Failed to parse " + apkPath, e);
         } finally {
@@ -3160,6 +3160,10 @@
                 com.android.internal.R.styleable.AndroidManifestInstrumentation_targetPackage);
         a.info.targetPackage = str != null ? str.intern() : null;
 
+        str = sa.getNonResourceString(
+                com.android.internal.R.styleable.AndroidManifestInstrumentation_targetProcess);
+        a.info.targetProcess = str != null ? str.intern() : null;
+
         a.info.handleProfiling = sa.getBoolean(
                 com.android.internal.R.styleable.AndroidManifestInstrumentation_handleProfiling,
                 false);
@@ -4105,10 +4109,6 @@
                 a.info.flags |= FLAG_ALWAYS_FOCUSABLE;
             }
 
-            if (sa.getBoolean(R.styleable.AndroidManifestActivity_onTopLauncher, false)) {
-                a.info.flags |= FLAG_ON_TOP_LAUNCHER;
-            }
-
             a.info.lockTaskLaunchMode =
                     sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
 
@@ -5033,9 +5033,7 @@
     }
 
     private boolean isWebBrowsableIntent(IntentInfo intent) {
-        return intent.hasAction(Intent.ACTION_VIEW)
-                && intent.hasCategory(Intent.CATEGORY_BROWSABLE)
-                && (intent.hasDataScheme("http") || intent.hasDataScheme("https"));
+        return intent.hasCategory(Intent.CATEGORY_BROWSABLE);
     }
 
     private boolean parseAllMetaData(Resources res, XmlResourceParser parser, String tag,
diff --git a/core/java/android/content/res/FontResourcesParser.java b/core/java/android/content/res/FontResourcesParser.java
index 15f3a09..7ea62db 100644
--- a/core/java/android/content/res/FontResourcesParser.java
+++ b/core/java/android/content/res/FontResourcesParser.java
@@ -33,7 +33,7 @@
  */
 public class FontResourcesParser {
     private static final int NORMAL_WEIGHT = 400;
-    private static final String ITALIC = "italic";
+    private static final int ITALIC = 1;
 
     public static FontConfig parse(XmlPullParser parser, Resources resources)
             throws XmlPullParserException, IOException {
@@ -82,9 +82,12 @@
         AttributeSet attrs = Xml.asAttributeSet(parser);
         TypedArray array = resources.obtainAttributes(attrs, R.styleable.FontFamilyFont);
         int weight = array.getInt(R.styleable.FontFamilyFont_fontWeight, NORMAL_WEIGHT);
-        boolean isItalic = ITALIC.equals(array.getString(R.styleable.FontFamilyFont_fontStyle));
+        boolean isItalic = ITALIC == array.getInt(R.styleable.FontFamilyFont_fontStyle, 0);
         String filename = array.getString(R.styleable.FontFamilyFont_font);
         array.recycle();
+        while (parser.next() != XmlPullParser.END_TAG) {
+            skip(parser);
+        }
         return new FontConfig.Font(filename, 0, null, weight, isItalic);
     }
 
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 522575f..d951294 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -259,10 +259,6 @@
             throw new IllegalArgumentException("Unknow surface source class type");
         }
 
-        if (surfaceSize.getWidth() == 0 || surfaceSize.getHeight() == 0) {
-            throw new IllegalArgumentException("Surface size needs to be non-zero");
-        }
-
         mSurfaceGroupId = SURFACE_GROUP_ID_NONE;
         mSurfaces = new ArrayList<Surface>();
         mRotation = ROTATION_0;
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 3eb5844..98a5749 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -230,9 +230,6 @@
         public int dozeScreenBrightness;
         public int dozeScreenState;
 
-        // If true, use twilight to affect the brightness.
-        public boolean useTwilight;
-
         public DisplayPowerRequest() {
             policy = POLICY_BRIGHT;
             useProximitySensor = false;
@@ -268,7 +265,6 @@
             boostScreenBrightness = other.boostScreenBrightness;
             dozeScreenBrightness = other.dozeScreenBrightness;
             dozeScreenState = other.dozeScreenState;
-            useTwilight = other.useTwilight;
         }
 
         @Override
@@ -289,8 +285,7 @@
                     && lowPowerMode == other.lowPowerMode
                     && boostScreenBrightness == other.boostScreenBrightness
                     && dozeScreenBrightness == other.dozeScreenBrightness
-                    && dozeScreenState == other.dozeScreenState
-                    && useTwilight == other.useTwilight;
+                    && dozeScreenState == other.dozeScreenState;
         }
 
         @Override
@@ -310,8 +305,7 @@
                     + ", lowPowerMode=" + lowPowerMode
                     + ", boostScreenBrightness=" + boostScreenBrightness
                     + ", dozeScreenBrightness=" + dozeScreenBrightness
-                    + ", dozeScreenState=" + Display.stateToString(dozeScreenState)
-                    + ", useTwilight=" + useTwilight;
+                    + ", dozeScreenState=" + Display.stateToString(dozeScreenState);
         }
 
         public static String policyToString(int policy) {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 222953e..dc5750d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -46,6 +46,7 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.SparseArray;
+import android.util.SparseIntArray;
 
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.PhoneConstants;
@@ -1240,36 +1241,27 @@
 
     private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
         if (networkType == TYPE_MOBILE) {
-            int cap = -1;
-            if ("enableMMS".equals(feature)) {
-                cap = NetworkCapabilities.NET_CAPABILITY_MMS;
-            } else if ("enableSUPL".equals(feature)) {
-                cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
-            } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
-                cap = NetworkCapabilities.NET_CAPABILITY_DUN;
-            } else if ("enableHIPRI".equals(feature)) {
-                cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
-            } else if ("enableFOTA".equals(feature)) {
-                cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
-            } else if ("enableIMS".equals(feature)) {
-                cap = NetworkCapabilities.NET_CAPABILITY_IMS;
-            } else if ("enableCBS".equals(feature)) {
-                cap = NetworkCapabilities.NET_CAPABILITY_CBS;
-            } else {
-                return null;
+            switch (feature) {
+                case "enableCBS":
+                    return networkCapabilitiesForType(TYPE_MOBILE_CBS);
+                case "enableDUN":
+                case "enableDUNAlways":
+                    return networkCapabilitiesForType(TYPE_MOBILE_DUN);
+                case "enableFOTA":
+                    return networkCapabilitiesForType(TYPE_MOBILE_FOTA);
+                case "enableHIPRI":
+                    return networkCapabilitiesForType(TYPE_MOBILE_HIPRI);
+                case "enableIMS":
+                    return networkCapabilitiesForType(TYPE_MOBILE_IMS);
+                case "enableMMS":
+                    return networkCapabilitiesForType(TYPE_MOBILE_MMS);
+                case "enableSUPL":
+                    return networkCapabilitiesForType(TYPE_MOBILE_SUPL);
+                default:
+                    return null;
             }
-            NetworkCapabilities netCap = new NetworkCapabilities();
-            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
-            netCap.maybeMarkCapabilitiesRestricted();
-            return netCap;
-        } else if (networkType == TYPE_WIFI) {
-            if ("p2p".equals(feature)) {
-                NetworkCapabilities netCap = new NetworkCapabilities();
-                netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
-                netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
-                netCap.maybeMarkCapabilitiesRestricted();
-                return netCap;
-            }
+        } else if (networkType == TYPE_WIFI && "p2p".equals(feature)) {
+            return networkCapabilitiesForType(TYPE_WIFI_P2P);
         }
         return null;
     }
@@ -1477,6 +1469,59 @@
         return true;
     }
 
+    private static final SparseIntArray sLegacyTypeToTransport = new SparseIntArray();
+    static {
+        sLegacyTypeToTransport.put(TYPE_MOBILE,       NetworkCapabilities.TRANSPORT_CELLULAR);
+        sLegacyTypeToTransport.put(TYPE_MOBILE_CBS,   NetworkCapabilities.TRANSPORT_CELLULAR);
+        sLegacyTypeToTransport.put(TYPE_MOBILE_DUN,   NetworkCapabilities.TRANSPORT_CELLULAR);
+        sLegacyTypeToTransport.put(TYPE_MOBILE_FOTA,  NetworkCapabilities.TRANSPORT_CELLULAR);
+        sLegacyTypeToTransport.put(TYPE_MOBILE_HIPRI, NetworkCapabilities.TRANSPORT_CELLULAR);
+        sLegacyTypeToTransport.put(TYPE_MOBILE_IMS,   NetworkCapabilities.TRANSPORT_CELLULAR);
+        sLegacyTypeToTransport.put(TYPE_MOBILE_MMS,   NetworkCapabilities.TRANSPORT_CELLULAR);
+        sLegacyTypeToTransport.put(TYPE_MOBILE_SUPL,  NetworkCapabilities.TRANSPORT_CELLULAR);
+        sLegacyTypeToTransport.put(TYPE_WIFI,         NetworkCapabilities.TRANSPORT_WIFI);
+        sLegacyTypeToTransport.put(TYPE_WIFI_P2P,     NetworkCapabilities.TRANSPORT_WIFI);
+        sLegacyTypeToTransport.put(TYPE_BLUETOOTH,    NetworkCapabilities.TRANSPORT_BLUETOOTH);
+        sLegacyTypeToTransport.put(TYPE_ETHERNET,     NetworkCapabilities.TRANSPORT_ETHERNET);
+    }
+
+    private static final SparseIntArray sLegacyTypeToCapability = new SparseIntArray();
+    static {
+        sLegacyTypeToCapability.put(TYPE_MOBILE_CBS,  NetworkCapabilities.NET_CAPABILITY_CBS);
+        sLegacyTypeToCapability.put(TYPE_MOBILE_DUN,  NetworkCapabilities.NET_CAPABILITY_DUN);
+        sLegacyTypeToCapability.put(TYPE_MOBILE_FOTA, NetworkCapabilities.NET_CAPABILITY_FOTA);
+        sLegacyTypeToCapability.put(TYPE_MOBILE_IMS,  NetworkCapabilities.NET_CAPABILITY_IMS);
+        sLegacyTypeToCapability.put(TYPE_MOBILE_MMS,  NetworkCapabilities.NET_CAPABILITY_MMS);
+        sLegacyTypeToCapability.put(TYPE_MOBILE_SUPL, NetworkCapabilities.NET_CAPABILITY_SUPL);
+        sLegacyTypeToCapability.put(TYPE_WIFI_P2P,    NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
+    }
+
+    /**
+     * Given a legacy type (TYPE_WIFI, ...) returns a NetworkCapabilities
+     * instance suitable for registering a request or callback.  Throws an
+     * IllegalArgumentException if no mapping from the legacy type to
+     * NetworkCapabilities is known.
+     *
+     * @hide
+     */
+    public static NetworkCapabilities networkCapabilitiesForType(int type) {
+        final NetworkCapabilities nc = new NetworkCapabilities();
+
+        // Map from type to transports.
+        final int NOT_FOUND = -1;
+        final int transport = sLegacyTypeToTransport.get(type, NOT_FOUND);
+        if (transport == NOT_FOUND) {
+            throw new IllegalArgumentException("unknown legacy type: " + type);
+        }
+        nc.addTransportType(transport);
+
+        // Map from type to capabilities.
+        nc.addCapability(sLegacyTypeToCapability.get(
+                type, NetworkCapabilities.NET_CAPABILITY_INTERNET));
+        nc.maybeMarkCapabilitiesRestricted();
+        return nc;
+    }
+
     /** @hide */
     public static class PacketKeepaliveCallback {
         /** The requested keepalive was successfully started. */
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index ae72470..cb78009 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -178,6 +178,20 @@
         }
 
         /**
+         * Set the {@code NetworkCapabilities} for this builder instance,
+         * overriding any capabilities that had been previously set.
+         *
+         * @param nc The superseding {@code NetworkCapabilities} instance.
+         * @return The builder to facilitate chaining.
+         * @hide
+         */
+        public Builder setCapabilities(NetworkCapabilities nc) {
+            mNetworkCapabilities.clearAll();
+            mNetworkCapabilities.combineCapabilities(nc);
+            return this;
+        }
+
+        /**
          * Completely clears all the {@code NetworkCapabilities} from this builder instance,
          * removing even the capabilities that are set by default when the object is constructed.
          *
diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java
index 9e4dd87..9dcf4f4 100644
--- a/core/java/android/net/NetworkScorerAppManager.java
+++ b/core/java/android/net/NetworkScorerAppManager.java
@@ -18,6 +18,7 @@
 
 import android.Manifest.permission;
 import android.annotation.Nullable;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -33,6 +34,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Internal class for discovering and managing the network scorer/recommendation application.
@@ -53,33 +55,43 @@
      * Holds metadata about a discovered network scorer/recommendation application.
      */
     public static class NetworkScorerAppData {
-        /** Package name of this scorer app. */
-        public final String packageName;
-
         /** UID of the scorer app. */
         public final int packageUid;
+        private final ComponentName mRecommendationService;
 
-        /**
-         * Name of the recommendation service we can bind to.
-         */
-        public final String recommendationServiceClassName;
-
-        public NetworkScorerAppData(String packageName, int packageUid,
-                String recommendationServiceClassName) {
-            this.packageName = packageName;
+        public NetworkScorerAppData(int packageUid, ComponentName recommendationServiceComp) {
             this.packageUid = packageUid;
-            this.recommendationServiceClassName = recommendationServiceClassName;
+            this.mRecommendationService = recommendationServiceComp;
+        }
+
+        public String getRecommendationServicePackageName() {
+            return mRecommendationService.getPackageName();
+        }
+
+        public ComponentName getRecommendationServiceComponent() {
+            return mRecommendationService;
         }
 
         @Override
         public String toString() {
-            final StringBuilder sb = new StringBuilder("NetworkScorerAppData{");
-            sb.append("mPackageName='").append(packageName).append('\'');
-            sb.append(", packageUid=").append(packageUid);
-            sb.append(", recommendationServiceClassName='")
-                    .append(recommendationServiceClassName).append('\'');
-            sb.append('}');
-            return sb.toString();
+            return "NetworkScorerAppData{" +
+                    "packageUid=" + packageUid +
+                    ", mRecommendationService=" + mRecommendationService +
+                    '}';
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            NetworkScorerAppData that = (NetworkScorerAppData) o;
+            return packageUid == that.packageUid &&
+                    Objects.equals(mRecommendationService, that.mRecommendationService);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(packageUid, mRecommendationService);
         }
     }
 
@@ -110,16 +122,16 @@
             return null;
         }
 
-        final PackageManager pm = mContext.getPackageManager();
         for (int i = 0; i < potentialPkgs.size(); i++) {
             final String potentialPkg = potentialPkgs.get(i);
 
             // Look for the recommendation service class and required receiver.
             final ResolveInfo resolveServiceInfo = findRecommendationService(potentialPkg);
             if (resolveServiceInfo != null) {
-                return new NetworkScorerAppData(potentialPkg,
-                    resolveServiceInfo.serviceInfo.applicationInfo.uid,
-                    resolveServiceInfo.serviceInfo.name);
+                final ComponentName componentName =
+                        new ComponentName(potentialPkg, resolveServiceInfo.serviceInfo.name);
+                return new NetworkScorerAppData(resolveServiceInfo.serviceInfo.applicationInfo.uid,
+                        componentName);
             } else {
                 if (DEBUG) {
                     Log.d(TAG, potentialPkg + " does not have the required components, skipping.");
diff --git a/core/java/android/net/RecommendationRequest.java b/core/java/android/net/RecommendationRequest.java
index b89a245..9f97c5a 100644
--- a/core/java/android/net/RecommendationRequest.java
+++ b/core/java/android/net/RecommendationRequest.java
@@ -50,7 +50,7 @@
         private WifiConfiguration mDefaultConfig;
         private WifiConfiguration mConnectedConfig;
         private WifiConfiguration[] mConnectableConfigs;
-        private int mLastSelectedNetworkId;
+        private int mLastSelectedNetworkId = -1;
         private long mLastSelectedTimestamp;
 
         public Builder setScanResults(ScanResult[] scanResults) {
@@ -161,7 +161,7 @@
 
     /**
      * @return The {@link WifiConfiguration#networkId} of the last user selected network.
-     *         {@code 0} if not set.
+     *         {@code -1} if not set.
      */
     public int getLastSelectedNetworkId() {
         return mLastSelectedNetworkId;
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index e99d303..f94e89a 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.annotation.IntegerRes;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -1339,7 +1340,7 @@
     }
 
     /**
-     * Flatten a heterogeneous array containing a particular object type into
+     * Flatten a homogeneous array containing a particular object type into
      * the parcel, at
      * the current dataPosition() and growing dataCapacity() if needed.  The
      * type of the objects in the array must be one that implements Parcelable.
@@ -1361,7 +1362,7 @@
         if (val != null) {
             int N = val.length;
             writeInt(N);
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < N; i++) {
                 T item = val[i];
                 if (item != null) {
                     writeInt(1);
@@ -1376,6 +1377,146 @@
     }
 
     /**
+     * Write a uniform (all items are null or the same class) array list of
+     * parcelables.
+     *
+     * @param list The list to write.
+     *
+     * @hide
+     */
+    public final <T extends Parcelable> void writeTypedArrayList(@Nullable ArrayList<T> list,
+            int parcelableFlags) {
+        if (list != null) {
+            int N = list.size();
+            writeInt(N);
+            boolean wroteCreator = false;
+            for (int i = 0; i < N; i++) {
+                T item = list.get(i);
+                if (item != null) {
+                    writeInt(1);
+                    if (!wroteCreator) {
+                        writeParcelableCreator(item);
+                        wroteCreator = true;
+                    }
+                    item.writeToParcel(this, parcelableFlags);
+                } else {
+                    writeInt(0);
+                }
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    /**
+     * Reads a uniform (all items are null or the same class) array list of
+     * parcelables.
+     *
+     * @return The list or null.
+     *
+     * @hide
+     */
+    public final @Nullable <T> ArrayList<T> readTypedArrayList(@Nullable ClassLoader loader) {
+        int N = readInt();
+        if (N <= 0) {
+            return null;
+        }
+        Parcelable.Creator<?> creator = null;
+        ArrayList<T> result = new ArrayList<T>(N);
+        for (int i = 0; i < N; i++) {
+            if (readInt() != 0) {
+                if (creator == null) {
+                    creator = readParcelableCreator(loader);
+                    if (creator == null) {
+                        return null;
+                    }
+                }
+                final T parcelable;
+                if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
+                    Parcelable.ClassLoaderCreator<?> classLoaderCreator =
+                            (Parcelable.ClassLoaderCreator<?>) creator;
+                    parcelable = (T) classLoaderCreator.createFromParcel(this, loader);
+                } else {
+                    parcelable = (T) creator.createFromParcel(this);
+                }
+                result.add(parcelable);
+            } else {
+                result.add(null);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Write a uniform (all items are null or the same class) array set of
+     * parcelables.
+     *
+     * @param set The set to write.
+     *
+     * @hide
+     */
+    public final <T extends Parcelable> void writeTypedArraySet(@Nullable ArraySet<T> set,
+            int parcelableFlags) {
+        if (set != null) {
+            int N = set.size();
+            writeInt(N);
+            boolean wroteCreator = false;
+            for (int i = 0; i < N; i++) {
+                T item = set.valueAt(i);
+                if (item != null) {
+                    writeInt(1);
+                    if (!wroteCreator) {
+                        writeParcelableCreator(item);
+                        wroteCreator = true;
+                    }
+                    item.writeToParcel(this, parcelableFlags);
+                } else {
+                    writeInt(0);
+                }
+            }
+        } else {
+            writeInt(-1);
+        }
+    }
+
+    /**
+     * Reads a uniform (all items are null or the same class) array set of
+     * parcelables.
+     *
+     * @return The set or null.
+     *
+     * @hide
+     */
+    public final @Nullable <T> ArraySet<T> readTypedArraySet(@Nullable ClassLoader loader) {
+        int N = readInt();
+        if (N <= 0) {
+            return null;
+        }
+        Parcelable.Creator<?> creator = null;
+        ArraySet<T> result = new ArraySet<T>(N);
+        for (int i = 0; i < N; i++) {
+            T parcelable = null;
+            if (readInt() != 0) {
+                if (creator == null) {
+                    creator = readParcelableCreator(loader);
+                    if (creator == null) {
+                        return null;
+                    }
+                }
+                if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
+                    Parcelable.ClassLoaderCreator<?> classLoaderCreator =
+                            (Parcelable.ClassLoaderCreator<?>) creator;
+                    parcelable = (T) classLoaderCreator.createFromParcel(this, loader);
+                } else {
+                    parcelable = (T) creator.createFromParcel(this);
+                }
+            }
+            result.append(parcelable);
+        }
+        return result;
+    }
+
+    /**
      * Flatten the Parcelable object into the parcel.
      *
      * @param val The Parcelable object to be written.
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index dff0a28..31b3bc9 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -508,15 +508,6 @@
     }
 
     /**
-     * Returns true if the twilight service should be used to adjust screen brightness
-     * policy.  This setting is experimental and disabled by default.
-     * @hide
-     */
-    public static boolean useTwilightAdjustmentFeature() {
-        return SystemProperties.getBoolean("persist.power.usetwilightadj", false);
-    }
-
-    /**
      * Creates a new wake lock with the specified level and flags.
      * <p>
      * The {@code levelAndFlags} parameter specifies a wake lock level and optional flags
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/core/java/android/os/Seccomp.java
similarity index 69%
copy from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
copy to core/java/android/os/Seccomp.java
index 62d5603..f14e93f 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
+++ b/core/java/android/os/Seccomp.java
@@ -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,11 @@
  * limitations under the License.
  */
 
-package android.net.wifi.hotspot2.pps;
+package android.os;
 
-parcelable HomeSP;
+/**
+ * @hide
+ */
+public final class Seccomp {
+    public static final native void setPolicy();
+}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 388054d..dfcab3d 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -516,6 +516,7 @@
      * <li>{@link LayoutParams#TYPE_SYSTEM_ALERT}</li>
      * <li>{@link LayoutParams#TYPE_SYSTEM_ERROR}</li>
      * <li>{@link LayoutParams#TYPE_SYSTEM_OVERLAY}</li>
+     * <li>{@link LayoutParams#TYPE_APPLICATION_OVERLAY}</li>
      *
      * <p>This can only be set by device owners and profile owners on the primary user.
      * The default value is <code>false</code>.
diff --git a/core/java/android/provider/OneTimeUseBuilder.java b/core/java/android/provider/OneTimeUseBuilder.java
new file mode 100644
index 0000000..682e9c7
--- /dev/null
+++ b/core/java/android/provider/OneTimeUseBuilder.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+/**
+ * A builder that facilitates prohibiting its use after an instance was created with it.
+ *
+ * Suggested usage:
+ * call {@link #checkNotUsed} in each setter, and {@link #markUsed} in {@link #build}
+ *
+ * @param <T> Type of object being built
+ * @hide
+ */
+public abstract class OneTimeUseBuilder<T> {
+    private boolean used = false;
+
+    protected void markUsed() {
+        checkNotUsed();
+        used = true;
+    }
+
+    protected void checkNotUsed() {
+        if (used) {
+            throw new IllegalStateException(
+                    "This Builder should not be reused. Use a new Builder instance instead");
+        }
+    }
+
+    /**
+     * Builds the instance
+     *
+     * Once this method is called, this builder should no longer be used. Any subsequent calls to a
+     * setter or {@code build()} will throw an exception
+     */
+    public abstract T build();
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d83f2cb..2936dfb 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6721,12 +6721,6 @@
         public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time";
 
         /**
-         * Whether brightness should automatically adjust based on twilight state.
-         * @hide
-         */
-        public static final String BRIGHTNESS_USE_TWILIGHT = "brightness_use_twilight";
-
-        /**
          * Names of the service components that the current user has explicitly allowed to
          * be a VR mode listener, separated by ':'.
          *
diff --git a/core/java/android/provider/SettingsStringUtil.java b/core/java/android/provider/SettingsStringUtil.java
new file mode 100644
index 0000000..f242d79
--- /dev/null
+++ b/core/java/android/provider/SettingsStringUtil.java
@@ -0,0 +1,174 @@
+/*
+ * 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 android.content.ComponentName;
+import android.content.ContentResolver;
+import android.text.TextUtils;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.function.Function;
+
+/**
+ * Utilities for dealing with {@link String} values in {@link Settings}
+ *
+ * @hide
+ */
+public class SettingsStringUtil {
+    private SettingsStringUtil() {}
+
+    public static final String DELIMITER = ":";
+
+    /**
+     * A {@link HashSet} of items, that uses a common convention of setting string
+     * serialization/deserialization of separating multiple items with {@link #DELIMITER}
+     */
+    public static abstract class ColonDelimitedSet<T> extends HashSet<T> {
+
+        public ColonDelimitedSet(String colonSeparatedItems) {
+            for (String cn :
+                    TextUtils.split(TextUtils.emptyIfNull(colonSeparatedItems), DELIMITER)) {
+                add(itemFromString(cn));
+            }
+        }
+
+        protected abstract T itemFromString(String s);
+        protected String itemToString(T item) {
+            return String.valueOf(item);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            Iterator<T> it = iterator();
+            if (it.hasNext()) {
+                sb.append(it.next());
+                while (it.hasNext()) {
+                    sb.append(DELIMITER);
+                    sb.append(itemToString(it.next()));
+                }
+            }
+            return sb.toString();
+        }
+
+
+        public static class OfStrings extends ColonDelimitedSet<String> {
+            public OfStrings(String colonSeparatedItems) {
+                super(colonSeparatedItems);
+            }
+
+            @Override
+            protected String itemFromString(String s) {
+                return s;
+            }
+
+            public static String add(String delimitedElements, String element) {
+                final ColonDelimitedSet<String> set
+                        = new ColonDelimitedSet.OfStrings(delimitedElements);
+                if (set.contains(element)) {
+                    return delimitedElements;
+                }
+                set.add(element);
+                return set.toString();
+            }
+
+            public static String remove(String delimitedElements, String element) {
+                final ColonDelimitedSet<String> set
+                        = new ColonDelimitedSet.OfStrings(delimitedElements);
+                if (!set.contains(element)) {
+                    return delimitedElements;
+                }
+                set.remove(element);
+                return set.toString();
+            }
+
+            public static boolean contains(String delimitedElements, String element) {
+                final String[] elements = TextUtils.split(delimitedElements, DELIMITER);
+                return ArrayUtils.indexOf(elements, element) != -1;
+            }
+        }
+    }
+
+    public static class ComponentNameSet extends ColonDelimitedSet<ComponentName> {
+        public ComponentNameSet(String colonSeparatedPackageNames) {
+            super(colonSeparatedPackageNames);
+        }
+
+        @Override
+        protected ComponentName itemFromString(String s) {
+            return ComponentName.unflattenFromString(s);
+        }
+
+        @Override
+        protected String itemToString(ComponentName item) {
+            return item.flattenToString();
+        }
+
+        public static String add(String delimitedElements, ComponentName element) {
+            final ComponentNameSet set = new ComponentNameSet(delimitedElements);
+            if (set.contains(element)) {
+                return delimitedElements;
+            }
+            set.add(element);
+            return set.toString();
+        }
+
+        public static String remove(String delimitedElements, ComponentName element) {
+            final ComponentNameSet set = new ComponentNameSet(delimitedElements);
+            if (!set.contains(element)) {
+                return delimitedElements;
+            }
+            set.remove(element);
+            return set.toString();
+        }
+
+        public static boolean contains(String delimitedElements, ComponentName element) {
+            return ColonDelimitedSet.OfStrings.contains(
+                    delimitedElements, element.flattenToString());
+        }
+    }
+
+    public static class SettingStringHelper {
+        private final ContentResolver mContentResolver;
+        private final String mSettingName;
+        private final int mUserId;
+
+        public SettingStringHelper(ContentResolver contentResolver, String name, int userId) {
+            mContentResolver = contentResolver;
+            mUserId = userId;
+            mSettingName = name;
+        }
+
+        public String read() {
+            return Settings.Secure.getStringForUser(
+                    mContentResolver, mSettingName, mUserId);
+        }
+
+        public boolean write(String value) {
+            return Settings.Secure.putStringForUser(
+                    mContentResolver, mSettingName, value, mUserId);
+        }
+
+        public boolean modify(Function<String, String> change) {
+            return write(change.apply(read()));
+        }
+    }
+}
diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java
index bfaf23c..aa4d26c 100644
--- a/core/java/android/service/autofill/AutoFillService.java
+++ b/core/java/android/service/autofill/AutoFillService.java
@@ -15,7 +15,10 @@
  */
 package android.service.autofill;
 
-import android.annotation.CallSuper;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.RemoteException;
+import com.android.internal.os.HandlerCaller;
 import android.annotation.SdkConstant;
 import android.app.Activity;
 import android.app.Service;
@@ -24,21 +27,13 @@
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.IBinder;
+import android.os.ICancellationSignal;
 import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
 import android.util.Log;
-import android.view.autofill.Dataset;
 import android.view.autofill.FillResponse;
 
-import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.SomeArgs;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-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.
 
@@ -48,12 +43,7 @@
  * <p>Apps providing auto-fill capabilities must extend this service.
  */
 public abstract class AutoFillService extends Service {
-
     private static final String TAG = "AutoFillService";
-    static final boolean DEBUG = true; // TODO(b/33197203): set to false once stable
-
-    // TODO(b/33197203): check for device's memory size instead of DEBUG?
-    static final boolean DEBUG_PENDING_CALLBACKS = DEBUG;
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
@@ -79,85 +69,33 @@
 
     // Internal bundle keys.
     /** @hide */ public static final String KEY_CALLBACK = "callback";
-    /** @hide */ public static final String KEY_SAVABLE_IDS = "savable_ids";
-    /** @hide */ public static final String EXTRA_CRYPTO_OBJECT_ID = "crypto_object_id";
-
-    // Prefix for public bundle keys.
-    private static final String KEY_PREFIX = "android.service.autofill.extra.";
-
-    /**
-     * Key of the {@link Bundle} passed to methods such as
-     * {@link #onSaveRequest(AssistStructure, Bundle, SaveCallback)} containing the extras set by
-     * {@link android.view.autofill.FillResponse.Builder#setExtras(Bundle)}.
-     */
-    public static final String EXTRA_RESPONSE_EXTRAS = KEY_PREFIX + "RESPONSE_EXTRAS";
-
-    /**
-     * Key of the {@link Bundle} passed to methods such as
-     * {@link #onSaveRequest(AssistStructure, Bundle, SaveCallback)} containing the extras set by
-     * {@link android.view.autofill.Dataset.Builder#setExtras(Bundle)}.
-     */
-    public static final String EXTRA_DATASET_EXTRAS = KEY_PREFIX + "DATASET_EXTRAS";
-
-    /**
-     * Used to indicate the user selected an action that requires authentication.
-     */
-    public static final int FLAG_AUTHENTICATION_REQUESTED = 1 << 0;
-
-    /**
-     * Used to indicate the user authentication succeeded.
-     */
-    public static final int FLAG_AUTHENTICATION_SUCCESS = 1 << 1;
-
-    /**
-     * Used to indicate the user authentication failed.
-     */
-    public static final int FLAG_AUTHENTICATION_ERROR = 1 << 2;
-
-    /**
-     * Used when the service requested Fingerprint authentication but such option is not available.
-     */
-    public static final int FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE  = 1 << 3;
 
     // Handler messages.
     private static final int MSG_CONNECT = 1;
     private static final int MSG_DISCONNECT = 2;
-    private static final int MSG_AUTO_FILL_ACTIVITY = 3;
-    private static final int MSG_AUTHENTICATE_FILL_RESPONSE = 4;
-    private static final int MSG_AUTHENTICATE_DATASET = 5;
-    private static final int MSG_SAVE = 6;
+    private static final int MSG_ON_FILL_REQUEST = 3;
+    private static final int MSG_ON_SAVE_REQUEST = 4;
 
     private final IAutoFillService mInterface = new IAutoFillService.Stub() {
-
         @Override
-        public void autoFill(AssistStructure structure, IAutoFillServerCallback callback) {
-            mHandlerCaller
-                    .obtainMessageOO(MSG_AUTO_FILL_ACTIVITY, structure, callback)
+        public void onFillRequest(AssistStructure structure, Bundle extras,
+                IFillCallback callback) {
+            ICancellationSignal transport = CancellationSignal.createTransport();
+            try {
+                callback.onCancellable(transport);
+            } catch (RemoteException e) {
+                e.rethrowFromSystemServer();
+            }
+            mHandlerCaller.obtainMessageOOOO(MSG_ON_FILL_REQUEST, structure,
+                    CancellationSignal.fromTransport(transport), extras, callback)
                     .sendToTarget();
         }
 
         @Override
-        public void save(AssistStructure structure, IAutoFillServerCallback callback,
-                Bundle extras) throws RemoteException {
-            mHandlerCaller
-                    .obtainMessageOOO(MSG_SAVE, structure, callback, extras)
-                    .sendToTarget();
-        }
-
-        @Override
-        public void authenticateFillResponse(Bundle extras, int flags) {
-            final Message msg = mHandlerCaller.obtainMessage(MSG_AUTHENTICATE_FILL_RESPONSE);
-            msg.arg1 = flags;
-            msg.obj = extras;
-            mHandlerCaller.sendMessage(msg);
-        }
-
-        @Override
-        public void authenticateDataset(Bundle extras, int flags) {
-            final Message msg = mHandlerCaller.obtainMessage(MSG_AUTHENTICATE_DATASET);
-            msg.arg1 = flags;
-            msg.obj = extras;
-            mHandlerCaller.sendMessage(msg);
+        public void onSaveRequest(AssistStructure structure, Bundle extras,
+                ISaveCallback callback) {
+            mHandlerCaller.obtainMessageOOO(MSG_ON_SAVE_REQUEST, structure,
+                    extras, callback).sendToTarget();
         }
 
         @Override
@@ -171,63 +109,41 @@
         }
     };
 
-    private final HandlerCaller.Callback mHandlerCallback = new HandlerCaller.Callback() {
-
-        @Override
-        public void executeMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_CONNECT: {
-                    onConnected();
-                    break;
-                } case MSG_AUTO_FILL_ACTIVITY: {
-                    final SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        final AssistStructure structure = (AssistStructure) args.arg1;
-                        final IAutoFillServerCallback callback =
-                                (IAutoFillServerCallback) args.arg2;
-                        handleAutoFill(structure, callback);
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                } case MSG_SAVE: {
-                    final SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        final AssistStructure structure = (AssistStructure) args.arg1;
-                        final IAutoFillServerCallback callback =
-                                (IAutoFillServerCallback) args.arg2;
-                        final Bundle extras = (Bundle) args.arg3;
-                        handleSave(structure, callback, extras);
-                    } finally {
-                        args.recycle();
-                    }
-                    break;
-                } case MSG_AUTHENTICATE_FILL_RESPONSE: {
-                    final int flags = msg.arg1;
-                    final Bundle extras = (Bundle) msg.obj;
-                    onFillResponseAuthenticationRequest(extras, flags);
-                    break;
-                } case MSG_AUTHENTICATE_DATASET: {
-                    final int flags = msg.arg1;
-                    final Bundle extras = (Bundle) msg.obj;
-                    onDatasetAuthenticationRequest(extras, flags);
-                    break;
-                } case MSG_DISCONNECT: {
-                    onDisconnected();
-                    break;
-                } default: {
-                    Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
-                }
+    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
+        switch (msg.what) {
+            case MSG_CONNECT: {
+                onConnected();
+                break;
+            } case MSG_ON_FILL_REQUEST: {
+                final SomeArgs args = (SomeArgs) msg.obj;
+                final AssistStructure structure = (AssistStructure) args.arg1;
+                final CancellationSignal cancellation = (CancellationSignal) args.arg2;
+                final Bundle extras = (Bundle) args.arg3;
+                final IFillCallback callback = (IFillCallback) args.arg4;
+                final FillCallback fillCallback = new FillCallback(callback);
+                args.recycle();
+                onFillRequest(structure, extras, cancellation, fillCallback);
+                break;
+            } case MSG_ON_SAVE_REQUEST: {
+                final SomeArgs args = (SomeArgs) msg.obj;
+                final AssistStructure structure = (AssistStructure) args.arg1;
+                final Bundle extras = (Bundle) args.arg2;
+                final ISaveCallback callback = (ISaveCallback) args.arg3;
+                final SaveCallback saveCallback = new SaveCallback(callback);
+                args.recycle();
+                onSaveRequest(structure, extras, saveCallback);
+                break;
+            } case MSG_DISCONNECT: {
+                onDisconnected();
+                break;
+            } default: {
+                Log.w(TAG, "MyCallbacks received invalid message type: " + msg);
             }
         }
     };
 
     private HandlerCaller mHandlerCaller;
 
-    // User for debugging purposes
-    private final List<CallbackHelper.Dumpable> mPendingCallbacks =
-            DEBUG_PENDING_CALLBACKS ? new ArrayList<>() : null;
-
     /**
      * {@inheritDoc}
      *
@@ -236,7 +152,6 @@
     @Override
     public void onCreate() {
         super.onCreate();
-
         mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
     }
 
@@ -255,7 +170,7 @@
      * <p>You should generally do initialization here rather than in {@link #onCreate}.
      */
     public void onConnected() {
-        if (DEBUG) Log.d(TAG, "onConnected()");
+
     }
 
     /**
@@ -267,14 +182,18 @@
      * to notify the result of the request.
      *
      * @param structure {@link Activity}'s view structure.
-     * @param data bundle containing additional arguments set by the Android system (currently none)
-     * or data passed by the service on previous calls to fullfill other sections of this activity
-     * (see {@link FillResponse} Javadoc for examples of multiple-sections requests).
-     * @param cancellationSignal signal for observing cancel requests.
+     * @param data bundle containing data passed by the service on previous calls to fill.
+     *     This bundle allows your service to keep state between fill and save requests
+     *     as well as when filling different sections of the UI as the system will try to
+     *     aggressively unbind from the service to conserve resources. See {@link FillResponse}
+     *     Javadoc for examples of multiple-sections requests.
+     * @param cancellationSignal signal for observing cancellation requests. The system will use
+     *     this to notify you that the fill result is no longer needed and you should stop
+     *     handling this fill request in order to save resources.
      * @param callback object used to notify the result of the request.
      */
-    public abstract void onFillRequest(AssistStructure structure, Bundle data,
-            CancellationSignal cancellationSignal, FillCallback callback);
+    public abstract void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
+            @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback);
 
     /**
      * Called when user requests service to save the fields of an {@link Activity}.
@@ -284,108 +203,15 @@
      * to notify the result of the request.
      *
      * @param structure {@link Activity}'s view structure.
-     * @param data bundle containing additional arguments set by the Android system (currently none)
-     * or data passed by the service in the {@link FillResponse} that originated this call.
+     * @param data bundle containing data passed by the service on previous calls to fill.
+     *     This bundle allows your service to keep state between fill and save requests
+     *     as well as when filling different sections of the UI as the system will try to
+     *     aggressively unbind from the service to conserve resources. See {@link FillResponse}
+     *     Javadoc for examples of multiple-sections requests.
      * @param callback object used to notify the result of the request.
      */
-    public abstract void onSaveRequest(AssistStructure structure, Bundle data,
-            SaveCallback callback);
-
-    /**
-     * Called as result of the user action for a {@link FillResponse} that required authentication.
-     *
-     * <p>When the {@link FillResponse} required authentication through
-     * {@link android.view.autofill.FillResponse.Builder#requiresCustomAuthentication(Bundle, int)},
-     * this call indicates the user is requesting the service to authenticate him/her (and
-     * {@code flags} contains {@link #FLAG_AUTHENTICATION_REQUESTED}), and {@code extras} contains
-     * the {@link Bundle} passed to that method.
-     *
-     * <p>When the {@link FillResponse} required authentication through
-     * {@link android.view.autofill.FillResponse.Builder#requiresFingerprintAuthentication(
-     * android.hardware.fingerprint.FingerprintManager.CryptoObject, Bundle, int)},
-     * {@code flags} this call contains the result of the fingerprint authentication (such as
-     * {@link #FLAG_AUTHENTICATION_SUCCESS}, {@link #FLAG_AUTHENTICATION_ERROR}, and
-     * {@link #FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}) and {@code extras} contains the
-     * {@link Bundle} passed to that method.
-     */
-    public void onFillResponseAuthenticationRequest(@SuppressWarnings("unused") Bundle extras,
-            int flags) {
-        if (DEBUG) Log.d(TAG, "onFillResponseAuthenticationRequest(): flags=" + flags);
-    }
-
-    /**
-     * Called as result of the user action for a {@link Dataset} that required authentication.
-     *
-     * <p>When the {@link Dataset} required authentication through
-     * {@link android.view.autofill.Dataset.Builder#requiresCustomAuthentication(Bundle, int)}, this
-     * call indicates the user is requesting the service to authenticate him/her (and {@code flags}
-     * contains {@link #FLAG_AUTHENTICATION_REQUESTED}), and {@code extras} contains the
-     * {@link Bundle} passed to that method.
-     *
-     * <p>When the {@link Dataset} required authentication through
-     * {@link android.view.autofill.Dataset.Builder#requiresFingerprintAuthentication(
-     * android.hardware.fingerprint.FingerprintManager.CryptoObject, Bundle, int)},
-     * {@code flags} this call contains the result of the fingerprint authentication (such as
-     * {@link #FLAG_AUTHENTICATION_SUCCESS}, {@link #FLAG_AUTHENTICATION_ERROR}, and
-     * {@link #FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}) and {@code extras} contains the
-     * {@link Bundle} passed to that method.
-     */
-    public void onDatasetAuthenticationRequest(@SuppressWarnings("unused") Bundle extras,
-            int flags) {
-        if (DEBUG) Log.d(TAG, "onDatasetAuthenticationRequest(): flags=" + flags);
-    }
-
-    @Override
-    @CallSuper
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mPendingCallbacks != null) {
-            pw.print("Number of pending callbacks: "); pw.println(mPendingCallbacks.size());
-            final String prefix = "  ";
-            for (int i = 0; i < mPendingCallbacks.size(); i++) {
-                final CallbackHelper.Dumpable cb = mPendingCallbacks.get(i);
-                pw.print('#'); pw.print(i + 1); pw.println(':');
-                cb.dump(prefix, pw);
-            }
-            pw.println();
-        } else {
-            pw.println("Dumping disabled");
-        }
-    }
-
-    private void handleAutoFill(AssistStructure structure, IAutoFillServerCallback callback) {
-        final FillCallback fillCallback = new FillCallback(callback);
-        if (DEBUG_PENDING_CALLBACKS) {
-            addPendingCallback(fillCallback);
-        }
-        // TODO(b/33197203): hook up the cancelationSignal
-        onFillRequest(structure, null, new CancellationSignal(), fillCallback);
-        return;
-    }
-
-    private void handleSave(AssistStructure structure, IAutoFillServerCallback callback,
-            Bundle extras) {
-        final SaveCallback saveCallback = new SaveCallback(callback);
-        if (DEBUG_PENDING_CALLBACKS) {
-            addPendingCallback(saveCallback);
-        }
-        onSaveRequest(structure, extras, saveCallback);
-    }
-
-    private void addPendingCallback(CallbackHelper.Dumpable callback) {
-        if (mPendingCallbacks == null) {
-            // Shouldn't happend since call is controlled by DEBUG_PENDING_CALLBACKS guard.
-            Log.wtf(TAG, "addPendingCallback(): mPendingCallbacks not set");
-            return;
-        }
-
-        if (DEBUG) Log.d(TAG, "Adding pending callback: " + callback);
-
-        callback.setFinalizer(() -> {
-            if (DEBUG) Log.d(TAG, "Removing pending callback: " + callback);
-            mPendingCallbacks.remove(callback);
-        });
-        mPendingCallbacks.add(callback);
-    }
+    public abstract void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle data,
+            @NonNull SaveCallback callback);
 
     /**
      * Called when the Android system disconnects from the service.
@@ -393,6 +219,6 @@
      * <p> At this point this service may no longer be an active {@link AutoFillService}.
      */
     public void onDisconnected() {
-        if (DEBUG) Log.d(TAG, "onDisconnected()");
+
     }
 }
diff --git a/core/java/android/service/autofill/AutoFillServiceInfo.java b/core/java/android/service/autofill/AutoFillServiceInfo.java
index fd957f1..985e32f 100644
--- a/core/java/android/service/autofill/AutoFillServiceInfo.java
+++ b/core/java/android/service/autofill/AutoFillServiceInfo.java
@@ -16,6 +16,7 @@
 package android.service.autofill;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.AppGlobals;
 import android.content.ComponentName;
@@ -25,7 +26,6 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.os.RemoteException;
-import android.util.AndroidException;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Xml;
@@ -40,13 +40,10 @@
 /**
  * {@link ServiceInfo} and meta-data about an {@link AutoFillService}.
  *
- * <p>Upon construction, if {@link #getParseError()} is {@code null}, then the service is configured
- * correctly. Otherwise, {@link #getParseError()} indicates the parsing error.
- *
  * @hide
  */
 public final class AutoFillServiceInfo {
-    static final String TAG = "AutoFillServiceInfo";
+    private static final String TAG = "AutoFillServiceInfo";
 
     private static ServiceInfo getServiceInfoOrThrow(ComponentName comp, int userHandle)
             throws PackageManager.NameNotFoundException {
@@ -63,10 +60,9 @@
         throw new PackageManager.NameNotFoundException(comp.toString());
     }
 
-    @Nullable
-    private final String mParseError;
-
+    @NonNull
     private final ServiceInfo mServiceInfo;
+
     @Nullable
     private final String mSettingsActivity;
 
@@ -77,17 +73,7 @@
 
     public AutoFillServiceInfo(PackageManager pm, ServiceInfo si) {
         mServiceInfo = si;
-        TypedArray metaDataArray;
-        try {
-            metaDataArray = getMetaDataArray(pm, si);
-        } catch (AndroidException e) {
-            mParseError = e.getMessage();
-            mSettingsActivity = null;
-            Log.w(TAG, mParseError, e);
-            return;
-        }
-
-        mParseError = null;
+        final TypedArray metaDataArray = getMetaDataArray(pm, si);
         if (metaDataArray != null) {
             mSettingsActivity =
                     metaDataArray.getString(R.styleable.AutoFillService_settingsActivity);
@@ -101,12 +87,11 @@
      * Gets the meta-data as a TypedArray, or null if not provided, or throws if invalid.
      */
     @Nullable
-    private static TypedArray getMetaDataArray(PackageManager pm, ServiceInfo si)
-            throws AndroidException {
+    private static TypedArray getMetaDataArray(PackageManager pm, ServiceInfo si) {
         // Check for permissions.
         if (!Manifest.permission.BIND_AUTO_FILL.equals(si.permission)) {
-            throw new AndroidException(
-                "Service does not require permission " + Manifest.permission.BIND_AUTO_FILL);
+            Log.e(TAG, "Service does not require permission " + Manifest.permission.BIND_AUTO_FILL);
+            return null;
         }
 
         // Get the AutoFill metadata, if declared.
@@ -125,11 +110,13 @@
                         && type != XmlPullParser.START_TAG) {
                 }
             } catch (XmlPullParserException | IOException e) {
-                throw new AndroidException("Error parsing auto fill service meta-data: " + e, e);
+                Log.e(TAG, "Error parsing auto fill service meta-data", e);
+                return null;
             }
 
             if (!"autofill-service".equals(parser.getName())) {
-                throw new AndroidException("Meta-data does not start with autofill-service tag");
+                Log.e(TAG, "Meta-data does not start with autofill-service tag");
+                return null;
             }
             attrs = Xml.asAttributeSet(parser);
 
@@ -138,7 +125,8 @@
             try {
                 res = pm.getResourcesForApplication(si.applicationInfo);
             } catch (PackageManager.NameNotFoundException e) {
-                throw new AndroidException("Error getting application resources: " + e, e);
+                Log.e(TAG, "Error getting application resources", e);
+                return null;
             }
 
             return res.obtainAttributes(attrs, R.styleable.AutoFillService);
@@ -147,11 +135,6 @@
         }
     }
 
-    @Nullable
-    public String getParseError() {
-        return mParseError;
-    }
-
     public ServiceInfo getServiceInfo() {
         return mServiceInfo;
     }
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index 7cab7ae..a306809 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -16,56 +16,32 @@
 
 package android.service.autofill;
 
-import static android.service.autofill.AutoFillService.DEBUG;
-import static android.util.DebugUtils.flagsToString;
-
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.os.RemoteException;
-import android.service.autofill.CallbackHelper.Dumpable;
-import android.service.autofill.CallbackHelper.Finalizer;
-import android.util.Log;
-import android.view.autofill.Dataset;
 import android.view.autofill.FillResponse;
 
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
-
-import java.io.PrintWriter;
-
 /**
  * Handles auto-fill requests from the {@link AutoFillService} into the {@link Activity} being
  * auto-filled.
- *
- * <p>This class is thread safe.
  */
-public final class FillCallback implements Dumpable {
-
-    private static final String TAG = "FillCallback";
-
-    // NOTE: constants below are public so they can be used by flagsToString()
-    /** @hide */ public static final int STATE_INITIAL = 1 << 0;
-    /** @hide */ public static final int STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE = 1 << 1;
-    /** @hide */ public static final int STATE_WAITING_DATASET_AUTH_RESPONSE = 1 << 2;
-    /** @hide */ public static final int STATE_FINISHED_OK = 1 << 3;
-    /** @hide */ public static final int STATE_FINISHED_FAILURE = 1 << 4;
-    /** @hide */ public static final int STATE_FINISHED_ERROR = 1 << 5;
-    /** @hide */ public static final int STATE_FINISHED_AUTHENTICATED = 1 << 6;
-
-    private final IAutoFillServerCallback mCallback;
-
-    @GuardedBy("mCallback")
-    private int mState = STATE_INITIAL;
-
-    @GuardedBy("mCallback")
-    private Finalizer mFinalizer;
+public final class FillCallback implements Parcelable {
+    private final IFillCallback mCallback;
+    private boolean mCalled;
 
     /** @hide */
-    FillCallback(IAutoFillServerCallback callback) {
+    public FillCallback(IFillCallback callback) {
         mCallback = callback;
     }
 
+    /** @hide */
+    private FillCallback(Parcel parcel) {
+        mCallback = IFillCallback.Stub.asInterface(parcel.readStrongBinder());
+    }
+
     /**
      * Notifies the Android System that an
      * {@link AutoFillService#onFillRequest(android.app.assist.AssistStructure, Bundle,
@@ -76,43 +52,12 @@
      * {@link FillResponse} for examples.
      */
     public void onSuccess(@Nullable FillResponse response) {
-        final boolean authRequired = response != null && response.isAuthRequired();
-
-        if (DEBUG) Log.d(TAG, "onSuccess(): authReq= " + authRequired + ", resp=" + response);
-
-        synchronized (mCallback) {
-            if (authRequired) {
-                assertOnStateLocked(STATE_INITIAL);
-            } else {
-                assertOnStateLocked(STATE_INITIAL | STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE
-                        | STATE_WAITING_DATASET_AUTH_RESPONSE);
-            }
-
-            try {
-                mCallback.showResponse(response);
-                if (authRequired) {
-                    mState = STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE;
-                } else {
-                    // Check if at least one dataset requires authentication.
-                    boolean waitingAuth = false;
-                    if (response != null) {
-                        for (Dataset dataset : response.getDatasets()) {
-                            if (dataset.isAuthRequired()) {
-                                waitingAuth = true;
-                                break;
-                            }
-                        }
-                    }
-                    if (waitingAuth) {
-                        mState = STATE_WAITING_DATASET_AUTH_RESPONSE;
-                    } else {
-                        setFinalStateLocked(STATE_FINISHED_OK);
-                    }
-                }
-            } catch (RemoteException e) {
-                setFinalStateLocked(STATE_FINISHED_ERROR);
-                e.rethrowAsRuntimeException();
-            }
+        assertNotCalled();
+        mCalled = true;
+        try {
+            mCallback.onSuccess(response);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
         }
     }
 
@@ -124,118 +69,43 @@
      *
      * @param message error message to be displayed to the user.
      */
-    public void onFailure(CharSequence message) {
-        if (DEBUG) Log.d(TAG, "onFailure(): message=" + message);
-
-        Preconditions.checkArgument(message != null, "message cannot be null");
-
-        synchronized (mCallback) {
-            assertOnStateLocked(STATE_INITIAL | STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE
-                    | STATE_WAITING_DATASET_AUTH_RESPONSE);
-
-            try {
-                mCallback.showError(message);
-                setFinalStateLocked(STATE_FINISHED_FAILURE);
-            } catch (RemoteException e) {
-                setFinalStateLocked(STATE_FINISHED_ERROR);
-                e.rethrowAsRuntimeException();
-            }
+    public void onFailure(@Nullable CharSequence message) {
+        assertNotCalled();
+        mCalled = true;
+        try {
+            mCallback.onFailure(message);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
         }
     }
 
-    /**
-     * Notifies the Android System when the user authenticated a {@link FillResponse} previously
-     * passed to {@link #onSuccess(FillResponse)}.
-     *
-     * @param flags must contain either
-     * {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} or
-     * {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS}.
-     */
-    public void onFillResponseAuthentication(int flags) {
-        if (DEBUG) Log.d(TAG, "onFillResponseAuthentication(): flags=" + flags);
-
-        synchronized (mCallback) {
-            assertOnStateLocked(STATE_WAITING_FILL_RESPONSE_AUTH_RESPONSE);
-
-            try {
-                mCallback.unlockFillResponse(flags);
-                setFinalStateLocked(STATE_FINISHED_AUTHENTICATED);
-            } catch (RemoteException e) {
-                setFinalStateLocked(STATE_FINISHED_ERROR);
-                e.rethrowAsRuntimeException();
-            }
-        }
-    }
-
-    /**
-     * Notifies the Android System when the user authenticated a {@link Dataset} previously passed
-     * to {@link #onSuccess(FillResponse)}.
-     *
-     * @param dataset values to fill the activity with in case of successful authentication of a
-     * previously locked (and empty) dataset).
-     * @param flags must contain either
-     * {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} or
-     * {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS}.
-     */
-    public void onDatasetAuthentication(@Nullable Dataset dataset, int flags) {
-        if (DEBUG) Log.d(TAG, "onDatasetAuthentication(): dataset=" + dataset + ", flags=" + flags);
-
-        synchronized (mCallback) {
-            assertOnStateLocked(STATE_WAITING_DATASET_AUTH_RESPONSE);
-
-            try {
-                mCallback.unlockDataset(dataset, flags);
-                setFinalStateLocked(STATE_FINISHED_AUTHENTICATED);
-            } catch (RemoteException e) {
-                setFinalStateLocked(STATE_FINISHED_ERROR);
-                e.rethrowAsRuntimeException();
-            }
-        }
-    }
-
-    @Override
-    public String toString() {
-        if (!DEBUG) return super.toString();
-
-        return "FillCallback: [mState = " + mState + "]";
-    }
-
     /** @hide */
     @Override
-    public void dump(String prefix, PrintWriter pw) {
-        pw.print(prefix); pw.print("FillCallback: mState="); pw.println(mState);
+    public int describeContents() {
+        return 0;
     }
 
     /** @hide */
     @Override
-    public void setFinalizer(Finalizer f) {
-        synchronized (mCallback) {
-            mFinalizer = f;
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeStrongBinder(mCallback.asBinder());
+    }
+
+    private void assertNotCalled() {
+        if (mCalled) {
+            throw new IllegalStateException("Already called");
         }
     }
 
-    /**
-     * Sets a final state (where the callback cannot be used anymore) and notifies the
-     * {@link Finalizer} (if any).
-     */
-    private void setFinalStateLocked(int state) {
-        if (DEBUG) Log.d(TAG, "setFinalState(): " + state);
-        mState = state;
-
-        if (mFinalizer != null) {
-            mFinalizer.gone();
+    public static final Creator<FillCallback> CREATOR = new Creator<FillCallback>() {
+        @Override
+        public FillCallback createFromParcel(Parcel parcel) {
+            return new FillCallback(parcel);
         }
-    }
 
-    // TODO(b/33197203): move and/or re-add state check logic on server side to avoid malicious app
-    // calling the callback on wrong state.
-
-    // Make sure callback method is called during the proper lifecycle state.
-    private void assertOnStateLocked(int flags) {
-        if (DEBUG) Log.d(TAG, "assertOnState(): current=" + mState + ", required=" + flags);
-
-        Preconditions.checkState((flags & mState) != 0,
-                "invalid state: required " + flagsToString(FillCallback.class, "STATE_", flags)
-                + ", current is " + flagsToString(FillCallback.class, "STATE_", mState));
-    }
+        @Override
+        public FillCallback[] newArray(int size) {
+            return new FillCallback[size];
+        }
+    };
 }
diff --git a/core/java/android/service/autofill/IAutoFillAppCallback.aidl b/core/java/android/service/autofill/IAutoFillAppCallback.aidl
index 8c3898a..d9c161c 100644
--- a/core/java/android/service/autofill/IAutoFillAppCallback.aidl
+++ b/core/java/android/service/autofill/IAutoFillAppCallback.aidl
@@ -18,6 +18,8 @@
 
 import java.util.List;
 
+import android.content.Intent;
+import android.content.IntentSender;
 import android.view.autofill.Dataset;
 
 /**
@@ -31,4 +33,9 @@
       * Auto-fills the activity with the contents of a dataset.
       */
     void autoFill(in Dataset dataset);
+
+    /**
+      * Start an intent sender from the context of the filled app
+      */
+    void startIntentSender(in IntentSender intent, in Intent fillInIntent);
 }
diff --git a/core/java/android/service/autofill/IAutoFillServerCallback.aidl b/core/java/android/service/autofill/IAutoFillServerCallback.aidl
deleted file mode 100644
index 480438a..0000000
--- a/core/java/android/service/autofill/IAutoFillServerCallback.aidl
+++ /dev/null
@@ -1,39 +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.service.autofill;
-
-import java.util.List;
-
-import android.os.Bundle;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.Dataset;
-import android.view.autofill.FillResponse;
-
-/**
- * Object running in the AutoFillService process and used to communicate back with system_server.
- *
- * @hide
- */
-// TODO(b/33197203): rename to IAutoFillServerSession
-oneway interface IAutoFillServerCallback {
-    // TODO(b/33197203): document methods
-    void showResponse(in FillResponse response);
-    void showError(CharSequence message);
-    void onSaved();
-    void unlockFillResponse(int flags);
-    void unlockDataset(in Dataset dataset, int flags);
-}
diff --git a/core/java/android/service/autofill/IAutoFillService.aidl b/core/java/android/service/autofill/IAutoFillService.aidl
index a4e6ebc..fa1ea65 100644
--- a/core/java/android/service/autofill/IAutoFillService.aidl
+++ b/core/java/android/service/autofill/IAutoFillService.aidl
@@ -18,19 +18,20 @@
 
 import android.app.assist.AssistStructure;
 import android.os.Bundle;
-import android.service.autofill.IAutoFillServerCallback;
+import android.service.autofill.IFillCallback;
+import android.service.autofill.ISaveCallback;
 import com.android.internal.os.IResultReceiver;
 
 /**
+ * Interface from the system to an auto fill service.
+ *
  * @hide
  */
-// TODO(b/33197203): document class and methods
 oneway interface IAutoFillService {
-    // TODO(b/33197203): rename method to make them more consistent
-    void autoFill(in AssistStructure structure, in IAutoFillServerCallback callback);
-    void save(in AssistStructure structure, in IAutoFillServerCallback callback, in Bundle extras);
-    void authenticateFillResponse(in Bundle extras, int flags);
-    void authenticateDataset(in Bundle extras, int flags);
+    void onFillRequest(in AssistStructure structure, in Bundle extras,
+            in IFillCallback callback);
+    void onSaveRequest(in AssistStructure structure, in Bundle extras,
+            in ISaveCallback callback);
     void onConnected();
     void onDisconnected();
 }
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/service/autofill/IFillCallback.aidl
similarity index 66%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/android/service/autofill/IFillCallback.aidl
index ded8f97..537403e 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/service/autofill/IFillCallback.aidl
@@ -13,18 +13,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package android.service.autofill;
 
-import java.io.PrintWriter;
+import android.os.ICancellationSignal;
 
-final class CallbackHelper {
+import android.view.autofill.FillResponse;
 
-    static interface Dumpable {
-        void dump(String prefix, PrintWriter pw);
-        void setFinalizer(Finalizer f);
-    }
-
-    static interface Finalizer {
-        void gone();
-    }
+/**
+ * Interface to receive the result of a save request.
+ *
+ * @hide
+ */
+interface IFillCallback {
+    void onCancellable(in ICancellationSignal cancellation);
+    void onSuccess(in FillResponse response);
+    void onFailure(CharSequence message);
 }
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/android/service/autofill/ISaveCallback.aidl
similarity index 72%
rename from core/java/android/service/autofill/CallbackHelper.java
rename to core/java/android/service/autofill/ISaveCallback.aidl
index ded8f97..e260c73 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/android/service/autofill/ISaveCallback.aidl
@@ -13,18 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package android.service.autofill;
 
-import java.io.PrintWriter;
-
-final class CallbackHelper {
-
-    static interface Dumpable {
-        void dump(String prefix, PrintWriter pw);
-        void setFinalizer(Finalizer f);
-    }
-
-    static interface Finalizer {
-        void gone();
-    }
+/**
+ * Interface to receive the result of a save request.
+ *
+ * @hide
+ */
+interface ISaveCallback {
+    void onSuccess();
+    void onFailure(CharSequence message);
 }
diff --git a/core/java/android/service/autofill/SaveCallback.java b/core/java/android/service/autofill/SaveCallback.java
index 9dd9795..46b3072 100644
--- a/core/java/android/service/autofill/SaveCallback.java
+++ b/core/java/android/service/autofill/SaveCallback.java
@@ -16,21 +16,9 @@
 
 package android.service.autofill;
 
-import static android.service.autofill.AutoFillService.DEBUG;
-
 import android.app.Activity;
-import android.app.assist.AssistStructure.ViewNode;
 import android.os.Bundle;
 import android.os.RemoteException;
-import android.service.autofill.CallbackHelper.Dumpable;
-import android.service.autofill.CallbackHelper.Finalizer;
-import android.util.Log;
-import android.view.autofill.AutoFillId;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
-
-import java.io.PrintWriter;
 
 /**
  * Handles save requests from the {@link AutoFillService} into the {@link Activity} being
@@ -38,20 +26,12 @@
  *
  * <p>This class is thread safe.
  */
-public final class SaveCallback implements Dumpable {
-
-    private static final String TAG = "SaveCallback";
-
-    private final IAutoFillServerCallback mCallback;
-
-    @GuardedBy("mCallback")
-    private boolean mReplied = false;
-
-    @GuardedBy("mCallback")
-    private Finalizer mFinalizer;
+public final class SaveCallback {
+    private final ISaveCallback mCallback;
+    private boolean mCalled;
 
     /** @hide */
-    SaveCallback(IAutoFillServerCallback callback) {
+    SaveCallback(ISaveCallback callback) {
         mCallback = callback;
     }
 
@@ -63,17 +43,12 @@
      * @throws RuntimeException if an error occurred while calling the Android System.
      */
     public void onSuccess() {
-        if (DEBUG) Log.d(TAG, "onSuccess()");
-
-        synchronized (mCallback) {
-            checkNotRepliedYetLocked();
-            try {
-                mCallback.onSaved();
-            } catch (RemoteException e) {
-                e.rethrowAsRuntimeException();
-            } finally {
-                setRepliedLocked();
-            }
+        assertNotCalled();
+        mCalled = true;
+        try {
+            mCallback.onSuccess();
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
         }
     }
 
@@ -87,54 +62,18 @@
      * @throws RuntimeException if an error occurred while calling the Android System.
      */
     public void onFailure(CharSequence message) {
-        if (DEBUG) Log.d(TAG, "onFailure(): message=" + message);
-
-        synchronized (mCallback) {
-            checkNotRepliedYetLocked();
-
-            try {
-                mCallback.showError(message);
-            } catch (RemoteException e) {
-                e.rethrowAsRuntimeException();
-            } finally {
-                setRepliedLocked();
-            }
+        assertNotCalled();
+        mCalled = true;
+        try {
+            mCallback.onFailure(message);
+        } catch (RemoteException e) {
+            e.rethrowAsRuntimeException();
         }
     }
 
-    /** @hide */
-    @Override
-    public void dump(String prefix, PrintWriter pw) {
-        pw.print(prefix); pw.print("SaveCallback: mReplied="); pw.println(mReplied);
-    }
-
-    /** @hide */
-    @Override
-    public void setFinalizer(Finalizer f) {
-        synchronized (mCallback) {
-            mFinalizer = f;
-        }
-    }
-
-    @Override
-    public String toString() {
-        if (!DEBUG) return super.toString();
-
-        return "SaveCallback: [mReplied= " + mReplied + "]";
-    }
-
-    // There can be only one!!
-    private void checkNotRepliedYetLocked() {
-        Preconditions.checkState(!mReplied, "already replied");
-    }
-
-    private void setRepliedLocked() {
-        if (DEBUG) Log.d(TAG, "setReplied()");
-
-        mReplied = true;
-
-        if (mFinalizer != null) {
-            mFinalizer.gone();
+    private void assertNotCalled() {
+        if (mCalled) {
+            throw new IllegalStateException("Already called");
         }
     }
 }
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 887f4b6..1781c2a 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -130,6 +130,11 @@
      */
     public static final String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
 
+    /**
+     * @hide
+     */
+    public static final String EXTRA_STATE = "state";
+
     private final H mHandler = new H(Looper.getMainLooper());
 
     private boolean mListening = false;
diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl
index 62ecab3..10e4177 100644
--- a/core/java/android/service/vr/IVrManager.aidl
+++ b/core/java/android/service/vr/IVrManager.aidl
@@ -42,5 +42,13 @@
      */
     boolean getVrModeState();
 
+    /**
+     * 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.
+     *
+     * @param enabled true if the device should be placed in persistent VR mode.
+     */
+    void setPersistentVrModeEnabled(in boolean enabled);
 }
 
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index bb952ab..55aeb1e 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -62,6 +62,7 @@
 
 import com.android.internal.R;
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Preconditions;
 
 import java.lang.reflect.Array;
 import java.util.Iterator;
@@ -466,6 +467,16 @@
         return isEmpty(str) ? null : str;
     }
 
+    /** {@hide} */
+    public static String emptyIfNull(@Nullable String str) {
+        return str == null ? "" : str;
+    }
+
+    /** {@hide} */
+    public static String firstNotEmpty(@Nullable String a, @NonNull String b) {
+        return !isEmpty(a) ? a : Preconditions.checkStringNotEmpty(b);
+    }
+
     /**
      * Returns the length that the specified CharSequence would have if
      * spaces and ASCII control characters were trimmed from the start and end,
diff --git a/core/java/android/transition/ChangeTransform.java b/core/java/android/transition/ChangeTransform.java
index 4b0b065..584c114 100644
--- a/core/java/android/transition/ChangeTransform.java
+++ b/core/java/android/transition/ChangeTransform.java
@@ -465,7 +465,7 @@
         }
     }
 
-    private static class GhostListener extends Transition.TransitionListenerAdapter {
+    private static class GhostListener extends TransitionListenerAdapter {
         private View mView;
         private View mStartView;
         private GhostView mGhostView;
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index 8823605..af2547e 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -2342,34 +2342,6 @@
     }
 
     /**
-     * Utility adapter class to avoid having to override all three methods
-     * whenever someone just wants to listen for a single event.
-     *
-     * @hide
-     * */
-    public static class TransitionListenerAdapter implements TransitionListener {
-        @Override
-        public void onTransitionStart(Transition transition) {
-        }
-
-        @Override
-        public void onTransitionEnd(Transition transition) {
-        }
-
-        @Override
-        public void onTransitionCancel(Transition transition) {
-        }
-
-        @Override
-        public void onTransitionPause(Transition transition) {
-        }
-
-        @Override
-        public void onTransitionResume(Transition transition) {
-        }
-    }
-
-    /**
      * Holds information about each animator used when a new transition starts
      * while other transitions are still running to determine whether a running
      * animation should be canceled or a new animation noop'd. The structure holds
diff --git a/core/java/android/transition/TransitionListenerAdapter.java b/core/java/android/transition/TransitionListenerAdapter.java
new file mode 100644
index 0000000..c217949
--- /dev/null
+++ b/core/java/android/transition/TransitionListenerAdapter.java
@@ -0,0 +1,61 @@
+/*
+ * 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.transition;
+
+/**
+ * This adapter class provides empty implementations of the methods from {@link
+ * android.transition.Transition.TransitionListener}.
+ * Any custom listener that cares only about a subset of the methods of this listener can
+ * simply subclass this adapter class instead of implementing the interface directly.
+ */
+public abstract class TransitionListenerAdapter implements Transition.TransitionListener {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onTransitionStart(Transition transition) {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onTransitionEnd(Transition transition) {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onTransitionCancel(Transition transition) {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onTransitionPause(Transition transition) {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onTransitionResume(Transition transition) {
+    }
+}
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 6e4d78d..325ff38 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -298,7 +298,7 @@
                 previousRunningTransitions = new ArrayList<Transition>(currentTransitions);
             }
             currentTransitions.add(mTransition);
-            mTransition.addListener(new Transition.TransitionListenerAdapter() {
+            mTransition.addListener(new TransitionListenerAdapter() {
                 @Override
                 public void onTransitionEnd(Transition transition) {
                     ArrayList<Transition> currentTransitions =
diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java
index 0da710a..c3d3f39 100644
--- a/core/java/android/view/NotificationHeaderView.java
+++ b/core/java/android/view/NotificationHeaderView.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import android.annotation.Nullable;
+import android.app.Notification;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Outline;
@@ -39,7 +40,7 @@
  */
 @RemoteViews.RemoteView
 public class NotificationHeaderView extends ViewGroup {
-    public static final int NO_COLOR = -1;
+    public static final int NO_COLOR = Notification.COLOR_INVALID;
     private final int mChildMinWidth;
     private final int mContentEndMargin;
     private View mAppName;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e2eee95..a150529 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -19942,9 +19942,9 @@
      * @return the view of the specified id, null if cannot be found
      * @hide
      */
-    protected <T extends View> T findViewTraversal(@IdRes int id) {
+    protected View findViewTraversal(@IdRes int id) {
         if (id == mID) {
-            return (T) this;
+            return this;
         }
         return null;
     }
@@ -19954,9 +19954,9 @@
      * @return the view of specified tag, null if cannot be found
      * @hide
      */
-    protected <T extends View> T findViewWithTagTraversal(Object tag) {
+    protected View findViewWithTagTraversal(Object tag) {
         if (tag != null && tag.equals(mTag)) {
-            return (T) this;
+            return this;
         }
         return null;
     }
@@ -19967,10 +19967,9 @@
      * @return The first view that matches the predicate or null.
      * @hide
      */
-    protected <T extends View> T findViewByPredicateTraversal(Predicate<View> predicate,
-            View childToSkip) {
+    protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
         if (predicate.apply(this)) {
-            return (T) this;
+            return this;
         }
         return null;
     }
@@ -19983,7 +19982,7 @@
      * @return The view that has the given id in the hierarchy or null
      */
     @Nullable
-    public final <T extends View> T findViewById(@IdRes int id) {
+    public final View findViewById(@IdRes int id) {
         if (id < 0) {
             return null;
         }
@@ -19996,11 +19995,11 @@
      * @param accessibilityId The searched accessibility id.
      * @return The found view.
      */
-    final <T extends View> T  findViewByAccessibilityId(int accessibilityId) {
+    final View findViewByAccessibilityId(int accessibilityId) {
         if (accessibilityId < 0) {
             return null;
         }
-        T view = findViewByAccessibilityIdTraversal(accessibilityId);
+        View view = findViewByAccessibilityIdTraversal(accessibilityId);
         if (view != null) {
             return view.includeForAccessibility() ? view : null;
         }
@@ -20019,11 +20018,12 @@
      *
      * @param accessibilityId The accessibility id.
      * @return The found view.
+     *
      * @hide
      */
-    public <T extends View> T findViewByAccessibilityIdTraversal(int accessibilityId) {
+    public View findViewByAccessibilityIdTraversal(int accessibilityId) {
         if (getAccessibilityViewId() == accessibilityId) {
-            return (T) this;
+            return this;
         }
         return null;
     }
@@ -20035,7 +20035,7 @@
      * @param tag The tag to search for, using "tag.equals(getTag())".
      * @return The View that has the given tag in the hierarchy or null
      */
-    public final <T extends View> T findViewWithTag(Object tag) {
+    public final View findViewWithTag(Object tag) {
         if (tag == null) {
             return null;
         }
@@ -20050,7 +20050,7 @@
      * @return The first view that matches the predicate or null.
      * @hide
      */
-    public final <T extends View> T findViewByPredicate(Predicate<View> predicate) {
+    public final View findViewByPredicate(Predicate<View> predicate) {
         return findViewByPredicateTraversal(predicate, null);
     }
 
@@ -20070,11 +20070,10 @@
      * @return The first view that matches the predicate or null.
      * @hide
      */
-    public final <T extends View> T findViewByPredicateInsideOut(
-            View start, Predicate<View> predicate) {
+    public final View findViewByPredicateInsideOut(View start, Predicate<View> predicate) {
         View childToSkip = null;
         for (;;) {
-            T view = start.findViewByPredicateTraversal(predicate, childToSkip);
+            View view = start.findViewByPredicateTraversal(predicate, childToSkip);
             if (view != null || start == this) {
                 return view;
             }
@@ -24660,7 +24659,7 @@
      * Determine if this view is rendered on a round wearable device and is the main view
      * on the screen.
      */
-    private boolean shouldDrawRoundScrollbar() {
+    boolean shouldDrawRoundScrollbar() {
         if (!mResources.getConfiguration().isScreenRound() || mAttachInfo == null) {
             return false;
         }
@@ -24677,7 +24676,7 @@
             return false;
         }
 
-        getLocationOnScreen(mAttachInfo.mTmpLocation);
+        getLocationInWindow(mAttachInfo.mTmpLocation);
         return mAttachInfo.mTmpLocation[0] == insets.getStableInsetLeft()
                 && mAttachInfo.mTmpLocation[1] == insets.getStableInsetTop();
     }
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index b11b3d7..aa580fa 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -4208,9 +4208,9 @@
      * {@hide}
      */
     @Override
-    protected <T extends View> T findViewTraversal(@IdRes int id) {
+    protected View findViewTraversal(@IdRes int id) {
         if (id == mID) {
-            return (T) this;
+            return this;
         }
 
         final View[] where = mChildren;
@@ -4223,7 +4223,7 @@
                 v = v.findViewById(id);
 
                 if (v != null) {
-                    return (T) v;
+                    return v;
                 }
             }
         }
@@ -4235,9 +4235,9 @@
      * {@hide}
      */
     @Override
-    protected <T extends View> T findViewWithTagTraversal(Object tag) {
+    protected View findViewWithTagTraversal(Object tag) {
         if (tag != null && tag.equals(mTag)) {
-            return (T) this;
+            return this;
         }
 
         final View[] where = mChildren;
@@ -4250,7 +4250,7 @@
                 v = v.findViewWithTag(tag);
 
                 if (v != null) {
-                    return (T) v;
+                    return v;
                 }
             }
         }
@@ -4262,10 +4262,9 @@
      * {@hide}
      */
     @Override
-    protected <T extends View> T findViewByPredicateTraversal(Predicate<View> predicate,
-            View childToSkip) {
+    protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
         if (predicate.apply(this)) {
-            return (T) this;
+            return this;
         }
 
         final View[] where = mChildren;
@@ -4278,7 +4277,7 @@
                 v = v.findViewByPredicate(predicate);
 
                 if (v != null) {
-                    return (T) v;
+                    return v;
                 }
             }
         }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index bf840e5..5a640fa 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -335,7 +335,9 @@
                 @ViewDebug.IntToString(from = TYPE_QS_DIALOG,
                         to = "TYPE_QS_DIALOG"),
                 @ViewDebug.IntToString(from = TYPE_SCREENSHOT,
-                        to = "TYPE_SCREENSHOT")
+                        to = "TYPE_SCREENSHOT"),
+                @ViewDebug.IntToString(from = TYPE_APPLICATION_OVERLAY,
+                        to = "TYPE_APPLICATION_OVERLAY")
         })
         public int type;
 
@@ -462,14 +464,18 @@
          * These windows are normally placed above all applications, but behind
          * the status bar.
          * In multiuser systems shows on all users' windows.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;
 
         /**
          * Window type: system window, such as low power alert. These windows
          * are always on top of application windows.
          * In multiuser systems shows only on the owning user's window.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;
 
         /**
@@ -482,7 +488,9 @@
         /**
          * Window type: transient notifications.
          * In multiuser systems shows only on the owning user's window.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5;
 
         /**
@@ -490,7 +498,9 @@
          * on top of everything else.  These windows must not take input
          * focus, or they will interfere with the keyguard.
          * In multiuser systems shows only on the owning user's window.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6;
 
         /**
@@ -498,7 +508,9 @@
          * the keyguard is active.  These windows must not take input
          * focus, or they will interfere with the keyguard.
          * In multiuser systems shows on all users' windows.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7;
 
         /**
@@ -517,7 +529,9 @@
          * Window type: internal system error windows, appear on top of
          * everything they can.
          * In multiuser systems shows only on the owning user's window.
+         * @deprecated for non-system apps. Use {@link #TYPE_APPLICATION_OVERLAY} instead.
          */
+        @Deprecated
         public static final int TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10;
 
         /**
@@ -703,10 +717,44 @@
         public static final int TYPE_PRESENTATION = FIRST_SYSTEM_WINDOW + 37;
 
         /**
+         * Window type: Application overlay windows are displayed above all activity windows
+         * (types between {@link #FIRST_APPLICATION_WINDOW} and {@link #LAST_APPLICATION_WINDOW})
+         * but below critical system windows like the status bar or IME.
+         * <p>
+         * The system may change the position, size, or visibility of these windows at anytime
+         * to reduce visual clutter to the user and also manage resources.
+         * <p>
+         * Requires {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission.
+         * <p>
+         * In mult-iuser systems shows only on the owning user's screen.
+         */
+        public static final int TYPE_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 38;
+
+        /**
          * End of types of system windows.
          */
         public static final int LAST_SYSTEM_WINDOW      = 2999;
 
+        /**
+         * Return true if the window type is an alert window.
+         *
+         * @param type The window type.
+         * @return If the window type is an alert window.
+         * @hide
+         */
+        public static boolean isSystemAlertWindowType(int type) {
+            switch (type) {
+                case TYPE_PHONE:
+                case TYPE_PRIORITY_PHONE:
+                case TYPE_SYSTEM_ALERT:
+                case TYPE_SYSTEM_ERROR:
+                case TYPE_SYSTEM_OVERLAY:
+                case TYPE_APPLICATION_OVERLAY:
+                    return true;
+            }
+            return false;
+        }
+
         /** @deprecated this is ignored, this value is set automatically when needed. */
         @Deprecated
         public static final int MEMORY_TYPE_NORMAL = 0;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index bc4ae6d..8e597dc 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -16,6 +16,51 @@
 
 package android.view;
 
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
+import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
+import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
+import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
+
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -30,6 +75,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.util.Slog;
 import android.view.animation.Animation;
 
 import com.android.internal.policy.IKeyguardDismissCallback;
@@ -423,6 +469,14 @@
         public boolean isInputMethodWindow();
 
         public int getDisplayId();
+
+        /**
+         * Returns true if the window owner can add internal system windows.
+         * That is, they have {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW}.
+         */
+        default boolean canAddInternalSystemWindow() {
+            return false;
+        }
     }
 
     /**
@@ -659,27 +713,181 @@
             int navigationPresence);
 
     /**
-     * Assign a window type to a layer.  Allows you to control how different
+     * Returns the layer assignment for the window state. Allows you to control how different
+     * kinds of windows are ordered on-screen.
+     *
+     * @param win The window state
+     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
+     */
+    default int getWindowLayerLw(WindowState win) {
+        return getWindowLayerFromTypeLw(win.getBaseType(), win.canAddInternalSystemWindow());
+    }
+
+    /**
+     * Returns the layer assignment for the window type. Allows you to control how different
      * kinds of windows are ordered on-screen.
      *
      * @param type The type of window being assigned.
-     *
-     * @return int An arbitrary integer used to order windows, with lower
-     *         numbers below higher ones.
+     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
      */
-    public int windowTypeToLayerLw(int type);
+    default int getWindowLayerFromTypeLw(int type) {
+        if (isSystemAlertWindowType(type)) {
+            throw new IllegalArgumentException("Use getWindowLayerFromTypeLw() or"
+                    + " getWindowLayerLw() for alert window types");
+        }
+        return getWindowLayerFromTypeLw(type, false /* canAddInternalSystemWindow */);
+    }
 
     /**
-     * Return how to Z-order sub-windows in relation to the window they are
-     * attached to.  Return positive to have them ordered in front, negative for
-     * behind.
+     * Returns the layer assignment for the window type. Allows you to control how different
+     * kinds of windows are ordered on-screen.
+     *
+     * @param type The type of window being assigned.
+     * @param canAddInternalSystemWindow If the owner window associated with the type we are
+     *        evaluating can add internal system windows. I.e they have
+     *        {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
+     *        types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
+     *        can be assigned layers greater than the layer for
+     *        {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
+     *        layers would be lesser.
+     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
+     */
+    default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
+        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
+            return APPLICATION_LAYER;
+        }
+
+        switch (type) {
+            case TYPE_WALLPAPER:
+                // wallpaper is at the bottom, though the window manager may move it.
+                return  1;
+            case TYPE_PRESENTATION:
+            case TYPE_PRIVATE_PRESENTATION:
+                return  APPLICATION_LAYER;
+            case TYPE_DOCK_DIVIDER:
+                return  APPLICATION_LAYER;
+            case TYPE_QS_DIALOG:
+                return  APPLICATION_LAYER;
+            case TYPE_PHONE:
+                return  3;
+            case TYPE_SEARCH_BAR:
+            case TYPE_VOICE_INTERACTION_STARTING:
+                return  4;
+            case TYPE_VOICE_INTERACTION:
+                // voice interaction layer is almost immediately above apps.
+                return  5;
+            case TYPE_INPUT_CONSUMER:
+                return  6;
+            case TYPE_SYSTEM_DIALOG:
+                return  7;
+            case TYPE_TOAST:
+                // toasts and the plugged-in battery thing
+                return  8;
+            case TYPE_PRIORITY_PHONE:
+                // SIM errors and unlock.  Not sure if this really should be in a high layer.
+                return  9;
+            case TYPE_DREAM:
+                // used for Dreams (screensavers with TYPE_DREAM windows)
+                return  10;
+            case TYPE_SYSTEM_ALERT:
+                // like the ANR / app crashed dialogs
+                return  canAddInternalSystemWindow ? 11 : 10;
+            case TYPE_APPLICATION_OVERLAY:
+                return  13;
+            case TYPE_INPUT_METHOD:
+                // on-screen keyboards and other such input method user interfaces go here.
+                return  14;
+            case TYPE_INPUT_METHOD_DIALOG:
+                // on-screen keyboards and other such input method user interfaces go here.
+                return  15;
+            case TYPE_STATUS_BAR_SUB_PANEL:
+                return  17;
+            case TYPE_STATUS_BAR:
+                return  18;
+            case TYPE_STATUS_BAR_PANEL:
+                return  19;
+            case TYPE_KEYGUARD_DIALOG:
+                return  20;
+            case TYPE_VOLUME_OVERLAY:
+                // the on-screen volume indicator and controller shown when the user
+                // changes the device volume
+                return  21;
+            case TYPE_SYSTEM_OVERLAY:
+                // the on-screen volume indicator and controller shown when the user
+                // changes the device volume
+                return  canAddInternalSystemWindow ? 22 : 11;
+            case TYPE_NAVIGATION_BAR:
+                // the navigation bar, if available, shows atop most things
+                return  23;
+            case TYPE_NAVIGATION_BAR_PANEL:
+                // some panels (e.g. search) need to show on top of the navigation bar
+                return  24;
+            case TYPE_SCREENSHOT:
+                // screenshot selection layer shouldn't go above system error, but it should cover
+                // navigation bars at the very least.
+                return  25;
+            case TYPE_SYSTEM_ERROR:
+                // system-level error dialogs
+                return  canAddInternalSystemWindow ? 26 : 10;
+            case TYPE_MAGNIFICATION_OVERLAY:
+                // used to highlight the magnified portion of a display
+                return  27;
+            case TYPE_DISPLAY_OVERLAY:
+                // used to simulate secondary display devices
+                return  28;
+            case TYPE_DRAG:
+                // the drag layer: input for drag-and-drop is associated with this window,
+                // which sits above all other focusable windows
+                return  29;
+            case TYPE_ACCESSIBILITY_OVERLAY:
+                // overlay put by accessibility services to intercept user interaction
+                return  30;
+            case TYPE_SECURE_SYSTEM_OVERLAY:
+                return  31;
+            case TYPE_BOOT_PROGRESS:
+                return  32;
+            case TYPE_POINTER:
+                // the (mouse) pointer layer
+                return  33;
+            default:
+                Slog.e("WindowManager", "Unknown window type: " + type);
+                return APPLICATION_LAYER;
+        }
+    }
+
+    int APPLICATION_LAYER = 2;
+    int APPLICATION_MEDIA_SUBLAYER = -2;
+    int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
+    int APPLICATION_PANEL_SUBLAYER = 1;
+    int APPLICATION_SUB_PANEL_SUBLAYER = 2;
+    int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;
+
+    /**
+     * Return how to Z-order sub-windows in relation to the window they are attached to.
+     * Return positive to have them ordered in front, negative for behind.
      *
      * @param type The sub-window type code.
      *
      * @return int Layer in relation to the attached window, where positive is
      *         above and negative is below.
      */
-    public int subWindowTypeToLayerLw(int type);
+    default int getSubWindowLayerFromTypeLw(int type) {
+        switch (type) {
+            case TYPE_APPLICATION_PANEL:
+            case TYPE_APPLICATION_ATTACHED_DIALOG:
+                return APPLICATION_PANEL_SUBLAYER;
+            case TYPE_APPLICATION_MEDIA:
+                return APPLICATION_MEDIA_SUBLAYER;
+            case TYPE_APPLICATION_MEDIA_OVERLAY:
+                return APPLICATION_MEDIA_OVERLAY_SUBLAYER;
+            case TYPE_APPLICATION_SUB_PANEL:
+                return APPLICATION_SUB_PANEL_SUBLAYER;
+            case TYPE_APPLICATION_ABOVE_SUB_PANEL:
+                return APPLICATION_ABOVE_SUB_PANEL_SUBLAYER;
+        }
+        Slog.e("WindowManager", "Unknown sub-window type: " + type);
+        return 0;
+    }
 
     /**
      * Get the highest layer (actually one more than) that the wallpaper is
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 1ef0d17..45302b6 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -779,6 +779,49 @@
         }
     }
 
+    /**
+     * Notifies that the accessibility button in the system's navigation area has been clicked
+     *
+     * @hide
+     */
+    public void notifyAccessibilityButtonClicked() {
+        final IAccessibilityManager service;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return;
+            }
+        }
+        try {
+            service.notifyAccessibilityButtonClicked();
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error while dispatching accessibility button click", re);
+        }
+    }
+
+    /**
+     * Notifies that the availability of the accessibility button in the system's navigation area
+     * has changed.
+     *
+     * @param available {@code true} if the accessibility button is available within the system
+     *                  navigation area, {@code false} otherwise
+     * @hide
+     */
+    public void notifyAccessibilityButtonAvailabilityChanged(boolean available) {
+        final IAccessibilityManager service;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return;
+            }
+        }
+        try {
+            service.notifyAccessibilityButtonAvailabilityChanged(available);
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error while dispatching accessibility button availability change", re);
+        }
+    }
+
     private IAccessibilityManager getServiceLocked() {
         if (mService == null) {
             tryConnectToServiceLocked(null);
diff --git a/core/java/android/view/accessibility/IAccessibilityManager.aidl b/core/java/android/view/accessibility/IAccessibilityManager.aidl
index 136bbbe..8fde47a 100644
--- a/core/java/android/view/accessibility/IAccessibilityManager.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityManager.aidl
@@ -59,6 +59,10 @@
 
     IBinder getWindowToken(int windowId, int userId);
 
+    void notifyAccessibilityButtonClicked();
+
+    void notifyAccessibilityButtonAvailabilityChanged(boolean available);
+
     // Requires WRITE_SECURE_SETTINGS
     void performAccessibilityShortcut();
 
diff --git a/core/java/android/view/autofill/AutoFillManager.java b/core/java/android/view/autofill/AutoFillManager.java
index f2f522d..147d72a 100644
--- a/core/java/android/view/autofill/AutoFillManager.java
+++ b/core/java/android/view/autofill/AutoFillManager.java
@@ -16,6 +16,8 @@
 
 package android.view.autofill;
 
+import static android.view.autofill.Helper.DEBUG;
+
 import android.annotation.Nullable;
 import android.content.Context;
 import android.graphics.Rect;
@@ -31,7 +33,6 @@
 public final class AutoFillManager {
 
     private static final String TAG = "AutoFillManager";
-    private static final boolean DEBUG = true; // TODO(b/33197203): change to false once stable
 
     /**
      * Flag used to show the auto-fill UI affordance for a view.
diff --git a/core/java/android/view/autofill/AutoFillSession.java b/core/java/android/view/autofill/AutoFillSession.java
index eec7a82..efc1df6 100644
--- a/core/java/android/view/autofill/AutoFillSession.java
+++ b/core/java/android/view/autofill/AutoFillSession.java
@@ -19,7 +19,8 @@
 import static android.view.autofill.Helper.DEBUG;
 
 import android.app.Activity;
-import android.os.RemoteException;
+import android.content.Intent;
+import android.content.IntentSender;
 import android.service.autofill.IAutoFillAppCallback;
 import android.util.Log;
 import android.view.View;
@@ -39,7 +40,7 @@
 
     private final IAutoFillAppCallback mCallback = new IAutoFillAppCallback.Stub() {
         @Override
-        public void autoFill(Dataset dataset) throws RemoteException {
+        public void autoFill(Dataset dataset) {
             final Activity activity = mActivity.get();
             if (activity == null) {
                 if (DEBUG) Log.d(TAG, "autoFill(): activity already GCed");
@@ -49,12 +50,10 @@
             // dataset.extras to service
             activity.runOnUiThread(() -> {
                 final View root = activity.getWindow().getDecorView().getRootView();
-                for (DatasetField field : dataset.getFields()) {
-                    final AutoFillId id = field.getId();
-                    if (id == null) {
-                        Log.w(TAG, "autoFill(): null id on " + field);
-                        continue;
-                    }
+                final int itemCount = dataset.getFieldIds().size();
+                for (int i = 0; i < itemCount; i++) {
+                    final AutoFillId id = dataset.getFieldIds().get(i);
+                    final AutoFillValue value = dataset.getFieldValues().get(i);
                     final int viewId = id.getViewId();
                     final View view = root.findViewByAccessibilityIdTraversal(viewId);
                     if (view == null) {
@@ -79,14 +78,28 @@
                             Log.d(TAG, "autoFill(): delegating " + id
                                     + " to VirtualViewDelegate  " + delegate);
                         }
-                        delegate.autoFill(id.getVirtualChildId(), field.getValue());
+                        delegate.autoFill(id.getVirtualChildId(), value);
                     } else {
                         // Handle non-virtual fields itself.
-                        view.autoFill(field.getValue());
+                        view.autoFill(value);
                     }
                 }
             });
         }
+
+        @Override
+        public void startIntentSender(IntentSender intent, Intent fillInIntent) {
+            final Activity activity = mActivity.get();
+            if (activity != null) {
+                activity.runOnUiThread(() -> {
+                    try {
+                        activity.startIntentSender(intent, fillInIntent, 0, 0, 0);
+                    } catch (IntentSender.SendIntentException e) {
+                        Log.e(TAG, "startIntentSender() failed for intent:" + intent, e);
+                    }
+                });
+            }
+        }
     };
 
     private final WeakReference<Activity> mActivity;
@@ -114,5 +127,4 @@
             }
         }
     }
-
 }
diff --git a/core/java/android/view/autofill/Dataset.java b/core/java/android/view/autofill/Dataset.java
index 18a08f9..2708358 100644
--- a/core/java/android/view/autofill/Dataset.java
+++ b/core/java/android/view/autofill/Dataset.java
@@ -17,12 +17,12 @@
 package android.view.autofill;
 
 import static android.view.autofill.Helper.DEBUG;
-import static android.view.autofill.Helper.append;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.assist.AssistStructure.ViewNode;
-import android.hardware.fingerprint.FingerprintManager.CryptoObject;
+import android.content.IntentSender;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -30,8 +30,6 @@
 import com.android.internal.util.Preconditions;
 
 import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
 
 /**
  * A set of data that can be used to auto-fill an {@link Activity}.
@@ -44,221 +42,184 @@
  *   <li>An optional {@link Bundle} with extras (used only by the service creating it).
  * </ol>
  *
- * See {@link FillResponse} for examples.
+ * @see FillResponse for examples.
  */
 public final class Dataset implements Parcelable {
-
+    private final String mId;
     private final CharSequence mName;
-    private final ArrayList<DatasetField> mFields;
+    private final ArrayList<AutoFillId> mFieldIds;
+    private final ArrayList<AutoFillValue> mFieldValues;
     private final Bundle mExtras;
-    private final int mFlags;
-    private final boolean mRequiresAuth;
-    private final boolean mHasCryptoObject;
-    private final long mCryptoOpId;
+    private final IntentSender mAuthentication;
 
-    private Dataset(Dataset.Builder builder) {
+    private Dataset(Builder builder) {
+        mId = builder.mId;
         mName = builder.mName;
-        // TODO(b/33197203): make an immutable copy of mFields?
-        mFields = builder.mFields;
+        mFieldIds = builder.mFieldIds;
+        mFieldValues = builder.mFieldValues;
         mExtras = builder.mExtras;
-        mFlags = builder.mFlags;
-        mRequiresAuth = builder.mRequiresAuth;
-        mHasCryptoObject = builder.mHasCryptoObject;
-        mCryptoOpId = builder.mCryptoOpId;
+        mAuthentication = builder.mAuthentication;
     }
 
     /** @hide */
-    public CharSequence getName() {
+    public @NonNull String getId() {
+        return mId;
+    }
+
+    /** @hide */
+    public @NonNull CharSequence getName() {
         return mName;
     }
 
     /** @hide */
-    public List<DatasetField> getFields() {
-        return mFields;
+    public @Nullable ArrayList<AutoFillId> getFieldIds() {
+        return mFieldIds;
     }
 
     /** @hide */
-    public Bundle getExtras() {
+    public @Nullable ArrayList<AutoFillValue> getFieldValues() {
+        return mFieldValues;
+    }
+
+    /** @hide */
+    public @Nullable Bundle getExtras() {
         return mExtras;
     }
 
     /** @hide */
-    public int getFlags() {
-        return mFlags;
-    }
-
-    /** @hide */
-    public boolean isAuthRequired() {
-        return mRequiresAuth;
+    public @Nullable IntentSender getAuthentication() {
+        return mAuthentication;
     }
 
     /** @hide */
     public boolean isEmpty() {
-        return mFields.isEmpty();
-    }
-
-    /** @hide */
-    public boolean hasCryptoObject() {
-        return mHasCryptoObject;
-    }
-
-    /** @hide */
-    public long getCryptoObjectOpId() {
-        return mCryptoOpId;
+        return mFieldIds == null || mFieldIds.isEmpty();
     }
 
     @Override
     public String toString() {
         if (!DEBUG) return super.toString();
 
-        final StringBuilder builder = new StringBuilder("Dataset [name=").append(mName)
-                .append(", fields=").append(mFields).append(", extras=");
-        append(builder, mExtras)
-            .append(", flags=").append(mFlags)
-            .append(", requiresAuth: ").append(mRequiresAuth)
-            .append(", hasCrypto: ").append(mHasCryptoObject);
+        final StringBuilder builder = new StringBuilder("Dataset [id=").append(mId)
+                .append(", name=").append(mName)
+                .append(", fieldIds=").append(mFieldIds)
+                .append(", fieldValues=").append(mFieldValues)
+                .append(", hasAuthentication=").append(mAuthentication != null)
+                .append(", hasExtras=").append(mExtras != null);
         return builder.append(']').toString();
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final Dataset other = (Dataset) obj;
+        if (mId == null) {
+            if (other.mId != null) {
+                return false;
+            }
+        } else if (!mId.equals(other.mId)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return mId != null ? mId.hashCode() : 0;
+    }
+
     /**
-     * A builder for {@link Dataset} objects.
+     * A builder for {@link Dataset} objects. You must to provide at least
+     * one value for a field or set an authentication intent.
      */
     public static final class Builder {
+        private String mId;
         private CharSequence mName;
-        private final ArrayList<DatasetField> mFields = new ArrayList<>();
+        private ArrayList<AutoFillId> mFieldIds;
+        private ArrayList<AutoFillValue> mFieldValues;
         private Bundle mExtras;
-        private int mFlags;
-        private boolean mRequiresAuth;
-        private boolean mHasCryptoObject;
-        private long mCryptoOpId;
+        private IntentSender mAuthentication;
+        private boolean mDestroyed;
+
+        /** @hide */
+        // TODO(b/33197203): Remove once GCore migrates
+        public Builder(@NonNull CharSequence name) {
+            this(String.valueOf(System.currentTimeMillis()), name);
+        }
 
         /**
          * Creates a new builder.
          *
+         * @param id A required id to identify this dataset for future interactions related to it.
          * @param name Name used to identify the dataset in the UI. Typically it's the same value as
-         * the first field in the dataset (like username or email address) or an user-provided name
+         * the first field in the dataset (like username or email address) or a user-provided name
          * (like "My Work Address").
          */
-        public Builder(CharSequence name) {
+        public Builder(@NonNull String id, @NonNull CharSequence name) {
+            mId = Preconditions.checkStringNotEmpty(id, "id cannot be empty or null");
             mName = Preconditions.checkStringNotEmpty(name, "name cannot be empty or null");
         }
 
         /**
-         * Requires dataset authentication through the {@link
-         * android.service.autofill.AutoFillService} before auto-filling the activity with this
-         * dataset.
+         * Requires a dataset authentication before auto-filling the activity with this dataset.
          *
-         * <p>This method is typically called when the device (or the service) does not support
-         * fingerprint authentication (and hence it cannot use {@link
-         * #requiresFingerprintAuthentication(CryptoObject, Bundle, int)}) or when the service needs
-         * to use a custom authentication UI for the dataset. For example, when a dataset contains
-         * credit card information (such as number, expiration date, and verification code), the
-         * service displays an authentication dialog asking for the verification code to unlock the
-         * rest of the data).
+         * <p>This method is called when you need to provide an authentication
+         * UI for the dataset. For example, when a dataset contains credit card information
+         * (such as number, expiration date, and verification code), you can display UI
+         * asking for the verification code to before filing in the data). Even if the
+         * dataset is completely populated the system will launch the specified authentication
+         * intent and will need your approval to fill it in. Since the dataset is "locked"
+         * until the user authenticates it, typically this dataset name is masked
+         * (for example, "VISA....1234"). Typically you would want to store the dataset
+         * labels non-encypted and the actual sensitive data encrypted and not in memory.
+         * This allows showing the labels in the UI while involving the user if one of
+         * the items with these labels is chosen. Note that if you use sensitive data as
+         * a label, for example an email address, then it should also be encrypted.
+         *</p>
          *
-         * <p>Since the dataset is "locked" until the user authenticates it, typically this dataset
-         * name is masked (for example, "VISA....1234").
+         * <p>When a user selects this dataset, the system triggers the provided intent
+         * whose extras will have the {@link android.content.Intent#EXTRA_AUTO_FILL_ITEM_ID id}
+         * of the {@link android.view.autofill.Dataset dataset} to authenticate, the {@link
+         * android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras} associated with this
+         * dataset, and a {@link android.content.Intent#EXTRA_AUTO_FILL_CALLBACK callback}
+         * to dispatch the authentication result.</p>
          *
-         * <p>When the user selects this dataset, the Android System calls {@link
-         * android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle, int)}
-         * passing {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_REQUESTED} in
-         * the flags and the same {@code extras} passed to this method. The service can then
-         * displays its custom authentication UI, and then call the proper method on {@link
-         * android.service.autofill.FillCallback} depending on the authentication result and whether
-         * this dataset already contains the fields needed to auto-fill the activity:
+         * <p>Once you complete your authentication flow you should use the provided callback
+         * to notify for a failure or a success. In case of a success you need to provide
+         * only the fully populated dataset that is being authenticated. For example, if you
+         * provided a {@link FillResponse} with two {@link Dataset}s and marked that
+         * only the first dataset needs an authentication then in the provided response
+         * you need to provide only the fully populated dataset being authenticated instead
+         * of both of them.
+         * </p>
          *
-         * <ul>
-         *   <li>If authentication failed, call
-         *   {@link android.service.autofill.FillCallback#onDatasetAuthentication(Dataset,
-         *       int)} passing {@link
-         *       android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} in the flags.
-         *   <li>If authentication succeeded and this datast is empty (no fields), call {@link
-         *       android.service.autofill.FillCallback#onSuccess(FillResponse)} with a new dataset
-         *       (with the proper fields).
-         *   <li>If authentication succeeded and this response is not empty, call {@link
-         *       android.service.autofill.FillCallback#onDatasetAuthentication(Dataset, int)}
-         *       passing
-         *       {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS} in the
-         *       {@code flags} and {@code null} as the {@code dataset}.
-         * </ul>
+         * <p>The indent sender mechanism allows you to have your authentication UI
+         * implemented as an activity or a service or a receiver. However, the recommended
+         * way is to do this is with an activity which the system will start in the
+         * filled activity's task meaning it will properly work with back, recent apps, and
+         * free-form multi-window, while avoiding the need for the "draw on top of other"
+         * apps special permission. You can still theme your authentication activity's
+         * UI to look like a dialog if desired.</p>
          *
-         * @param extras when set, will be passed back in the {@link
-         *     android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle,
-         *     int)}, call so it could be used by the service to handle state.
-         * @param flags optional parameters, currently ignored.
+         * <p></><strong>Note:</strong> Do not make the provided intent sender
+         * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
+         * platform needs to fill in the authentication arguments.</p>
+         *
+         * @param authentication Intent to trigger your authentication flow.
+         *
+         * @see android.app.PendingIntent#getIntentSender()
          */
-        public Builder requiresCustomAuthentication(@Nullable Bundle extras, int flags) {
-            return requiresAuthentication(null, extras, flags);
-        }
-
-        /**
-         * Requires dataset authentication through the Fingerprint sensor before auto-filling the
-         * activity with this dataset.
-         *
-         * <p>This method is typically called when the dataset contains sensitive information (for
-         * example, credit card information) and the provider requires the user to re-authenticate
-         * before using it.
-         *
-         * <p>Since the dataset is "locked" until the user authenticates it, typically this dataset
-         * name is masked (for example, "VISA....1234").
-         *
-         * <p>When the user selects this dataset, the Android System displays an UI affordance
-         * asking the user to use the fingerprint sensor unlock the dataset, and what happens after
-         * a successful fingerprint authentication depends on whether the dataset is empty (no
-         * fields, only the masked name) or not:
-         *
-         * <ul>
-         *   <li>If it's empty, the Android System will call {@link
-         *       android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle,
-         *       int)} passing {@link
-         *       android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS}} in the
-         *       flags.
-         *   <li>If it's not empty, the activity will be auto-filled with its data.
-         * </ul>
-         *
-         * <p>If the fingerprint authentication fails, the Android System will call {@link
-         * android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle, int)}
-         * passing {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} in the
-         * flags.
-         *
-         * <p><strong>NOTE: </note> the {@link android.service.autofill.AutoFillService} should use
-         * the {@link android.hardware.fingerprint.FingerprintManager} to check if fingerpint
-         * authentication is available before using this method, and use other alternatives (such as
-         * {@link #requiresCustomAuthentication(Bundle, int)}) if it is not: if this method is
-         * called when fingerprint is not available, Android System will call {@link
-         * android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle, int)}
-         * passing {@link
-         * android.service.autofill.AutoFillService#FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}
-         * in the flags, but it would be wasting system resources (and worsening the user
-         * experience) in the process.
-         *
-         * @param crypto object that will be authenticated.
-         * @param extras when set, will be passed back in the {@link
-         *     android.service.autofill.AutoFillService#onDatasetAuthenticationRequest(Bundle, int)}
-         *     call so it could be used by the service to handle state.
-         * @param flags optional parameters, currently ignored.
-         */
-        public Builder requiresFingerprintAuthentication(CryptoObject crypto,
-                @Nullable Bundle extras, int flags) {
-            // TODO(b/33197203): should we allow crypto to be null?
-            Preconditions.checkArgument(crypto != null, "must pass a CryptoObject");
-            return requiresAuthentication(crypto, extras, flags);
-        }
-
-        private Builder requiresAuthentication(CryptoObject cryptoObject, Bundle extras,
-                int flags) {
-            // There can be only one!
-            Preconditions.checkState(!mRequiresAuth,
-                    "requires-authentication methods already called");
-            // TODO(b/33197203): make sure that either this method or setExtras() is called, but
-            // not both
-            mExtras = extras;
-            mFlags = flags;
-            mRequiresAuth = true;
-            if (cryptoObject != null) {
-                mHasCryptoObject = true;
-                mCryptoOpId = cryptoObject.getOpId();
-            }
+        public @NonNull Builder setAuthentication(@Nullable IntentSender authentication) {
+            throwIfDestroyed();
+            mAuthentication = authentication;
             return this;
         }
 
@@ -268,41 +229,55 @@
          * @param id id returned by {@link ViewNode#getAutoFillId()}.
          * @param value value to be auto filled.
          */
-        public Dataset.Builder setValue(AutoFillId id, AutoFillValue value) {
-            putField(new DatasetField(id, value));
+        public @NonNull Builder setValue(@NonNull AutoFillId id, @NonNull AutoFillValue value) {
+            throwIfDestroyed();
+            Preconditions.checkNotNull(id, "id cannot be null");
+            Preconditions.checkNotNull(value, "value cannot be null");
+            if (mFieldIds != null) {
+                final int existingIdx = mFieldIds.indexOf(id);
+                if (existingIdx >= 0) {
+                    mFieldValues.set(existingIdx, value);
+                    return this;
+                }
+            } else {
+                mFieldIds = new ArrayList<>();
+                mFieldValues = new ArrayList<>();
+            }
+            mFieldIds.add(id);
+            mFieldValues.add(value);
             return this;
         }
 
         /**
-         * Creates a new {@link Dataset} instance.
+         * Sets a {@link Bundle} that will be passed to subsequent APIs that
+         * manipulate this dataset. For example, they are passed in as {@link
+         * android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras} to your
+         * authentication flow.
          */
-        public Dataset build() {
+        public @NonNull Builder setExtras(@Nullable Bundle extras) {
+            throwIfDestroyed();
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Creates a new {@link Dataset} instance. You should not interact
+         * with this builder once this method is called.
+         */
+        public @NonNull Dataset build() {
+            throwIfDestroyed();
+            mDestroyed = true;
+            if (mFieldIds == null && mAuthentication == null) {
+                throw new IllegalArgumentException(
+                        "at least one value or an authentication must be set");
+            }
             return new Dataset(this);
         }
 
-        /**
-         * Sets a {@link Bundle} that will be passed to subsequent calls to
-         * {@link android.service.autofill.AutoFillService} methods such as
- * {@link android.service.autofill.AutoFillService#onSaveRequest(android.app.assist.AssistStructure,
-         * Bundle, android.service.autofill.SaveCallback)}, using
-         * {@link android.service.autofill.AutoFillService#EXTRA_DATASET_EXTRAS} as the key.
-         *
-         * <p>It can be used to keep service state in between calls.
-         */
-        public Builder setExtras(Bundle extras) {
-            // TODO(b/33197203): make sure that either this method or the requires-Authentication
-            // ones are called, but not both
-            mExtras = Objects.requireNonNull(extras, "extras cannot be null");
-            return this;
-        }
-
-        /**
-         * Emulates {@code Map.put()} by adding a new field to the list if its id is not the yet,
-         * or replacing the existing one.
-         */
-        private void putField(DatasetField field) {
-            // TODO(b/33197203): check if already exists and replaces it if so
-            mFields.add(field);
+        private void throwIfDestroyed() {
+            if (mDestroyed) {
+                throw new IllegalStateException("Already called #build()");
+            }
         }
     }
 
@@ -317,32 +292,33 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeString(mId);
         parcel.writeCharSequence(mName);
-        parcel.writeList(mFields);
+        parcel.writeTypedArrayList(mFieldIds, 0);
+        parcel.writeTypedArrayList(mFieldValues, 0);
         parcel.writeBundle(mExtras);
-        parcel.writeInt(mFlags);
-        parcel.writeInt(mRequiresAuth ? 1 : 0);
-        parcel.writeInt(mHasCryptoObject ? 1 : 0);
-        if (mHasCryptoObject) {
-            parcel.writeLong(mCryptoOpId);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private Dataset(Parcel parcel) {
-        mName = parcel.readCharSequence();
-        mFields = parcel.readArrayList(null);
-        mExtras = parcel.readBundle();
-        mFlags = parcel.readInt();
-        mRequiresAuth = parcel.readInt() == 1;
-        mHasCryptoObject = parcel.readInt() == 1;
-        mCryptoOpId = mHasCryptoObject ? parcel.readLong() : 0;
+        parcel.writeParcelable(mAuthentication, flags);
     }
 
     public static final Parcelable.Creator<Dataset> CREATOR = new Parcelable.Creator<Dataset>() {
         @Override
-        public Dataset createFromParcel(Parcel source) {
-            return new Dataset(source);
+        public Dataset createFromParcel(Parcel parcel) {
+            // Always go through the builder to ensure the data ingested by
+            // the system obeys the contract of the builder to avoid attacks
+            // using specially crafted parcels.
+            final Builder builder = new Builder(parcel.readString(), parcel.readCharSequence());
+            final ArrayList<AutoFillId> ids = parcel.readTypedArrayList(null);
+            final ArrayList<AutoFillValue> values = parcel.readTypedArrayList(null);
+            final int idCount = (ids != null) ? ids.size() : 0;
+            final int valueCount = (values != null) ? values.size() : 0;
+            for (int i = 0; i < idCount; i++) {
+                AutoFillId id = ids.get(i);
+                AutoFillValue value = (valueCount > i) ? values.get(i) : null;
+                builder.setValue(id, value);
+            }
+            builder.setExtras(parcel.readBundle());
+            builder.setAuthentication(parcel.readParcelable(null));
+            return builder.build();
         }
 
         @Override
diff --git a/core/java/android/view/autofill/DatasetField.java b/core/java/android/view/autofill/DatasetField.java
deleted file mode 100644
index c6b92ac..0000000
--- a/core/java/android/view/autofill/DatasetField.java
+++ /dev/null
@@ -1,86 +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.view.autofill;
-
-import static android.view.autofill.Helper.DEBUG;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/** @hide */
-public final class DatasetField implements Parcelable {
-
-    private final AutoFillId mId;
-    private final AutoFillValue mValue;
-
-    DatasetField(AutoFillId id, AutoFillValue value) {
-        mId = id;
-        mValue = value;
-    }
-
-    public AutoFillId getId() {
-        return mId;
-    }
-
-    public AutoFillValue getValue() {
-        return mValue;
-    }
-
-    /////////////////////////////////
-    //  Object "contract" methods. //
-    /////////////////////////////////
-
-    @Override
-    public String toString() {
-        if (!DEBUG) return super.toString();
-
-        return "DatasetField [id=" + mId + ", value=" + mValue + "]";
-    }
-
-    /////////////////////////////////////
-    //  Parcelable "contract" methods. //
-    /////////////////////////////////////
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeParcelable(mId, 0);
-        parcel.writeParcelable(mValue, 0);
-    }
-
-    private DatasetField(Parcel parcel) {
-        mId = parcel.readParcelable(null);
-        mValue = parcel.readParcelable(null);
-    }
-
-    public static final Parcelable.Creator<DatasetField> CREATOR =
-            new Parcelable.Creator<DatasetField>() {
-        @Override
-        public DatasetField createFromParcel(Parcel source) {
-            return new DatasetField(source);
-        }
-
-        @Override
-        public DatasetField[] newArray(int size) {
-            return new DatasetField[size];
-        }
-    };
-}
diff --git a/core/java/android/view/autofill/FillResponse.java b/core/java/android/view/autofill/FillResponse.java
index 48dbb84..596a06c 100644
--- a/core/java/android/view/autofill/FillResponse.java
+++ b/core/java/android/view/autofill/FillResponse.java
@@ -16,36 +16,30 @@
 package android.view.autofill;
 
 import static android.view.autofill.Helper.DEBUG;
-import static android.view.autofill.Helper.append;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
-import android.hardware.fingerprint.FingerprintManager.CryptoObject;
+import android.content.IntentSender;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.service.autofill.FillCallback;
+import android.util.ArraySet;
 
 import com.android.internal.util.Preconditions;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
 /**
  * Response for a {@link
  * android.service.autofill.AutoFillService#onFillRequest(android.app.assist.AssistStructure,
- * Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback)} request.
+ * Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback)} and
+ * authentication requests.
  *
  * <p>The response typically contains one or more {@link Dataset}s, each representing a set of
- * fields that can be auto-filled together, and the Android System displays a dataset picker UI
+ * fields that can be auto-filled together, and the Android system displays a dataset picker UI
  * affordance that the user must use before the {@link Activity} is filled with the dataset.
  *
  * <p>For example, for a login page with username/password where the user only has one account in
- * the service, the response could be:
+ * the response could be:
  *
  * <pre class="prettyprint">
  *  new FillResponse.Builder()
@@ -102,12 +96,17 @@
  * <p>Notice that the ids that are part of a dataset (ids 1 to 4, in this example) are automatically
  * added to the {@code savableIds} list.
  *
- * <p>If the service has multiple {@link Dataset}s with multiple options for some fields on each
- * dataset (for example, multiple accounts with both a home and work address), then it should
- * "partition" the {@link Activity} in sections and populate the response with just a subset of the
- * data that would fulfill the first section; then once the user fills the first section and taps a
- * field from the next section, the Android system would issue another request for that section, and
- * so on. For example, the first response could be:
+ * <p>If the service has multiple {@link Dataset}s for different sections of the activity,
+ * for example, a user section for which there are two datasets followed by an address
+ * section for which there are two datasets for each user user, then it should "partition"
+ * the activity in sections and populate the response with just a subset of the data that would
+ * fulfill the first section (the name in our example); then once the user fills the first
+ * section and taps a field from the next section (the address in our example), the Android
+ * system would issue another request for that section, and so on. Note that if the user
+ * chooses to populate the first section with a service provided dataset, the subsequent request
+ * would contain the populated values so you don't try to provide suggestions for the first
+ * section but ony for the second one based on the context of what was already filled. For
+ * example, the first response could be:
  *
  * <pre class="prettyprint">
  *  new FillResponse.Builder()
@@ -132,236 +131,182 @@
  *          .setTextFieldValue(id4, "Springfield")
  *          .build())
  *      .add(new Dataset.Builder("Work")
- *          .setTextFieldValue(id3, "Springfield Nuclear Power Plant")
+ *          .setTextFieldValue(id3, "Springfield Power Plant")
  *          .setTextFieldValue(id4, "Springfield")
  *          .build())
  *      .build();
  * </pre>
  *
- * <p>The service could require user authentication, either at the {@link FillResponse} or {@link
- * Dataset} levels, prior to auto-filling the activity - see {@link
- * FillResponse.Builder#requiresFingerprintAuthentication(CryptoObject, Bundle, int)}, {@link
- * FillResponse.Builder#requiresCustomAuthentication(Bundle, int)}, {@link
- * Dataset.Builder#requiresFingerprintAuthentication(CryptoObject, Bundle, int)}, and {@link
- * Dataset.Builder#requiresCustomAuthentication(Bundle, int)} for details.
+ * <p>The service could require user authentication at the {@link FillResponse} or the
+ * {@link Dataset} level, prior to auto-filling an activity - see {@link FillResponse.Builder
+ * #setAuthentication(IntentSender)} and {@link Dataset.Builder#setAuthentication(IntentSender)}.
+ * It is recommended that you encrypt only the sensitive data but leave the labels unencrypted
+ * which would allow you to provide the dataset names to the user and if they choose one
+ * them challenge the user to authenticate. For example, if the user has a home and a work
+ * address the Home and Work labels could be stored unencrypted as they don't have any sensitive
+ * data while the address data is in an encrypted storage. If the user chooses Home, then the
+ * platform will start your authentication flow. If you encrypt all data and require auth
+ * at the response level the user will have to interact with the fill UI to trigger a request
+ * for the datasets as they don't see Home and Work options which will trigger your auth
+ * flow and after successfully authenticating the user will be presented with the Home and
+ * Work options where they can pick one. Hence, you have flexibility how to implement your
+ * auth while storing labels non-encrypted and data encrypted provides a better user
+ * experience.</p>
  *
- * <p>Finally, the service can use the {@link FillResponse.Builder#setExtras(Bundle)} and/or {@link
- * Dataset.Builder#setExtras(Bundle)} methods to pass {@link Bundle}s with service-specific data use
- * to identify this response on future calls (like {@link
- * android.service.autofill.AutoFillService#onSaveRequest(android.app.assist.AssistStructure,
- * Bundle, android.service.autofill.SaveCallback)}) - such bundles will be available as the
- * {@link android.service.autofill.AutoFillService#EXTRA_RESPONSE_EXTRAS} and
- * {@link android.service.autofill.AutoFillService#EXTRA_DATASET_EXTRAS} extras in that method's
- * {@code extras} argument.
+ * <p>Finally, the service can use {@link Dataset.Builder#setExtras(Bundle)} methods
+ * to pass {@link Bundle extras} provided to all future calls related to a dataset,
+ * for example during authentication and saving.</p>
  */
 public final class FillResponse implements Parcelable {
-
-    private final List<Dataset> mDatasets;
-    private final AutoFillId[] mSavableIds;
+    private final String mId;
+    private final ArraySet<Dataset> mDatasets;
+    private final ArraySet<AutoFillId> mSavableIds;
     private final Bundle mExtras;
-    private final int mFlags;
-    private final boolean mRequiresAuth;
-    private final boolean mHasCryptoObject;
-    private final long mCryptoOpId;
+    private final IntentSender mAuthentication;
 
-    private FillResponse(Builder builder) {
-        // TODO(b/33197203): make it immutable?
+    private FillResponse(@NonNull Builder builder) {
+        mId = builder.mId;
         mDatasets = builder.mDatasets;
-        final int size = builder.mSavableIds.size();
-        mSavableIds = new AutoFillId[size];
-        int i = 0;
-        for (AutoFillId id : builder.mSavableIds) {
-            mSavableIds[i++] = id;
-        }
+        mSavableIds = builder.mSavableIds;
         mExtras = builder.mExtras;
-        mFlags = builder.mFlags;
-        mRequiresAuth = builder.mRequiresAuth;
-        mHasCryptoObject = builder.mHasCryptoObject;
-        mCryptoOpId = builder.mCryptoOpId;
+        mAuthentication = builder.mAuthentication;
     }
 
     /** @hide */
-    public List<Dataset> getDatasets() {
-        return mDatasets;
+    public @NonNull String getId() {
+        return mId;
     }
 
     /** @hide */
-    public AutoFillId[] getSavableIds() {
-        return mSavableIds;
-    }
-
-    /** @hide */
-    public Bundle getExtras() {
+    public @Nullable Bundle getExtras() {
         return mExtras;
     }
 
     /** @hide */
-    public int getFlags() {
-        return mFlags;
+    public @Nullable ArraySet<Dataset> getDatasets() {
+        return mDatasets;
     }
 
     /** @hide */
-    public boolean isAuthRequired() {
-        return mRequiresAuth;
+    public @Nullable ArraySet<AutoFillId> getSavableIds() {
+        return mSavableIds;
     }
 
     /** @hide */
-    public boolean hasCryptoObject() {
-        return mHasCryptoObject;
-    }
-
-    /** @hide */
-    public long getCryptoObjectOpId() {
-        return mCryptoOpId;
+    public @Nullable IntentSender getAuthentication() {
+        return mAuthentication;
     }
 
     /**
-     * Builder for {@link FillResponse} objects.
+     * Builder for {@link FillResponse} objects. You must to provide at least
+     * one dataset or set an authentication intent.
      */
     public static final class Builder {
-        private final List<Dataset> mDatasets = new ArrayList<>();
-        private final Set<AutoFillId> mSavableIds = new HashSet<>();
+        private final String mId;
+        private ArraySet<Dataset> mDatasets;
+        private ArraySet<AutoFillId> mSavableIds;
         private Bundle mExtras;
-        private int mFlags;
-        private boolean mRequiresAuth;
-        private boolean mHasCryptoObject;
-        private long mCryptoOpId;
+        private IntentSender mAuthentication;
+        private boolean mDestroyed;
 
-        /**
-         * Requires user authentication through the {@link android.service.autofill.AutoFillService}
-         * before handling an auto-fill request.
-         *
-         * <p>This method is typically called when the device (or the service) does not support
-         * fingerprint authentication (and hence it cannot use {@link
-         * #requiresFingerprintAuthentication(CryptoObject, Bundle, int)}) or when the service needs
-         * to use a custom authentication UI and is used in 2 scenarios:
-         *
-         * <ol>
-         *   <li>When the user data is encrypted and the service must authenticate an object that
-         *       will be used to decrypt it.
-         *   <li>When the service already acquired the user data but wants to confirm the user's
-         *       identity before the activity is filled with it.
-         * </ol>
-         *
-         * <p>When this method is called, the Android System displays an UI affordance asking the
-         * user to tap it to auto-fill the activity; if the user taps it, the Android System calls
-         * {@link
-         * android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
-         * int)} passing {@link
-         * android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_REQUESTED} in the flags and
-         * the same {@code extras} passed to this method. The service can then displays its custom
-         * authentication UI, and then call the proper method on {@link FillCallback} depending on
-         * the authentication result and whether this response already contains the {@link Dataset}s
-         * need to auto-fill the activity:
-         *
-         * <ul>
-         *   <li>If authentication failed, call {@link
-         *       FillCallback#onFillResponseAuthentication(int)} passing {@link
-         *       android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR} in the flags.
-         *   <li>If authentication succeeded and this response is empty (no datasets), call {@link
-         *       FillCallback#onSuccess(FillResponse)} with a new dataset (that does not require
-         *       authentication).
-         *   <li>If authentication succeeded and this response is not empty, call {@link
-         *       FillCallback#onFillResponseAuthentication(int)} passing {@link
-         *       android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS} in the flags.
-         * </ul>
-         *
-         * @param extras when set, will be passed back in the {@link
-         *     android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
-         *     int)} call so it could be used by the service to handle state.
-         * @param flags optional parameters, currently ignored.
-         */
-        public Builder requiresCustomAuthentication(@Nullable Bundle extras, int flags) {
-            return requiresAuthentication(null, extras, flags);
+        /** @hide */
+        // TODO(b/33197203): Remove once GCore migrates
+        public Builder() {
+            this(String.valueOf(System.currentTimeMillis()));
         }
 
         /**
-         * Requires user authentication through the Fingerprint sensor before handling an auto-fill
-         * request.
+         * Creates a new {@link FillResponse} builder.
          *
-         * <p>The {@link android.service.autofill.AutoFillService} typically uses this method in 2
-         * situations:
-         *
-         * <ol>
-         *   <li>When the user data is encrypted and the service must authenticate an object that
-         *       will be used to decrypt it.
-         *   <li>When the service already acquired the user data but wants to confirm the user's
-         *       identity before the activity is filled with it.
-         * </ol>
-         *
-         * <p>When this method is called, the Android System displays an UI affordance asking the
-         * user to use the fingerprint sensor to auto-fill the activity, and what happens after a
-         * successful fingerprint authentication depends on the number of {@link Dataset}s included
-         * in this response:
-         *
-         * <ul>
-         *   <li>If it's empty (scenario #1 above), the Android System will call {@link
-         *     android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
-         *       int)} passing {@link
-         *       android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_SUCCESS}} in the
-         *       flags.
-         *   <li>If it contains one dataset, the activity will be auto-filled right away.
-         *   <li>If it contains many datasets, the Android System will show dataset picker UI, and
-         *       then auto-fill the activity once the user select the proper datased.
-         * </ul>
-         *
-         * <p>If the fingerprint authentication fails, the Android System will call {@link
-         * android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
-         * int)} passing {@link android.service.autofill.AutoFillService#FLAG_AUTHENTICATION_ERROR}
-         * in the flags.
-         *
-         * <p><strong>NOTE: </note> the {@link android.service.autofill.AutoFillService} should use
-         * the {@link android.hardware.fingerprint.FingerprintManager} to check if fingerpint
-         * authentication is available before using this method, and use other alternatives (such as
-         * {@link #requiresCustomAuthentication(Bundle, int)}) if it is not: if this method is
-         * called when fingerprint is not available, Android System will call {@link
-         * android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
-         * int)} passing {@link
-         * android.service.autofill.AutoFillService#FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE}
-         * in the flags, but it would be wasting system resources (and worsening the user
-         * experience) in the process.
-         *
-         * @param crypto object that will be authenticated.
-         * @param extras when set, will be passed back in the {@link
-         *     android.service.autofill.AutoFillService#onFillResponseAuthenticationRequest(Bundle,
-         *     int)} call so it could be used by the service to handle state.
-         * @param flags optional parameters, currently ignored.
+         * @param id A required id to identify this dataset for future interactions related to it.
          */
-        public Builder requiresFingerprintAuthentication(CryptoObject crypto,
-                @Nullable Bundle extras, int flags) {
-            // TODO(b/33197203): should we allow crypto to be null?
-            Preconditions.checkArgument(crypto != null, "must pass a CryptoObject");
-            return requiresAuthentication(crypto, extras, flags);
+        public Builder(@NonNull String id) {
+            mId = Preconditions.checkStringNotEmpty(id, "id cannot be empty or null");
         }
 
-        private Builder requiresAuthentication(CryptoObject cryptoObject, Bundle extras,
-                int flags) {
-            // There can be only one!
-            Preconditions.checkState(!mRequiresAuth,
-                    "requires-authentication methods already called");
-            // TODO(b/33197203): make sure that either this method or setExtras() is called, but
-            // not both
-            mExtras = extras;
-            mFlags = flags;
-            mRequiresAuth = true;
-            if (cryptoObject != null) {
-                mHasCryptoObject = true;
-                mCryptoOpId = cryptoObject.getOpId();
-            }
+        /**
+         * Requires a fill response authentication before auto-filling the activity with
+         * any dataset in this response. This is typically useful when a user interaction
+         * is required to unlock their data vault if you encrypt the dataset labels and
+         * dataset data. It is recommended to encrypt only the sensitive data and not the
+         * dataset labels which would allow auth on the dataset level leading to a better
+         * user experience. Note that if you use sensitive data as a label, for example an
+         * email address, then it should also be encrypted.
+         *
+         * <p>This method is called when you need to provide an authentication
+         * UI for the fill response. For example, when the user's data is stored
+         * encrypted and needs a user interaction to decrypt before offering fill
+         * suggestions.</p>
+         *
+         * <p>When a user initiates an auto fill, the system triggers the provided
+         * intent whose extras will have the {@link android.content.Intent
+         * #EXTRA_AUTO_FILL_ITEM_ID id} of the {@link android.view.autofill.FillResponse})
+         * to authenticate, the {@link android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras}
+         * associated with this response, and a {@link android.content.Intent
+         * #EXTRA_AUTO_FILL_CALLBACK callback} to dispatch the authentication result.</p>
+         *
+         * <p>Once you complete your authentication flow you should use the provided callback
+         * to notify for a failure or a success. In case of a success you need to provide
+         * the fully populated response that is being authenticated. For example, if you
+         * provided an empty {@link FillResponse} because the user's data was locked and
+         * marked that the response needs an authentication then in the response returned
+         * if authentication succeeds you need to provide all available datasets some of
+         * which may need to be further authenticated, for example a credit card whose
+         * CVV needs to be entered.</p>
+         *
+         * <p>The indent sender mechanism allows you to have your authentication UI
+         * implemented as an activity or a service or a receiver. However, the recommended
+         * way is to do this is with an activity which the system will start in the
+         * filled activity's task meaning it will properly work with back, recent apps, and
+         * free-form multi-window, while avoiding the need for the "draw on top of other"
+         * apps special permission. You can still theme your authentication activity's
+         * UI to look like a dialog if desired.</p>
+         *
+         * <p></><strong>Note:</strong> Do not make the provided intent sender
+         * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
+         * platform needs to fill in the authentication arguments.</p>
+         *
+         * @param authentication Intent to trigger your authentication flow.
+         *
+         * @see android.app.PendingIntent#getIntentSender()
+         */
+        public @NonNull Builder setAuthentication(@Nullable IntentSender authentication) {
+            throwIfDestroyed();
+            mAuthentication = authentication;
             return this;
         }
 
         /**
-         * Adds a new {@link Dataset} to this response.
+         * Adds a new {@link Dataset} to this response. Adding a dataset with the
+         * same id updates the existing one.
          *
          * @throws IllegalArgumentException if a dataset with same {@code name} already exists.
          */
-        public Builder addDataset(Dataset dataset) {
-            Preconditions.checkNotNull(dataset, "dataset cannot be null");
-            // TODO(b/33197203): check if name already exists
-            mDatasets.add(dataset);
-            for (DatasetField field : dataset.getFields()) {
-                mSavableIds.add(field.getId());
+        public@NonNull Builder addDataset(@Nullable Dataset dataset) {
+            throwIfDestroyed();
+            if (dataset == null) {
+                return this;
+            }
+            if (mDatasets == null) {
+                mDatasets = new ArraySet<>();
+            }
+            final int datasetCount = mDatasets.size();
+            for (int i = 0; i < datasetCount; i++) {
+                if (mDatasets.valueAt(i).getName().equals(dataset.getName())) {
+                    throw new IllegalArgumentException("Duplicate dataset name: "
+                            + dataset.getName());
+                }
+            }
+            if (!mDatasets.add(dataset)) {
+                return this;
+            }
+            final int fieldCount = dataset.getFieldIds().size();
+            for (int i = 0; i < fieldCount; i++) {
+                final AutoFillId id = dataset.getFieldIds().get(i);
+                if (mSavableIds == null) {
+                    mSavableIds = new ArraySet<>();
+                }
+                mSavableIds.add(id);
             }
             return this;
         }
@@ -374,27 +319,35 @@
          *
          * <p>See {@link FillResponse} for examples.
          */
-        public Builder addSavableFields(AutoFillId... ids) {
+        public @NonNull Builder addSavableFields(@Nullable AutoFillId... ids) {
+            throwIfDestroyed();
+            if (ids == null) {
+                return this;
+            }
             for (AutoFillId id : ids) {
+                if (mSavableIds == null) {
+                    mSavableIds = new ArraySet<>();
+                }
                 mSavableIds.add(id);
             }
             return this;
         }
 
         /**
-         * Sets a {@link Bundle} that will be passed to subsequent calls to {@link
-         * android.service.autofill.AutoFillService} methods such as {@link
+         * Sets a {@link Bundle} that will be passed to subsequent APIs that
+         * manipulate this response. For example, they are passed in as {@link
+         * android.content.Intent#EXTRA_AUTO_FILL_EXTRAS extras} to your
+         * authentication flow and to subsequent calls to {@link
+         * android.service.autofill.AutoFillService#onFillRequest(
+         * android.app.assist.AssistStructure, Bundle, android.os.CancellationSignal,
+         * android.service.autofill.FillCallback)} and {@link
          * android.service.autofill.AutoFillService#onSaveRequest(
-         * android.app.assist.AssistStructure, Bundle, android.service.autofill.SaveCallback)},
-         * using {@link
-         * android.service.autofill.AutoFillService#EXTRA_RESPONSE_EXTRAS} as the key.
-         *
-         * <p>It can be used when to keep service state in between calls.
+         * android.app.assist.AssistStructure, Bundle,
+         * android.service.autofill.SaveCallback)}.
          */
         public Builder setExtras(Bundle extras) {
-            // TODO(b/33197203): make sure that either this method or the requires-Authentication
-            // ones are called, but not both
-            mExtras = Objects.requireNonNull(extras, "extras cannot be null");
+            throwIfDestroyed();
+            mExtras = extras;
             return this;
         }
 
@@ -402,8 +355,16 @@
          * Builds a new {@link FillResponse} instance.
          */
         public FillResponse build() {
+            throwIfDestroyed();
+            mDestroyed = true;
             return new FillResponse(this);
         }
+
+        private void throwIfDestroyed() {
+            if (mDestroyed) {
+                throw new IllegalStateException("Already called #build()");
+            }
+        }
     }
 
     /////////////////////////////////////
@@ -412,14 +373,12 @@
     @Override
     public String toString() {
         if (!DEBUG) return super.toString();
-
-        final StringBuilder builder = new StringBuilder("FillResponse: [datasets=")
-                .append(mDatasets).append(", savableIds=").append(Arrays.toString(mSavableIds))
-                .append(", extras=");
-        append(builder, mExtras)
-            .append(", flags=").append(mFlags)
-            .append(", requiresAuth: ").append(mRequiresAuth)
-            .append(", hasCrypto: ").append(mHasCryptoObject);
+        final StringBuilder builder = new StringBuilder(
+                "FillResponse: [id=").append(mId)
+                .append(", datasets=").append(mDatasets)
+                .append(", savableIds=").append(mSavableIds)
+                .append(", hasExtras=").append(mExtras != null)
+                .append(", hasAuthentication=").append(mAuthentication != null);
         return builder.append(']').toString();
     }
 
@@ -434,33 +393,34 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeList(mDatasets);
-        parcel.writeParcelableArray(mSavableIds, 0);
-        parcel.writeBundle(mExtras);
-        parcel.writeInt(mFlags);
-        parcel.writeInt(mRequiresAuth ? 1 : 0);
-        parcel.writeInt(mHasCryptoObject ? 1 : 0);
-        if (mHasCryptoObject) {
-            parcel.writeLong(mCryptoOpId);
-        }
-    }
-
-    private FillResponse(Parcel parcel) {
-        mDatasets = new ArrayList<>();
-        parcel.readList(mDatasets, null);
-        mSavableIds = parcel.readParcelableArray(null, AutoFillId.class);
-        mExtras = parcel.readBundle();
-        mFlags = parcel.readInt();
-        mRequiresAuth = parcel.readInt() == 1;
-        mHasCryptoObject = parcel.readInt() == 1;
-        mCryptoOpId = mHasCryptoObject ? parcel.readLong() : 0;
+        parcel.writeString(mId);
+        parcel.writeTypedArraySet(mDatasets, 0);
+        parcel.writeTypedArraySet(mSavableIds, 0);
+        parcel.writeParcelable(mExtras, 0);
+        parcel.writeParcelable(mAuthentication, 0);
     }
 
     public static final Parcelable.Creator<FillResponse> CREATOR =
             new Parcelable.Creator<FillResponse>() {
         @Override
-        public FillResponse createFromParcel(Parcel source) {
-            return new FillResponse(source);
+        public FillResponse createFromParcel(Parcel parcel) {
+            // Always go through the builder to ensure the data ingested by
+            // the system obeys the contract of the builder to avoid attacks
+            // using specially crafted parcels.
+            final Builder builder = new Builder(parcel.readString());
+            final ArraySet<Dataset> datasets = parcel.readTypedArraySet(null);
+            final int datasetCount = (datasets != null) ? datasets.size() : 0;
+            for (int i = 0; i < datasetCount; i++) {
+                builder.addDataset(datasets.valueAt(i));
+            }
+            final ArraySet<AutoFillId> fillIds = parcel.readTypedArraySet(null);
+            final int fillIdCount = (fillIds != null) ? fillIds.size() : 0;
+            for (int i = 0; i < fillIdCount; i++) {
+                builder.addSavableFields(fillIds.valueAt(i));
+            }
+            builder.setExtras(parcel.readParcelable(null));
+            builder.setAuthentication(parcel.readParcelable(null));
+            return builder.build();
         }
 
         @Override
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index b6da1d8..71809bd 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -16,6 +16,7 @@
 
 package android.view.inputmethod;
 
+import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -42,7 +43,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 /**
  * This class is used to specify meta information of an input method.
@@ -110,6 +110,19 @@
     private final boolean mSupportsDismissingWindow;
 
     /**
+     * @param service the {@link ResolveInfo} corresponds in which the IME is implemented.
+     * @return a unique ID to be returned by {@link #getId()}. We have used
+     *         {@link ComponentName#flattenToShortString()} for this purpose (and it is already
+     *         unrealistic to switch to a different scheme as it is already implicitly assumed in
+     *         many places).
+     * @hide
+     */
+    public static String computeId(@NonNull ResolveInfo service) {
+        final ServiceInfo si = service.serviceInfo;
+        return new ComponentName(si.packageName, si.name).flattenToShortString();
+    }
+
+    /**
      * Constructor.
      *
      * @param context The Context in which we are parsing the input method.
@@ -127,15 +140,15 @@
      * @param context The Context in which we are parsing the input method.
      * @param service The ResolveInfo returned from the package manager about
      * this input method's component.
-     * @param additionalSubtypesMap additional subtypes being added to this InputMethodInfo
+     * @param additionalSubtypes additional subtypes being added to this InputMethodInfo
      * @hide
      */
     public InputMethodInfo(Context context, ResolveInfo service,
-            Map<String, List<InputMethodSubtype>> additionalSubtypesMap)
+            List<InputMethodSubtype> additionalSubtypes)
             throws XmlPullParserException, IOException {
         mService = service;
         ServiceInfo si = service.serviceInfo;
-        mId = new ComponentName(si.packageName, si.name).flattenToShortString();
+        mId = computeId(service);
         boolean isAuxIme = true;
         boolean supportsSwitchingToNextInputMethod = false; // false as default
         boolean supportsDismissingWindow = false; // false as default
@@ -233,8 +246,7 @@
             isAuxIme = false;
         }
 
-        if (additionalSubtypesMap != null && additionalSubtypesMap.containsKey(mId)) {
-            final List<InputMethodSubtype> additionalSubtypes = additionalSubtypesMap.get(mId);
+        if (additionalSubtypes != null) {
             final int N = additionalSubtypes.size();
             for (int i = 0; i < N; ++i) {
                 final InputMethodSubtype subtype = additionalSubtypes.get(i);
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 4673c50..a85dea9 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -55,7 +55,7 @@
     /**
      * Returns the default text classifier.
      */
-    public TextClassifier getDefaultTextClassifier() {
+    public synchronized TextClassifier getDefaultTextClassifier() {
         if (mDefault == null) {
             try {
                 mFd = ParcelFileDescriptor.open(
@@ -95,7 +95,7 @@
         return Collections.emptyList();
     }
 
-    private LangId getLanguageDetector() {
+    private synchronized LangId getLanguageDetector() {
         if (mLangId == null) {
             // TODO: Use a file descriptor as soon as we start to depend on a model file
             // for language detection.
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 0657067..7838918 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -157,18 +158,29 @@
                 .setEntityType(type, 1.0f /* confidence */)
                 .setIntent(intent)
                 .setOnClickListener(TextClassificationResult.createStartActivityOnClick(
-                        mContext, intent))
-                .setLabel(IntentFactory.getLabel(mContext, type));
+                        mContext, intent));
         final PackageManager pm = mContext.getPackageManager();
         final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
-        // TODO: If the resolveInfo is the "chooser", do not set the package name and use a default
-        // icon for this classification type.
-        intent.setPackage(resolveInfo.activityInfo.packageName);
-        Drawable icon = resolveInfo.activityInfo.loadIcon(pm);
-        if (icon == null) {
-            icon = resolveInfo.loadIcon(pm);
+        if (resolveInfo != null && resolveInfo.activityInfo != null) {
+            final String packageName = resolveInfo.activityInfo.packageName;
+            if ("android".equals(packageName)) {
+                // Requires the chooser to find an activity to handle the intent.
+                builder.setLabel(IntentFactory.getLabel(mContext, type));
+            } else {
+                // A default activity will handle the intent.
+                intent.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
+                Drawable icon = resolveInfo.activityInfo.loadIcon(pm);
+                if (icon == null) {
+                    icon = resolveInfo.loadIcon(pm);
+                }
+                builder.setIcon(icon);
+                CharSequence label = resolveInfo.activityInfo.loadLabel(pm);
+                if (label == null) {
+                    label = resolveInfo.loadLabel(pm);
+                }
+                builder.setLabel(label != null ? label.toString() : null);
+            }
         }
-        builder.setIcon(icon);
         return builder.build();
     }
 
@@ -211,9 +223,12 @@
                     final String type =
                             smartSelection.classifyText(text, selectionStart, selectionEnd);
                     if (matches(type, linkMask)) {
-                        final ClickableSpan span = createSpan(
-                                context, type, text.substring(selectionStart, selectionEnd));
-                        spans.add(new SpanSpec(selectionStart, selectionEnd, span));
+                        final Intent intent = IntentFactory.create(
+                                type, text.substring(selectionStart, selectionEnd));
+                        if (hasActivityHandler(context, intent)) {
+                            final ClickableSpan span = createSpan(context, intent);
+                            spans.add(new SpanSpec(selectionStart, selectionEnd, span));
+                        }
                     }
                 }
                 start = end;
@@ -279,17 +294,24 @@
             return result;
         }
 
-        private static ClickableSpan createSpan(
-                final Context context, final String type, final String text) {
+        private static ClickableSpan createSpan(final Context context, final Intent intent) {
             return new ClickableSpan() {
                 // TODO: Style this span.
                 @Override
                 public void onClick(View widget) {
-                    context.startActivity(IntentFactory.create(type, text));
+                    context.startActivity(intent);
                 }
             };
         }
 
+        private static boolean hasActivityHandler(Context context, @Nullable Intent intent) {
+            if (intent == null) {
+                return false;
+            }
+            final ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, 0);
+            return resolveInfo != null && resolveInfo.activityInfo != null;
+        }
+
         /**
          * Implementation of LinksInfo that adds ClickableSpans to the specified text.
          */
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 9a39a17..51587a7 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -250,7 +250,7 @@
         mDefaultActivityButton = (FrameLayout) findViewById(R.id.default_activity_button);
         mDefaultActivityButton.setOnClickListener(mCallbacks);
         mDefaultActivityButton.setOnLongClickListener(mCallbacks);
-        mDefaultActivityButtonImage = mDefaultActivityButton.findViewById(R.id.image);
+        mDefaultActivityButtonImage = (ImageView) mDefaultActivityButton.findViewById(R.id.image);
 
         final FrameLayout expandButton = (FrameLayout) findViewById(R.id.expand_activities_button);
         expandButton.setOnClickListener(mCallbacks);
@@ -282,7 +282,7 @@
         mExpandActivityOverflowButton = expandButton;
 
         mExpandActivityOverflowButtonImage =
-            expandButton.findViewById(R.id.image);
+            (ImageView) expandButton.findViewById(R.id.image);
         mExpandActivityOverflowButtonImage.setImageDrawable(expandActivityOverflowButtonDrawable);
 
         mAdapter = new ActivityChooserViewAdapter();
@@ -760,7 +760,7 @@
                         convertView = LayoutInflater.from(getContext()).inflate(
                                 R.layout.activity_chooser_view_list_item, parent, false);
                         convertView.setId(ITEM_VIEW_TYPE_FOOTER);
-                        TextView titleView = convertView.findViewById(R.id.title);
+                        TextView titleView = (TextView) convertView.findViewById(R.id.title);
                         titleView.setText(mContext.getString(
                                 R.string.activity_chooser_view_see_all));
                     }
@@ -772,11 +772,11 @@
                     }
                     PackageManager packageManager = mContext.getPackageManager();
                     // Set the icon
-                    ImageView iconView = convertView.findViewById(R.id.icon);
+                    ImageView iconView = (ImageView) convertView.findViewById(R.id.icon);
                     ResolveInfo activity = (ResolveInfo) getItem(position);
                     iconView.setImageDrawable(activity.loadIcon(packageManager));
                     // Set the title.
-                    TextView titleView = convertView.findViewById(R.id.title);
+                    TextView titleView = (TextView) convertView.findViewById(R.id.title);
                     titleView.setText(activity.loadLabel(packageManager));
                     // Highlight the default.
                     if (mShowDefaultActivity && position == 0 && mHighlightDefaultActivity) {
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 06d4868..68e6809 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -451,7 +451,7 @@
 
     private View getPermissionsView(int which, boolean showRevokeUI) {
         LinearLayout permsView = (LinearLayout) mInflater.inflate(R.layout.app_perms_summary, null);
-        LinearLayout displayList = permsView.findViewById(R.id.perms_list);
+        LinearLayout displayList = (LinearLayout) permsView.findViewById(R.id.perms_list);
         View noPermsView = permsView.findViewById(R.id.no_permissions);
 
         displayPermissions(mPermGroupsList, displayList, which, showRevokeUI);
@@ -517,8 +517,8 @@
             CharSequence grpName, CharSequence permList, boolean dangerous, Drawable icon) {
         View permView = inflater.inflate(R.layout.app_permission_item_old, null);
 
-        TextView permGrpView = permView.findViewById(R.id.permission_group);
-        TextView permDescView = permView.findViewById(R.id.permission_list);
+        TextView permGrpView = (TextView) permView.findViewById(R.id.permission_group);
+        TextView permDescView = (TextView) permView.findViewById(R.id.permission_list);
 
         ImageView imgView = (ImageView)permView.findViewById(R.id.perm_icon);
         imgView.setImageDrawable(icon);
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index 81f0d3d..bbc50da 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -388,7 +388,7 @@
                 text = (TextView) view;
             } else {
                 //  Otherwise, find the TextView field within the layout
-                text = view.findViewById(mFieldId);
+                text = (TextView) view.findViewById(mFieldId);
 
                 if (text == null) {
                     throw new RuntimeException("Failed to find view with ID "
diff --git a/core/java/android/widget/CalendarViewLegacyDelegate.java b/core/java/android/widget/CalendarViewLegacyDelegate.java
index 1b899db..557d411 100644
--- a/core/java/android/widget/CalendarViewLegacyDelegate.java
+++ b/core/java/android/widget/CalendarViewLegacyDelegate.java
@@ -316,9 +316,9 @@
         View content = layoutInflater.inflate(R.layout.calendar_view, null, false);
         mDelegator.addView(content);
 
-        mListView = mDelegator.findViewById(R.id.list);
-        mDayNamesHeader = content.findViewById(R.id.day_names);
-        mMonthName = content.findViewById(R.id.month_name);
+        mListView = (ListView) mDelegator.findViewById(R.id.list);
+        mDayNamesHeader = (ViewGroup) content.findViewById(R.id.day_names);
+        mMonthName = (TextView) content.findViewById(R.id.month_name);
 
         setUpHeader();
         setUpListView();
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 907250a..f712685 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -115,10 +115,10 @@
         mDelegator.addView(mContainer);
 
         // Set up header views.
-        final ViewGroup header = mContainer.findViewById(R.id.date_picker_header);
-        mHeaderYear = header.findViewById(R.id.date_picker_header_year);
+        final ViewGroup header = (ViewGroup) mContainer.findViewById(R.id.date_picker_header);
+        mHeaderYear = (TextView) header.findViewById(R.id.date_picker_header_year);
         mHeaderYear.setOnClickListener(mOnHeaderClickListener);
-        mHeaderMonthDay = header.findViewById(R.id.date_picker_header_date);
+        mHeaderMonthDay = (TextView) header.findViewById(R.id.date_picker_header_date);
         mHeaderMonthDay.setOnClickListener(mOnHeaderClickListener);
 
         // For the sake of backwards compatibility, attempt to extract the text
@@ -154,10 +154,10 @@
         a.recycle();
 
         // Set up picker container.
-        mAnimator = mContainer.findViewById(R.id.animator);
+        mAnimator = (ViewAnimator) mContainer.findViewById(R.id.animator);
 
         // Set up day picker view.
-        mDayPickerView = mAnimator.findViewById(R.id.date_picker_day_picker);
+        mDayPickerView = (DayPickerView) mAnimator.findViewById(R.id.date_picker_day_picker);
         mDayPickerView.setFirstDayOfWeek(mFirstDayOfWeek);
         mDayPickerView.setMinDate(mMinDate.getTimeInMillis());
         mDayPickerView.setMaxDate(mMaxDate.getTimeInMillis());
@@ -165,7 +165,7 @@
         mDayPickerView.setOnDaySelectedListener(mOnDaySelectedListener);
 
         // Set up year picker view.
-        mYearPickerView = mAnimator.findViewById(R.id.date_picker_year_picker);
+        mYearPickerView = (YearPickerView) mAnimator.findViewById(R.id.date_picker_year_picker);
         mYearPickerView.setRange(mMinDate, mMaxDate);
         mYearPickerView.setYear(mCurrentDate.get(Calendar.YEAR));
         mYearPickerView.setOnYearSelectedListener(mOnYearSelectedListener);
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index 63621e1..8d5bf8f 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -225,7 +225,7 @@
     public Object instantiateItem(ViewGroup container, int position) {
         final View itemView = mInflater.inflate(mLayoutResId, container, false);
 
-        final SimpleMonthView v = itemView.findViewById(mCalendarViewId);
+        final SimpleMonthView v = (SimpleMonthView) itemView.findViewById(mCalendarViewId);
         v.setOnDayClickListener(mOnDayClickListener);
         v.setMonthTextAppearance(mMonthTextAppearance);
         v.setDayOfWeekTextAppearance(mDayOfWeekTextAppearance);
diff --git a/core/java/android/widget/DayPickerViewPager.java b/core/java/android/widget/DayPickerViewPager.java
index 058baa6..94022ae 100644
--- a/core/java/android/widget/DayPickerViewPager.java
+++ b/core/java/android/widget/DayPickerViewPager.java
@@ -137,10 +137,9 @@
     }
 
     @Override
-    protected <T extends View> T findViewByPredicateTraversal(Predicate<View> predicate,
-            View childToSkip) {
+    protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
         if (predicate.apply(this)) {
-            return (T) this;
+            return this;
         }
 
         // Always try the selected view first.
@@ -149,7 +148,7 @@
         if (current != childToSkip && current != null) {
             final View v = current.findViewByPredicate(predicate);
             if (v != null) {
-                return (T) v;
+                return v;
             }
         }
 
@@ -161,7 +160,7 @@
                 final View v = child.findViewByPredicate(predicate);
 
                 if (v != null) {
-                    return (T) v;
+                    return v;
                 }
             }
         }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index c1834f1..a2cb491 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3917,12 +3917,18 @@
         private void updateAssistMenuItem(
                 Menu menu, TextClassificationResult textClassificationResult) {
             menu.removeItem(TextView.ID_ASSIST);
-            if (textClassificationResult != null
-                    && textClassificationResult.getIcon() != null
-                    && textClassificationResult.getOnClickListener() != null) {
-                menu.add(Menu.NONE, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST, null)
-                        .setIcon(textClassificationResult.getIcon())
-                        .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+            if (textClassificationResult != null) {
+                final Drawable icon = textClassificationResult.getIcon();
+                final CharSequence label = textClassificationResult.getLabel();
+                final OnClickListener onClickListener =
+                        textClassificationResult.getOnClickListener();
+                final Intent intent = textClassificationResult.getIntent();
+                if ((icon != null || !TextUtils.isEmpty(label))
+                        && (onClickListener != null || intent != null)) {
+                    menu.add(Menu.NONE, TextView.ID_ASSIST, MENU_ITEM_ORDER_ASSIST, label)
+                            .setIcon(icon)
+                            .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+                }
             }
         }
 
@@ -3935,9 +3941,22 @@
             if (customCallback != null && customCallback.onActionItemClicked(mode, item)) {
                 return true;
             }
-            if (TextView.ID_ASSIST == item.getItemId() && mTextClassificationResult != null) {
-                mTextClassificationResult.getOnClickListener().onClick(mTextView);
+            final TextClassificationResult textClassificationResult = mTextClassificationResult;
+            if (TextView.ID_ASSIST == item.getItemId() && textClassificationResult != null) {
+                final OnClickListener onClickListener =
+                        textClassificationResult.getOnClickListener();
+                if (onClickListener != null) {
+                    onClickListener.onClick(mTextView);
+                } else {
+                    final Intent intent = textClassificationResult.getIntent();
+                    if (intent != null) {
+                        TextClassificationResult.createStartActivityOnClick(
+                                mTextView.getContext(), intent)
+                                .onClick(mTextView);
+                    }
+                }
                 stopTextActionMode();
+                return true;
             }
             return mTextView.onTextContextMenuItem(item.getItemId());
         }
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index b7da04e..80780a6 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -3740,21 +3740,20 @@
      * @removed For internal use only. This should have been hidden.
      */
     @Override
-    protected <T extends View> T findViewTraversal(@IdRes int id) {
-        // First look in our children, then in any header and footer views that
-        // may be scrolled off.
-        View v = super.findViewTraversal(id);
+    protected View findViewTraversal(@IdRes int id) {
+        View v;
+        v = super.findViewTraversal(id);
         if (v == null) {
             v = findViewInHeadersOrFooters(mHeaderViewInfos, id);
             if (v != null) {
-                return (T) v;
+                return v;
             }
             v = findViewInHeadersOrFooters(mFooterViewInfos, id);
             if (v != null) {
-                return (T) v;
+                return v;
             }
         }
-        return (T) v;
+        return v;
     }
 
     View findViewInHeadersOrFooters(ArrayList<FixedViewInfo> where, int id) {
@@ -3783,22 +3782,21 @@
      * @removed For internal use only. This should have been hidden.
      */
     @Override
-    protected <T extends View> T findViewWithTagTraversal(Object tag) {
-        // First look in our children, then in any header and footer views that
-        // may be scrolled off.
-        View v = super.findViewWithTagTraversal(tag);
+    protected View findViewWithTagTraversal(Object tag) {
+        View v;
+        v = super.findViewWithTagTraversal(tag);
         if (v == null) {
             v = findViewWithTagInHeadersOrFooters(mHeaderViewInfos, tag);
             if (v != null) {
-                return (T) v;
+                return v;
             }
 
             v = findViewWithTagInHeadersOrFooters(mFooterViewInfos, tag);
             if (v != null) {
-                return (T) v;
+                return v;
             }
         }
-        return (T) v;
+        return v;
     }
 
     View findViewWithTagInHeadersOrFooters(ArrayList<FixedViewInfo> where, Object tag) {
@@ -3831,21 +3829,21 @@
      * @hide
      */
     @Override
-    protected <T extends View> T findViewByPredicateTraversal(
-            Predicate<View> predicate, View childToSkip) {
-        View v = super.findViewByPredicateTraversal(predicate, childToSkip);
+    protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
+        View v;
+        v = super.findViewByPredicateTraversal(predicate, childToSkip);
         if (v == null) {
             v = findViewByPredicateInHeadersOrFooters(mHeaderViewInfos, predicate, childToSkip);
             if (v != null) {
-                return (T) v;
+                return v;
             }
 
             v = findViewByPredicateInHeadersOrFooters(mFooterViewInfos, predicate, childToSkip);
             if (v != null) {
-                return (T) v;
+                return v;
             }
         }
-        return (T) v;
+        return v;
     }
 
     /**
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 8e04f1c..8008637 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -257,13 +257,13 @@
                 .getText(com.android.internal.R.string.lockscreen_transport_play_description);
         mPauseDescription = res
                 .getText(com.android.internal.R.string.lockscreen_transport_pause_description);
-        mPauseButton = v.findViewById(com.android.internal.R.id.pause);
+        mPauseButton = (ImageButton) v.findViewById(com.android.internal.R.id.pause);
         if (mPauseButton != null) {
             mPauseButton.requestFocus();
             mPauseButton.setOnClickListener(mPauseListener);
         }
 
-        mFfwdButton = v.findViewById(com.android.internal.R.id.ffwd);
+        mFfwdButton = (ImageButton) v.findViewById(com.android.internal.R.id.ffwd);
         if (mFfwdButton != null) {
             mFfwdButton.setOnClickListener(mFfwdListener);
             if (!mFromXml) {
@@ -271,7 +271,7 @@
             }
         }
 
-        mRewButton = v.findViewById(com.android.internal.R.id.rew);
+        mRewButton = (ImageButton) v.findViewById(com.android.internal.R.id.rew);
         if (mRewButton != null) {
             mRewButton.setOnClickListener(mRewListener);
             if (!mFromXml) {
@@ -280,16 +280,16 @@
         }
 
         // By default these are hidden. They will be enabled when setPrevNextListeners() is called
-        mNextButton = v.findViewById(com.android.internal.R.id.next);
+        mNextButton = (ImageButton) v.findViewById(com.android.internal.R.id.next);
         if (mNextButton != null && !mFromXml && !mListenersSet) {
             mNextButton.setVisibility(View.GONE);
         }
-        mPrevButton = v.findViewById(com.android.internal.R.id.prev);
+        mPrevButton = (ImageButton) v.findViewById(com.android.internal.R.id.prev);
         if (mPrevButton != null && !mFromXml && !mListenersSet) {
             mPrevButton.setVisibility(View.GONE);
         }
 
-        mProgress = v.findViewById(com.android.internal.R.id.mediacontroller_progress);
+        mProgress = (ProgressBar) v.findViewById(com.android.internal.R.id.mediacontroller_progress);
         if (mProgress != null) {
             if (mProgress instanceof SeekBar) {
                 SeekBar seeker = (SeekBar) mProgress;
@@ -298,8 +298,8 @@
             mProgress.setMax(1000);
         }
 
-        mEndTime = v.findViewById(com.android.internal.R.id.time);
-        mCurrentTime = v.findViewById(com.android.internal.R.id.time_current);
+        mEndTime = (TextView) v.findViewById(com.android.internal.R.id.time);
+        mCurrentTime = (TextView) v.findViewById(com.android.internal.R.id.time_current);
         mFormatBuilder = new StringBuilder();
         mFormatter = new Formatter(mFormatBuilder, Locale.getDefault());
 
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 5199b26..989927e 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -35,8 +35,8 @@
 import android.transition.Transition;
 import android.transition.Transition.EpicenterCallback;
 import android.transition.Transition.TransitionListener;
-import android.transition.Transition.TransitionListenerAdapter;
 import android.transition.TransitionInflater;
+import android.transition.TransitionListenerAdapter;
 import android.transition.TransitionManager;
 import android.transition.TransitionSet;
 import android.util.AttributeSet;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 5505f2f..359d04e 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1578,7 +1578,7 @@
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
             final Context context = root.getContext();
-            final ViewGroup target = root.findViewById(viewId);
+            final ViewGroup target = (ViewGroup) root.findViewById(viewId);
             if (target == null) return;
             if (nestedViews != null) {
                 // Inflate nested views and add as children
@@ -1757,7 +1757,7 @@
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
-            final TextView target = root.findViewById(viewId);
+            final TextView target = (TextView) root.findViewById(viewId);
             if (target == null) return;
             if (drawablesLoaded) {
                 if (isRelative) {
@@ -1857,7 +1857,7 @@
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
-            final TextView target = root.findViewById(viewId);
+            final TextView target = (TextView) root.findViewById(viewId);
             if (target == null) return;
             target.setTextSize(units, size);
         }
@@ -2045,7 +2045,7 @@
 
         @Override
         public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
-            final TextView target = root.findViewById(viewId);
+            final TextView target = (TextView) root.findViewById(viewId);
             if (target == null) return;
             Drawable[] drawables = isRelative
                     ? target.getCompoundDrawablesRelative()
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index fbb8993..f833d1b 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -286,7 +286,7 @@
         v.setTag(new ChildViewCache(v));
 
         // Set up icon.
-        final ImageView iconRefine = v.findViewById(R.id.edit_query);
+        final ImageView iconRefine = (ImageView) v.findViewById(R.id.edit_query);
         iconRefine.setImageResource(mCommitIconResId);
 
         return v;
@@ -304,11 +304,11 @@
         public final ImageView mIconRefine;
 
         public ChildViewCache(View v) {
-            mText1 = v.findViewById(com.android.internal.R.id.text1);
-            mText2 = v.findViewById(com.android.internal.R.id.text2);
-            mIcon1 = v.findViewById(com.android.internal.R.id.icon1);
-            mIcon2 = v.findViewById(com.android.internal.R.id.icon2);
-            mIconRefine = v.findViewById(com.android.internal.R.id.edit_query);
+            mText1 = (TextView) v.findViewById(com.android.internal.R.id.text1);
+            mText2 = (TextView) v.findViewById(com.android.internal.R.id.text2);
+            mIcon1 = (ImageView) v.findViewById(com.android.internal.R.id.icon1);
+            mIcon2 = (ImageView) v.findViewById(com.android.internal.R.id.icon2);
+            mIconRefine = (ImageView) v.findViewById(com.android.internal.R.id.edit_query);
         }
     }
 
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 7e2cadf..32418cd 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -619,7 +619,7 @@
                     mTabWidget, // tab widget is the parent
                     false); // no inflate params
 
-            final TextView tv = tabIndicator.findViewById(R.id.title);
+            final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
             tv.setText(mLabel);
 
             if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
@@ -653,8 +653,8 @@
                     mTabWidget, // tab widget is the parent
                     false); // no inflate params
 
-            final TextView tv = tabIndicator.findViewById(R.id.title);
-            final ImageView iconView = tabIndicator.findViewById(R.id.icon);
+            final TextView tv = (TextView) tabIndicator.findViewById(R.id.title);
+            final ImageView iconView = (ImageView) tabIndicator.findViewById(R.id.icon);
 
             // when icon is gone by default, we're in exclusive mode
             final boolean exclusive = iconView.getVisibility() == View.GONE;
diff --git a/core/java/android/widget/TextInputTimePickerView.java b/core/java/android/widget/TextInputTimePickerView.java
new file mode 100644
index 0000000..ef91576
--- /dev/null
+++ b/core/java/android/widget/TextInputTimePickerView.java
@@ -0,0 +1,249 @@
+/*
+ * 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.widget;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.InputFilter;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.util.MathUtils;
+import android.view.View;
+
+import com.android.internal.R;
+
+/**
+ * View to show text input based time picker with hour and minute fields and an optional AM/PM
+ * spinner.
+ *
+ * @hide
+ */
+public class TextInputTimePickerView extends RelativeLayout {
+    public static final int HOURS = 0;
+    public static final int MINUTES = 1;
+    public static final int AMPM = 2;
+
+    private static final int AM = 0;
+    private static final int PM = 1;
+
+    private final EditText mHourEditText;
+    private final EditText mMinuteEditText;
+    private final TextView mInputSeparatorView;
+    private final Spinner mAmPmSpinner;
+    private final TextView mErrorLabel;
+    private final TextView mHourLabel;
+    private final TextView mMinuteLabel;
+
+    private boolean mIs24Hour;
+    private boolean mHourFormatStartsAtZero;
+    private OnValueTypedListener mListener;
+
+    private boolean mErrorShowing;
+
+    interface OnValueTypedListener {
+        void onValueChanged(int inputType, int newValue);
+    }
+
+    public TextInputTimePickerView(Context context) {
+        this(context, null);
+    }
+
+    public TextInputTimePickerView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TextInputTimePickerView(Context context, AttributeSet attrs, int defStyle) {
+        this(context, attrs, defStyle, 0);
+    }
+
+    public TextInputTimePickerView(Context context, AttributeSet attrs, int defStyle,
+            int defStyleRes) {
+        super(context, attrs, defStyle, defStyleRes);
+
+        inflate(context, R.layout.time_picker_text_input_material, this);
+
+        mHourEditText = (EditText) findViewById(R.id.input_hour);
+        mMinuteEditText = (EditText) findViewById(R.id.input_minute);
+        mInputSeparatorView = (TextView) findViewById(R.id.input_separator);
+        mErrorLabel = (TextView) findViewById(R.id.label_error);
+        mHourLabel = (TextView) findViewById(R.id.label_hour);
+        mMinuteLabel = (TextView) findViewById(R.id.label_minute);
+
+        mHourEditText.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
+
+            @Override
+            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
+
+            @Override
+            public void afterTextChanged(Editable editable) {
+                parseAndSetHourInternal(editable.toString());
+            }
+        });
+
+        mMinuteEditText.addTextChangedListener(new TextWatcher() {
+            @Override
+            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
+
+            @Override
+            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
+
+            @Override
+            public void afterTextChanged(Editable editable) {
+                parseAndSetMinuteInternal(editable.toString());
+            }
+        });
+
+        mAmPmSpinner = (Spinner) findViewById(R.id.am_pm_spinner);
+        final String[] amPmStrings = TimePicker.getAmPmStrings(context);
+        ArrayAdapter<CharSequence> adapter =
+                new ArrayAdapter<CharSequence>(context, R.layout.simple_spinner_dropdown_item);
+        adapter.add(TimePickerClockDelegate.obtainVerbatim(amPmStrings[0]));
+        adapter.add(TimePickerClockDelegate.obtainVerbatim(amPmStrings[1]));
+        mAmPmSpinner.setAdapter(adapter);
+        mAmPmSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> adapterView, View view, int position,
+                    long id) {
+                if (position == 0) {
+                    mListener.onValueChanged(AMPM, AM);
+                } else {
+                    mListener.onValueChanged(AMPM, PM);
+                }
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> adapterView) {}
+        });
+    }
+
+    void setListener(OnValueTypedListener listener) {
+        mListener = listener;
+    }
+
+    void setHourFormat(int maxCharLength) {
+        mHourEditText.setFilters(new InputFilter[] {
+                new InputFilter.LengthFilter(maxCharLength)});
+        mMinuteEditText.setFilters(new InputFilter[] {
+                new InputFilter.LengthFilter(maxCharLength)});
+    }
+
+    boolean validateInput() {
+        final boolean inputValid = parseAndSetHourInternal(mHourEditText.getText().toString())
+                && parseAndSetMinuteInternal(mMinuteEditText.getText().toString());
+        setError(!inputValid);
+        return inputValid;
+    }
+
+    void updateSeparator(String separatorText) {
+        mInputSeparatorView.setText(separatorText);
+    }
+
+    private void setError(boolean enabled) {
+        mErrorShowing = enabled;
+
+        mErrorLabel.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
+        mHourLabel.setVisibility(enabled ? View.INVISIBLE : View.VISIBLE);
+        mMinuteLabel.setVisibility(enabled ? View.INVISIBLE : View.VISIBLE);
+    }
+
+    /**
+     * Computes the display value and updates the text of the view.
+     * <p>
+     * This method should be called whenever the current value or display
+     * properties (leading zeroes, max digits) change.
+     */
+    void updateTextInputValues(int localizedHour, int minute, int amOrPm, boolean is24Hour,
+            boolean hourFormatStartsAtZero) {
+        final String format = "%d";
+
+        mIs24Hour = is24Hour;
+        mHourFormatStartsAtZero = hourFormatStartsAtZero;
+
+        mAmPmSpinner.setVisibility(is24Hour ? View.INVISIBLE : View.VISIBLE);
+
+        mHourEditText.setText(String.format(format, localizedHour));
+        mMinuteEditText.setText(String.format(format, minute));
+
+        if (amOrPm == AM) {
+            mAmPmSpinner.setSelection(0);
+        } else {
+            mAmPmSpinner.setSelection(1);
+        }
+
+        if (mErrorShowing) {
+            validateInput();
+        }
+    }
+
+    private boolean parseAndSetHourInternal(String input) {
+        try {
+            final int hour = Integer.parseInt(input);
+            if (!isValidLocalizedHour(hour)) {
+                final int minHour = mHourFormatStartsAtZero ? 0 : 1;
+                final int maxHour = mIs24Hour ? 23 : 11 + minHour;
+                mListener.onValueChanged(HOURS, getHourOfDayFromLocalizedHour(
+                        MathUtils.constrain(hour, minHour, maxHour)));
+                return false;
+            }
+            mListener.onValueChanged(HOURS, getHourOfDayFromLocalizedHour(hour));
+            return true;
+        } catch (NumberFormatException e) {
+            // Do nothing since we cannot parse the input.
+            return false;
+        }
+    }
+
+    private boolean parseAndSetMinuteInternal(String input) {
+        try {
+            final int minutes = Integer.parseInt(input);
+            if (minutes < 0 || minutes > 59) {
+                mListener.onValueChanged(MINUTES, MathUtils.constrain(minutes, 0, 59));
+                return false;
+            }
+            mListener.onValueChanged(MINUTES, minutes);
+            return true;
+        } catch (NumberFormatException e) {
+            // Do nothing since we cannot parse the input.
+            return false;
+        }
+    }
+
+    private boolean isValidLocalizedHour(int localizedHour) {
+        final int minHour = mHourFormatStartsAtZero ? 0 : 1;
+        final int maxHour = (mIs24Hour ? 23 : 11) + minHour;
+        return localizedHour >= minHour && localizedHour <= maxHour;
+    }
+
+    private int getHourOfDayFromLocalizedHour(int localizedHour) {
+        int hourOfDay = localizedHour;
+        if (mIs24Hour) {
+            if (!mHourFormatStartsAtZero && localizedHour == 24) {
+                hourOfDay = 0;
+            }
+        } else {
+            if (!mHourFormatStartsAtZero && localizedHour == 12) {
+                hourOfDay = 0;
+            }
+            if (mAmPmSpinner.getSelectedItemPosition() == 1) {
+                hourOfDay += 12;
+            }
+        }
+        return hourOfDay;
+    }
+}
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index e6cd798..9f38b04 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -278,6 +278,16 @@
         return mDelegate.getBaseline();
     }
 
+    /**
+     * Validates whether current input by the user is a valid time based on the locale. TimePicker
+     * will show an error message to the user if the time is not valid.
+     *
+     * @return {@code true} if the input is valid, {@code false} otherwise
+     */
+    public boolean validateInput() {
+        return mDelegate.validateInput();
+    }
+
     @Override
     protected Parcelable onSaveInstanceState() {
         Parcelable superState = super.onSaveInstanceState();
@@ -341,6 +351,8 @@
         void setIs24Hour(boolean is24Hour);
         boolean is24Hour();
 
+        boolean validateInput();
+
         void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener);
 
         void setEnabled(boolean enabled);
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index 1d37a21..3a09063 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -16,12 +16,14 @@
 
 package android.widget;
 
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.icu.text.DecimalFormatSymbols;
 import android.os.Parcelable;
 import android.text.SpannableStringBuilder;
 import android.text.format.DateFormat;
@@ -40,11 +42,14 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.widget.RadialTimePickerView.OnValueSelectedListener;
+import android.widget.TextInputTimePickerView.OnValueTypedListener;
 
 import com.android.internal.R;
 import com.android.internal.widget.NumericTextView;
 import com.android.internal.widget.NumericTextView.OnValueChangedListener;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Calendar;
 
 /**
@@ -58,6 +63,13 @@
      */
     private static final long DELAY_COMMIT_MILLIS = 2000;
 
+    @IntDef({FROM_EXTERNAL_API, FROM_RADIAL_PICKER, FROM_INPUT_PICKER})
+    @Retention(RetentionPolicy.SOURCE)
+    private @interface ChangeSource {}
+    private static final int FROM_EXTERNAL_API = 0;
+    private static final int FROM_RADIAL_PICKER = 1;
+    private static final int FROM_INPUT_PICKER = 2;
+
     // Index used by RadialPickerLayout
     private static final int HOUR_INDEX = RadialTimePickerView.HOURS;
     private static final int MINUTE_INDEX = RadialTimePickerView.MINUTES;
@@ -78,6 +90,15 @@
     private final RadialTimePickerView mRadialTimePickerView;
     private final TextView mSeparatorView;
 
+    private boolean mRadialPickerModeEnabled = true;
+    private final ImageButton mRadialTimePickerModeButton;
+    private final String mRadialTimePickerModeEnabledDescription;
+    private final String mTextInputPickerModeEnabledDescription;
+    private final View mRadialTimePickerHeader;
+    private final View mTextInputPickerHeader;
+
+    private final TextInputTimePickerView mTextInputPickerView;
+
     private final Calendar mTempCalendar;
 
     // Accessibility strings.
@@ -116,8 +137,8 @@
         final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout,
                 R.layout.time_picker_material);
         final View mainView = inflater.inflate(layoutResourceId, delegator);
-        final View headerView = mainView.findViewById(R.id.time_header);
-        headerView.setOnTouchListener(new NearestTouchDelegate());
+        mRadialTimePickerHeader = mainView.findViewById(R.id.time_header);
+        mRadialTimePickerHeader.setOnTouchListener(new NearestTouchDelegate());
 
         // Set up hour/minute labels.
         mHourView = (NumericTextView) mainView.findViewById(R.id.hours);
@@ -170,6 +191,8 @@
             headerTextColor = a.getColorStateList(R.styleable.TimePicker_headerTextColor);
         }
 
+        mTextInputPickerHeader = mainView.findViewById(R.id.input_header);
+
         if (headerTextColor != null) {
             mHourView.setTextColor(headerTextColor);
             mSeparatorView.setTextColor(headerTextColor);
@@ -180,7 +203,10 @@
 
         // Set up header background, if available.
         if (a.hasValueOrEmpty(R.styleable.TimePicker_headerBackground)) {
-            headerView.setBackground(a.getDrawable(R.styleable.TimePicker_headerBackground));
+            mRadialTimePickerHeader.setBackground(a.getDrawable(
+                    R.styleable.TimePicker_headerBackground));
+            mTextInputPickerHeader.setBackground(a.getDrawable(
+                    R.styleable.TimePicker_headerBackground));
         }
 
         a.recycle();
@@ -189,6 +215,22 @@
         mRadialTimePickerView.applyAttributes(attrs, defStyleAttr, defStyleRes);
         mRadialTimePickerView.setOnValueSelectedListener(mOnValueSelectedListener);
 
+        mTextInputPickerView = (TextInputTimePickerView) mainView.findViewById(R.id.input_mode);
+        mTextInputPickerView.setListener(mOnValueTypedListener);
+
+        mRadialTimePickerModeButton =
+                (ImageButton) mainView.findViewById(R.id.toggle_mode);
+        mRadialTimePickerModeButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                toggleRadialPickerMode();
+            }
+        });
+        mRadialTimePickerModeEnabledDescription = context.getResources().getString(
+                R.string.time_picker_radial_mode_description);
+        mTextInputPickerModeEnabledDescription = context.getResources().getString(
+                R.string.time_picker_text_input_mode_description);
+
         mAllowAutoAdvance = true;
 
         updateHourFormat();
@@ -200,6 +242,34 @@
         initialize(currentHour, currentMinute, mIs24Hour, HOUR_INDEX);
     }
 
+    private void toggleRadialPickerMode() {
+        if (mRadialPickerModeEnabled) {
+            mRadialTimePickerView.setVisibility(View.GONE);
+            mRadialTimePickerHeader.setVisibility(View.GONE);
+            mTextInputPickerHeader.setVisibility(View.VISIBLE);
+            mTextInputPickerView.setVisibility(View.VISIBLE);
+            mRadialTimePickerModeButton.setImageResource(R.drawable.btn_event_material);
+            mRadialTimePickerModeButton.setContentDescription(
+                    mRadialTimePickerModeEnabledDescription);
+            mRadialPickerModeEnabled = false;
+        } else {
+            mRadialTimePickerView.setVisibility(View.VISIBLE);
+            mRadialTimePickerHeader.setVisibility(View.VISIBLE);
+            mTextInputPickerHeader.setVisibility(View.GONE);
+            mTextInputPickerView.setVisibility(View.GONE);
+            mRadialTimePickerModeButton.setImageResource(R.drawable.btn_keyboard_key_material);
+            mRadialTimePickerModeButton.setContentDescription(
+                    mTextInputPickerModeEnabledDescription);
+            updateTextInputPicker();
+            mRadialPickerModeEnabled = true;
+        }
+    }
+
+    @Override
+    public boolean validateInput() {
+        return mTextInputPickerView.validateInput();
+    }
+
     /**
      * Ensures that a TextView is wide enough to contain its text without
      * wrapping or clipping. Measures the specified view and sets the minimum
@@ -249,9 +319,16 @@
         final int maxHour = (mIs24Hour ? 23 : 11) + minHour;
         mHourView.setRange(minHour, maxHour);
         mHourView.setShowLeadingZeroes(mHourFormatShowLeadingZero);
+
+        final String[] digits = DecimalFormatSymbols.getInstance(mLocale).getDigitStrings();
+        int maxCharLength = 0;
+        for (int i = 0; i < 10; i++) {
+            maxCharLength = Math.max(maxCharLength, digits[i].length());
+        }
+        mTextInputPickerView.setHourFormat(maxCharLength * 2);
     }
 
-    private static final CharSequence obtainVerbatim(String text) {
+    static final CharSequence obtainVerbatim(String text) {
         return new SpannableStringBuilder().append(text,
                 new TtsSpan.VerbatimBuilder(text).build(), 0);
     }
@@ -333,10 +410,16 @@
         updateHeaderSeparator();
         updateHeaderMinute(mCurrentMinute, false);
         updateRadialPicker(index);
+        updateTextInputPicker();
 
         mDelegator.invalidate();
     }
 
+    private void updateTextInputPicker() {
+        mTextInputPickerView.updateTextInputValues(getLocalizedHour(mCurrentHour), mCurrentMinute,
+                mCurrentHour < 12 ? AM : PM, mIs24Hour, mHourFormatStartsAtZero);
+    }
+
     private void updateRadialPicker(int index) {
         mRadialTimePickerView.initialize(mCurrentHour, mCurrentMinute, mIs24Hour);
         setCurrentItemShowing(index, false, true);
@@ -381,10 +464,10 @@
      */
     @Override
     public void setHour(int hour) {
-        setHourInternal(hour, false, true);
+        setHourInternal(hour, FROM_EXTERNAL_API, true);
     }
 
-    private void setHourInternal(int hour, boolean isFromPicker, boolean announce) {
+    private void setHourInternal(int hour, @ChangeSource int source, boolean announce) {
         if (mCurrentHour == hour) {
             return;
         }
@@ -393,10 +476,13 @@
         updateHeaderHour(hour, announce);
         updateHeaderAmPm();
 
-        if (!isFromPicker) {
+        if (source != FROM_RADIAL_PICKER) {
             mRadialTimePickerView.setCurrentHour(hour);
             mRadialTimePickerView.setAmOrPm(hour < 12 ? AM : PM);
         }
+        if (source != FROM_INPUT_PICKER) {
+            updateTextInputPicker();
+        }
 
         mDelegator.invalidate();
         onTimeChanged();
@@ -424,10 +510,10 @@
      */
     @Override
     public void setMinute(int minute) {
-        setMinuteInternal(minute, false);
+        setMinuteInternal(minute, FROM_EXTERNAL_API);
     }
 
-    private void setMinuteInternal(int minute, boolean isFromPicker) {
+    private void setMinuteInternal(int minute, @ChangeSource int source) {
         if (mCurrentMinute == minute) {
             return;
         }
@@ -435,9 +521,12 @@
         mCurrentMinute = minute;
         updateHeaderMinute(minute, true);
 
-        if (!isFromPicker) {
+        if (source != FROM_RADIAL_PICKER) {
             mRadialTimePickerView.setCurrentMinute(minute);
         }
+        if (source != FROM_INPUT_PICKER) {
+            updateTextInputPicker();
+        }
 
         mDelegator.invalidate();
         onTimeChanged();
@@ -661,6 +750,7 @@
             separatorText = Character.toString(bestDateTimePattern.charAt(hIndex + 1));
         }
         mSeparatorView.setText(separatorText);
+        mTextInputPickerView.updateSeparator(separatorText);
     }
 
     static private int lastIndexOfAny(String str, char[] any) {
@@ -712,7 +802,7 @@
 
         if (mRadialTimePickerView.setAmOrPm(amOrPm)) {
             mCurrentHour = getHour();
-
+            updateTextInputPicker();
             if (mOnTimeChangedListener != null) {
                 mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(), getMinute());
             }
@@ -726,7 +816,7 @@
             switch (pickerType) {
                 case RadialTimePickerView.HOURS:
                     final boolean isTransition = mAllowAutoAdvance && autoAdvance;
-                    setHourInternal(newValue, true, !isTransition);
+                    setHourInternal(newValue, FROM_RADIAL_PICKER, !isTransition);
                     if (isTransition) {
                         setCurrentItemShowing(MINUTE_INDEX, true, false);
 
@@ -735,7 +825,7 @@
                     }
                     break;
                 case RadialTimePickerView.MINUTES:
-                    setMinuteInternal(newValue, true);
+                    setMinuteInternal(newValue, FROM_RADIAL_PICKER);
                     break;
             }
 
@@ -745,6 +835,23 @@
         }
     };
 
+    private final OnValueTypedListener mOnValueTypedListener = new OnValueTypedListener() {
+        @Override
+        public void onValueChanged(int pickerType, int newValue) {
+            switch (pickerType) {
+                case TextInputTimePickerView.HOURS:
+                    setHourInternal(newValue, FROM_INPUT_PICKER, false);
+                    break;
+                case TextInputTimePickerView.MINUTES:
+                    setMinuteInternal(newValue, FROM_INPUT_PICKER);
+                    break;
+                case TextInputTimePickerView.AMPM:
+                    setAmOrPm(newValue);
+                    break;
+            }
+        }
+    };
+
     /** Listener for keyboard interaction. */
     private final OnValueChangedListener mDigitEnteredListener = new OnValueChangedListener() {
         @Override
diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java
index 4634631..7ef54a5 100644
--- a/core/java/android/widget/TimePickerSpinnerDelegate.java
+++ b/core/java/android/widget/TimePickerSpinnerDelegate.java
@@ -86,7 +86,7 @@
         inflater.inflate(layoutResourceId, mDelegator, true);
 
         // hour
-        mHourSpinner = delegator.findViewById(R.id.hour);
+        mHourSpinner = (NumberPicker) delegator.findViewById(R.id.hour);
         mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
             public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
                 updateInputState();
@@ -100,17 +100,17 @@
                 onTimeChanged();
             }
         });
-        mHourSpinnerInput = mHourSpinner.findViewById(R.id.numberpicker_input);
+        mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
         mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
 
         // divider (only for the new widget style)
-        mDivider = mDelegator.findViewById(R.id.divider);
+        mDivider = (TextView) mDelegator.findViewById(R.id.divider);
         if (mDivider != null) {
             setDividerText();
         }
 
         // minute
-        mMinuteSpinner = mDelegator.findViewById(R.id.minute);
+        mMinuteSpinner = (NumberPicker) mDelegator.findViewById(R.id.minute);
         mMinuteSpinner.setMinValue(0);
         mMinuteSpinner.setMaxValue(59);
         mMinuteSpinner.setOnLongPressUpdateInterval(100);
@@ -138,7 +138,7 @@
                 onTimeChanged();
             }
         });
-        mMinuteSpinnerInput = mMinuteSpinner.findViewById(R.id.numberpicker_input);
+        mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
         mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
 
         // Get the localized am/pm strings and use them in the spinner.
@@ -173,13 +173,13 @@
                     onTimeChanged();
                 }
             });
-            mAmPmSpinnerInput = mAmPmSpinner.findViewById(R.id.numberpicker_input);
+            mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
             mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
         }
 
         if (isAmPmAtStart()) {
             // Move the am/pm view to the beginning
-            ViewGroup amPmParent = delegator.findViewById(R.id.timePickerLayout);
+            ViewGroup amPmParent = (ViewGroup) delegator.findViewById(R.id.timePickerLayout);
             amPmParent.removeView(amPmView);
             amPmParent.addView(amPmView, 0);
             // Swap layout margins if needed. They may be not symmetrical (Old Standard Theme
@@ -219,6 +219,11 @@
         }
     }
 
+    @Override
+    public boolean validateInput() {
+        return true;
+    }
+
     private void getHourFormatData() {
         final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mLocale,
                 (mIs24HourView) ? "Hm" : "hm");
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index bf0601d..789e60b 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -299,7 +299,7 @@
         if (mNextView == null) {
             throw new RuntimeException("This Toast was not created with Toast.makeText()");
         }
-        TextView tv = mNextView.findViewById(com.android.internal.R.id.message);
+        TextView tv = (TextView) mNextView.findViewById(com.android.internal.R.id.message);
         if (tv == null) {
             throw new RuntimeException("This Toast was not created with Toast.makeText()");
         }
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index 1a3ca86..69b79971 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -264,7 +264,7 @@
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         inflater.inflate(com.android.internal.R.layout.zoom_container, container);
 
-        mControls = container.findViewById(com.android.internal.R.id.zoomControls);
+        mControls = (ZoomControls) container.findViewById(com.android.internal.R.id.zoomControls);
         mControls.setOnZoomInClickListener(new OnClickListener() {
             public void onClick(View v) {
                 dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
diff --git a/core/java/com/android/internal/logging/legacy/EventLogCollector.java b/core/java/com/android/internal/logging/legacy/EventLogCollector.java
index 46e70ea..598f0d5 100644
--- a/core/java/com/android/internal/logging/legacy/EventLogCollector.java
+++ b/core/java/com/android/internal/logging/legacy/EventLogCollector.java
@@ -45,8 +45,6 @@
 
     private EventLogCollector() {
         mTagParsers = new ArrayMap<>();
-        addParser(new LockscreenGestureParser());
-        addParser(new StatusBarStateParser());
         addParser(new PowerScreenStateParser());
         addParser(new SysuiMultiActionParser());
 
diff --git a/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java b/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java
index 91e968b..1209e4d 100644
--- a/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java
+++ b/core/java/com/android/internal/logging/legacy/LegacyConversionLogger.java
@@ -24,14 +24,6 @@
 
 /** @hide */
 public class LegacyConversionLogger implements TronLogger {
-    public static final String VIEW_KEY = "view";
-    public static final String TYPE_KEY = "type";
-    public static final String EVENT_KEY = "data";
-
-    public static final int TYPE_COUNTER = 1;
-    public static final int TYPE_HISTOGRAM = 2;
-    public static final int TYPE_EVENT = 3;
-
     private final Queue<LogMaker> mQueue;
     private HashMap<String, Boolean> mConfig;
 
diff --git a/core/java/com/android/internal/logging/legacy/LockscreenGestureParser.java b/core/java/com/android/internal/logging/legacy/LockscreenGestureParser.java
deleted file mode 100644
index df08ee0..0000000
--- a/core/java/com/android/internal/logging/legacy/LockscreenGestureParser.java
+++ /dev/null
@@ -1,80 +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 com.android.internal.logging.legacy;
-
-import android.util.Log;
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-/**
- * Parse the Android lockscreen gesture logs.
- * @hide
- */
-public class LockscreenGestureParser extends TagParser {
-    private static final String TAG = "LockscreenGestureParser";
-    private static final int EVENTLOG_TAG = 36021;
-
-    // source of truth is com.android.systemui.EventLogConstants
-    public static final int[] GESTURE_TYPE_MAP = {
-            MetricsEvent.VIEW_UNKNOWN,  // there is no type 0
-            MetricsEvent.ACTION_LS_UNLOCK,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1
-            MetricsEvent.ACTION_LS_SHADE,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2
-            MetricsEvent.ACTION_LS_HINT,  // SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3
-            MetricsEvent.ACTION_LS_CAMERA,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4
-            MetricsEvent.ACTION_LS_DIALER,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5
-            MetricsEvent.ACTION_LS_LOCK,  // SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6
-            MetricsEvent.ACTION_LS_NOTE,  // SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7
-            MetricsEvent.ACTION_LS_QS,  // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8
-            MetricsEvent.ACTION_SHADE_QS_PULL,  // SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9
-            MetricsEvent.ACTION_SHADE_QS_TAP  // SYSUI_TAP_TO_OPEN_QS = 10
-    };
-
-    @Override
-    public int getTag() {
-        return EVENTLOG_TAG;
-    }
-
-    @Override
-    public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
-        final boolean debug = Util.debug();
-        if (operands.length >= 1) {
-            try {
-                int type = ((Integer) operands[0]).intValue();
-                // ignore gesture length in operands[1]
-                // ignore gesture velocity in operands[2]
-
-                int category = MetricsEvent.VIEW_UNKNOWN;
-                if (type < GESTURE_TYPE_MAP.length) {
-                    category = GESTURE_TYPE_MAP[type];
-                }
-                if (category != MetricsEvent.VIEW_UNKNOWN) {
-                    LogMaker proto = logger.obtain();
-                    proto.setCategory(category);
-                    proto.setType(MetricsEvent.TYPE_ACTION);
-                    proto.setTimestamp(eventTimeMs);
-                    logger.addEvent(proto);
-                }
-            } catch (ClassCastException e) {
-                if (debug) {
-                    Log.e(TAG, "unexpected operand type: ", e);
-                }
-            }
-        } else if (debug) {
-            Log.w(TAG, "wrong number of operands: " + operands.length);
-        }
-    }
-}
diff --git a/core/java/com/android/internal/logging/legacy/StatusBarStateParser.java b/core/java/com/android/internal/logging/legacy/StatusBarStateParser.java
deleted file mode 100644
index 226253f..0000000
--- a/core/java/com/android/internal/logging/legacy/StatusBarStateParser.java
+++ /dev/null
@@ -1,74 +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 com.android.internal.logging.legacy;
-
-import android.util.Log;
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-/**
- * Parse the Android lockscreen gesture logs.
- * @hide
- */
-public class StatusBarStateParser extends TagParser {
-    private static final String TAG = "StatusBarStateParser";
-    private static final int EVENTLOG_TAG = 36004;
-
-    // source of truth is com.android.systemui.statusbar.StatusBarState
-    public static final int SHADE = 0;
-    public static final int KEYGUARD = 1;
-    public static final int SHADE_LOCKED = 2;
-
-    @Override
-    public int getTag() {
-        return EVENTLOG_TAG;
-    }
-
-    @Override
-    public void parseEvent(TronLogger logger, long eventTimeMs, Object[] operands) {
-        final boolean debug = Util.debug();
-        if (operands.length >= 6) {
-            try {
-                // [state, isShowing, isOccluded, isBouncerShowing, isSecure, isCurrentlyInsecure]
-                int state = ((Integer) operands[0]).intValue();
-                boolean isBouncerShowing = (((Integer) operands[3]).intValue()) == 1;
-                int isSecure = ((Integer) operands[4]).intValue();
-
-                int view = MetricsEvent.LOCKSCREEN;
-                int type = MetricsEvent.TYPE_OPEN;
-                if (state == SHADE) {
-                    type = MetricsEvent.TYPE_CLOSE;
-                } else if (isBouncerShowing) {
-                    view = MetricsEvent.BOUNCER;
-                }
-
-                LogMaker proto = logger.obtain();
-                proto.setCategory(view);
-                proto.setType(type);
-                proto.setTimestamp(eventTimeMs);
-                proto.setSubtype(isSecure);
-                logger.addEvent(proto);
-            } catch (ClassCastException e) {
-                if (debug) {
-                    Log.e(TAG, "unexpected operand type: ", e);
-                }
-            }
-        } else if (debug) {
-            Log.w(TAG, "wrong number of operands: " + operands.length);
-        }
-    }
-}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f3f34a8..63622f1 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -377,6 +377,8 @@
     int mScreenBrightnessBin = -1;
     final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
 
+    boolean mPretendScreenOff;
+
     boolean mInteractive;
     StopwatchTimer mInteractiveTimer;
 
@@ -3395,6 +3397,11 @@
         mNoAutoReset = enabled;
     }
 
+    public void setPretendScreenOff(boolean pretendScreenOff) {
+        mPretendScreenOff = pretendScreenOff;
+        noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON);
+    }
+
     private String mInitialAcquireWakeName;
     private int mInitialAcquireWakeUid = -1;
 
@@ -3698,6 +3705,7 @@
     }
 
     public void noteScreenStateLocked(int state) {
+        state = mPretendScreenOff ? Display.STATE_OFF : state;
         if (mScreenState != state) {
             recordDailyStatsIfNeededLocked(true);
             final int oldState = mScreenState;
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index a3b066a..5049738 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -28,6 +28,7 @@
 import android.os.IInstalld;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.Seccomp;
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.os.SystemClock;
@@ -712,6 +713,9 @@
             // Zygote process unmounts root storage spaces.
             Zygote.nativeUnmountStorageOnInit();
 
+            // Set seccomp policy
+            Seccomp.setPolicy();
+
             ZygoteHooks.stopZygoteNoThreadCreation();
 
             if (startSystemServer) {
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 20f10b3..9cbbc5a 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -53,9 +53,6 @@
     void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher);
     void setWindowState(int window, int state);
-    void buzzBeepBlinked();
-    void notificationLightOff();
-    void notificationLightPulse(int argb, int millisOn, int millisOff);
 
     void showRecentApps(boolean triggeredFromAltTab, boolean fromHome);
     void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index a9a6364..cb3a250 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -435,10 +435,6 @@
         }
     }
 
-    public static <T> boolean contains(@Nullable ArraySet<T> cur, T val) {
-        return (cur != null) ? cur.contains(val) : false;
-    }
-
     public static @NonNull <T> ArrayList<T> add(@Nullable ArrayList<T> cur, T val) {
         if (cur == null) {
             cur = new ArrayList<>();
@@ -459,6 +455,16 @@
         }
     }
 
+    /**
+     * Returns the given list, or an immutable empty list if the provided list is null
+     *
+     * @see Collections#emptyList
+     */
+
+    public static @NonNull <T> List<T> emptyIfNull(@Nullable List<T> cur) {
+        return cur == null ? Collections.emptyList() : cur;
+    }
+
     public static <T> boolean contains(@Nullable Collection<T> cur, T val) {
         return (cur != null) ? cur.contains(val) : false;
     }
diff --git a/core/java/com/android/internal/util/NotificationMessagingUtil.java b/core/java/com/android/internal/util/NotificationMessagingUtil.java
new file mode 100644
index 0000000..518cf41
--- /dev/null
+++ b/core/java/com/android/internal/util/NotificationMessagingUtil.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.internal.util;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.service.notification.StatusBarNotification;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+import java.util.Objects;
+
+/**
+ * A util to look up messaging related functions for notifications. This is used for both the
+ * ranking and the actual layout.
+ */
+public class NotificationMessagingUtil {
+
+    private static final String DEFAULT_SMS_APP_SETTING = Settings.Secure.SMS_DEFAULT_APPLICATION;
+    private final Context mContext;
+    private ArrayMap<Integer, String> mDefaultSmsApp = new ArrayMap<>();
+
+    public NotificationMessagingUtil(Context context) {
+        mContext = context;
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING), false, mSmsContentObserver);
+    }
+
+    @SuppressWarnings("deprecation")
+    private boolean isDefaultMessagingApp(StatusBarNotification sbn) {
+        final int userId = sbn.getUserId();
+        if (userId == UserHandle.USER_NULL || userId == UserHandle.USER_ALL) return false;
+        if (mDefaultSmsApp.get(userId) == null) {
+            cacheDefaultSmsApp(userId);
+        }
+        return Objects.equals(mDefaultSmsApp.get(userId), sbn.getPackageName());
+    }
+
+    private void cacheDefaultSmsApp(int userId) {
+        mDefaultSmsApp.put(userId, Settings.Secure.getStringForUser(
+                mContext.getContentResolver(),
+                Settings.Secure.SMS_DEFAULT_APPLICATION, userId));
+    }
+
+    private final ContentObserver mSmsContentObserver = new ContentObserver(
+            new Handler(Looper.getMainLooper())) {
+        @Override
+        public void onChange(boolean selfChange, Uri uri, int userId) {
+            if (Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING).equals(uri)) {
+                cacheDefaultSmsApp(userId);
+            }
+        }
+    };
+
+    public boolean isImportantMessaging(StatusBarNotification sbn, int importance) {
+        if (importance < NotificationManager.IMPORTANCE_LOW) {
+            return false;
+        }
+
+        Class<? extends Notification.Style> style = sbn.getNotification().getNotificationStyle();
+        if (Notification.MessagingStyle.class.equals(style)) {
+            return true;
+        }
+
+        if (Notification.CATEGORY_MESSAGE.equals(sbn.getNotification().category)
+                && isDefaultMessagingApp(sbn)) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/core/java/com/android/internal/util/ObjectUtils.java
similarity index 65%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to core/java/com/android/internal/util/ObjectUtils.java
index ded8f97..d109a5a 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/core/java/com/android/internal/util/ObjectUtils.java
@@ -13,18 +13,19 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.service.autofill;
 
-import java.io.PrintWriter;
 
-final class CallbackHelper {
+package com.android.internal.util;
 
-    static interface Dumpable {
-        void dump(String prefix, PrintWriter pw);
-        void setFinalizer(Finalizer f);
-    }
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 
-    static interface Finalizer {
-        void gone();
+/** @hide */
+public class ObjectUtils {
+    private ObjectUtils() {}
+
+    @NonNull
+    public static <T> T firstNotNull(@Nullable T a, @NonNull T b) {
+        return a != null ? a : Preconditions.checkNotNull(b);
     }
 }
diff --git a/core/java/com/android/internal/widget/DrawingSpace.java b/core/java/com/android/internal/widget/DrawingSpace.java
deleted file mode 100644
index b8222db..0000000
--- a/core/java/com/android/internal/widget/DrawingSpace.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.widget;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-
-/**
- * Implementation of {@link android.widget.Space} that uses normal View drawing
- * rather than a no-op. Useful for dialogs and other places where the base View
- * class is too greedy when measured with AT_MOST.
- */
-public final class DrawingSpace extends View {
-    public DrawingSpace(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    public DrawingSpace(Context context, AttributeSet attrs, int defStyleAttr) {
-        this(context, attrs, defStyleAttr, 0);
-    }
-
-    public DrawingSpace(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public DrawingSpace(Context context) {
-        this(context, null);
-    }
-
-    /**
-     * Compare to: {@link View#getDefaultSize(int, int)}
-     * <p>
-     * If mode is AT_MOST, return the child size instead of the parent size
-     * (unless it is too big).
-     */
-    private static int getDefaultSizeNonGreedy(int size, int measureSpec) {
-        int result = size;
-        int specMode = MeasureSpec.getMode(measureSpec);
-        int specSize = MeasureSpec.getSize(measureSpec);
-
-        switch (specMode) {
-            case MeasureSpec.UNSPECIFIED:
-                result = size;
-                break;
-            case MeasureSpec.AT_MOST:
-                result = Math.min(size, specSize);
-                break;
-            case MeasureSpec.EXACTLY:
-                result = specSize;
-                break;
-        }
-        return result;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        setMeasuredDimension(
-                getDefaultSizeNonGreedy(getSuggestedMinimumWidth(), widthMeasureSpec),
-                getDefaultSizeNonGreedy(getSuggestedMinimumHeight(), heightMeasureSpec));
-    }
-}
diff --git a/core/java/com/android/internal/widget/WatchHeaderListView.java b/core/java/com/android/internal/widget/WatchHeaderListView.java
index 53fa7ab..4fd19c3 100644
--- a/core/java/com/android/internal/widget/WatchHeaderListView.java
+++ b/core/java/com/android/internal/widget/WatchHeaderListView.java
@@ -92,14 +92,13 @@
     }
 
     @Override
-    protected <T extends View> T findViewByPredicateTraversal(
-            Predicate<View> predicate, View childToSkip) {
+    protected View findViewByPredicateTraversal(Predicate<View> predicate, View childToSkip) {
         View v = super.findViewByPredicateTraversal(predicate, childToSkip);
         if (v == null && mTopPanel != null && mTopPanel != childToSkip
                 && !mTopPanel.isRootNamespace()) {
-            return (T) mTopPanel.findViewByPredicate(predicate);
+            return mTopPanel.findViewByPredicate(predicate);
         }
-        return (T) v;
+        return v;
     }
 
     @Override
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index cf9441b..db3ea8c 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -91,6 +91,7 @@
     android_os_MessageQueue.cpp \
     android_os_Parcel.cpp \
     android_os_SELinux.cpp \
+    android_os_seccomp.cpp \
     android_os_SystemClock.cpp \
     android_os_SystemProperties.cpp \
     android_os_Trace.cpp \
@@ -230,6 +231,7 @@
 
 LOCAL_STATIC_LIBRARIES := \
     libgif \
+    libseccomp_policy \
 
 LOCAL_SHARED_LIBRARIES := \
     libmemtrack \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 340f2ee..407e69c 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -159,6 +159,7 @@
 extern int register_android_os_MessageQueue(JNIEnv* env);
 extern int register_android_os_Parcel(JNIEnv* env);
 extern int register_android_os_SELinux(JNIEnv* env);
+extern int register_android_os_seccomp(JNIEnv* env);
 extern int register_android_os_SystemProperties(JNIEnv *env);
 extern int register_android_os_SystemClock(JNIEnv* env);
 extern int register_android_os_Trace(JNIEnv* env);
@@ -1360,6 +1361,7 @@
     REG_JNI(register_android_os_GraphicsEnvironment),
     REG_JNI(register_android_os_MessageQueue),
     REG_JNI(register_android_os_SELinux),
+    REG_JNI(register_android_os_seccomp),
     REG_JNI(register_android_os_Trace),
     REG_JNI(register_android_os_UEventObserver),
     REG_JNI(register_android_net_LocalSocketImpl),
diff --git a/core/jni/android_os_seccomp.cpp b/core/jni/android_os_seccomp.cpp
new file mode 100644
index 0000000..3f7bab2
--- /dev/null
+++ b/core/jni/android_os_seccomp.cpp
@@ -0,0 +1,245 @@
+/*
+ * 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.
+ */
+
+#include "JNIHelp.h"
+#include "core_jni_helpers.h"
+#include "JniConstants.h"
+#include "utils/Log.h"
+#include "utils/misc.h"
+
+#if defined __arm__ || defined __aarch64__
+
+#include <vector>
+
+#include <sys/prctl.h>
+
+#include <linux/unistd.h>
+#include <linux/audit.h>
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+
+#include "seccomp_policy.h"
+
+#define syscall_nr (offsetof(struct seccomp_data, nr))
+#define arch_nr (offsetof(struct seccomp_data, arch))
+
+typedef std::vector<sock_filter> filter;
+
+// We want to keep the below inline functions for debugging and future
+// development even though they are not all sed currently.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-function"
+
+static inline void Kill(filter& f) {
+    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL));
+}
+
+static inline void Trap(filter& f) {
+    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP));
+}
+
+static inline void Error(filter& f, __u16 retcode) {
+    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO + retcode));
+}
+
+inline static void Trace(filter& f) {
+    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE));
+}
+
+inline static void Allow(filter& f) {
+    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW));
+}
+
+#pragma clang diagnostic pop
+
+inline static void AllowSyscall(filter& f, __u32 num) {
+    f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, num, 0, 1));
+    Allow(f);
+}
+
+inline static void ExamineSyscall(filter& f) {
+    f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_nr));
+}
+
+inline static int SetValidateArchitectureJumpTarget(size_t offset, filter& f) {
+    size_t jump_length = f.size() - offset - 1;
+    auto u8_jump_length = (__u8) jump_length;
+    if (u8_jump_length != jump_length) {
+        ALOGE("Can't set jump greater than 255 - actual jump is %zu",
+              jump_length);
+        return -1;
+    }
+    f[offset] = BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_ARM, u8_jump_length, 0);
+    return 0;
+}
+
+inline static size_t ValidateArchitectureAndJumpIfNeeded(filter& f) {
+    f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, arch_nr));
+
+    f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_AARCH64, 2, 0));
+    f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_ARM, 1, 0));
+    Trap(f);
+    return f.size() - 2;
+}
+
+static bool install_filter(filter const& f) {
+    struct sock_fprog prog = {
+        (unsigned short) f.size(),
+        (struct sock_filter*) &f[0],
+    };
+
+    if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
+        ALOGE("SECCOMP: Could not set seccomp filter of size %zu: %s", f.size(), strerror(errno));
+        return false;
+    }
+
+    ALOGI("SECCOMP: Global filter of size %zu installed", f.size());
+    return true;
+}
+
+bool set_seccomp_filter() {
+    filter f;
+
+    // Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
+    // jump that must be changed to point to the start of the 32-bit policy
+    // 32 bit syscalls will not hit the policy between here and the call to SetJump
+    auto offset_to_32bit_filter =
+        ValidateArchitectureAndJumpIfNeeded(f);
+
+    // 64-bit filter
+    ExamineSyscall(f);
+
+    // arm64-only filter - autogenerated from bionic syscall usage
+    for (size_t i = 0; i < arm64_filter_size; ++i)
+        f.push_back(arm64_filter[i]);
+
+    // Syscalls needed to boot Android
+    AllowSyscall(f, 41);  // __NR_pivot_root
+    AllowSyscall(f, 31);  // __NR_ioprio_get
+    AllowSyscall(f, 30);  // __NR_ioprio_set
+    AllowSyscall(f, 178); // __NR_gettid
+    AllowSyscall(f, 98);  // __NR_futex
+    AllowSyscall(f, 220); // __NR_clone
+    AllowSyscall(f, 139); // __NR_rt_sigreturn
+    AllowSyscall(f, 240); // __NR_rt_tgsigqueueinfo
+    AllowSyscall(f, 128); // __NR_restart_syscall
+    AllowSyscall(f, 278); // __NR_getrandom
+
+    // Needed for performance tools
+    AllowSyscall(f, 241); // __NR_perf_event_open
+
+    // Needed for strace
+    AllowSyscall(f, 130); // __NR_tkill
+
+    // Needed for kernel to restart syscalls
+    AllowSyscall(f, 128); // __NR_restart_syscall
+
+    // b/35034743
+    AllowSyscall(f, 267); // __NR_fstatfs64
+
+    Trap(f);
+
+    if (SetValidateArchitectureJumpTarget(offset_to_32bit_filter, f) != 0)
+        return -1;
+
+    // 32-bit filter
+    ExamineSyscall(f);
+
+    // arm32 filter - autogenerated from bionic syscall usage
+    for (size_t i = 0; i < arm_filter_size; ++i)
+        f.push_back(arm_filter[i]);
+
+    // Syscalls needed to boot android
+    AllowSyscall(f, 120); // __NR_clone
+    AllowSyscall(f, 240); // __NR_futex
+    AllowSyscall(f, 119); // __NR_sigreturn
+    AllowSyscall(f, 173); // __NR_rt_sigreturn
+    AllowSyscall(f, 363); // __NR_rt_tgsigqueueinfo
+    AllowSyscall(f, 224); // __NR_gettid
+
+    // Syscalls needed to run Chrome
+    AllowSyscall(f, 383); // __NR_seccomp - needed to start Chrome
+    AllowSyscall(f, 384); // __NR_getrandom - needed to start Chrome
+
+    // Syscalls needed to run GFXBenchmark
+    AllowSyscall(f, 190); // __NR_vfork
+
+    // Needed for strace
+    AllowSyscall(f, 238); // __NR_tkill
+
+    // Needed for kernel to restart syscalls
+    AllowSyscall(f, 0);   // __NR_restart_syscall
+
+    // Needed for debugging 32-bit Chrome
+    AllowSyscall(f, 42);  // __NR_pipe
+
+    // b/34732712
+    AllowSyscall(f, 364); // __NR_perf_event_open
+
+    // b/34651972
+    AllowSyscall(f, 33);  // __NR_access
+    AllowSyscall(f, 195); // __NR_stat64
+
+    // b/34813887
+    AllowSyscall(f, 5);   // __NR_open
+    AllowSyscall(f, 141); // __NR_getdents
+    AllowSyscall(f, 217); // __NR_getdents64
+
+    // b/34719286
+    AllowSyscall(f, 351); // __NR_eventfd
+
+    // b/34817266
+    AllowSyscall(f, 252); // __NR_epoll_wait
+
+    // Needed by sanitizers (b/34606909)
+    // 5 (__NR_open) and 195 (__NR_stat64) are also required, but they are
+    // already allowed.
+    AllowSyscall(f, 85);  // __NR_readlink
+
+    // b/34908783
+    AllowSyscall(f, 250); // __NR_epoll_create
+
+    Trap(f);
+
+    return install_filter(f);
+}
+
+static void Seccomp_setPolicy(JNIEnv* /*env*/) {
+    if (!set_seccomp_filter()) {
+        ALOGE("Failed to set seccomp policy - killing");
+        exit(1);
+    }
+}
+
+#else // #if defined __arm__ || defined __aarch64__
+
+static void Seccomp_setPolicy(JNIEnv* /*env*/) {
+}
+
+#endif
+
+static const JNINativeMethod method_table[] = {
+    NATIVE_METHOD(Seccomp, setPolicy, "()V"),
+};
+
+namespace android {
+
+int register_android_os_seccomp(JNIEnv* env) {
+    return android::RegisterMethodsOrDie(env, "android/os/Seccomp",
+                                         method_table, NELEM(method_table));
+}
+
+}
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 5c65241..e2fc444 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -247,24 +247,42 @@
 
 static void DropCapabilitiesBoundingSet(JNIEnv* env) {
   for (int i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) {
-    // Keep CAP_SYS_PTRACE in our bounding set so crash_dump can gain it.
-    if (i == CAP_SYS_PTRACE) {
-      continue;
-    }
-
     int rc = prctl(PR_CAPBSET_DROP, i, 0, 0, 0);
     if (rc == -1) {
       if (errno == EINVAL) {
         ALOGE("prctl(PR_CAPBSET_DROP) failed with EINVAL. Please verify "
               "your kernel is compiled with file capabilities support");
       } else {
+        ALOGE("prctl(PR_CAPBSET_DROP, %d) failed: %s", i, strerror(errno));
         RuntimeAbort(env, __LINE__, "prctl(PR_CAPBSET_DROP) failed");
       }
     }
   }
 }
 
-static void SetCapabilities(JNIEnv* env, int64_t permitted, int64_t effective) {
+static void SetInheritable(JNIEnv* env, uint64_t inheritable) {
+  __user_cap_header_struct capheader;
+  memset(&capheader, 0, sizeof(capheader));
+  capheader.version = _LINUX_CAPABILITY_VERSION_3;
+  capheader.pid = 0;
+
+  __user_cap_data_struct capdata[2];
+  if (capget(&capheader, &capdata[0]) == -1) {
+    ALOGE("capget failed: %s", strerror(errno));
+    RuntimeAbort(env, __LINE__, "capget failed");
+  }
+
+  capdata[0].inheritable = inheritable;
+  capdata[1].inheritable = inheritable >> 32;
+
+  if (capset(&capheader, &capdata[0]) == -1) {
+    ALOGE("capset(inh=%" PRIx64 ") failed: %s", inheritable, strerror(errno));
+    RuntimeAbort(env, __LINE__, "capset failed");
+  }
+}
+
+static void SetCapabilities(JNIEnv* env, uint64_t permitted, uint64_t effective,
+                            uint64_t inheritable) {
   __user_cap_header_struct capheader;
   memset(&capheader, 0, sizeof(capheader));
   capheader.version = _LINUX_CAPABILITY_VERSION_3;
@@ -276,9 +294,12 @@
   capdata[1].effective = effective >> 32;
   capdata[0].permitted = permitted;
   capdata[1].permitted = permitted >> 32;
+  capdata[0].inheritable = inheritable;
+  capdata[1].inheritable = inheritable >> 32;
 
   if (capset(&capheader, &capdata[0]) == -1) {
-    ALOGE("capset(%" PRId64 ", %" PRId64 ") failed", permitted, effective);
+    ALOGE("capset(perm=%" PRIx64 ", eff=%" PRIx64 ", inh=%" PRIx64 ") failed: %s", permitted,
+          effective, inheritable, strerror(errno));
     RuntimeAbort(env, __LINE__, "capset failed");
   }
 }
@@ -532,6 +553,7 @@
       EnableKeepCapabilities(env);
     }
 
+    SetInheritable(env, permittedCapabilities);
     DropCapabilitiesBoundingSet(env);
 
     bool use_native_bridge = !is_system_server && (instructionSet != NULL)
@@ -604,7 +626,7 @@
         }
     }
 
-    SetCapabilities(env, permittedCapabilities, effectiveCapabilities);
+    SetCapabilities(env, permittedCapabilities, effectiveCapabilities, permittedCapabilities);
 
     SetSchedulerPolicy(env);
 
diff --git a/core/proto/android/service/battery.proto b/core/proto/android/service/battery.proto
new file mode 100644
index 0000000..33ad682b
--- /dev/null
+++ b/core/proto/android/service/battery.proto
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+syntax = "proto3";
+
+package android.service.battery;
+
+option java_multiple_files = true;
+option java_outer_classname = "BatteryServiceProto";
+
+message BatteryServiceDumpProto {
+    enum BatteryPlugged {
+        BATTERY_PLUGGED_NONE = 0;
+        BATTERY_PLUGGED_AC = 1;
+        BATTERY_PLUGGED_USB = 2;
+        BATTERY_PLUGGED_WIRELESS = 4;
+    }
+    enum BatteryStatus {
+        BATTERY_STATUS_INVALID = 0;
+        BATTERY_STATUS_UNKNOWN = 1;
+        BATTERY_STATUS_CHARGING = 2;
+        BATTERY_STATUS_DISCHARGING = 3;
+        BATTERY_STATUS_NOT_CHARGING = 4;
+        BATTERY_STATUS_FULL = 5;
+    }
+    enum BatteryHealth {
+        BATTERY_HEALTH_INVALID = 0;
+        BATTERY_HEALTH_UNKNOWN = 1;
+        BATTERY_HEALTH_GOOD = 2;
+        BATTERY_HEALTH_OVERHEAT = 3;
+        BATTERY_HEALTH_DEAD = 4;
+        BATTERY_HEALTH_OVER_VOLTAGE = 5;
+        BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6;
+        BATTERY_HEALTH_COLD = 7;
+    }
+
+    // If true: UPDATES STOPPED -- use 'reset' to restart
+    bool are_updates_stopped = 1;
+    // Plugged status of power sources
+    BatteryPlugged plugged = 2;
+    // Max current in microamperes
+    int32 max_charging_current = 3;
+    // Max voltage
+    int32 max_charging_voltage = 4;
+    // Battery capacity in microampere-hours
+    int32 charge_counter = 5;
+    // Charging status
+    BatteryStatus status = 6;
+    // Battery health
+    BatteryHealth health = 7;
+    // True if the battery is present
+    bool is_present = 8;
+    // Charge level, from 0 through "scale" inclusive
+    int32 level = 9;
+    // The maximum value for the charge level
+    int32 scale = 10;
+    // Battery voltage in millivolts
+    int32 voltage = 11;
+    // Battery temperature in tenths of a degree Centigrade
+    int32 temperature = 12;
+    // The type of battery installed, e.g. "Li-ion"
+    string technology = 13;
+}
diff --git a/core/proto/android/service/netstats.proto b/core/proto/android/service/netstats.proto
index 5cca6ab..5a577b1 100644
--- a/core/proto/android/service/netstats.proto
+++ b/core/proto/android/service/netstats.proto
@@ -27,12 +27,16 @@
 
     repeated NetworkInterfaceProto active_uid_interfaces = 2;
 
+    // Device level network stats, which may include non-IP layer traffic.
     NetworkStatsRecorderProto dev_stats = 3;
 
+    // IP-layer traffic stats.
     NetworkStatsRecorderProto xt_stats = 4;
 
+    // Per-UID network stats.
     NetworkStatsRecorderProto uid_stats = 5;
 
+    // Per-UID, per-tag network stats, excluding the default tag (i.e. tag=0).
     NetworkStatsRecorderProto uid_tag_stats = 6;
 }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 11eb47b..a6e43ff 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2365,6 +2365,11 @@
     <permission android:name="android.permission.BIND_PRINT_SPOOLER_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by the CompanionDeviceManager to ensure that only the system can bind to it.
+         @hide -->
+    <permission android:name="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
+        android:protectionLevel="signature" />
+
     <!-- @SystemApi Must be required by the RuntimePermissionPresenterService to ensure
          that only the system can bind to it.
          @hide -->
diff --git a/core/res/res/drawable/btn_event_material.xml b/core/res/res/drawable/btn_event_material.xml
new file mode 100644
index 0000000..47c49cf
--- /dev/null
+++ b/core/res/res/drawable/btn_event_material.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+
+    <path
+        android:fillColor="#90ffffff"
+        android:pathData="M17 12h-5v5h5v-5zM16 1v2H8V1H6v2H5c-1.11 0-1.99 .9 -1.99 2L3 19c0 1.1 .89 2 2
+2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-1V1h-2zm3 18H5V8h14v11z" />
+    <path android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/btn_keyboard_key_material.xml b/core/res/res/drawable/btn_keyboard_key_material.xml
new file mode 100644
index 0000000..14a9492f
--- /dev/null
+++ b/core/res/res/drawable/btn_keyboard_key_material.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+
+    <path
+        android:fillColor="#90ffffff"
+        android:pathData="M20 5H4c-1.1 0-1.99 .9 -1.99 2L2 17c0 1.1 .9 2 2 2h16c1.1 0 2-.9
+2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0
+3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9
+7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z" />
+    <path
+        android:pathData="M0 0h24v24H0zm0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/layout-land/time_picker_material.xml b/core/res/res/layout-land/time_picker_material.xml
index 70833d6..8b95f9f 100644
--- a/core/res/res/layout-land/time_picker_material.xml
+++ b/core/res/res/layout-land/time_picker_material.xml
@@ -15,28 +15,17 @@
      limitations under the License.
 -->
 
-<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layoutDirection="ltr">
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
 
-    <!-- Provides a background for the time layout that extends into the button bar area. -->
-    <com.android.internal.widget.DrawingSpace
+    <LinearLayout
         android:id="@+id/time_header"
-        android:layout_width="0dp"
-        android:layout_height="wrap_content"
-        android:layout_column="@dimen/time_picker_column_start_material"
-        android:layout_row="0"
-        android:layout_rowSpan="3"
-        android:layout_gravity="center|fill"
-        android:layoutDirection="locale" />
-
-    <RelativeLayout
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_column="@dimen/time_picker_column_start_material"
-        android:layout_row="1"
-        android:layout_gravity="center|fill"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:gravity="center"
         android:paddingStart="?attr/dialogPreferredPadding"
         android:paddingEnd="?attr/dialogPreferredPadding">
 
@@ -44,10 +33,8 @@
             android:id="@+id/time_layout"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:orientation="horizontal"
-            android:layout_centerInParent="true"
             android:paddingTop="@dimen/timepicker_radial_picker_top_margin"
-            android:layout_marginBottom="-12dp">
+            android:orientation="horizontal">
 
             <!-- The hour should always be to the left of the separator,
                  regardless of the current locale's layout direction. -->
@@ -125,38 +112,71 @@
                 android:includeFontPadding="false"
                 android:button="@null" />
         </RadioGroup>
-    </RelativeLayout>
+    </LinearLayout>
 
-    <ViewStub
-        android:id="@id/topPanel"
-        android:layout="@layout/alert_dialog_title_material"
+    <TextView
+        android:visibility="gone"
+        android:id="@+id/input_header"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:paddingStart="@dimen/dialog_padding_material"
+        android:paddingEnd="@dimen/dialog_padding_material"
+        android:paddingTop="20dp"
+        android:paddingBottom="20dp"
+        android:includeFontPadding="false"
+        android:textAppearance="@style/TextAppearance.Material.TimePicker.InputHeader"
+        android:text="@string/time_picker_header_text"/>
+
+    <LinearLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_column="@dimen/time_picker_column_end_material"
-        android:layout_row="0"
-        android:layout_gravity="top|fill_horizontal"
-        android:layoutDirection="locale" />
+        android:orientation="vertical">
 
-    <android.widget.RadialTimePickerView
-        android:id="@+id/radial_picker"
-        android:layout_width="@dimen/timepicker_radial_picker_dimen"
-        android:layout_height="@dimen/timepicker_radial_picker_dimen"
-        android:layout_column="@dimen/time_picker_column_end_material"
-        android:layout_row="1"
-        android:layout_rowWeight="1"
-        android:layout_gravity="center|fill"
-        android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin"
-        android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin"
-        android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin"
-        android:layoutDirection="locale" />
+        <android.widget.RadialTimePickerView
+            android:id="@+id/radial_picker"
+            android:layout_width="@dimen/timepicker_radial_picker_dimen"
+            android:layout_height="@dimen/timepicker_radial_picker_dimen"
+            android:layout_gravity="center|fill"
+            android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin"
+            android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin"
+            android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin"
+            android:layoutDirection="locale" />
 
-    <ViewStub
-        android:id="@id/buttonPanel"
-        android:layout="@layout/alert_dialog_button_bar_material"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_column="@dimen/time_picker_column_end_material"
-        android:layout_row="2"
-        android:layout_gravity="bottom|fill_horizontal"
-        android:layoutDirection="locale" />
-</GridLayout>
+        <android.widget.TextInputTimePickerView
+            android:id="@+id/input_mode"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingStart="?attr/dialogPreferredPadding"
+            android:paddingEnd="?attr/dialogPreferredPadding"
+            android:visibility="gone" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <ImageButton
+                android:id="@+id/toggle_mode"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:layout_marginStart="12dp"
+                android:layout_marginEnd="12dp"
+                android:padding="12dp"
+                android:background="?attr/selectableItemBackgroundBorderless"
+                android:tint="?attr/colorControlNormal"
+                android:src="@drawable/btn_keyboard_key_material"
+                android:contentDescription="@string/time_picker_text_input_mode_description" />
+            <Space
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+            <ViewStub
+                android:id="@id/buttonPanel"
+                android:layout="@layout/alert_dialog_button_bar_material"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layoutDirection="locale" />
+        </LinearLayout>
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/time_picker_material.xml b/core/res/res/layout/time_picker_material.xml
index 37a7384..7597379 100644
--- a/core/res/res/layout/time_picker_material.xml
+++ b/core/res/res/layout/time_picker_material.xml
@@ -34,4 +34,53 @@
         android:layout_marginTop="@dimen/timepicker_radial_picker_top_margin"
         android:layout_marginStart="@dimen/timepicker_radial_picker_horizontal_margin"
         android:layout_marginEnd="@dimen/timepicker_radial_picker_horizontal_margin" />
+    <TextView
+        android:visibility="gone"
+        android:id="@+id/input_header"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="@dimen/dialog_padding_material"
+        android:paddingEnd="@dimen/dialog_padding_material"
+        android:paddingTop="20dp"
+        android:paddingBottom="20dp"
+        android:includeFontPadding="false"
+        android:fontFamily="sans-serif-medium"
+        android:textSize="34sp"
+        android:textColor="@color/white"
+        android:text="@string/time_picker_header_text"/>
+    <android.widget.TextInputTimePickerView
+        android:id="@+id/input_mode"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="?attr/dialogPreferredPadding"
+        android:paddingEnd="?attr/dialogPreferredPadding"
+        android:visibility="gone" />
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+        <ImageButton
+            android:id="@+id/toggle_mode"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_marginStart="12dp"
+            android:layout_marginEnd="12dp"
+            android:padding="12dp"
+            android:background="?attr/selectableItemBackgroundBorderless"
+            android:tint="?attr/colorControlNormal"
+            android:src="@drawable/btn_keyboard_key_material"
+            android:contentDescription="@string/time_picker_text_input_mode_description" />
+        <Space
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1" />
+        <ViewStub
+            android:id="@id/buttonPanel"
+            android:layout="@layout/alert_dialog_button_bar_material"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layoutDirection="locale" />
+    </LinearLayout>
+
 </LinearLayout>
diff --git a/core/res/res/layout/time_picker_text_input_material.xml b/core/res/res/layout/time_picker_text_input_material.xml
new file mode 100644
index 0000000..f17b80e
--- /dev/null
+++ b/core/res/res/layout/time_picker_text_input_material.xml
@@ -0,0 +1,90 @@
+<?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.
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <TextView
+        android:id="@+id/top_label"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="26dp"
+        android:layout_marginBottom="8dp"
+        android:text="@string/time_picker_prompt_label"
+        android:textAppearance="@style/TextAppearance.Material.TimePicker.PromptLabel" />
+
+    <RelativeLayout
+        android:id="@+id/input_block"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/top_label"
+        android:layoutDirection="ltr">
+        <EditText
+            android:id="@+id/input_hour"
+            android:layout_width="50dp"
+            android:layout_height="wrap_content"
+            android:inputType="number"
+            android:textAppearance="@style/TextAppearance.Material.TimePicker.InputField" />
+        <TextView
+            android:id="@+id/label_hour"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/input_hour"
+            android:layout_alignStart="@id/input_hour"
+            android:text="@string/time_picker_hour_label"/>
+
+        <TextView
+            android:id="@+id/input_separator"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignEnd="@id/input_hour"
+            android:layout_alignBaseline="@id/input_hour"
+            android:textAppearance="@style/TextAppearance.Material.TimePicker.InputField" />
+
+        <EditText
+            android:id="@+id/input_minute"
+            android:layout_width="50dp"
+            android:layout_height="wrap_content"
+            android:layout_alignBaseline="@id/input_hour"
+            android:layout_toEndOf="@id/input_separator"
+            android:inputType="number"
+            android:textAppearance="@style/TextAppearance.Material.TimePicker.InputField" />
+        <TextView
+            android:id="@+id/label_minute"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/input_minute"
+            android:layout_alignStart="@id/input_minute"
+            android:text="@string/time_picker_minute_label"/>
+
+        <TextView
+            android:visibility="invisible"
+            android:id="@+id/label_error"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/input_hour"
+            android:layout_alignStart="@id/input_hour"
+            android:textColor="?attr/textColorError"
+            android:text="@string/time_picker_input_error" />
+    </RelativeLayout>
+    <Spinner
+        android:id="@+id/am_pm_spinner"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignBaseline="@id/input_block"
+        android:layout_alignParentEnd="true"/>
+
+</merge>
\ No newline at end of file
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index c548219..7f49f05 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3392,6 +3392,8 @@
             <flag name="flagRetrieveInteractiveWindows" value="0x00000040" />
             <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_ENABLE_ACCESSIBILITY_VOLUME} -->
             <flag name="flagEnableAccessibilityVolume" value="0x00000080" />
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} -->
+            <flag name="flagRequestAccessibilityButton" value="0x00000100" />
             <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_CAPTURE_FINGERPRINT_GESTURES} -->
             <flag name="flagCaptureFingerprintGestures" value="0x00000200" />
         </attr>
@@ -3429,18 +3431,9 @@
         <attr name="canRequestFilterKeyEvents" format="boolean" />
         <!-- Attribute whether the accessibility service wants to be able to control
              display magnification.
-             <p>
-             Required to allow setting the {@link android.accessibilityservice
-             #AccessibilityServiceInfo#FLAG_CAN_CONTROL_MAGNIFICATION} flag.
-             </p>
          -->
         <attr name="canControlMagnification" format="boolean" />
-        <!-- Attribute whether the accessibility service wants to be able to perform gestures.
-             <p>
-             Required to allow setting the {@link android.accessibilityservice
-             #AccessibilityServiceInfo#FLAG_CAN_PERFORM_GESTURES} flag.
-             </p>
-         -->
+        <!-- Attribute whether the accessibility service wants to be able to perform gestures. -->
         <attr name="canPerformGestures" format="boolean" />
         <!-- Attribute whether the accessibility service wants to be able to capture gestures from
              the fingerprint sensor.
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 6d0fdb6..76f4a76 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -885,6 +885,12 @@
          will run against. -->
     <attr name="targetPackage" format="string" />
 
+    <!-- The name of an application's processes that an Instrumentation object
+         will run against.  If not specified, only runs in the main process of the targetPackage.
+         Can either be a comma-separated list of process names or '*' for any process that
+         launches to run targetPackage code. -->
+    <attr name="targetProcess" format="string" />
+
     <!-- Flag indicating that an Instrumentation class wants to take care
          of starting/stopping profiling itself, rather than relying on
          the default behavior of profiling the complete time it is running.
@@ -2050,9 +2056,6 @@
              in a task/stack that isn't focusable. This flag allows them to be focusable.-->
         <attr name="alwaysFocusable" format="boolean" />
         <attr name="enableVrMode" />
-        <!-- @hide This activity is a launcher which should always show up on the top of others.
-             This attribute is ignored if the activity isn't a launcher. -->
-        <attr name="onTopLauncher" format="boolean" />
         <attr name="rotationAnimation" />
         <attr name="visibleToInstantApps" />
         <!-- The code for this component is located in the given split. -->
@@ -2297,6 +2300,7 @@
             is a period then it is appended to your package name. -->
         <attr name="name" />
         <attr name="targetPackage" />
+        <attr name="targetProcess" />
         <attr name="label" />
         <attr name="icon" />
         <attr name="roundIcon" />
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 927988f..9824051 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -475,9 +475,6 @@
 
     <dimen name="chooser_grid_padding">0dp</dimen>
 
-    <item type="dimen" format="integer" name="time_picker_column_start_material">0</item>
-    <item type="dimen" format="integer" name="time_picker_column_end_material">1</item>
-
     <item type="dimen" name="aerr_padding_list_top">15dp</item>
     <item type="dimen" name="aerr_padding_list_bottom">8dp</item>
 
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index ebe577c..e3fdcec 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -149,6 +149,7 @@
     <dimen name="timepicker_radial_picker_dimen">296dp</dimen>
     <dimen name="timepicker_radial_picker_top_margin">16dp</dimen>
     <dimen name="timepicker_radial_picker_horizontal_margin">16dp</dimen>
+    <dimen name="timepicker_edit_text_size">24sp</dimen>
 
     <!-- Used by RadialTimePicker in clock-style TimePicker. -->
     <dimen name="timepicker_selector_radius">20dp</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index d795d80..1b48469 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2777,7 +2777,7 @@
         <public name="paddingVertical" />
         <public name="visibleToInstantApps" />
         <public name="keyboardNavigationCluster" />
-        <public name="__removed0" />
+        <public name="targetProcess" />
         <public name="nextClusterForward" />
         <public name="__removed1" />
         <public name="textColorError" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8b9b3b2..19c5643 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3064,6 +3064,7 @@
     <string name="adb_active_notification_title">USB debugging connected</string>
     <!-- Message of notification shown when ADB is actively connected to the phone. -->
     <string name="adb_active_notification_message">Tap to disable USB debugging.</string>
+    <string name="adb_active_notification_message" product="tv">Select to disable USB debugging.</string>
 
     <!-- Title of notification shown to indicate that bug report is being collected. -->
     <string name="taking_remote_bugreport_notification_title">Taking bug report\u2026</string>
@@ -4468,4 +4469,22 @@
 
     <!-- Channel name for DeviceStorageMonitor notifications -->
     <string name="device_storage_monitor_notification_channel">Device storage</string>
+    <!-- Channel name for UsbDeviceManager adb debugging notifications -->
+    <string name="adb_debugging_notification_channel_tv">USB debugging</string>
+
+    <!-- Label for the time picker hour input field. [CHAR LIMIT=20] -->
+    <string name="time_picker_hour_label">hour</string>
+    <!-- Label for the time picker minute input field. [CHAR LIMIT=20] -->
+    <string name="time_picker_minute_label">minute</string>
+    <!-- The title for the time picker dialog. [CHAR LIMIT=NONE] -->
+    <string name="time_picker_header_text">Set time</string>
+    <!-- Error shown to the user if they type in invalid hour or minute in the time picker. [CHAR LIMIT=NONE] -->
+    <string name="time_picker_input_error">Enter a valid time</string>
+    <!-- Label shown to the user in time picker to let them know that should type in time. [CHAR LIMIT=NONE] -->
+    <string name="time_picker_prompt_label">Type in time</string>
+    <!-- Accessibility string used for describing the button in time picker that changes the dialog to text input mode. [CHAR LIMIT=NONE] -->
+    <string name="time_picker_text_input_mode_description">Switch to text input mode for the time input.</string>
+    <!-- Accessibility string used for describing the button in time picker that changes the dialog to circular clock mode. [CHAR LIMIT=NONE] -->
+    <string name="time_picker_radial_mode_description">Switch to clock mode for the time input.</string>
+
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 1e15348..8f061a3 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -426,6 +426,21 @@
         <item name="textColor">@color/primary_text_secondary_when_activated_material_inverse</item>
     </style>
 
+    <style name="TextAppearance.Material.TimePicker.InputHeader" parent="TextAppearance.Material">
+        <item name="textSize">@dimen/text_size_display_1_material</item>
+        <item name="textColor">@color/white</item>
+        <item name="fontFamily">sans-serif-medium</item>
+    </style>
+
+    <style name="TextAppearance.Material.TimePicker.InputField" parent="TextAppearance.Material">
+        <item name="textSize">@dimen/timepicker_edit_text_size</item>
+    </style>
+
+    <style name="TextAppearance.Material.TimePicker.PromptLabel" parent="TextAppearance.Material">
+        <item name="textSize">@dimen/timepicker_text_size_normal</item>
+        <item name="fontFamily">sans-serif-medium</item>
+    </style>
+
     <style name="TextAppearance.Material.DatePicker.YearLabel" parent="TextAppearance.Material">
         <item name="textColor">@color/primary_text_secondary_when_activated_material_inverse</item>
         <item name="textSize">@dimen/date_picker_year_label_size</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 571aa17..a420055 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1914,6 +1914,7 @@
   <java-symbol type="string" name="smv_process" />
   <java-symbol type="string" name="tethered_notification_message" />
   <java-symbol type="string" name="tethered_notification_title" />
+  <java-symbol type="string" name="adb_debugging_notification_channel_tv" />
   <java-symbol type="string" name="usb_accessory_notification_title" />
   <java-symbol type="string" name="usb_mtp_notification_title" />
   <java-symbol type="string" name="usb_charging_notification_title" />
@@ -2841,4 +2842,21 @@
   <!-- Accessibility fingerprint gestures -->
   <java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
   <java-symbol type="string" name="capability_desc_canCaptureFingerprintGestures" />
+
+  <!-- Time picker -->
+  <java-symbol type="id" name="toggle_mode"/>
+  <java-symbol type="id" name="input_mode"/>
+  <java-symbol type="id" name="input_header"/>
+  <java-symbol type="id" name="input_separator"/>
+  <java-symbol type="id" name="input_hour"/>
+  <java-symbol type="id" name="input_minute"/>
+  <java-symbol type="id" name="am_pm_spinner"/>
+  <java-symbol type="id" name="label_hour"/>
+  <java-symbol type="id" name="label_minute"/>
+  <java-symbol type="id" name="label_error"/>
+  <java-symbol type="layout" name="time_picker_text_input_material"/>
+  <java-symbol type="drawable" name="btn_keyboard_key_material"/>
+  <java-symbol type="drawable" name="btn_event_material"/>
+  <java-symbol type="string" name="time_picker_text_input_mode_description"/>
+  <java-symbol type="string" name="time_picker_radial_mode_description"/>
 </resources>
diff --git a/core/tests/coretests/res/font/samplefont.ttf b/core/tests/coretests/res/font/samplefont.ttf
new file mode 100644
index 0000000..2852302
--- /dev/null
+++ b/core/tests/coretests/res/font/samplefont.ttf
Binary files differ
diff --git a/core/tests/coretests/res/font/samplefont2.ttf b/core/tests/coretests/res/font/samplefont2.ttf
new file mode 100644
index 0000000..2852302
--- /dev/null
+++ b/core/tests/coretests/res/font/samplefont2.ttf
Binary files differ
diff --git a/core/tests/coretests/res/font/samplefont3.ttf b/core/tests/coretests/res/font/samplefont3.ttf
new file mode 100644
index 0000000..2852302
--- /dev/null
+++ b/core/tests/coretests/res/font/samplefont3.ttf
Binary files differ
diff --git a/core/tests/coretests/res/font/samplefont4.ttf b/core/tests/coretests/res/font/samplefont4.ttf
new file mode 100644
index 0000000..2852302
--- /dev/null
+++ b/core/tests/coretests/res/font/samplefont4.ttf
Binary files differ
diff --git a/core/tests/coretests/res/font/samplexmlfont.xml b/core/tests/coretests/res/font/samplexmlfont.xml
new file mode 100644
index 0000000..bb813e1
--- /dev/null
+++ b/core/tests/coretests/res/font/samplexmlfont.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<font-family xmlns:android="http://schemas.android.com/apk/res/android">
+    <font android:fontStyle="normal" android:fontWeight="400" android:font="@font/samplefont" />
+    <font android:fontStyle="italic" android:fontWeight="400" android:font="@font/samplefont2" />
+    <font android:fontStyle="normal" android:fontWeight="800" android:font="@font/samplefont3" />
+    <font android:fontStyle="italic" android:fontWeight="800" android:font="@font/samplefont4" />
+</font-family>
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
new file mode 100644
index 0000000..380a28774
--- /dev/null
+++ b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.content.res;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.app.Instrumentation;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.FontConfig;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Tests for {@link FontResourcesParser}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class FontResourcesParserTest {
+
+    private Instrumentation mInstrumentation;
+    private Resources mResources;
+
+    @Before
+    public void setup() {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mResources = mInstrumentation.getContext().getResources();
+    }
+
+    @Test
+    public void testParse() throws XmlPullParserException, IOException {
+        XmlResourceParser parser = mResources.getXml(R.font.samplexmlfont);
+
+        FontConfig result = FontResourcesParser.parse(parser, mResources);
+
+        assertNotNull(result);
+        List<FontConfig.Family> families = result.getFamilies();
+        assertEquals(1, families.size());
+        List<FontConfig.Font> fonts = families.get(0).getFonts();
+        assertEquals(4, fonts.size());
+        FontConfig.Font font1 = fonts.get(0);
+        assertEquals(400, font1.getWeight());
+        assertEquals(false, font1.isItalic());
+        assertEquals("res/font/samplefont.ttf", font1.getFontName());
+        FontConfig.Font font2 = fonts.get(1);
+        assertEquals(400, font2.getWeight());
+        assertEquals(true, font2.isItalic());
+        assertEquals("res/font/samplefont2.ttf", font2.getFontName());
+        FontConfig.Font font3 = fonts.get(2);
+        assertEquals(800, font3.getWeight());
+        assertEquals(false, font3.isItalic());
+        assertEquals("res/font/samplefont3.ttf", font3.getFontName());
+        FontConfig.Font font4 = fonts.get(3);
+        assertEquals(800, font4.getWeight());
+        assertEquals(true, font4.isItalic());
+        assertEquals("res/font/samplefont4.ttf", font4.getFontName());
+    }
+}
diff --git a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
index 5bfff26..ce5d3ef 100644
--- a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
+++ b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
@@ -19,6 +19,7 @@
 import static org.mockito.Mockito.when;
 
 import android.Manifest.permission;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -30,13 +31,16 @@
 import android.net.NetworkScorerAppManager.NetworkScorerAppData;
 import android.provider.Settings;
 import android.test.InstrumentationTestCase;
+
 import com.android.internal.R;
-import java.util.List;
+
 import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
+
 public class NetworkScorerAppManagerTest extends InstrumentationTestCase {
     @Mock private Context mMockContext;
     @Mock private PackageManager mMockPm;
@@ -114,39 +118,40 @@
 
     public void testGetNetworkRecommendationProviderData_scoreNetworksNotGranted()
             throws Exception {
-        setNetworkRecommendationPackageNames("package1");
-        mockScoreNetworksDenied("package1");
-        mockRecommendationServiceAvailable("package1", 924 /* packageUid */);
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        setNetworkRecommendationPackageNames(recoComponent.getPackageName());
+        mockScoreNetworksDenied(recoComponent.getPackageName());
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
 
         assertNull(mNetworkScorerAppManager.getNetworkRecommendationProviderData());
     }
 
     public void testGetNetworkRecommendationProviderData_available() throws Exception {
-        setNetworkRecommendationPackageNames("package1");
-        mockScoreNetworksGranted("package1");
-        mockRecommendationServiceAvailable("package1", 924 /* packageUid */);
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        setNetworkRecommendationPackageNames(recoComponent.getPackageName());
+        mockScoreNetworksGranted(recoComponent.getPackageName());
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
 
         NetworkScorerAppData appData =
                 mNetworkScorerAppManager.getNetworkRecommendationProviderData();
         assertNotNull(appData);
-        assertEquals("package1", appData.packageName);
+        assertEquals(recoComponent, appData.getRecommendationServiceComponent());
         assertEquals(924, appData.packageUid);
-        assertEquals(".RecommendationService", appData.recommendationServiceClassName);
     }
 
     public void testGetActiveScorer_providerAvailable() throws Exception {
-        setNetworkRecommendationPackageNames("package1");
-        mockScoreNetworksGranted("package1");
-        mockRecommendationServiceAvailable("package1", 924 /* packageUid */);
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        setNetworkRecommendationPackageNames(recoComponent.getPackageName());
+        mockScoreNetworksGranted(recoComponent.getPackageName());
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
 
         ContentResolver cr = mTargetContext.getContentResolver();
         Settings.Global.putInt(cr, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 1);
 
         final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
         assertNotNull(activeScorer);
-        assertEquals("package1", activeScorer.packageName);
+        assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
         assertEquals(924, activeScorer.packageUid);
-        assertEquals(".RecommendationService", activeScorer.recommendationServiceClassName);
     }
 
     public void testGetActiveScorer_providerNotAvailable()
@@ -159,9 +164,10 @@
     }
 
     public void testGetActiveScorer_recommendationsDisabled() throws Exception {
-        setNetworkRecommendationPackageNames("package1");
-        mockScoreNetworksGranted("package1");
-        mockRecommendationServiceAvailable("package1", 924 /* packageUid */);
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        setNetworkRecommendationPackageNames(recoComponent.getPackageName());
+        mockScoreNetworksGranted(recoComponent.getPackageName());
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */);
         ContentResolver cr = mTargetContext.getContentResolver();
         Settings.Global.putInt(cr, Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 0);
 
@@ -187,11 +193,11 @@
                 .thenReturn(PackageManager.PERMISSION_DENIED);
     }
 
-    private void mockRecommendationServiceAvailable(final String packageName, int packageUid) {
+    private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid) {
         final ResolveInfo serviceInfo = new ResolveInfo();
         serviceInfo.serviceInfo = new ServiceInfo();
-        serviceInfo.serviceInfo.name = ".RecommendationService";
-        serviceInfo.serviceInfo.packageName = packageName;
+        serviceInfo.serviceInfo.name = compName.getClassName();
+        serviceInfo.serviceInfo.packageName = compName.getPackageName();
         serviceInfo.serviceInfo.applicationInfo = new ApplicationInfo();
         serviceInfo.serviceInfo.applicationInfo.uid = packageUid;
 
@@ -203,7 +209,7 @@
                         Intent intent = (Intent) object;
                         return NetworkScoreManager.ACTION_RECOMMEND_NETWORKS
                                 .equals(intent.getAction())
-                                && packageName.equals(intent.getPackage());
+                                && compName.getPackageName().equals(intent.getPackage());
                     }
                 }), Mockito.eq(flags))).thenReturn(serviceInfo);
     }
diff --git a/core/tests/coretests/src/android/net/RecommendationRequestTest.java b/core/tests/coretests/src/android/net/RecommendationRequestTest.java
index bd25500..e2e6883 100644
--- a/core/tests/coretests/src/android/net/RecommendationRequestTest.java
+++ b/core/tests/coretests/src/android/net/RecommendationRequestTest.java
@@ -96,7 +96,7 @@
 
         RecommendationRequest parceled = passThroughParcel(request);
 
-        assertEquals(0, parceled.getLastSelectedNetworkId());
+        assertEquals(-1, parceled.getLastSelectedNetworkId());
         assertEquals(0, parceled.getLastSelectedNetworkTimestamp());
     }
 
diff --git a/core/tests/coretests/src/android/provider/SettingsTest.java b/core/tests/coretests/src/android/provider/SettingsTest.java
index d76980a..1ff2056 100644
--- a/core/tests/coretests/src/android/provider/SettingsTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsTest.java
@@ -392,7 +392,6 @@
                  Settings.Secure.BACKUP_PROVISIONED,
                  Settings.Secure.BACKUP_TRANSPORT,
                  Settings.Secure.BLUETOOTH_HCI_LOG,
-                 Settings.Secure.BRIGHTNESS_USE_TWILIGHT,  // Candidate for backup?
                  Settings.Secure.CARRIER_APPS_HANDLED,
                  Settings.Secure.COMPLETED_CATEGORY_PREFIX,
                  Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS,
diff --git a/core/tests/coretests/src/android/transition/FadeTransitionTest.java b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
index dc60423..7e7e815 100644
--- a/core/tests/coretests/src/android/transition/FadeTransitionTest.java
+++ b/core/tests/coretests/src/android/transition/FadeTransitionTest.java
@@ -21,7 +21,7 @@
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.transition.Transition.TransitionListener;
-import android.transition.Transition.TransitionListenerAdapter;
+import android.transition.TransitionListenerAdapter;
 import android.view.View;
 import android.view.ViewGroup;
 
diff --git a/core/tests/coretests/src/android/view/ViewAttachTest.java b/core/tests/coretests/src/android/view/ViewAttachTest.java
index a73f5a6..44fcd13 100644
--- a/core/tests/coretests/src/android/view/ViewAttachTest.java
+++ b/core/tests/coretests/src/android/view/ViewAttachTest.java
@@ -16,9 +16,17 @@
 
 package android.view;
 
+import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.graphics.PixelFormat;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+import com.android.frameworks.coretests.R;
 
 public class ViewAttachTest extends
         ActivityInstrumentationTestCase2<ViewAttachTestActivity> {
@@ -51,4 +59,38 @@
             SystemClock.sleep(250);
         }
     }
+
+    /**
+     * Make sure that on any attached view, if the view is full-screen and hosted
+     * on a round device, the round scrollbars will be displayed even if the activity
+     * window is offset.
+     *
+     * @throws Throwable
+     */
+    @UiThreadTest
+    public void testRoundScrollbars() throws Throwable {
+        final ViewAttachTestActivity activity = getActivity();
+        final View rootView = activity.getWindow().getDecorView();
+        final WindowManager.LayoutParams params =
+            new WindowManager.LayoutParams(
+                rootView.getWidth(),
+                rootView.getHeight(),
+                50, /* xPosition */
+                0, /* yPosition */
+                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
+                PixelFormat.TRANSLUCENT);
+
+        rootView.setLayoutParams(params);
+
+        View contentView = activity.findViewById(R.id.view_attach_view);
+        boolean shouldDrawRoundScrollbars = contentView.shouldDrawRoundScrollbar();
+
+        if (activity.getResources().getConfiguration().isScreenRound()) {
+            assertTrue(shouldDrawRoundScrollbars);
+        } else {
+            // Never draw round scrollbars on non-round devices.
+            assertFalse(shouldDrawRoundScrollbars);
+        }
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/logging/legacy/LockscreenGestureParserTest.java b/core/tests/coretests/src/com/android/internal/logging/legacy/LockscreenGestureParserTest.java
deleted file mode 100644
index c023b57..0000000
--- a/core/tests/coretests/src/com/android/internal/logging/legacy/LockscreenGestureParserTest.java
+++ /dev/null
@@ -1,100 +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 com.android.internal.logging.legacy;
-
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class LockscreenGestureParserTest extends ParserTest {
-
-    public LockscreenGestureParserTest() {
-        mParser = new LockscreenGestureParser();
-    }
-
-    public void testSwipeUpUnlock() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_UNLOCK, 1, 359, 6382);
-    }
-
-    public void testSwipeToShade() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_SHADE, 2, 324, 0);
-    }
-
-    public void testTapLockHint() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_HINT, 3, 0, 0);
-    }
-
-    public void testCamera() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_CAMERA, 4, 223, 1756);
-    }
-
-    public void testDialer() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_DIALER, 5, 163, 861);
-    }
-
-    public void testTapToLock() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_LOCK, 6, 0, 0);
-    }
-
-    public void testTapOnNotification() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_NOTE, 7, 0, 0);
-    }
-
-    public void testLockscreenQuickSettings() throws Throwable {
-        validate(MetricsEvent.ACTION_LS_QS, 8, 284, 3824);
-    }
-
-    public void testShadePullQuickSettings() throws Throwable {
-        validate(MetricsEvent.ACTION_SHADE_QS_PULL, 9, 175, 3444);
-    }
-
-    public void testShadeTapQuickSettings() throws Throwable {
-        validate(MetricsEvent.ACTION_SHADE_QS_TAP, 10, 0, 0);
-    }
-
-    private void validate(int view, int type, int len, int vel) {
-        int t = 1000;
-        Object[] objects = new Object[3];
-        objects[0] = type;
-        objects[1] = len;
-        objects[2] = vel;
-
-        mParser.parseEvent(mLogger, t, objects);
-
-        verify(mLogger, times(1)).addEvent(mProtoCaptor.capture());
-
-        LogMaker proto = mProtoCaptor.getValue();
-        assertEquals(t, proto.getTimestamp());
-        assertEquals(view, proto.getCategory());
-        assertEquals(MetricsEvent.TYPE_ACTION, proto.getType());
-    }
-
-    public void testIgnoreUnexpectedData() throws Throwable {
-        int t = 1000;
-        Object[] objects = new Object[4];
-        objects[0] = 1;
-        objects[1] = 0;
-        objects[2] = 0;
-        objects[3] = "foo";
-
-        mParser.parseEvent(mLogger, t, objects);
-
-        verify(mLogger, times(1)).addEvent((LogMaker) anyObject());
-    }
-}
diff --git a/core/tests/coretests/src/com/android/internal/logging/legacy/StatusBarStateParserTest.java b/core/tests/coretests/src/com/android/internal/logging/legacy/StatusBarStateParserTest.java
deleted file mode 100644
index def9628..0000000
--- a/core/tests/coretests/src/com/android/internal/logging/legacy/StatusBarStateParserTest.java
+++ /dev/null
@@ -1,73 +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 com.android.internal.logging.legacy;
-
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-
-import android.metrics.LogMaker;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-
-public class StatusBarStateParserTest extends ParserTest {
-
-    public StatusBarStateParserTest() {
-        mParser = new StatusBarStateParser();
-    }
-
-    public void testLockScreen() throws Throwable {
-        validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_OPEN, 1, "1,1,0,0,1,0");
-    }
-
-    public void testBounce() throws Throwable {
-        validate(MetricsEvent.BOUNCER, MetricsEvent.TYPE_OPEN, 1, "1,1,0,1,1,0");
-    }
-
-    public void testUnlock() throws Throwable {
-        validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_CLOSE, 1, "0,0,0,0,1,0");
-    }
-
-    public void testSecure() throws Throwable {
-        validate(MetricsEvent.BOUNCER, MetricsEvent.TYPE_OPEN, 1, "2,1,0,1,1,0");
-    }
-
-    public void testInsecure() throws Throwable {
-        validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_OPEN, 0, "1,1,0,0,0,0");
-    }
-
-    public void testIgnoreUnexpectedData() throws Throwable {
-        validate(MetricsEvent.LOCKSCREEN, MetricsEvent.TYPE_OPEN, 0, "1,1,0,0,0,0,5");
-    }
-
-    private void validate(int view, int type, int subType, String log) {
-        String[] parts = log.split(",");
-        int t = 1000;
-        Object[] objects = new Object[parts.length];
-        for (int i = 0; i < parts.length; i++) {
-            objects[i] = Integer.valueOf(parts[i]);
-        }
-
-        mParser.parseEvent(mLogger, t, objects);
-
-        verify(mLogger, times(1)).addEvent(mProtoCaptor.capture());
-
-        LogMaker proto = mProtoCaptor.getValue();
-        assertEquals(t, proto.getTimestamp());
-        assertEquals(view, proto.getCategory());
-        assertEquals(type, proto.getType());
-        assertEquals(subType, proto.getSubtype());
-    }
-}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index c5961ab..039ab1f 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -132,6 +132,7 @@
         <permission name="android.permission.ACCESS_IMS_CALL_SERVICE"/>
         <permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
         <permission name="android.permission.BIND_CARRIER_SERVICES"/>
+        <permission name="android.permission.BIND_IMS_SERVICE"/>
         <permission name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"/>
         <permission name="android.permission.CALL_PRIVILEGED"/>
         <permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
@@ -339,4 +340,4 @@
         <permission name="android.permission.CONTROL_VPN"/>
     </privapp-permissions>
 
-</permissions>
\ No newline at end of file
+</permissions>
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index 7a2cbd0..03df5de 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -29,6 +29,8 @@
  */
 public abstract class GateKeeper {
 
+    public static final long INVALID_SECURE_USER_ID = 0;
+
     private GateKeeper() {}
 
     public static IGateKeeperService getService() {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index b234d0f..9701b0e 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -17,6 +17,7 @@
 package android.security.keystore;
 
 import android.security.Credentials;
+import android.security.GateKeeper;
 import android.security.KeyStore;
 import android.security.keymaster.KeyCharacteristics;
 import android.security.keymaster.KeymasterArguments;
@@ -235,7 +236,8 @@
                         spec.isUserAuthenticationRequired(),
                         spec.getUserAuthenticationValidityDurationSeconds(),
                         spec.isUserAuthenticationValidWhileOnBody(),
-                        spec.isInvalidatedByBiometricEnrollment());
+                        spec.isInvalidatedByBiometricEnrollment(),
+                        GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
             } catch (IllegalStateException | IllegalArgumentException e) {
                 throw new InvalidAlgorithmParameterException(e);
             }
@@ -275,7 +277,8 @@
                 spec.isUserAuthenticationRequired(),
                 spec.getUserAuthenticationValidityDurationSeconds(),
                 spec.isUserAuthenticationValidWhileOnBody(),
-                spec.isInvalidatedByBiometricEnrollment());
+                spec.isInvalidatedByBiometricEnrollment(),
+                GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
         KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
                 args,
                 mKeymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index 1818f52..dba3949 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -18,6 +18,7 @@
 
 import android.annotation.Nullable;
 import android.security.Credentials;
+import android.security.GateKeeper;
 import android.security.KeyPairGeneratorSpec;
 import android.security.KeyStore;
 import android.security.keymaster.KeyCharacteristics;
@@ -346,7 +347,8 @@
                         mSpec.isUserAuthenticationRequired(),
                         mSpec.getUserAuthenticationValidityDurationSeconds(),
                         mSpec.isUserAuthenticationValidWhileOnBody(),
-                        mSpec.isInvalidatedByBiometricEnrollment());
+                        mSpec.isInvalidatedByBiometricEnrollment(),
+                        GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
             } catch (IllegalArgumentException | IllegalStateException e) {
                 throw new InvalidAlgorithmParameterException(e);
             }
@@ -533,7 +535,8 @@
                 mSpec.isUserAuthenticationRequired(),
                 mSpec.getUserAuthenticationValidityDurationSeconds(),
                 mSpec.isUserAuthenticationValidWhileOnBody(),
-                mSpec.isInvalidatedByBiometricEnrollment());
+                mSpec.isInvalidatedByBiometricEnrollment(),
+                GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
         args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
         args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
                 mSpec.getKeyValidityForOriginationEnd());
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index fcbb553..64b10ab 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -500,7 +500,8 @@
                         spec.isUserAuthenticationRequired(),
                         spec.getUserAuthenticationValidityDurationSeconds(),
                         spec.isUserAuthenticationValidWhileOnBody(),
-                        spec.isInvalidatedByBiometricEnrollment());
+                        spec.isInvalidatedByBiometricEnrollment(),
+                        spec.getBoundToSpecificSecureUserId());
                 importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
                         spec.getKeyValidityStart());
                 importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
@@ -696,7 +697,8 @@
                     params.isUserAuthenticationRequired(),
                     params.getUserAuthenticationValidityDurationSeconds(),
                     params.isUserAuthenticationValidWhileOnBody(),
-                    params.isInvalidatedByBiometricEnrollment());
+                    params.isInvalidatedByBiometricEnrollment(),
+                    params.getBoundToSpecificSecureUserId());
             KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
                     args,
                     keymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index e70d33a..2592a97 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.app.KeyguardManager;
 import android.hardware.fingerprint.FingerprintManager;
+import android.security.GateKeeper;
 
 import java.security.Key;
 import java.security.Signature;
@@ -225,6 +226,7 @@
     private final int mUserAuthenticationValidityDurationSeconds;
     private final boolean mUserAuthenticationValidWhileOnBody;
     private final boolean mInvalidatedByBiometricEnrollment;
+    private final long mBoundToSecureUserId;
 
     private KeyProtection(
             Date keyValidityStart,
@@ -239,7 +241,8 @@
             boolean userAuthenticationRequired,
             int userAuthenticationValidityDurationSeconds,
             boolean userAuthenticationValidWhileOnBody,
-            boolean invalidatedByBiometricEnrollment) {
+            boolean invalidatedByBiometricEnrollment,
+            long boundToSecureUserId) {
         mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
         mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
         mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
@@ -255,6 +258,7 @@
         mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
         mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
         mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
+        mBoundToSecureUserId = boundToSecureUserId;
     }
 
     /**
@@ -436,6 +440,24 @@
     }
 
     /**
+     * Return the secure user id that this key should be bound to.
+     *
+     * Normally an authentication-bound key is tied to the secure user id of the current user
+     * (either the root SID from GateKeeper for auth-bound keys with a timeout, or the authenticator
+     * id of the current fingerprint set for keys requiring explicit fingerprint authorization).
+     * If this parameter is set (this method returning non-zero value), the key should be tied to
+     * the specified secure user id, overriding the logic above.
+     *
+     * This is only applicable when {@link #isUserAuthenticationRequired} is {@code true}
+     *
+     * @see KeymasterUtils#addUserAuthArgs
+     * @hide
+     */
+    public long getBoundToSpecificSecureUserId() {
+        return mBoundToSecureUserId;
+    }
+
+    /**
      * Builder of {@link KeyProtection} instances.
      */
     public final static class Builder {
@@ -454,6 +476,7 @@
         private boolean mUserAuthenticationValidWhileOnBody;
         private boolean mInvalidatedByBiometricEnrollment = true;
 
+        private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
         /**
          * Creates a new instance of the {@code Builder}.
          *
@@ -774,6 +797,26 @@
         }
 
         /**
+         * Set the secure user id that this key should be bound to.
+         *
+         * Normally an authentication-bound key is tied to the secure user id of the current user
+         * (either the root SID from GateKeeper for auth-bound keys with a timeout, or the
+         * authenticator id of the current fingerprint set for keys requiring explicit fingerprint
+         * authorization). If this parameter is set (this method returning non-zero value), the key
+         * should be tied to the specified secure user id, overriding the logic above.
+         *
+         * This is only applicable when {@link #setUserAuthenticationRequired} is set to
+         * {@code true}
+         *
+         * @see KeyProtection#getBoundToSpecificSecureUserId()
+         * @hide
+         */
+        public Builder setBoundToSpecificSecureUserId(long secureUserId) {
+            mBoundToSecureUserId = secureUserId;
+            return this;
+        }
+
+        /**
          * Builds an instance of {@link KeyProtection}.
          *
          * @throws IllegalArgumentException if a required field is missing
@@ -793,7 +836,8 @@
                     mUserAuthenticationRequired,
                     mUserAuthenticationValidityDurationSeconds,
                     mUserAuthenticationValidWhileOnBody,
-                    mInvalidatedByBiometricEnrollment);
+                    mInvalidatedByBiometricEnrollment,
+                    mBoundToSecureUserId);
         }
     }
 }
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index f5272aa..34c8d1f 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -89,7 +89,10 @@
      * @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user
      *        authentication is valid as authorization for using the key or {@code -1} if every
      *        use of the key needs authorization.
-     *
+     * @param boundToSpecificSecureUserId if non-zero, specify which SID the key will be bound to,
+     *        overriding the default logic in this method where the key is bound to either the root
+     *        SID of the current user, or the fingerprint SID if explicit fingerprint authorization
+     *        is requested.
      * @throws IllegalStateException if user authentication is required but the system is in a wrong
      *         state (e.g., secure lock screen not set up) for generating or importing keys that
      *         require user authentication.
@@ -98,7 +101,8 @@
             boolean userAuthenticationRequired,
             int userAuthenticationValidityDurationSeconds,
             boolean userAuthenticationValidWhileOnBody,
-            boolean invalidatedByBiometricEnrollment) {
+            boolean invalidatedByBiometricEnrollment,
+            long boundToSpecificSecureUserId) {
         if (!userAuthenticationRequired) {
             args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
             return;
@@ -120,7 +124,9 @@
             }
 
             long sid;
-            if (invalidatedByBiometricEnrollment) {
+            if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
+                sid = boundToSpecificSecureUserId;
+            } else if (invalidatedByBiometricEnrollment) {
                 // The fingerprint-only SID will change on fingerprint enrollment or removal of all,
                 // enrolled fingerprints, invalidating the key.
                 sid = fingerprintOnlySid;
@@ -138,11 +144,16 @@
                         + "supported for keys requiring fingerprint authentication");
             }
         } else {
-            // The key is authorized for use for the specified amount of time after the user has
-            // authenticated. Whatever unlocks the secure lock screen should authorize this key.
-            long rootSid = getRootSid();
+            long sid;
+            if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
+                sid = boundToSpecificSecureUserId;
+            } else {
+                // The key is authorized for use for the specified amount of time after the user has
+                // authenticated. Whatever unlocks the secure lock screen should authorize this key.
+                sid = getRootSid();
+            }
             args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
-                    KeymasterArguments.toUint64(rootSid));
+                    KeymasterArguments.toUint64(sid));
             args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
                     KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
             args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 9a08f63..fe68ec0 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -27,16 +27,17 @@
 
 namespace android {
 
-std::unique_ptr<ApkAssets> ApkAssets::Load(const std::string& path) {
-  return ApkAssets::LoadImpl(path, false /*load_as_shared_library*/);
+std::unique_ptr<const ApkAssets> ApkAssets::Load(const std::string& path, bool system) {
+  return ApkAssets::LoadImpl(path, system, false /*load_as_shared_library*/);
 }
 
-std::unique_ptr<ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path) {
-  return ApkAssets::LoadImpl(path, true /*load_as_shared_library*/);
+std::unique_ptr<const ApkAssets> ApkAssets::LoadAsSharedLibrary(const std::string& path,
+                                                                bool system) {
+  return ApkAssets::LoadImpl(path, system, true /*load_as_shared_library*/);
 }
 
-std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(const std::string& path,
-                                               bool load_as_shared_library) {
+std::unique_ptr<const ApkAssets> ApkAssets::LoadImpl(const std::string& path, bool system,
+                                                     bool load_as_shared_library) {
   ATRACE_CALL();
   ::ZipArchiveHandle unmanaged_handle;
   int32_t result = ::OpenArchive(path.c_str(), &unmanaged_handle);
@@ -70,11 +71,13 @@
   loaded_apk->path_ = path;
   loaded_apk->loaded_arsc_ =
       LoadedArsc::Load(loaded_apk->resources_asset_->getBuffer(true /*wordAligned*/),
-                       loaded_apk->resources_asset_->getLength(), load_as_shared_library);
+                       loaded_apk->resources_asset_->getLength(), system, load_as_shared_library);
   if (loaded_apk->loaded_arsc_ == nullptr) {
     return {};
   }
-  return loaded_apk;
+
+  // Need to force a move for mingw32.
+  return std::move(loaded_apk);
 }
 
 std::unique_ptr<Asset> ApkAssets::Open(const std::string& path, Asset::AccessMode /*mode*/) const {
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index d2eff65..542a125 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -18,6 +18,8 @@
 
 #include "androidfw/AssetManager2.h"
 
+#include <set>
+
 #include "android-base/logging.h"
 #include "android-base/stringprintf.h"
 #include "utils/ByteOrder.h"
@@ -143,6 +145,36 @@
   }
 }
 
+std::set<ResTable_config> AssetManager2::GetResourceConfigurations(bool exclude_system,
+                                                                   bool exclude_mipmap) {
+  ATRACE_CALL();
+  std::set<ResTable_config> configurations;
+  for (const PackageGroup& package_group : package_groups_) {
+    for (const LoadedPackage* package : package_group.packages_) {
+      if (exclude_system && package->IsSystem()) {
+        continue;
+      }
+      package->CollectConfigurations(exclude_mipmap, &configurations);
+    }
+  }
+  return configurations;
+}
+
+std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system,
+                                                        bool merge_equivalent_languages) {
+  ATRACE_CALL();
+  std::set<std::string> locales;
+  for (const PackageGroup& package_group : package_groups_) {
+    for (const LoadedPackage* package : package_group.packages_) {
+      if (exclude_system && package->IsSystem()) {
+        continue;
+      }
+      package->CollectLocales(merge_equivalent_languages, &locales);
+    }
+  }
+  return locales;
+}
+
 std::unique_ptr<Asset> AssetManager2::Open(const std::string& filename, Asset::AccessMode mode) {
   const std::string new_path = "assets/" + filename;
   return OpenNonAsset(new_path, mode);
@@ -325,8 +357,15 @@
   if (dtohl(entry.entry->flags) & ResTable_entry::FLAG_COMPLEX) {
     if (!may_be_bag) {
       LOG(ERROR) << base::StringPrintf("Resource %08x is a complex map type.", resid);
+      return kInvalidCookie;
     }
-    return kInvalidCookie;
+
+    // Create a reference since we can't represent this complex type as a Res_value.
+    out_value->dataType = Res_value::TYPE_REFERENCE;
+    out_value->data = resid;
+    *out_selected_config = config;
+    *out_flags = flags;
+    return cookie;
   }
 
   const Res_value* device_value = reinterpret_cast<const Res_value*>(
@@ -341,6 +380,37 @@
   return cookie;
 }
 
+ApkAssetsCookie AssetManager2::ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value,
+                                                ResTable_config* in_out_selected_config,
+                                                uint32_t* in_out_flags,
+                                                ResTable_ref* out_last_reference) {
+  ATRACE_CALL();
+  constexpr const int kMaxIterations = 20;
+
+  out_last_reference->ident = 0u;
+  for (size_t iteration = 0u; in_out_value->dataType == Res_value::TYPE_REFERENCE &&
+                              in_out_value->data != 0u && iteration < kMaxIterations;
+       iteration++) {
+    if (out_last_reference != nullptr) {
+      out_last_reference->ident = in_out_value->data;
+    }
+    uint32_t new_flags = 0u;
+    cookie = GetResource(in_out_value->data, true /*may_be_bag*/, 0u /*density_override*/,
+                         in_out_value, in_out_selected_config, &new_flags);
+    if (cookie == kInvalidCookie) {
+      return kInvalidCookie;
+    }
+    if (in_out_flags != nullptr) {
+      *in_out_flags |= new_flags;
+    }
+    if (out_last_reference->ident == in_out_value->data) {
+      // This reference can't be resolved, so exit now and let the caller deal with it.
+      return cookie;
+    }
+  }
+  return cookie;
+}
+
 const ResolvedBag* AssetManager2::GetBag(uint32_t resid) {
   ATRACE_CALL();
 
@@ -501,6 +571,15 @@
   return result;
 }
 
+uint32_t AssetManager2::GetResourceId(const std::string& resource_name,
+                                      const std::string& fallback_type,
+                                      const std::string& fallback_package) {
+  (void)resource_name;
+  (void)fallback_type;
+  (void)fallback_package;
+  return 0u;
+}
+
 void AssetManager2::InvalidateCaches(uint32_t diff) {
   if (diff == 0xffffffffu) {
     // Everything must go.
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index c7d0fa5..cb589ec 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -321,6 +321,57 @@
   return true;
 }
 
+void LoadedPackage::CollectConfigurations(bool exclude_mipmap,
+                                          std::set<ResTable_config>* out_configs) const {
+  const static std::u16string kMipMap = u"mipmap";
+  const size_t type_count = type_specs_.size();
+  for (size_t i = 0; i < type_count; i++) {
+    const util::unique_cptr<TypeSpec>& type_spec = type_specs_[i];
+    if (type_spec != nullptr) {
+      if (exclude_mipmap) {
+        const int type_idx = type_spec->type_spec->id - 1;
+        size_t type_name_len;
+        const char16_t* type_name16 = type_string_pool_.stringAt(type_idx, &type_name_len);
+        if (type_name16 != nullptr) {
+          if (kMipMap.compare(0, std::u16string::npos, type_name16, type_name_len) == 0) {
+            // This is a mipmap type, skip collection.
+            continue;
+          }
+        }
+        const char* type_name = type_string_pool_.string8At(type_idx, &type_name_len);
+        if (type_name != nullptr) {
+          if (strncmp(type_name, "mipmap", type_name_len) == 0) {
+            // This is a mipmap type, skip collection.
+            continue;
+          }
+        }
+      }
+
+      for (size_t j = 0; j < type_spec->type_count; j++) {
+        out_configs->insert(type_spec->types[j].configuration);
+      }
+    }
+  }
+}
+
+void LoadedPackage::CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const {
+  char temp_locale[RESTABLE_MAX_LOCALE_LEN];
+  const size_t type_count = type_specs_.size();
+  for (size_t i = 0; i < type_count; i++) {
+    const util::unique_cptr<TypeSpec>& type_spec = type_specs_[i];
+    if (type_spec != nullptr) {
+      for (size_t j = 0; j < type_spec->type_count; j++) {
+        const ResTable_config& configuration = type_spec->types[j].configuration;
+        if (configuration.locale != 0) {
+          configuration.getBcp47Locale(temp_locale, canonicalize);
+          std::string locale(temp_locale);
+          out_locales->insert(std::move(locale));
+        }
+      }
+    }
+  }
+}
+
 std::unique_ptr<LoadedPackage> LoadedPackage::Load(const Chunk& chunk) {
   ATRACE_CALL();
   std::unique_ptr<LoadedPackage> loaded_package{new LoadedPackage()};
@@ -574,6 +625,7 @@
         if (loaded_package->package_id_ == kAppPackageId) {
           loaded_package->dynamic_ = load_as_shared_library;
         }
+        loaded_package->system_ = system_;
         packages_.push_back(std::move(loaded_package));
       } break;
 
@@ -590,12 +642,13 @@
   return true;
 }
 
-std::unique_ptr<LoadedArsc> LoadedArsc::Load(const void* data, size_t len,
-                                             bool load_as_shared_library) {
+std::unique_ptr<const LoadedArsc> LoadedArsc::Load(const void* data, size_t len, bool system,
+                                                   bool load_as_shared_library) {
   ATRACE_CALL();
 
   // Not using make_unique because the constructor is private.
   std::unique_ptr<LoadedArsc> loaded_arsc(new LoadedArsc());
+  loaded_arsc->system_ = system;
 
   ChunkIterator iter(data, len);
   while (iter.HasNext()) {
@@ -617,7 +670,9 @@
     LOG(ERROR) << iter.GetLastError();
     return {};
   }
-  return loaded_arsc;
+
+  // Need to force a move for mingw32.
+  return std::move(loaded_arsc);
 }
 
 }  // namespace android
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index 9d4fd29..6d1578c 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -31,8 +31,9 @@
 // Holds an APK.
 class ApkAssets {
  public:
-  static std::unique_ptr<ApkAssets> Load(const std::string& path);
-  static std::unique_ptr<ApkAssets> LoadAsSharedLibrary(const std::string& path);
+  static std::unique_ptr<const ApkAssets> Load(const std::string& path, bool system = false);
+  static std::unique_ptr<const ApkAssets> LoadAsSharedLibrary(const std::string& path,
+                                                              bool system = false);
 
   std::unique_ptr<Asset> Open(const std::string& path,
                               Asset::AccessMode mode = Asset::AccessMode::ACCESS_RANDOM) const;
@@ -44,7 +45,8 @@
  private:
   DISALLOW_COPY_AND_ASSIGN(ApkAssets);
 
-  static std::unique_ptr<ApkAssets> LoadImpl(const std::string& path, bool load_as_shared_library);
+  static std::unique_ptr<const ApkAssets> LoadImpl(const std::string& path, bool system,
+                                                   bool load_as_shared_library);
 
   ApkAssets() = default;
 
@@ -57,7 +59,7 @@
   ZipArchivePtr zip_handle_;
   std::string path_;
   std::unique_ptr<Asset> resources_asset_;
-  std::unique_ptr<LoadedArsc> loaded_arsc_;
+  std::unique_ptr<const LoadedArsc> loaded_arsc_;
 };
 
 }  // namespace android
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index 8655339..81cdc46 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -21,6 +21,7 @@
 
 #include <array>
 #include <limits>
+#include <set>
 #include <unordered_map>
 
 #include "androidfw/ApkAssets.h"
@@ -112,6 +113,24 @@
 
   inline const ResTable_config& GetConfiguration() const { return configuration_; }
 
+  // Returns all configurations for which there are resources defined. This includes resource
+  // configurations in all the ApkAssets set for this AssetManager.
+  // If `exclude_system` is set to true, resource configurations from system APKs
+  // ('android' package, other libraries) will be excluded from the list.
+  // If `exclude_mipmap` is set to true, resource configurations defined for resource type 'mipmap'
+  // will be excluded from the list.
+  std::set<ResTable_config> GetResourceConfigurations(bool exclude_system = false,
+                                                      bool exclude_mipmap = false);
+
+  // Returns all the locales for which there are resources defined. This includes resource
+  // locales in all the ApkAssets set for this AssetManager.
+  // If `exclude_system` is set to true, resource locales from system APKs
+  // ('android' package, other libraries) will be excluded from the list.
+  // If `merge_equivalent_languages` is set to true, resource locales will be canonicalized
+  // and de-duped in the resulting list.
+  std::set<std::string> GetResourceLocales(bool exclude_system = false,
+                                           bool merge_equivalent_languages = false);
+
   // Searches the set of APKs loaded by this AssetManager and opens the first one found located
   // in the assets/ directory.
   // `mode` controls how the file is opened.
@@ -149,6 +168,14 @@
   // Returns false if the resource was not found.
   bool GetResourceFlags(uint32_t resid, uint32_t* out_flags);
 
+  // Finds the resource ID assigned to `resource_name`.
+  // `resource_name` must be of the form '[package:][type/]entry'.
+  // If no package is specified in `resource_name`, then `fallback_package` is used as the package.
+  // If no type is specified in `resource_name`, then `fallback_type` is used as the type.
+  // Returns 0x0 if no resource by that name was found.
+  uint32_t GetResourceId(const std::string& resource_name, const std::string& fallback_type = {},
+                         const std::string& fallback_package = {});
+
   // Retrieves the best matching resource with ID `resid`. The resource value is filled into
   // `out_value` and the configuration for the selected value is populated in `out_selected_config`.
   // `out_flags` holds the same flags as retrieved with GetResourceFlags().
@@ -162,6 +189,22 @@
                               Res_value* out_value, ResTable_config* out_selected_config,
                               uint32_t* out_flags);
 
+  // Resolves the resource reference in `in_out_value` if the data type is
+  // Res_value::TYPE_REFERENCE.
+  // `cookie` is the ApkAssetsCookie of the reference in `in_out_value`.
+  // `in_out_value` is the reference to resolve. The result is placed back into this object.
+  // `in_out_flags` is the type spec flags returned from calls to GetResource() or
+  // GetResourceFlags(). Configuration flags of the values pointed to by the reference
+  // are OR'd together with `in_out_flags`.
+  // `in_out_config` is populated with the configuration for which the resolved value was defined.
+  // `out_last_reference` is populated with the last reference ID before resolving to an actual
+  // value.
+  // Returns the cookie of the APK the resolved resource was defined in, or kInvalidCookie if
+  // it was not found.
+  ApkAssetsCookie ResolveReference(ApkAssetsCookie cookie, Res_value* in_out_value,
+                                   ResTable_config* in_out_selected_config, uint32_t* in_out_flags,
+                                   ResTable_ref* out_last_reference);
+
   // Retrieves the best matching bag/map resource with ID `resid`.
   // This method will resolve all parent references for this bag and merge keys with the child.
   // To iterate over the keys, use the following idiom:
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index e8cb164..91a7cb7 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -18,6 +18,7 @@
 #define LOADEDARSC_H_
 
 #include <memory>
+#include <set>
 #include <vector>
 
 #include "android-base/macros.h"
@@ -68,20 +69,38 @@
                  LoadedArscEntry* out_entry, ResTable_config* out_selected_config,
                  uint32_t* out_flags) const;
 
+  // Returns the string pool where type names are stored.
   inline const ResStringPool* GetTypeStringPool() const { return &type_string_pool_; }
 
+  // Returns the string pool where the names of resource entries are stored.
   inline const ResStringPool* GetKeyStringPool() const { return &key_string_pool_; }
 
   inline const std::string& GetPackageName() const { return package_name_; }
 
   inline int GetPackageId() const { return package_id_; }
 
+  // Returns true if this package is dynamic (shared library) and needs to have an ID assigned.
   inline bool IsDynamic() const { return dynamic_; }
 
+  // Returns true if this package originates from a system provided resource.
+  inline bool IsSystem() const { return system_; }
+
+  // Returns the map of package name to package ID used in this LoadedPackage. At runtime, a
+  // package could have been assigned a different package ID than what this LoadedPackage was
+  // compiled with. AssetManager rewrites the package IDs so that they are compatible at runtime.
   inline const std::vector<DynamicPackageEntry>& GetDynamicPackageMap() const {
     return dynamic_package_map_;
   }
 
+  // Populates a set of ResTable_config structs, possibly excluding configurations defined for
+  // the mipmap type.
+  void CollectConfigurations(bool exclude_mipmap, std::set<ResTable_config>* out_configs) const;
+
+  // Populates a set of strings representing locales.
+  // If `canonicalize` is set to true, each locale is transformed into its canonical format
+  // before being inserted into the set. This may cause some equivalent locales to de-dupe.
+  void CollectLocales(bool canonicalize, std::set<std::string>* out_locales) const;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(LoadedPackage);
 
@@ -93,8 +112,9 @@
   ResStringPool key_string_pool_;
   std::string package_name_;
   int package_id_ = -1;
-  bool dynamic_ = false;
   int type_id_offset_ = 0;
+  bool dynamic_ = false;
+  bool system_ = false;
 
   ByteBucketArray<util::unique_cptr<TypeSpec>> type_specs_;
   std::vector<DynamicPackageEntry> dynamic_package_map_;
@@ -104,10 +124,14 @@
 // when loading, including offsets and lengths.
 class LoadedArsc {
  public:
-  // Load the resource table from memory. The data's lifetime must out-live the
-  // object returned from this method.
-  static std::unique_ptr<LoadedArsc> Load(const void* data, size_t len,
-                                          bool load_as_shared_library = false);
+  // Load a resource table from memory pointed to by `data` of size `len`.
+  // The lifetime of `data` must out-live the LoadedArsc returned from this method.
+  // If `system` is set to true, the LoadedArsc is considered as a system provided resource.
+  // If `load_as_shared_library` is set to true, the application package (0x7f) is treated
+  // as a shared library (0x00). When loaded into an AssetManager, the package will be assigned an
+  // ID.
+  static std::unique_ptr<const LoadedArsc> Load(const void* data, size_t len, bool system = false,
+                                                bool load_as_shared_library = false);
 
   ~LoadedArsc();
 
@@ -125,6 +149,10 @@
   // Gets a pointer to the name of the package in `resid`, or nullptr if the package doesn't exist.
   const LoadedPackage* GetPackageForId(uint32_t resid) const;
 
+  // Returns true if this is a system provided resource.
+  inline bool IsSystem() const { return system_; }
+
+  // Returns a vector of LoadedPackage pointers, representing the packages in this LoadedArsc.
   inline const std::vector<std::unique_ptr<const LoadedPackage>>& GetPackages() const {
     return packages_;
   }
@@ -137,6 +165,7 @@
 
   ResStringPool global_string_pool_;
   std::vector<std::unique_ptr<const LoadedPackage>> packages_;
+  bool system_ = false;
 };
 
 }  // namespace android
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 56c22e6..04a5d95 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -1188,6 +1188,8 @@
     int compare(const ResTable_config& o) const;
     int compareLogical(const ResTable_config& o) const;
 
+    inline bool operator<(const ResTable_config& o) const { return compare(o) < 0; }
+
     // Flags indicating a set of config values.  These flag constants must
     // match the corresponding ones in android.content.pm.ActivityInfo and
     // attrs_manifest.xml.
diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h
index fd96730..96b42bf 100644
--- a/libs/androidfw/include/androidfw/Util.h
+++ b/libs/androidfw/include/androidfw/Util.h
@@ -94,8 +94,12 @@
 
   inline bool operator==(const unique_cptr& o) const { return ptr_ == o.ptr_; }
 
+  inline bool operator!=(const unique_cptr& o) const { return ptr_ != o.ptr_; }
+
   inline bool operator==(std::nullptr_t) const { return ptr_ == nullptr; }
 
+  inline bool operator!=(std::nullptr_t) const { return ptr_ != nullptr; }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(unique_cptr);
 
diff --git a/libs/androidfw/tests/ApkAssets_test.cpp b/libs/androidfw/tests/ApkAssets_test.cpp
index 0203712..6b4a719 100644
--- a/libs/androidfw/tests/ApkAssets_test.cpp
+++ b/libs/androidfw/tests/ApkAssets_test.cpp
@@ -24,7 +24,8 @@
 namespace android {
 
 TEST(ApkAssetsTest, LoadApk) {
-  std::unique_ptr<ApkAssets> loaded_apk = ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
+  std::unique_ptr<const ApkAssets> loaded_apk =
+      ApkAssets::Load(GetTestDataPath() + "/basic/basic.apk");
   ASSERT_NE(nullptr, loaded_apk);
   EXPECT_NE(nullptr, loaded_apk->GetLoadedArsc());
 
@@ -33,7 +34,7 @@
 }
 
 TEST(ApkAssetsTest, LoadApkAsSharedLibrary) {
-  std::unique_ptr<ApkAssets> loaded_apk =
+  std::unique_ptr<const ApkAssets> loaded_apk =
       ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk");
   ASSERT_NE(nullptr, loaded_apk);
   const LoadedArsc* loaded_arsc = loaded_apk->GetLoadedArsc();
diff --git a/libs/androidfw/tests/AssetManager2_bench.cpp b/libs/androidfw/tests/AssetManager2_bench.cpp
index b3c2dc3..273290a 100644
--- a/libs/androidfw/tests/AssetManager2_bench.cpp
+++ b/libs/androidfw/tests/AssetManager2_bench.cpp
@@ -38,7 +38,7 @@
 static void BM_AssetManagerLoadAssets(benchmark::State& state) {
   std::string path = GetTestDataPath() + "/basic/basic.apk";
   while (state.KeepRunning()) {
-    std::unique_ptr<ApkAssets> apk = ApkAssets::Load(path);
+    std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path);
     AssetManager2 assets;
     assets.SetApkAssets({apk.get()});
   }
@@ -61,7 +61,7 @@
 static void BM_AssetManagerLoadFrameworkAssets(benchmark::State& state) {
   std::string path = kFrameworkPath;
   while (state.KeepRunning()) {
-    std::unique_ptr<ApkAssets> apk = ApkAssets::Load(path);
+    std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path);
     AssetManager2 assets;
     assets.SetApkAssets({apk.get()});
   }
@@ -84,10 +84,10 @@
 static void GetResourceBenchmark(const std::vector<std::string>& paths,
                                  const ResTable_config* config, uint32_t resid,
                                  benchmark::State& state) {
-  std::vector<std::unique_ptr<ApkAssets>> apk_assets;
+  std::vector<std::unique_ptr<const ApkAssets>> apk_assets;
   std::vector<const ApkAssets*> apk_assets_ptrs;
   for (const std::string& path : paths) {
-    std::unique_ptr<ApkAssets> apk = ApkAssets::Load(path);
+    std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path);
     if (apk == nullptr) {
       state.SkipWithError(base::StringPrintf("Failed to load assets %s", path.c_str()).c_str());
       return;
@@ -187,7 +187,7 @@
 BENCHMARK(BM_AssetManagerGetResourceFrameworkLocaleOld);
 
 static void BM_AssetManagerGetBag(benchmark::State& state) {
-  std::unique_ptr<ApkAssets> apk = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
+  std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(GetTestDataPath() + "/styles/styles.apk");
   if (apk == nullptr) {
     state.SkipWithError("Failed to load assets");
     return;
@@ -234,4 +234,40 @@
 }
 BENCHMARK(BM_AssetManagerGetBagOld);
 
+static void BM_AssetManagerGetResourceLocales(benchmark::State& state) {
+  std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
+  if (apk == nullptr) {
+    state.SkipWithError("Failed to load assets");
+    return;
+  }
+
+  AssetManager2 assets;
+  assets.SetApkAssets({apk.get()});
+
+  while (state.KeepRunning()) {
+    std::set<std::string> locales =
+        assets.GetResourceLocales(false /*exclude_system*/, true /*merge_equivalent_languages*/);
+    benchmark::DoNotOptimize(locales);
+  }
+}
+BENCHMARK(BM_AssetManagerGetResourceLocales);
+
+static void BM_AssetManagerGetResourceLocalesOld(benchmark::State& state) {
+  AssetManager assets;
+  if (!assets.addAssetPath(String8(kFrameworkPath), nullptr /*cookie*/, false /*appAsLib*/,
+                           false /*isSystemAssets*/)) {
+    state.SkipWithError("Failed to load assets");
+    return;
+  }
+
+  const ResTable& table = assets.getResources(true);
+
+  while (state.KeepRunning()) {
+    Vector<String8> locales;
+    table.getLocales(&locales, true /*includeSystemLocales*/, true /*mergeEquivalentLangs*/);
+    benchmark::DoNotOptimize(locales);
+  }
+}
+BENCHMARK(BM_AssetManagerGetResourceLocalesOld);
+
 }  // namespace android
diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp
index 543456a..557d8d4 100644
--- a/libs/androidfw/tests/AssetManager2_test.cpp
+++ b/libs/androidfw/tests/AssetManager2_test.cpp
@@ -26,6 +26,7 @@
 #include "data/lib_two/R.h"
 #include "data/libclient/R.h"
 #include "data/styles/R.h"
+#include "data/system/R.h"
 
 namespace app = com::android::app;
 namespace appaslib = com::android::appaslib::app;
@@ -59,16 +60,20 @@
 
     appaslib_assets_ = ApkAssets::Load(GetTestDataPath() + "/appaslib/appaslib.apk");
     ASSERT_NE(nullptr, appaslib_assets_);
+
+    system_assets_ = ApkAssets::Load(GetTestDataPath() + "/system/system.apk", true /*system*/);
+    ASSERT_NE(nullptr, system_assets_);
   }
 
  protected:
-  std::unique_ptr<ApkAssets> basic_assets_;
-  std::unique_ptr<ApkAssets> basic_de_fr_assets_;
-  std::unique_ptr<ApkAssets> style_assets_;
-  std::unique_ptr<ApkAssets> lib_one_assets_;
-  std::unique_ptr<ApkAssets> lib_two_assets_;
-  std::unique_ptr<ApkAssets> libclient_assets_;
-  std::unique_ptr<ApkAssets> appaslib_assets_;
+  std::unique_ptr<const ApkAssets> basic_assets_;
+  std::unique_ptr<const ApkAssets> basic_de_fr_assets_;
+  std::unique_ptr<const ApkAssets> style_assets_;
+  std::unique_ptr<const ApkAssets> lib_one_assets_;
+  std::unique_ptr<const ApkAssets> lib_two_assets_;
+  std::unique_ptr<const ApkAssets> libclient_assets_;
+  std::unique_ptr<const ApkAssets> appaslib_assets_;
+  std::unique_ptr<const ApkAssets> system_assets_;
 };
 
 TEST_F(AssetManager2Test, FindsResourceFromSingleApkAssets) {
@@ -291,6 +296,131 @@
   EXPECT_EQ(0, bag_two->entries[4].cookie);
 }
 
+TEST_F(AssetManager2Test, ResolveReferenceToResource) {
+  AssetManager2 assetmanager;
+  assetmanager.SetApkAssets({basic_assets_.get()});
+
+  Res_value value;
+  ResTable_config selected_config;
+  uint32_t flags;
+  ApkAssetsCookie cookie =
+      assetmanager.GetResource(basic::R::integer::ref1, false /*may_be_bag*/,
+                               0u /*density_override*/, &value, &selected_config, &flags);
+  ASSERT_NE(kInvalidCookie, cookie);
+
+  EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
+  EXPECT_EQ(basic::R::integer::ref2, value.data);
+
+  ResTable_ref last_ref;
+  cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref);
+  ASSERT_NE(kInvalidCookie, cookie);
+  EXPECT_EQ(Res_value::TYPE_INT_DEC, value.dataType);
+  EXPECT_EQ(12000u, value.data);
+  EXPECT_EQ(basic::R::integer::ref2, last_ref.ident);
+}
+
+TEST_F(AssetManager2Test, ResolveReferenceToBag) {
+  AssetManager2 assetmanager;
+  assetmanager.SetApkAssets({basic_assets_.get()});
+
+  Res_value value;
+  ResTable_config selected_config;
+  uint32_t flags;
+  ApkAssetsCookie cookie =
+      assetmanager.GetResource(basic::R::integer::number2, true /*may_be_bag*/,
+                               0u /*density_override*/, &value, &selected_config, &flags);
+  ASSERT_NE(kInvalidCookie, cookie);
+
+  EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
+  EXPECT_EQ(basic::R::array::integerArray1, value.data);
+
+  ResTable_ref last_ref;
+  cookie = assetmanager.ResolveReference(cookie, &value, &selected_config, &flags, &last_ref);
+  ASSERT_NE(kInvalidCookie, cookie);
+  EXPECT_EQ(Res_value::TYPE_REFERENCE, value.dataType);
+  EXPECT_EQ(basic::R::array::integerArray1, value.data);
+  EXPECT_EQ(basic::R::array::integerArray1, last_ref.ident);
+}
+
+static bool IsConfigurationPresent(const std::set<ResTable_config>& configurations,
+                                   const ResTable_config& configuration) {
+  return configurations.count(configuration) > 0;
+}
+
+TEST_F(AssetManager2Test, GetResourceConfigurations) {
+  AssetManager2 assetmanager;
+  assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()});
+
+  std::set<ResTable_config> configurations = assetmanager.GetResourceConfigurations();
+
+  // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
+  // And one extra for the default configuration.
+  EXPECT_EQ(4u, configurations.size());
+
+  ResTable_config expected_config;
+  memset(&expected_config, 0, sizeof(expected_config));
+  expected_config.language[0] = 's';
+  expected_config.language[1] = 'v';
+  EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+
+  expected_config.language[0] = 'd';
+  expected_config.language[1] = 'e';
+  EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+
+  expected_config.language[0] = 'f';
+  expected_config.language[1] = 'r';
+  EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+
+  // Take out the system assets.
+  configurations = assetmanager.GetResourceConfigurations(true /* exclude_system */);
+
+  // We expect de and fr from basic_de_fr assets.
+  EXPECT_EQ(2u, configurations.size());
+
+  expected_config.language[0] = 's';
+  expected_config.language[1] = 'v';
+  EXPECT_FALSE(IsConfigurationPresent(configurations, expected_config));
+
+  expected_config.language[0] = 'd';
+  expected_config.language[1] = 'e';
+  EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+
+  expected_config.language[0] = 'f';
+  expected_config.language[1] = 'r';
+  EXPECT_TRUE(IsConfigurationPresent(configurations, expected_config));
+}
+
+TEST_F(AssetManager2Test, GetResourceLocales) {
+  AssetManager2 assetmanager;
+  assetmanager.SetApkAssets({system_assets_.get(), basic_de_fr_assets_.get()});
+
+  std::set<std::string> locales = assetmanager.GetResourceLocales();
+
+  // We expect the locale sv from the system assets, and de and fr from basic_de_fr assets.
+  EXPECT_EQ(3u, locales.size());
+  EXPECT_GT(locales.count("sv"), 0u);
+  EXPECT_GT(locales.count("de"), 0u);
+  EXPECT_GT(locales.count("fr"), 0u);
+
+  locales = assetmanager.GetResourceLocales(true /*exclude_system*/);
+  // We expect the de and fr locales from basic_de_fr assets.
+  EXPECT_EQ(2u, locales.size());
+  EXPECT_GT(locales.count("de"), 0u);
+  EXPECT_GT(locales.count("fr"), 0u);
+}
+
+TEST_F(AssetManager2Test, GetResourceId) {
+  AssetManager2 assetmanager;
+  assetmanager.SetApkAssets({basic_assets_.get()});
+
+  EXPECT_EQ(basic::R::layout::main,
+            assetmanager.GetResourceId("com.android.basic:layout/main", "", ""));
+  EXPECT_EQ(basic::R::layout::main,
+            assetmanager.GetResourceId("layout/main", "", "com.android.basic"));
+  EXPECT_EQ(basic::R::layout::main,
+            assetmanager.GetResourceId("main", "layout", "com.android.basic"));
+}
+
 TEST_F(AssetManager2Test, OpensFileFromSingleApkAssets) {}
 
 TEST_F(AssetManager2Test, OpensFileFromMultipleApkAssets) {}
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index f8aa61a..756869f 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -32,7 +32,8 @@
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/styles/styles.apk", "resources.arsc",
                                       &contents));
 
-  std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc =
+      LoadedArsc::Load(contents.data(), contents.size());
   ASSERT_NE(nullptr, loaded_arsc);
 
   const std::vector<std::unique_ptr<const LoadedPackage>>& packages = loaded_arsc->GetPackages();
@@ -58,7 +59,8 @@
   ASSERT_TRUE(
       ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc", &contents));
 
-  std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc =
+      LoadedArsc::Load(contents.data(), contents.size());
   ASSERT_NE(nullptr, loaded_arsc);
 
   ResTable_config desired_config;
@@ -80,7 +82,8 @@
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib_one/lib_one.apk", "resources.arsc",
                                       &contents));
 
-  std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc =
+      LoadedArsc::Load(contents.data(), contents.size());
   ASSERT_NE(nullptr, loaded_arsc);
 
   const auto& packages = loaded_arsc->GetPackages();
@@ -101,7 +104,8 @@
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/libclient/libclient.apk",
                                       "resources.arsc", &contents));
 
-  std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc =
+      LoadedArsc::Load(contents.data(), contents.size());
   ASSERT_NE(nullptr, loaded_arsc);
 
   const auto& packages = loaded_arsc->GetPackages();
@@ -128,8 +132,8 @@
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/appaslib/appaslib.apk",
                                       "resources.arsc", &contents));
 
-  std::unique_ptr<LoadedArsc> loaded_arsc =
-      LoadedArsc::Load(contents.data(), contents.size(), true /*load_as_shared_library*/);
+  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(
+      contents.data(), contents.size(), false /*system*/, true /*load_as_shared_library*/);
   ASSERT_NE(nullptr, loaded_arsc);
 
   const auto& packages = loaded_arsc->GetPackages();
@@ -143,7 +147,8 @@
   std::string contents;
   ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/feature/feature.apk", "resources.arsc",
                                       &contents));
-  std::unique_ptr<LoadedArsc> loaded_arsc = LoadedArsc::Load(contents.data(), contents.size());
+  std::unique_ptr<const LoadedArsc> loaded_arsc =
+      LoadedArsc::Load(contents.data(), contents.size());
   ASSERT_NE(nullptr, loaded_arsc);
 
   ResTable_config desired_config;
diff --git a/libs/androidfw/tests/Theme_bench.cpp b/libs/androidfw/tests/Theme_bench.cpp
index c471be6..594c39e 100644
--- a/libs/androidfw/tests/Theme_bench.cpp
+++ b/libs/androidfw/tests/Theme_bench.cpp
@@ -28,7 +28,7 @@
 constexpr const static uint32_t kAttrId = 0x01010030u;   // android:attr/colorForeground
 
 static void BM_ThemeApplyStyleFramework(benchmark::State& state) {
-  std::unique_ptr<ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
+  std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
   if (apk == nullptr) {
     state.SkipWithError("Failed to load assets");
     return;
@@ -62,7 +62,7 @@
 BENCHMARK(BM_ThemeApplyStyleFrameworkOld);
 
 static void BM_ThemeGetAttribute(benchmark::State& state) {
-  std::unique_ptr<ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
+  std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(kFrameworkPath);
 
   AssetManager2 assets;
   assets.SetApkAssets({apk.get()});
diff --git a/libs/androidfw/tests/Theme_test.cpp b/libs/androidfw/tests/Theme_test.cpp
index 59cb18a..daed28b 100644
--- a/libs/androidfw/tests/Theme_test.cpp
+++ b/libs/androidfw/tests/Theme_test.cpp
@@ -46,10 +46,10 @@
   }
 
  protected:
-  std::unique_ptr<ApkAssets> style_assets_;
-  std::unique_ptr<ApkAssets> libclient_assets_;
-  std::unique_ptr<ApkAssets> lib_one_assets_;
-  std::unique_ptr<ApkAssets> lib_two_assets_;
+  std::unique_ptr<const ApkAssets> style_assets_;
+  std::unique_ptr<const ApkAssets> libclient_assets_;
+  std::unique_ptr<const ApkAssets> lib_one_assets_;
+  std::unique_ptr<const ApkAssets> lib_two_assets_;
 };
 
 TEST_F(ThemeTest, EmptyTheme) {
diff --git a/libs/androidfw/tests/data/basic/R.h b/libs/androidfw/tests/data/basic/R.h
index 9352b5c..8e9741e 100644
--- a/libs/androidfw/tests/data/basic/R.h
+++ b/libs/androidfw/tests/data/basic/R.h
@@ -53,6 +53,8 @@
     enum : uint32_t {
       number1 = 0x7f040000,
       number2 = 0x7f040001,
+      ref1 = 0x7f040002,
+      ref2 = 0x7f040003,
 
       // From feature
       number3 = 0x7f090000,
diff --git a/libs/androidfw/tests/data/basic/basic.apk b/libs/androidfw/tests/data/basic/basic.apk
index 2c9771b..7ee6734 100644
--- a/libs/androidfw/tests/data/basic/basic.apk
+++ b/libs/androidfw/tests/data/basic/basic.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_de_fr.apk b/libs/androidfw/tests/data/basic/basic_de_fr.apk
index 0481444..e45258c 100644
--- a/libs/androidfw/tests/data/basic/basic_de_fr.apk
+++ b/libs/androidfw/tests/data/basic/basic_de_fr.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk
index a8d06e7..4ae1a7c 100644
--- a/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk
+++ b/libs/androidfw/tests/data/basic/basic_hdpi-v4.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk
index d1dfb14..a240d4c 100644
--- a/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk
+++ b/libs/androidfw/tests/data/basic/basic_xhdpi-v4.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk b/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk
index dca6f2f..fd3d9b2 100644
--- a/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk
+++ b/libs/androidfw/tests/data/basic/basic_xxhdpi-v4.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/basic/res/values/values.xml b/libs/androidfw/tests/data/basic/res/values/values.xml
index 11f6b8a..638c983 100644
--- a/libs/androidfw/tests/data/basic/res/values/values.xml
+++ b/libs/androidfw/tests/data/basic/res/values/values.xml
@@ -37,6 +37,12 @@
     <public type="integer" name="number2" id="0x7f040001" />
     <integer name="number2">@array/integerArray1</integer>
 
+    <public type="integer" name="ref1" id="0x7f040002" />
+    <integer name="ref1">@integer/ref2</integer>
+
+    <public type="integer" name="ref2" id="0x7f040003" />
+    <integer name="ref2">12000</integer>
+
     <public type="style" name="Theme1" id="0x7f050000" />
     <style name="Theme1">
         <item name="com.android.basic:attr1">100</item>
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index a799fdf..692199d 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -192,7 +192,7 @@
 ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
     hwui_cflags += -DANDROID_ENABLE_RENDERSCRIPT
     hwui_c_includes += \
-        $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,) \
+        $(call intermediates-dir-for,STATIC_LIBRARIES,TARGET,) \
         frameworks/rs/cpp \
         frameworks/rs
 endif
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index ee77643..415e850 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -169,13 +169,15 @@
 
 void DeferredLayerUpdater::detachSurfaceTexture() {
     if (mSurfaceTexture.get()) {
-        if (mLayer->getApi() == Layer::Api::OpenGL) {
+        if (mLayerApi == Layer::Api::OpenGL) {
             status_t err = mSurfaceTexture->detachFromContext();
             if (err != 0) {
                 // TODO: Elevate to fatal exception
                 ALOGE("Failed to detach SurfaceTexture from context %d", err);
             }
-            static_cast<GlLayer*>(mLayer)->clearTexture();
+            if (mLayer) {
+                static_cast<GlLayer*>(mLayer)->clearTexture();
+            }
         }
         mSurfaceTexture = nullptr;
     }
diff --git a/libs/hwui/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk
index 37126a6..f69da48 100644
--- a/libs/hwui/hwui_static_deps.mk
+++ b/libs/hwui/hwui_static_deps.mk
@@ -29,5 +29,5 @@
     libandroidfw
 
 ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
-    LOCAL_SHARED_LIBRARIES += libRS libRScpp
+    LOCAL_SHARED_LIBRARIES += libRScpp
 endif
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index d05e7f6..2ead5c5 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -24,6 +24,7 @@
 #include <SkGaussianEdgeShader.h>
 #include <SkPathOps.h>
 #include <SkRRectsGaussianEdgeMaskFilter.h>
+#include <SkShadowUtils.h>
 
 namespace android {
 namespace uirenderer {
@@ -115,498 +116,6 @@
     }
 }
 
-/**
- * @param canvas             the destination for the shadow draws
- * @param shape              the shape casting the shadow
- * @param casterZValue       the Z value of the caster RRect
- * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
- * @param draw               the function used to draw 'shape'
- */
-template <typename Shape, typename F>
-static void DrawAmbientShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue,
-        float ambientAlpha, F&& draw) {
-    if (ambientAlpha <= 0) {
-        return;
-    }
-
-    const float kHeightFactor = 1.f/128.f;
-    const float kGeomFactor = 64;
-
-    float umbraAlpha = 1 / (1 + SkMaxScalar(casterZValue*kHeightFactor, 0));
-    float radius = casterZValue*kHeightFactor*kGeomFactor;
-
-    sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
-            SkBlurMask::ConvertRadiusToSigma(radius), SkBlurMaskFilter::kNone_BlurFlag);
-    SkPaint paint;
-    paint.setAntiAlias(true);
-    paint.setMaskFilter(std::move(mf));
-    paint.setARGB(ambientAlpha*umbraAlpha, 0, 0, 0);
-
-    draw(shape, paint);
-}
-
-/**
- * @param canvas             the destination for the shadow draws
- * @param shape              the shape casting the shadow
- * @param casterZValue       the Z value of the caster RRect
- * @param lightPos           the position of the light casting the shadow
- * @param lightWidth
- * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
- * @param draw               the function used to draw 'shape'
- */
-template <typename Shape, typename F>
-static void DrawSpotShadowGeneral(SkCanvas* canvas, const Shape& shape, float casterZValue,
-        float spotAlpha, F&& draw) {
-    if (spotAlpha <= 0) {
-        return;
-    }
-
-    const Vector3 lightPos = SkiaPipeline::getLightCenter();
-    float zRatio = casterZValue / (lightPos.z - casterZValue);
-    // clamp
-    if (zRatio < 0.0f) {
-        zRatio = 0.0f;
-    } else if (zRatio > 0.95f) {
-        zRatio = 0.95f;
-    }
-
-    float blurRadius = SkiaPipeline::getLightRadius()*zRatio;
-
-    SkAutoCanvasRestore acr(canvas, true);
-
-    sk_sp<SkMaskFilter> mf = SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
-            SkBlurMask::ConvertRadiusToSigma(blurRadius), SkBlurMaskFilter::kNone_BlurFlag);
-
-    SkPaint paint;
-    paint.setAntiAlias(true);
-    paint.setMaskFilter(std::move(mf));
-    paint.setARGB(spotAlpha, 0, 0, 0);
-
-    // approximate projection by translating and scaling projected offset of bounds center
-    // TODO: compute the actual 2D projection
-    SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
-    canvas->scale(scale, scale);
-    SkPoint center = SkPoint::Make(shape.getBounds().centerX(), shape.getBounds().centerY());
-    SkMatrix ctmInverse;
-    if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
-        ALOGW("Matrix is degenerate. Will not render shadow!");
-        return;
-    }
-    SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
-    ctmInverse.mapPoints(&lightPos2D, 1);
-    canvas->translate(zRatio*(center.fX - lightPos2D.fX), zRatio*(center.fY - lightPos2D.fY));
-
-    draw(shape, paint);
-}
-
-#define MAX_BLUR_RADIUS 16383.75f
-#define MAX_PAD         64
-
-/**
- * @param casterRect         the rectangle bounds of the RRect casting the shadow
- * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
- * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
- * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
- * @param casterAlpha        the alpha value of the RRect casting the shadow (0.0-1.0 range)
- * @param casterZValue       the Z value of the caster RRect
- * @param scaleFactor        the scale needed to map from src-space to device-space
- * @param canvas             the destination for the shadow draws
- */
-static void DrawRRectShadows(const SkRect& casterRect, SkScalar casterCornerRadius,
-        SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue,
-        SkScalar scaleFactor, SkCanvas* canvas) {
-    SkASSERT(casterCornerRadius >= 0.0f);
-
-    // For all of these, we need to ensure we have a rrect with radius >= 0.5f in device space
-    const SkScalar minRadius = 0.5f / scaleFactor;
-
-    const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()),
-            SkScalarHalf(casterRect.height()));
-    const bool isRect = casterCornerRadius <= minRadius;
-
-    sk_sp<SkShader> edgeShader(SkGaussianEdgeShader::Make());
-
-    if (ambientAlpha > 0.0f) {
-        static const float kHeightFactor = 1.0f / 128.0f;
-        static const float kGeomFactor = 64.0f;
-
-        SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor;
-        // the device-space radius sent to the blur shader must fit in 14.2 fixed point
-        if (srcSpaceAmbientRadius*scaleFactor > MAX_BLUR_RADIUS) {
-            srcSpaceAmbientRadius = MAX_BLUR_RADIUS/scaleFactor;
-        }
-        const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f));
-        const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha;
-
-        // For the ambient rrect, we inset the offset rect by half the srcSpaceAmbientRadius
-        // to get our stroke shape.
-        SkScalar ambientPathOutset = std::max(ambientOffset - srcSpaceAmbientRadius * 0.5f,
-                minRadius);
-
-        SkRRect ambientRRect;
-        const SkRect temp = casterRect.makeOutset(ambientPathOutset, ambientPathOutset);
-        if (isOval) {
-            ambientRRect = SkRRect::MakeOval(temp);
-        } else if (isRect) {
-            ambientRRect = SkRRect::MakeRectXY(temp, ambientPathOutset, ambientPathOutset);
-        } else {
-            ambientRRect = SkRRect::MakeRectXY(temp, casterCornerRadius + ambientPathOutset,
-                    casterCornerRadius + ambientPathOutset);
-        }
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-        paint.setStyle(SkPaint::kStroke_Style);
-        // we outset the stroke a little to cover up AA on the interior edge
-        float pad = 0.5f;
-        paint.setStrokeWidth(srcSpaceAmbientRadius + 2.0f * pad);
-        // handle scale of radius and pad due to CTM
-        pad *= scaleFactor;
-        const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
-        SkASSERT(devSpaceAmbientRadius <= MAX_BLUR_RADIUS);
-        SkASSERT(pad < MAX_PAD);
-        // convert devSpaceAmbientRadius to 14.2 fixed point and place in the R & G components
-        // convert pad to 6.2 fixed point and place in the B component
-        uint16_t iDevSpaceAmbientRadius = (uint16_t)(4.0f * devSpaceAmbientRadius);
-        paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, iDevSpaceAmbientRadius >> 8,
-                iDevSpaceAmbientRadius & 0xff, (unsigned char)(4.0f * pad)));
-
-        paint.setShader(edgeShader);
-        canvas->drawRRect(ambientRRect, paint);
-    }
-
-    if (spotAlpha > 0.0f) {
-        const Vector3 lightPos = SkiaPipeline::getLightCenter();
-        float zRatio = casterZValue / (lightPos.z - casterZValue);
-        // clamp
-        if (zRatio < 0.0f) {
-            zRatio = 0.0f;
-        } else if (zRatio > 0.95f) {
-            zRatio = 0.95f;
-        }
-
-        const SkScalar lightWidth = SkiaPipeline::getLightRadius();
-        SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio;
-        // the device-space radius sent to the blur shader must fit in 14.2 fixed point
-        if (srcSpaceSpotRadius*scaleFactor > MAX_BLUR_RADIUS) {
-            srcSpaceSpotRadius = MAX_BLUR_RADIUS/scaleFactor;
-        }
-
-        SkRRect spotRRect;
-        if (isOval) {
-            spotRRect = SkRRect::MakeOval(casterRect);
-        } else if (isRect) {
-            spotRRect = SkRRect::MakeRectXY(casterRect, minRadius, minRadius);
-        } else {
-            spotRRect = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius);
-        }
-
-        SkRRect spotShadowRRect;
-        // Compute the scale and translation for the spot shadow.
-        const SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
-        spotRRect.transform(SkMatrix::MakeScale(scale, scale), &spotShadowRRect);
-
-        SkPoint center = SkPoint::Make(spotShadowRRect.rect().centerX(),
-                                       spotShadowRRect.rect().centerY());
-        SkMatrix ctmInverse;
-        if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
-            ALOGW("Matrix is degenerate. Will not render spot shadow!");
-            return;
-        }
-        SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
-        ctmInverse.mapPoints(&lightPos2D, 1);
-        const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX),
-                zRatio*(center.fY - lightPos2D.fY));
-
-        SkAutoCanvasRestore acr(canvas, true);
-
-        // We want to extend the stroked area in so that it meets up with the caster
-        // geometry. The stroked geometry will, by definition already be inset half the
-        // stroke width but we also have to account for the scaling.
-        // We also add 1/2 to cover up AA on the interior edge.
-        SkScalar scaleOffset = (scale - 1.0f) * SkTMax(SkTMax(SkTAbs(casterRect.fLeft),
-                SkTAbs(casterRect.fRight)), SkTMax(SkTAbs(casterRect.fTop),
-                SkTAbs(casterRect.fBottom)));
-        SkScalar insetAmount = spotOffset.length() - (0.5f * srcSpaceSpotRadius) +
-                scaleOffset + 0.5f;
-
-        // Compute area
-        SkScalar strokeWidth = srcSpaceSpotRadius + insetAmount;
-        SkScalar strokedArea = 2.0f*strokeWidth * (spotShadowRRect.width()
-                + spotShadowRRect.height());
-        SkScalar filledArea = (spotShadowRRect.height() + srcSpaceSpotRadius)
-                * (spotShadowRRect.width() + srcSpaceSpotRadius);
-
-        SkPaint paint;
-        paint.setAntiAlias(true);
-
-        // If the area of the stroked geometry is larger than the fill geometry, just fill it.
-        if (strokedArea > filledArea || casterAlpha < 1.0f || insetAmount < 0.0f) {
-            paint.setStyle(SkPaint::kStrokeAndFill_Style);
-            paint.setStrokeWidth(srcSpaceSpotRadius);
-        } else {
-            // Since we can't have unequal strokes, inset the shadow rect so the inner
-            // and outer edges of the stroke will land where we want.
-            SkRect insetRect = spotShadowRRect.rect().makeInset(insetAmount/2.0f, insetAmount/2.0f);
-            SkScalar insetRad = SkTMax(spotShadowRRect.getSimpleRadii().fX - insetAmount/2.0f,
-                    minRadius);
-            spotShadowRRect = SkRRect::MakeRectXY(insetRect, insetRad, insetRad);
-            paint.setStyle(SkPaint::kStroke_Style);
-            paint.setStrokeWidth(strokeWidth);
-        }
-
-        // handle scale of radius and pad due to CTM
-        const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor;
-        SkASSERT(devSpaceSpotRadius <= MAX_BLUR_RADIUS);
-
-        const SkScalar devSpaceSpotPad = 0;
-        SkASSERT(devSpaceSpotPad < MAX_PAD);
-
-        // convert devSpaceSpotRadius to 14.2 fixed point and place in the R & G
-        // components convert devSpaceSpotPad to 6.2 fixed point and place in the B component
-        uint16_t iDevSpaceSpotRadius = (uint16_t)(4.0f * devSpaceSpotRadius);
-        paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, iDevSpaceSpotRadius >> 8,
-                iDevSpaceSpotRadius & 0xff, (unsigned char)(4.0f * devSpaceSpotPad)));
-        paint.setShader(edgeShader);
-
-        canvas->translate(spotOffset.fX, spotOffset.fY);
-        canvas->drawRRect(spotShadowRRect, paint);
-    }
-}
-
-/**
- * @param casterRect         the rectangle bounds of the RRect casting the shadow
- * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
- * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
- * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
- * @param casterZValue       the Z value of the caster RRect
- * @param scaleFactor        the scale needed to map from src-space to device-space
- * @param clipRR             the oval or rect with which the drawn roundrect must be intersected
- * @param canvas             the destination for the shadow draws
- */
-static void DrawRRectShadowsWithClip(const SkRect& casterRect, SkScalar casterCornerRadius,
-        SkScalar ambientAlpha, SkScalar spotAlpha, SkScalar casterZValue, SkScalar scaleFactor,
-        const SkRRect& clipRR, SkCanvas* canvas) {
-    SkASSERT(casterCornerRadius >= 0.0f);
-
-    const bool isOval = casterCornerRadius >= std::max(SkScalarHalf(casterRect.width()),
-            SkScalarHalf(casterRect.height()));
-
-    if (ambientAlpha > 0.0f) {
-        static const float kHeightFactor = 1.0f / 128.0f;
-        static const float kGeomFactor = 64.0f;
-
-        const SkScalar srcSpaceAmbientRadius = casterZValue * kHeightFactor * kGeomFactor;
-        const SkScalar devSpaceAmbientRadius = srcSpaceAmbientRadius * scaleFactor;
-
-        const float umbraAlpha = 1.0f / (1.0f + std::max(casterZValue * kHeightFactor, 0.0f));
-        const SkScalar ambientOffset = srcSpaceAmbientRadius * umbraAlpha;
-
-        const SkRect srcSpaceAmbientRect = casterRect.makeOutset(ambientOffset, ambientOffset);
-        SkRect devSpaceAmbientRect;
-        canvas->getTotalMatrix().mapRect(&devSpaceAmbientRect, srcSpaceAmbientRect);
-
-        SkRRect devSpaceAmbientRRect;
-        if (isOval) {
-            devSpaceAmbientRRect = SkRRect::MakeOval(devSpaceAmbientRect);
-        } else {
-            const SkScalar devSpaceCornerRadius = scaleFactor * (casterCornerRadius + ambientOffset);
-            devSpaceAmbientRRect = SkRRect::MakeRectXY(devSpaceAmbientRect, devSpaceCornerRadius,
-                    devSpaceCornerRadius);
-        }
-
-        const SkRect srcSpaceAmbClipRect = clipRR.rect().makeOutset(ambientOffset, ambientOffset);
-        SkRect devSpaceAmbClipRect;
-        canvas->getTotalMatrix().mapRect(&devSpaceAmbClipRect, srcSpaceAmbClipRect);
-        SkRRect devSpaceAmbientClipRR;
-        if (clipRR.isOval()) {
-            devSpaceAmbientClipRR = SkRRect::MakeOval(devSpaceAmbClipRect);
-        } else {
-            SkASSERT(clipRR.isRect());
-            devSpaceAmbientClipRR = SkRRect::MakeRect(devSpaceAmbClipRect);
-        }
-
-        SkRect cover = srcSpaceAmbClipRect;
-        if (!cover.intersect(srcSpaceAmbientRect)) {
-            return;
-        }
-
-        SkPaint paint;
-        paint.setColor(SkColorSetARGB((unsigned char) ambientAlpha, 0, 0, 0));
-        paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceAmbientRRect,
-            devSpaceAmbientClipRR, devSpaceAmbientRadius));
-        canvas->drawRect(cover, paint);
-    }
-
-    if (spotAlpha > 0.0f) {
-        const Vector3 lightPos = SkiaPipeline::getLightCenter();
-        float zRatio = casterZValue / (lightPos.z - casterZValue);
-        // clamp
-        if (zRatio < 0.0f) {
-            zRatio = 0.0f;
-        } else if (zRatio > 0.95f) {
-            zRatio = 0.95f;
-        }
-
-        const SkScalar lightWidth = SkiaPipeline::getLightRadius();
-        const SkScalar srcSpaceSpotRadius = 2.0f * lightWidth * zRatio;
-        const SkScalar devSpaceSpotRadius = srcSpaceSpotRadius * scaleFactor;
-
-        // Compute the scale and translation for the spot shadow.
-        const SkScalar scale = lightPos.z / (lightPos.z - casterZValue);
-        const SkMatrix spotMatrix = SkMatrix::MakeScale(scale, scale);
-
-        SkRect srcSpaceScaledRect = casterRect;
-        spotMatrix.mapRect(&srcSpaceScaledRect);
-        srcSpaceScaledRect.outset(SkScalarHalf(srcSpaceSpotRadius),
-                SkScalarHalf(srcSpaceSpotRadius));
-
-        SkRRect srcSpaceSpotRRect;
-        if (isOval) {
-            srcSpaceSpotRRect = SkRRect::MakeOval(srcSpaceScaledRect);
-        } else {
-            srcSpaceSpotRRect = SkRRect::MakeRectXY(srcSpaceScaledRect, casterCornerRadius * scale,
-                    casterCornerRadius * scale);
-        }
-
-        SkPoint center = SkPoint::Make(srcSpaceSpotRRect.rect().centerX(),
-                srcSpaceSpotRRect.rect().centerY());
-        SkMatrix ctmInverse;
-        if (!canvas->getTotalMatrix().invert(&ctmInverse)) {
-            ALOGW("Matrix is degenerate. Will not render spot shadow!");
-            return;
-        }
-        SkPoint lightPos2D = SkPoint::Make(lightPos.x, lightPos.y);
-        ctmInverse.mapPoints(&lightPos2D, 1);
-        const SkPoint spotOffset = SkPoint::Make(zRatio*(center.fX - lightPos2D.fX),
-                zRatio*(center.fY - lightPos2D.fY));
-
-        SkAutoCanvasRestore acr(canvas, true);
-        canvas->translate(spotOffset.fX, spotOffset.fY);
-
-        SkRect devSpaceScaledRect;
-        canvas->getTotalMatrix().mapRect(&devSpaceScaledRect, srcSpaceScaledRect);
-
-        SkRRect devSpaceSpotRRect;
-        if (isOval) {
-            devSpaceSpotRRect = SkRRect::MakeOval(devSpaceScaledRect);
-        } else {
-            const SkScalar devSpaceScaledCornerRadius = casterCornerRadius * scale * scaleFactor;
-            devSpaceSpotRRect = SkRRect::MakeRectXY(devSpaceScaledRect, devSpaceScaledCornerRadius,
-                    devSpaceScaledCornerRadius);
-        }
-
-        SkPaint paint;
-        paint.setColor(SkColorSetARGB((unsigned char) spotAlpha, 0, 0, 0));
-
-        SkRect srcSpaceScaledClipRect = clipRR.rect();
-        spotMatrix.mapRect(&srcSpaceScaledClipRect);
-        srcSpaceScaledClipRect.outset(SkScalarHalf(srcSpaceSpotRadius),
-                SkScalarHalf(srcSpaceSpotRadius));
-
-        SkRect devSpaceScaledClipRect;
-        canvas->getTotalMatrix().mapRect(&devSpaceScaledClipRect, srcSpaceScaledClipRect);
-        SkRRect devSpaceSpotClipRR;
-        if (clipRR.isOval()) {
-            devSpaceSpotClipRR = SkRRect::MakeOval(devSpaceScaledClipRect);
-        } else {
-            SkASSERT(clipRR.isRect());
-            devSpaceSpotClipRR = SkRRect::MakeRect(devSpaceScaledClipRect);
-        }
-
-        paint.setMaskFilter(SkRRectsGaussianEdgeMaskFilter::Make(devSpaceSpotRRect,
-            devSpaceSpotClipRR, devSpaceSpotRadius));
-
-        SkRect cover = srcSpaceScaledClipRect;
-        if (!cover.intersect(srcSpaceSpotRRect.rect())) {
-            return;
-        }
-
-        canvas->drawRect(cover, paint);
-    }
-}
-
-/**
- * @param casterRect         the rectangle bounds of the RRect casting the shadow
- * @param casterCornerRadius the x&y radius for all the corners of the RRect casting the shadow
- * @param casterClipRect     a rectangular clip that must be intersected with the
- *                           shadow-casting RRect prior to casting the shadow
- * @param revealClip         a circular clip that must be interested with the castClipRect
- *                           and the shadow-casting rect prior to casting the shadow
- * @param ambientAlpha       the maximum alpha value to use when drawing the ambient shadow
- * @param spotAlpha          the maximum alpha value to use when drawing the spot shadow
- * @param casterAlpha        the alpha value of the RRect casting the shadow (0.0-1.0 range)
- * @param casterZValue       the Z value of the caster RRect
- * @param canvas             the destination for the shadow draws
- *
- * We have special cases for 4 round rect shadow draws:
- *    1) a RRect clipped by a reveal animation
- *    2) a RRect clipped by a rectangle
- *    3) an unclipped RRect with non-uniform scale
- *    4) an unclipped RRect with uniform scale
- * 1,2 and 4 require that the scale is uniform.
- * 1 and 2 require that rects stay rects.
- */
-static bool DrawShadowsAsRRects(const SkRect& casterRect, SkScalar casterCornerRadius,
-        const SkRect& casterClipRect, const RevealClip& revealClip, SkScalar ambientAlpha,
-        SkScalar spotAlpha, SkScalar casterAlpha, SkScalar casterZValue, SkCanvas* canvas) {
-    SkScalar scaleFactors[2];
-    if (!canvas->getTotalMatrix().getMinMaxScales(scaleFactors)) {
-        ALOGW("Matrix is degenerate. Will not render shadow!");
-        return false;
-    }
-
-    // The casterClipRect will be empty when bounds clipping is disabled
-    bool casterIsClippedByRect = !casterClipRect.isEmpty();
-    bool uniformScale = scaleFactors[0] == scaleFactors[1];
-
-    if (revealClip.willClip()) {
-        if (casterIsClippedByRect || !uniformScale || !canvas->getTotalMatrix().rectStaysRect()) {
-            return false;  // Fall back to the slow path since PathOps are required
-        }
-
-        const float revealRadius = revealClip.getRadius();
-        SkRect revealClipRect = SkRect::MakeLTRB(revealClip.getX()-revealRadius,
-                revealClip.getY()-revealRadius, revealClip.getX()+revealRadius,
-                revealClip.getY()+revealRadius);
-        SkRRect revealClipRR = SkRRect::MakeOval(revealClipRect);
-
-        DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha,
-                casterZValue, scaleFactors[0], revealClipRR, canvas);
-        return true;
-    }
-
-    if (casterIsClippedByRect) {
-        if (!uniformScale || !canvas->getTotalMatrix().rectStaysRect()) {
-            return false;  // Fall back to the slow path since PathOps are required
-        }
-
-        SkRRect casterClipRR = SkRRect::MakeRect(casterClipRect);
-
-        DrawRRectShadowsWithClip(casterRect, casterCornerRadius, ambientAlpha, spotAlpha,
-                casterZValue, scaleFactors[0], casterClipRR, canvas);
-        return true;
-    }
-
-    // The fast path needs uniform scale
-    if (!uniformScale) {
-        SkRRect casterRR = SkRRect::MakeRectXY(casterRect, casterCornerRadius, casterCornerRadius);
-        DrawAmbientShadowGeneral(canvas, casterRR, casterZValue, ambientAlpha,
-                [&](const SkRRect& rrect, const SkPaint& paint) {
-                    canvas->drawRRect(rrect, paint);
-                });
-        DrawSpotShadowGeneral(canvas, casterRR, casterZValue, spotAlpha,
-                [&](const SkRRect& rrect, const SkPaint& paint) {
-                canvas->drawRRect(rrect, paint);
-                });
-        return true;
-    }
-
-    DrawRRectShadows(casterRect, casterCornerRadius, ambientAlpha, spotAlpha, casterAlpha,
-            casterZValue, scaleFactors[0], canvas);
-    return true;
-}
-
 // copied from FrameBuilder::deferShadow
 void EndReorderBarrierDrawable::drawShadow(SkCanvas* canvas, RenderNodeDrawable* caster) {
     const RenderProperties& casterProperties = caster->getNodeProperties();
@@ -626,8 +135,8 @@
         return;
     }
 
-    float ambientAlpha = SkiaPipeline::getAmbientShadowAlpha()*casterAlpha;
-    float spotAlpha = SkiaPipeline::getSpotShadowAlpha()*casterAlpha;
+    float ambientAlpha = (SkiaPipeline::getAmbientShadowAlpha()/255.f)*casterAlpha;
+    float spotAlpha = (SkiaPipeline::getSpotShadowAlpha()/255.f)*casterAlpha;
     const float casterZValue = casterProperties.getZ();
 
     const RevealClip& revealClip = casterProperties.getRevealClip();
@@ -659,19 +168,7 @@
     hwuiMatrix.copyTo(shadowMatrix);
     canvas->concat(shadowMatrix);
 
-    const Outline& casterOutline = casterProperties.getOutline();
-    Rect possibleRect;
-    float radius;
-    if (casterOutline.getAsRoundRect(&possibleRect, &radius)) {
-        if (DrawShadowsAsRRects(possibleRect.toSkRect(), radius, casterClipRect, revealClip,
-                ambientAlpha, spotAlpha, casterAlpha, casterZValue, canvas)) {
-            return;
-        }
-    }
-
-    // Hard cases and calls to general shadow code
     const SkPath* casterOutlinePath = casterProperties.getOutline().getPath();
-
     // holds temporary SkPath to store the result of intersections
     SkPath tmpPath;
     const SkPath* casterPath = casterOutlinePath;
@@ -691,16 +188,11 @@
         Op(*casterPath, clipBoundsPath, kIntersect_SkPathOp, &tmpPath);
         casterPath = &tmpPath;
     }
-
-    DrawAmbientShadowGeneral(canvas, *casterPath, casterZValue, ambientAlpha,
-            [&](const SkPath& path, const SkPaint& paint) {
-                canvas->drawPath(path, paint);
-            });
-
-    DrawSpotShadowGeneral(canvas, *casterPath, casterZValue, spotAlpha,
-            [&](const SkPath& path, const SkPaint& paint) {
-                canvas->drawPath(path, paint);
-            });
+    const Vector3 lightPos = SkiaPipeline::getLightCenter();
+    SkPoint3 skiaLightPos = SkPoint3::Make(lightPos.x, lightPos.y, lightPos.z);
+    SkShadowUtils::DrawShadow(canvas, *casterPath, casterZValue, skiaLightPos,
+            SkiaPipeline::getLightRadius(), ambientAlpha, spotAlpha, SK_ColorBLACK,
+            casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 0d567f7..7dfc2ee 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -80,6 +80,7 @@
     delete mStencil;
     mStencil = nullptr;
 
+    destroyLayersInUpdater();
     GpuMemoryTracker::onGpuContextDestroyed();
 }
 
diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h
index a44fa9d..f78bf7a 100644
--- a/libs/hwui/renderstate/RenderState.h
+++ b/libs/hwui/renderstate/RenderState.h
@@ -99,8 +99,6 @@
         mActiveLayerUpdaters.erase(layerUpdater);
     }
 
-    void destroyLayersInUpdater();
-
     // TODO: This system is a little clunky feeling, this could use some
     // more thinking...
     void postDecStrong(VirtualLightRefBase* object);
@@ -121,6 +119,7 @@
 private:
     void interruptForFunctorInvoke();
     void resumeFromFunctorInvoke();
+    void destroyLayersInUpdater();
 
     explicit RenderState(renderthread::RenderThread& thread);
     ~RenderState();
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 5a7de1d..a53e5e0 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -570,7 +570,6 @@
         }
         mRenderPipeline->onDestroyHardwareResources();
     }
-    mRenderThread.renderState().destroyLayersInUpdater();
 }
 
 void CanvasContext::trimMemory(RenderThread& thread, int level) {
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 454ce4d..c2c2f22 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -603,6 +603,11 @@
 }
 
 void VulkanManager::swapBuffers(VulkanSurface* surface) {
+    if (CC_UNLIKELY(Properties::waitForGpuCompletion)) {
+        ATRACE_NAME("Finishing GPU work");
+        mDeviceWaitIdle(mBackendContext->fDevice);
+    }
+
     VulkanSurface::BackbufferInfo* backbuffer = surface->mBackbuffers +
             surface->mCurrentBackbufferIndex;
     GrVkImageInfo* imageInfo;
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 391a905..ce58a9c 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -913,13 +913,13 @@
         }
     }
     /**
-     * @hide
-     * CANDIDATE FOR PUBLIC (or at least SYSTEM) API
      * Returns the stream type matching the given attributes for volume control.
      * Use this method to derive the stream type needed to configure the volume
-     * control slider in an {@link Activity} with {@link Activity#setVolumeControlStream(int)}.
+     * control slider in an {@link android.app.Activity} with
+     * {@link android.app.Activity#setVolumeControlStream(int)}.
      * <BR>Do not use this method to set the stream type on an audio player object
-     * (e.g. {@link AudioTrack}, {@link MediaPlayer}), use <code>AudioAttributes</code> instead.
+     * (e.g. {@link AudioTrack}, {@link MediaPlayer}) as this is deprecated,
+     * use <code>AudioAttributes</code> instead.
      * @param aa non-null AudioAttributes.
      * @return a valid stream type for <code>Activity</code> or stream volume control that matches
      *     the attributes, or {@link AudioManager#USE_DEFAULT_STREAM_TYPE} if there isn't a direct
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 5c9f270..cd38b50 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -27,6 +27,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityThread;
 import android.content.Context;
 import android.os.Handler;
@@ -538,6 +539,15 @@
             throw new IllegalArgumentException("Illegal null AudioFormat");
         }
 
+        // Check if we should enable deep buffer mode
+        if (shouldEnablePowerSaving(mAttributes, format, bufferSizeInBytes, mode)) {
+            mAttributes = new AudioAttributes.Builder(mAttributes)
+                .replaceFlags((mAttributes.getAllFlags()
+                        | AudioAttributes.FLAG_DEEP_BUFFER)
+                        & ~AudioAttributes.FLAG_LOW_LATENCY)
+                .build();
+        }
+
         // remember which looper is associated with the AudioTrack instantiation
         Looper looper;
         if ((looper = Looper.myLooper()) == null) {
@@ -861,7 +871,10 @@
                     .build();
                 break;
             case PERFORMANCE_MODE_NONE:
-                break;
+                if (!shouldEnablePowerSaving(mAttributes, mFormat, mBufferSizeInBytes, mMode)) {
+                    break; // do not enable deep buffer mode.
+                }
+                // permitted to fall through to enable deep buffer
             case PERFORMANCE_MODE_POWER_SAVING:
                 mAttributes = new AudioAttributes.Builder(mAttributes)
                 .replaceFlags((mAttributes.getAllFlags()
@@ -912,6 +925,56 @@
             AudioFormat.CHANNEL_OUT_SIDE_LEFT |
             AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
 
+    // Returns a boolean whether the attributes, format, bufferSizeInBytes, mode allow
+    // power saving to be automatically enabled for an AudioTrack. Returns false if
+    // power saving is already enabled in the attributes parameter.
+    private static boolean shouldEnablePowerSaving(
+            @Nullable AudioAttributes attributes, @Nullable AudioFormat format,
+            int bufferSizeInBytes, int mode) {
+        // If no attributes, OK
+        // otherwise check attributes for USAGE_MEDIA and CONTENT_UNKNOWN, MUSIC, or MOVIE.
+        if (attributes != null &&
+                (attributes.getAllFlags() != 0  // cannot have any special flags
+                || attributes.getUsage() != AudioAttributes.USAGE_MEDIA
+                || (attributes.getContentType() != AudioAttributes.CONTENT_TYPE_UNKNOWN
+                    && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MUSIC
+                    && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MOVIE))) {
+            return false;
+        }
+
+        // Format must be fully specified and be linear pcm
+        if (format == null
+                || format.getSampleRate() == AudioFormat.SAMPLE_RATE_UNSPECIFIED
+                || !AudioFormat.isEncodingLinearPcm(format.getEncoding())
+                || !AudioFormat.isValidEncoding(format.getEncoding())
+                || format.getChannelCount() < 1) {
+            return false;
+        }
+
+        // Mode must be streaming
+        if (mode != MODE_STREAM) {
+            return false;
+        }
+
+        // A buffer size of 0 is always compatible with deep buffer (when called from the Builder)
+        // but for app compatibility we only use deep buffer power saving for large buffer sizes.
+        if (bufferSizeInBytes != 0) {
+            final long BUFFER_TARGET_MODE_STREAM_MS = 100;
+            final int MILLIS_PER_SECOND = 1000;
+            final long bufferTargetSize =
+                    BUFFER_TARGET_MODE_STREAM_MS
+                    * format.getChannelCount()
+                    * format.getBytesPerSample(format.getEncoding())
+                    * format.getSampleRate()
+                    / MILLIS_PER_SECOND;
+            if (bufferSizeInBytes < bufferTargetSize) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
     // Convenience method for the constructor's parameter checks.
     // This is where constructor IllegalArgumentException-s are thrown
     // postconditions:
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index a1f816b..80832f8 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -83,13 +83,17 @@
         private OutputFormat() {}
         /** MPEG4 media file format*/
         public static final int MUXER_OUTPUT_MPEG_4 = 0;
+        /** WEBM media file format*/
         public static final int MUXER_OUTPUT_WEBM   = 1;
+        /** 3GPP media file format*/
+        public static final int MUXER_OUTPUT_3GPP   = 2;
     };
 
     /** @hide */
     @IntDef({
         OutputFormat.MUXER_OUTPUT_MPEG_4,
         OutputFormat.MUXER_OUTPUT_WEBM,
+        OutputFormat.MUXER_OUTPUT_3GPP,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Format {}
@@ -166,8 +170,8 @@
     }
 
     private void setUpMediaMuxer(@NonNull FileDescriptor fd, @Format int format) throws IOException {
-        if (format != OutputFormat.MUXER_OUTPUT_MPEG_4 &&
-                format != OutputFormat.MUXER_OUTPUT_WEBM) {
+        if (format != OutputFormat.MUXER_OUTPUT_MPEG_4 && format != OutputFormat.MUXER_OUTPUT_WEBM
+                && format != OutputFormat.MUXER_OUTPUT_3GPP) {
             throw new IllegalArgumentException("format: " + format + " is invalid");
         }
         mNativeObject = nativeSetup(fd, format);
diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl
index 2f6e260..a146c62 100644
--- a/media/java/android/media/session/ISessionCallback.aidl
+++ b/media/java/android/media/session/ISessionCallback.aidl
@@ -16,6 +16,7 @@
 package android.media.session;
 
 import android.content.Intent;
+import android.media.MediaDescription;
 import android.media.Rating;
 import android.net.Uri;
 import android.os.Bundle;
@@ -49,6 +50,10 @@
     void onRepeatMode(int repeatMode);
     void onShuffleMode(boolean enabled);
     void onCustomAction(String action, in Bundle args);
+    void onAddQueueItem(in MediaDescription description);
+    void onAddQueueItemAt(in MediaDescription description, int index);
+    void onRemoveQueueItem(in MediaDescription description);
+    void onRemoveQueueItemAt(int index);
 
     // These callbacks are for volume handling
     void onAdjustVolume(int direction);
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index e92758c..7b5233a 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -18,6 +18,7 @@
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.content.pm.ParceledListSlice;
+import android.media.MediaDescription;
 import android.media.MediaMetadata;
 import android.media.Rating;
 import android.media.session.ISessionControllerCallback;
@@ -51,6 +52,11 @@
     MediaMetadata getMetadata();
     PlaybackState getPlaybackState();
     ParceledListSlice getQueue();
+    void addQueueItem(in MediaDescription description);
+    void addQueueItemAt(in MediaDescription description, int index);
+    void removeQueueItem(in MediaDescription description);
+    void removeQueueItemAt(int index);
+
     CharSequence getQueueTitle();
     Bundle getExtras();
     int getRatingType();
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 8cbf8e1..bab2af2 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -23,6 +23,7 @@
 import android.content.pm.ParceledListSlice;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
+import android.media.MediaDescription;
 import android.media.MediaMetadata;
 import android.media.Rating;
 import android.media.VolumeProvider;
@@ -38,6 +39,7 @@
 import android.view.KeyEvent;
 
 import java.lang.ref.WeakReference;
+import java.lang.UnsupportedOperationException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -111,8 +113,7 @@
     }
 
     /**
-     * Get a {@link TransportControls} instance to send transport actions to
-     * the associated session.
+     * Get a {@link TransportControls} instance to send transport actions to this session.
      *
      * @return A transport controls instance.
      */
@@ -151,7 +152,7 @@
         try {
             return mSessionBinder.getPlaybackState();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getPlaybackState.", e);
+            Log.wtf(TAG, "Error calling getPlaybackState", e);
             return null;
         }
     }
@@ -165,7 +166,7 @@
         try {
             return mSessionBinder.getMetadata();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getMetadata.", e);
+            Log.wtf(TAG, "Error calling getMetadata", e);
             return null;
         }
     }
@@ -183,12 +184,103 @@
                 return queue.getList();
             }
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getQueue.", e);
+            Log.wtf(TAG, "Error calling getQueue", e);
         }
         return null;
     }
 
     /**
+     * Add a queue item from the given {@code description} at the end of the play queue
+     * of this session. Not all sessions may support this.
+     *
+     * @param description The {@link MediaDescription} for creating the
+     *                    {@link MediaSession.QueueItem} to be inserted.
+     * @throws UnsupportedOperationException If this session doesn't support this.
+     * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
+     */
+    public void addQueueItem(MediaDescription description) {
+        try {
+            long flags = mSessionBinder.getFlags();
+            if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+                throw new UnsupportedOperationException(
+                        "This session doesn't support queue management operations");
+            }
+            mSessionBinder.addQueueItem(description);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling addQueueItem", e);
+        }
+    }
+
+    /**
+     * Add a queue item from the given {@code description} at the specified position
+     * in the play queue of this session. Shifts the queue item currently at that position
+     * (if any) and any subsequent queue items to the right (adds one to their indices).
+     * Not all sessions may support this.
+     *
+     * @param description The {@link MediaDescription} for creating the
+     *                    {@link MediaSession.QueueItem} to be inserted.
+     * @param index The index at which the created {@link MediaSession.QueueItem} is to be inserted.
+     * @throws UnsupportedOperationException If this session doesn't support this.
+     * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
+     */
+    public void addQueueItem(MediaDescription description, int index) {
+        try {
+            long flags = mSessionBinder.getFlags();
+            if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+                throw new UnsupportedOperationException(
+                        "This session doesn't support queue management operations");
+            }
+            mSessionBinder.addQueueItemAt(description, index);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling addQueueItemAt", e);
+        }
+    }
+
+    /**
+     * Remove the first occurrence of the specified {@link MediaSession.QueueItem}
+     * with the given {@link MediaDescription description} in the play queue of the associated
+     * session. Not all sessions may support this.
+     *
+     * @param description The {@link MediaDescription} for denoting the
+     *                    {@link MediaSession.QueueItem} to be removed.
+     * @throws UnsupportedOperationException If this session doesn't support this.
+     * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
+     */
+    public void removeQueueItem(MediaDescription description) {
+        try {
+            long flags = mSessionBinder.getFlags();
+            if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+                throw new UnsupportedOperationException(
+                        "This session doesn't support queue management operations");
+            }
+            mSessionBinder.removeQueueItem(description);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling removeQueueItem", e);
+        }
+    }
+
+    /**
+     * Remove an queue item at the specified position in the play queue
+     * of this session. Not all sessions may support this.
+     *
+     * @param index The index of the element to be removed.
+     * @throws UnsupportedOperationException If this session doesn't support this.
+     * @see MediaSession#FLAG_HANDLES_QUEUE_COMMANDS
+     */
+    public void removeQueueItemAt(int index) {
+        try {
+            long flags = mSessionBinder.getFlags();
+            if ((flags & MediaSession.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+                throw new UnsupportedOperationException(
+                        "This session doesn't support queue management operations");
+            }
+            mSessionBinder.removeQueueItemAt(index);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling removeQueueItemAt", e);
+        }
+    }
+
+    /**
      * Get the queue title for this session.
      */
     public @Nullable CharSequence getQueueTitle() {
@@ -230,7 +322,7 @@
         try {
             return mSessionBinder.getRatingType();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getRatingType.", e);
+            Log.wtf(TAG, "Error calling getRatingType", e);
             return Rating.RATING_NONE;
         }
     }
@@ -245,7 +337,7 @@
         try {
             return mSessionBinder.getRepeatMode();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getRepeatMode.", e);
+            Log.wtf(TAG, "Error calling getRepeatMode", e);
             return PlaybackState.REPEAT_MODE_NONE;
         }
     }
@@ -259,7 +351,7 @@
         try {
             return mSessionBinder.isShuffleModeEnabled();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling isShuffleModeEnabled.", e);
+            Log.wtf(TAG, "Error calling isShuffleModeEnabled", e);
             return false;
         }
     }
@@ -273,7 +365,7 @@
         try {
             return mSessionBinder.getFlags();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getFlags.", e);
+            Log.wtf(TAG, "Error calling getFlags", e);
         }
         return 0;
     }
@@ -290,7 +382,7 @@
                     result.maxVolume, result.currentVolume);
 
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getAudioInfo.", e);
+            Log.wtf(TAG, "Error calling getAudioInfo", e);
         }
         return null;
     }
@@ -305,7 +397,7 @@
         try {
             return mSessionBinder.getLaunchPendingIntent();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getPendingIntent.", e);
+            Log.wtf(TAG, "Error calling getPendingIntent", e);
         }
         return null;
     }
@@ -334,7 +426,7 @@
         try {
             mSessionBinder.setVolumeTo(value, flags, mContext.getPackageName());
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling setVolumeTo.", e);
+            Log.wtf(TAG, "Error calling setVolumeTo", e);
         }
     }
 
@@ -355,7 +447,7 @@
         try {
             mSessionBinder.adjustVolume(direction, flags, mContext.getPackageName());
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
+            Log.wtf(TAG, "Error calling adjustVolumeBy", e);
         }
     }
 
@@ -421,7 +513,7 @@
         try {
             mSessionBinder.sendCommand(command, args, cb);
         } catch (RemoteException e) {
-            Log.d(TAG, "Dead object in sendCommand.", e);
+            Log.d(TAG, "Dead object in sendCommand", e);
         }
     }
 
@@ -435,7 +527,7 @@
             try {
                 mPackageName = mSessionBinder.getPackageName();
             } catch (RemoteException e) {
-                Log.d(TAG, "Dead object in getPackageName.", e);
+                Log.d(TAG, "Dead object in getPackageName", e);
             }
         }
         return mPackageName;
@@ -452,7 +544,7 @@
             try {
                 mTag = mSessionBinder.getTag();
             } catch (RemoteException e) {
-                Log.d(TAG, "Dead object in getTag.", e);
+                Log.d(TAG, "Dead object in getTag", e);
             }
         }
         return mTag;
@@ -652,7 +744,7 @@
             try {
                 mSessionBinder.prepare();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling prepare.", e);
+                Log.wtf(TAG, "Error calling prepare", e);
             }
         }
 
@@ -671,12 +763,12 @@
         public void prepareFromMediaId(String mediaId, Bundle extras) {
             if (TextUtils.isEmpty(mediaId)) {
                 throw new IllegalArgumentException(
-                        "You must specify a non-empty String for prepareFromMediaId.");
+                        "You must specify a non-empty String for prepareFromMediaId");
             }
             try {
                 mSessionBinder.prepareFromMediaId(mediaId, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e);
+                Log.wtf(TAG, "Error calling prepare(" + mediaId + ")", e);
             }
         }
 
@@ -702,7 +794,7 @@
             try {
                 mSessionBinder.prepareFromSearch(query, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling prepare(" + query + ").", e);
+                Log.wtf(TAG, "Error calling prepare(" + query + ")", e);
             }
         }
 
@@ -721,12 +813,12 @@
         public void prepareFromUri(Uri uri, Bundle extras) {
             if (uri == null || Uri.EMPTY.equals(uri)) {
                 throw new IllegalArgumentException(
-                        "You must specify a non-empty Uri for prepareFromUri.");
+                        "You must specify a non-empty Uri for prepareFromUri");
             }
             try {
                 mSessionBinder.prepareFromUri(uri, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling prepare(" + uri + ").", e);
+                Log.wtf(TAG, "Error calling prepare(" + uri + ")", e);
             }
         }
 
@@ -737,7 +829,7 @@
             try {
                 mSessionBinder.play();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling play.", e);
+                Log.wtf(TAG, "Error calling play", e);
             }
         }
 
@@ -751,12 +843,12 @@
         public void playFromMediaId(String mediaId, Bundle extras) {
             if (TextUtils.isEmpty(mediaId)) {
                 throw new IllegalArgumentException(
-                        "You must specify a non-empty String for playFromMediaId.");
+                        "You must specify a non-empty String for playFromMediaId");
             }
             try {
                 mSessionBinder.playFromMediaId(mediaId, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling play(" + mediaId + ").", e);
+                Log.wtf(TAG, "Error calling play(" + mediaId + ")", e);
             }
         }
 
@@ -778,7 +870,7 @@
             try {
                 mSessionBinder.playFromSearch(query, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling play(" + query + ").", e);
+                Log.wtf(TAG, "Error calling play(" + query + ")", e);
             }
         }
 
@@ -792,12 +884,12 @@
         public void playFromUri(Uri uri, Bundle extras) {
             if (uri == null || Uri.EMPTY.equals(uri)) {
                 throw new IllegalArgumentException(
-                        "You must specify a non-empty Uri for playFromUri.");
+                        "You must specify a non-empty Uri for playFromUri");
             }
             try {
                 mSessionBinder.playFromUri(uri, extras);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling play(" + uri + ").", e);
+                Log.wtf(TAG, "Error calling play(" + uri + ")", e);
             }
         }
 
@@ -809,7 +901,7 @@
             try {
                 mSessionBinder.skipToQueueItem(id);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
+                Log.wtf(TAG, "Error calling skipToItem(" + id + ")", e);
             }
         }
 
@@ -821,7 +913,7 @@
             try {
                 mSessionBinder.pause();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling pause.", e);
+                Log.wtf(TAG, "Error calling pause", e);
             }
         }
 
@@ -833,7 +925,7 @@
             try {
                 mSessionBinder.stop();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling stop.", e);
+                Log.wtf(TAG, "Error calling stop", e);
             }
         }
 
@@ -846,7 +938,7 @@
             try {
                 mSessionBinder.seekTo(pos);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling seekTo.", e);
+                Log.wtf(TAG, "Error calling seekTo", e);
             }
         }
 
@@ -858,7 +950,7 @@
             try {
                 mSessionBinder.fastForward();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling fastForward.", e);
+                Log.wtf(TAG, "Error calling fastForward", e);
             }
         }
 
@@ -869,7 +961,7 @@
             try {
                 mSessionBinder.next();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling next.", e);
+                Log.wtf(TAG, "Error calling next", e);
             }
         }
 
@@ -881,7 +973,7 @@
             try {
                 mSessionBinder.rewind();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling rewind.", e);
+                Log.wtf(TAG, "Error calling rewind", e);
             }
         }
 
@@ -892,7 +984,7 @@
             try {
                 mSessionBinder.previous();
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling previous.", e);
+                Log.wtf(TAG, "Error calling previous", e);
             }
         }
 
@@ -907,7 +999,7 @@
             try {
                 mSessionBinder.rate(rating);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling rate.", e);
+                Log.wtf(TAG, "Error calling rate", e);
             }
         }
 
@@ -923,7 +1015,7 @@
             try {
                 mSessionBinder.repeatMode(repeatMode);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling setRepeatMode.", e);
+                Log.wtf(TAG, "Error calling setRepeatMode", e);
             }
         }
 
@@ -936,7 +1028,7 @@
             try {
                 mSessionBinder.shuffleMode(enabled);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling shuffleMode.", e);
+                Log.wtf(TAG, "Error calling shuffleMode", e);
             }
         }
 
@@ -950,7 +1042,7 @@
         public void sendCustomAction(@NonNull PlaybackState.CustomAction customAction,
                     @Nullable Bundle args) {
             if (customAction == null) {
-                throw new IllegalArgumentException("CustomAction cannot be null.");
+                throw new IllegalArgumentException("CustomAction cannot be null");
             }
             sendCustomAction(customAction.getAction(), args);
         }
@@ -966,12 +1058,12 @@
          */
         public void sendCustomAction(@NonNull String action, @Nullable Bundle args) {
             if (TextUtils.isEmpty(action)) {
-                throw new IllegalArgumentException("CustomAction cannot be null.");
+                throw new IllegalArgumentException("CustomAction cannot be null");
             }
             try {
                 mSessionBinder.sendCustomAction(action, args);
             } catch (RemoteException e) {
-                Log.d(TAG, "Dead object in sendCustomAction.", e);
+                Log.d(TAG, "Dead object in sendCustomAction", e);
             }
         }
     }
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 84dc93a..bee3f52 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -87,6 +87,12 @@
     public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1;
 
     /**
+     * Set this flag on the session to indicate that it handles queue
+     * management commands through its {@link Callback}.
+     */
+    public static final int FLAG_HANDLES_QUEUE_COMMANDS = 1 << 2;
+
+    /**
      * System only flag for a session that needs to have priority over all other
      * sessions. This flag ensures this session will receive media button events
      * regardless of the current ordering in the system.
@@ -100,6 +106,7 @@
     @IntDef(flag = true, value = {
             FLAG_HANDLES_MEDIA_BUTTONS,
             FLAG_HANDLES_TRANSPORT_CONTROLS,
+            FLAG_HANDLES_QUEUE_COMMANDS,
             FLAG_EXCLUSIVE_GLOBAL_PRIORITY })
     public @interface SessionFlags { }
 
@@ -645,6 +652,22 @@
         postToCallback(CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args);
     }
 
+    private void dispatchAddQueueItem(MediaDescription description) {
+        postToCallback(CallbackMessageHandler.MSG_ADD_QUEUE_ITEM, description);
+    }
+
+    private void dispatchAddQueueItem(MediaDescription description, int index) {
+        postToCallback(CallbackMessageHandler.MSG_ADD_QUEUE_ITEM_AT, description, index);
+    }
+
+    private void dispatchRemoveQueueItem(MediaDescription description) {
+        postToCallback(CallbackMessageHandler.MSG_REMOVE_QUEUE_ITEM, description);
+    }
+
+    private void dispatchRemoveQueueItemAt(int index) {
+        postToCallback(CallbackMessageHandler.MSG_REMOVE_QUEUE_ITEM_AT, index);
+    }
+
     private void dispatchMediaButton(Intent mediaButtonIntent) {
         postToCallback(CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent);
     }
@@ -666,10 +689,22 @@
         postToCallback(CallbackMessageHandler.MSG_COMMAND, cmd);
     }
 
+    private void postToCallback(int what, int arg1) {
+        postToCallback(what, null, arg1);
+    }
+
     private void postToCallback(int what, Object obj) {
         postToCallback(what, obj, null);
     }
 
+    private void postToCallback(int what, Object obj, int arg1) {
+        synchronized (mLock) {
+            if (mCallback != null) {
+                mCallback.post(what, obj, arg1);
+            }
+        }
+    }
+
     private void postToCallback(int what, Object obj, Bundle extras) {
         synchronized (mLock) {
             if (mCallback != null) {
@@ -1043,6 +1078,47 @@
          */
         public void onCustomAction(@NonNull String action, @Nullable Bundle extras) {
         }
+
+        /**
+         * Called when a {@link MediaController} wants to add a {@link QueueItem} with the given
+         * {@link MediaDescription description} at the end of the play queue.
+         *
+         * @param description The {@link MediaDescription} for creating the {@link QueueItem} to be
+         *                    inserted.
+         */
+        public void onAddQueueItem(MediaDescription description) {
+        }
+
+        /**
+         * Called when a {@link MediaController} wants to add a {@link QueueItem} with the given
+         * {@link MediaDescription description} at the specified position in the play queue.
+         *
+         * @param description The {@link MediaDescription} for creating the {@link QueueItem} to be
+         *                    inserted.
+         * @param index The index at which the created {@link QueueItem} is to be inserted.
+         */
+        public void onAddQueueItem(MediaDescription description, int index) {
+        }
+
+        /**
+         * Called when a {@link MediaController} wants to remove the first occurrence of the
+         * specified {@link QueueItem} with the given {@link MediaDescription description}
+         * in the play queue.
+         *
+         * @param description The {@link MediaDescription} for denoting the {@link QueueItem} to be
+         *                    removed.
+         */
+        public void onRemoveQueueItem(MediaDescription description) {
+        }
+
+        /**
+         * Called when a {@link MediaController} wants to remove a {@link QueueItem} at the
+         * specified position in the play queue.
+         *
+         * @param index The index of the element to be removed.
+         */
+        public void onRemoveQueueItemAt(int index) {
+        }
     }
 
     /**
@@ -1239,6 +1315,38 @@
         }
 
         @Override
+        public void onAddQueueItem(MediaDescription description) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchAddQueueItem(description);
+            }
+        }
+
+        @Override
+        public void onAddQueueItemAt(MediaDescription description, int index) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchAddQueueItem(description, index);
+            }
+        }
+
+        @Override
+        public void onRemoveQueueItem(MediaDescription description) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchRemoveQueueItem(description);
+            }
+        }
+
+        @Override
+        public void onRemoveQueueItemAt(int index) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchRemoveQueueItemAt(index);
+            }
+        }
+
+        @Override
         public void onAdjustVolume(int direction) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1376,6 +1484,10 @@
         private static final int MSG_CUSTOM_ACTION = 22;
         private static final int MSG_ADJUST_VOLUME = 23;
         private static final int MSG_SET_VOLUME = 24;
+        private static final int MSG_ADD_QUEUE_ITEM = 25;
+        private static final int MSG_ADD_QUEUE_ITEM_AT = 26;
+        private static final int MSG_REMOVE_QUEUE_ITEM = 27;
+        private static final int MSG_REMOVE_QUEUE_ITEM_AT = 28;
 
         private MediaSession.Callback mCallback;
 
@@ -1465,7 +1577,7 @@
                     mCallback.onSetRating((Rating) msg.obj);
                     break;
                 case MSG_REPEAT_MODE:
-                    mCallback.onSetRepeatMode((int) msg.obj);
+                    mCallback.onSetRepeatMode(msg.arg1);
                     break;
                 case MSG_SHUFFLE_MODE:
                     mCallback.onSetShuffleModeEnabled((boolean) msg.obj);
@@ -1473,12 +1585,24 @@
                 case MSG_CUSTOM_ACTION:
                     mCallback.onCustomAction((String) msg.obj, msg.getData());
                     break;
+                case MSG_ADD_QUEUE_ITEM:
+                    mCallback.onAddQueueItem((MediaDescription) msg.obj);
+                    break;
+                case MSG_ADD_QUEUE_ITEM_AT:
+                    mCallback.onAddQueueItem((MediaDescription) msg.obj, msg.arg1);
+                    break;
+                case MSG_REMOVE_QUEUE_ITEM:
+                    mCallback.onRemoveQueueItem((MediaDescription) msg.obj);
+                    break;
+                case MSG_REMOVE_QUEUE_ITEM_AT:
+                    mCallback.onRemoveQueueItemAt(msg.arg1);
+                    break;
                 case MSG_ADJUST_VOLUME:
                     synchronized (mLock) {
                         vp = mVolumeProvider;
                     }
                     if (vp != null) {
-                        vp.onAdjustVolume((int) msg.obj);
+                        vp.onAdjustVolume(msg.arg1);
                     }
                     break;
                 case MSG_SET_VOLUME:
@@ -1486,7 +1610,7 @@
                         vp = mVolumeProvider;
                     }
                     if (vp != null) {
-                        vp.onSetVolumeTo((int) msg.obj);
+                        vp.onSetVolumeTo(msg.arg1);
                     }
                     break;
             }
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 9a08fbe..b0df0e4 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringDef;
 import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -29,6 +30,8 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -372,6 +375,37 @@
         /** The MIME type of a single TV channel. */
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
 
+        /** @hide */
+        @StringDef({
+                TYPE_OTHER,
+                TYPE_NTSC,
+                TYPE_PAL,
+                TYPE_SECAM,
+                TYPE_DVB_T,
+                TYPE_DVB_T2,
+                TYPE_DVB_S,
+                TYPE_DVB_S2,
+                TYPE_DVB_C,
+                TYPE_DVB_C2,
+                TYPE_DVB_H,
+                TYPE_DVB_SH,
+                TYPE_ATSC_T,
+                TYPE_ATSC_C,
+                TYPE_ATSC_M_H,
+                TYPE_ISDB_T,
+                TYPE_ISDB_TB,
+                TYPE_ISDB_S,
+                TYPE_ISDB_C,
+                TYPE_1SEG,
+                TYPE_DTMB,
+                TYPE_CMMB,
+                TYPE_T_DMB,
+                TYPE_S_DMB,
+                TYPE_PREVIEW,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Type {}
+
         /**
          * A generic channel type.
          *
@@ -554,6 +588,15 @@
          */
         public static final String TYPE_PREVIEW = "TYPE_PREVIEW";
 
+        /** @hide */
+        @StringDef({
+                SERVICE_TYPE_OTHER,
+                SERVICE_TYPE_AUDIO_VIDEO,
+                SERVICE_TYPE_AUDIO,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface ServiceType {}
+
         /** A generic service type. */
         public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
 
@@ -563,6 +606,22 @@
         /** The service type for radio channels that have audio only. */
         public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
 
+        /** @hide */
+        @StringDef({
+                VIDEO_FORMAT_240P,
+                VIDEO_FORMAT_360P,
+                VIDEO_FORMAT_480I,
+                VIDEO_FORMAT_576I,
+                VIDEO_FORMAT_576P,
+                VIDEO_FORMAT_720P,
+                VIDEO_FORMAT_1080I,
+                VIDEO_FORMAT_1080P,
+                VIDEO_FORMAT_2160P,
+                VIDEO_FORMAT_4320P,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface VideoFormat {}
+
         /** The video format for 240p. */
         public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P";
 
@@ -596,6 +655,17 @@
         /** The video format for 4320p. */
         public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P";
 
+        /** @hide */
+        @StringDef({
+                VIDEO_RESOLUTION_SD,
+                VIDEO_RESOLUTION_ED,
+                VIDEO_RESOLUTION_HD,
+                VIDEO_RESOLUTION_FHD,
+                VIDEO_RESOLUTION_UHD,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface VideoResolution {}
+
         /** The video resolution for standard-definition. */
         public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD";
 
@@ -634,7 +704,7 @@
          * @see #COLUMN_VIDEO_FORMAT
          */
         @Nullable
-        public static final String getVideoResolution(String videoFormat) {
+        public static final String getVideoResolution(@VideoFormat String videoFormat) {
             return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat);
         }
 
@@ -1026,6 +1096,19 @@
         @SystemApi
         public static final String COLUMN_TRANSIENT = "transient";
 
+        /**
+         * The flag indicating whether this TV channel is approved to be shown by the system.
+         *
+         * <p>A value of 1 indicates that the channel is approved to be shown by the system, and a
+         * value of 0 indicates that the channel is blocked by system. If not specified, this value
+         * is set to 0 (not approved) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @hide
+         */
+        @SystemApi
+        public static final String COLUMN_SYSTEM_APPROVED = "system_approved";
+
         private Channels() {}
 
         /**
@@ -1087,6 +1170,24 @@
         /** The MIME type of a single TV program. */
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
 
+        /** @hide */
+        @StringDef({
+                TYPE_MOVIE,
+                TYPE_TV_SERIES,
+                TYPE_TV_SEASON,
+                TYPE_TV_EPISODE,
+                TYPE_CLIP,
+                TYPE_EVENT,
+                TYPE_CHANNEL,
+                TYPE_TRACK,
+                TYPE_ALBUM,
+                TYPE_ARTIST,
+                TYPE_PLAYLIST,
+                TYPE_STATION,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Type {}
+
         /**
          * The program type for movie.
          *
@@ -1171,6 +1272,15 @@
          */
         public static final String TYPE_STATION = "TYPE_STATION";
 
+        /** @hide */
+        @StringDef({
+                WATCH_NEXT_TYPE_CONTINUE,
+                WATCH_NEXT_TYPE_NEXT,
+                WATCH_NEXT_TYPE_NEW,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface WatchNextType {}
+
         /**
          * The watch next type for CONTINUE.
          *
@@ -1192,6 +1302,16 @@
          */
         public static final String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
 
+        /** @hide */
+        @StringDef({
+                ASPECT_RATIO_16_9,
+                ASPECT_RATIO_3_2,
+                ASPECT_RATIO_1_1,
+                ASPECT_RATIO_2_3,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface AspectRatio {}
+
         /**
          * The aspect ratio for 16:9.
          *
@@ -1224,6 +1344,15 @@
          */
         public static final String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
 
+        /** @hide */
+        @StringDef({
+                AVAILABILITY_AVAILABLE,
+                AVAILABILITY_FREE_WITH_SUBSCRIPTION,
+                AVAILABILITY_PAID_CONTENT,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Availability {}
+
         /**
          * The availability for "available to this user".
          *
@@ -1247,6 +1376,19 @@
          */
         public static final String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
 
+        /** @hide */
+        @StringDef({
+                INTERACTION_TYPE_LISTENS,
+                INTERACTION_TYPE_FOLLOWERS,
+                INTERACTION_TYPE_FANS,
+                INTERACTION_TYPE_LIKES,
+                INTERACTION_TYPE_THUMBS,
+                INTERACTION_TYPE_VIEWS,
+                INTERACTION_TYPE_VIEWERS,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface InteractionType {}
+
         /**
          * The interaction type for "listens".
          *
@@ -1296,6 +1438,15 @@
          */
         public static final String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
 
+        /** @hide */
+        @StringDef({
+                REVIEW_RATING_STYLE_STARS,
+                REVIEW_RATING_STYLE_THUMBS_UP_DOWN,
+                REVIEW_RATING_STYLE_PERCENTAGE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface ReviewRatingStyle {}
+
         /**
          * The review rating style for five star rating.
          *
@@ -1665,7 +1816,7 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_LOGO = "logo";
+        public static final String COLUMN_LOGO_URI = "logo_uri";
 
         /**
          * The availability of this TV program.
@@ -1860,8 +2011,8 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_PREVIEW_LAST_PLAYBACK_POSITION =
-                "preview_last_playback_position";
+        public static final String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
+                "last_playback_position_millis";
 
         /**
          * The duration (in milliseconds) of the preview video.
@@ -1872,7 +2023,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_PREVIEW_DURATION = "preview_duration";
+        public static final String COLUMN_DURATION_MILLIS = "duration_millis";
 
         /**
          * The intent URI which is launched when the preview video is selected.
@@ -1885,8 +2036,8 @@
          *
          * <p>Type: TEXT
          */
-        public static final String COLUMN_PREVIEW_INTENT_URI =
-                "preview_intent_uri";
+        public static final String COLUMN_APP_LINK_INTENT_URI =
+                "app_link_intent_uri";
 
         /**
          * The weight of the preview program within the channel.
@@ -1900,7 +2051,7 @@
          *
          * <p>Type: INTEGER
          */
-        public static final String COLUMN_PREVIEW_WEIGHT = "preview_weight";
+        public static final String COLUMN_WEIGHT = "weight";
 
         /**
          * The flag indicating whether this program is transient or not.
@@ -1981,6 +2132,29 @@
 
         /** Canonical genres for TV programs. */
         public static final class Genres {
+            /** @hide */
+            @StringDef({
+                    FAMILY_KIDS,
+                    SPORTS,
+                    SHOPPING,
+                    MOVIES,
+                    COMEDY,
+                    TRAVEL,
+                    DRAMA,
+                    EDUCATION,
+                    ANIMAL_WILDLIFE,
+                    NEWS,
+                    GAMING,
+                    ARTS,
+                    ENTERTAINMENT,
+                    LIFE_STYLE,
+                    MUSIC,
+                    PREMIER,
+                    TECH_SCIENCE,
+            })
+            @Retention(RetentionPolicy.SOURCE)
+            public @interface Genre {}
+
             /** The genre for Family/Kids. */
             public static final String FAMILY_KIDS = "FAMILY_KIDS";
 
@@ -2068,7 +2242,7 @@
              * @return an encoded genre string that can be inserted into the
              *         {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
              */
-            public static String encode(@NonNull String... genres) {
+            public static String encode(@NonNull @Genre String... genres) {
                 if (genres == null) {
                     // MNC and before will throw a NPE.
                     return null;
@@ -2107,7 +2281,7 @@
              *            {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
              * @return genre strings.
              */
-            public static String[] decode(@NonNull String genres) {
+            public static @Genre String[] decode(@NonNull String genres) {
                 if (TextUtils.isEmpty(genres)) {
                     // MNC and before will throw a NPE for {@code null} genres.
                     return EMPTY_STRING_ARRAY;
diff --git a/native/android/Android.mk b/native/android/Android.mk
index 355f52e..f510b48 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -1,6 +1,8 @@
 BASE_PATH := $(call my-dir)
 LOCAL_PATH:= $(call my-dir)
 
+common_cflags := -Wall -Werror -Wunused -Wunreachable-code
+
 include $(CLEAR_VARS)
 
 # our source files
@@ -43,6 +45,23 @@
 
 LOCAL_MODULE := libandroid
 
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+LOCAL_CFLAGS += $(common_cflags)
+
+include $(BUILD_SHARED_LIBRARY)
+
+# Network library.
+include $(CLEAR_VARS)
+LOCAL_MODULE := libandroid_net
+LOCAL_CFLAGS := $(common_cflags)
+LOCAL_SRC_FILES:= \
+    net.c \
+
+LOCAL_SHARED_LIBRARIES := \
+    libnetd_client \
+
+LOCAL_C_INCLUDES += \
+    frameworks/base/native/include \
+    bionic/libc/dns/include \
+    system/netd/include \
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/java/android/opengl/GLU.java b/opengl/java/android/opengl/GLU.java
index ed64556..ef9bf167 100644
--- a/opengl/java/android/opengl/GLU.java
+++ b/opengl/java/android/opengl/GLU.java
@@ -203,8 +203,8 @@
      * @param view the current view, {x, y, width, height}
      * @param viewOffset the offset into the view array where the view vector
      *        data starts.
-     * @param obj the output vector {objX, objY, objZ}, that returns the
-     *        computed object coordinates.
+     * @param obj the output vector {objX, objY, objZ, objW}, that returns the
+     *        computed homogeneous object coordinates.
      * @param objOffset the offset into the obj array where the obj vector data
      *        starts.
      * @return A return value of GL10.GL_TRUE indicates success, a return value
diff --git a/packages/CompanionDeviceManager/Android.mk b/packages/CompanionDeviceManager/Android.mk
new file mode 100644
index 0000000..f730356
--- /dev/null
+++ b/packages/CompanionDeviceManager/Android.mk
@@ -0,0 +1,27 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CompanionDeviceManager
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
new file mode 100644
index 0000000..3eede54
--- /dev/null
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2017 Google Inc.
+ *
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.companiondevicemanager">
+
+    <permission
+        android:name="com.android.companiondevicemanager.permission.BIND"
+        android:protectionLevel="signature" />
+
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+
+    <application
+        android:allowClearUserData="true"
+        android:label="@string/app_label"
+        android:allowBackup="false"
+        android:supportsRtl="true">
+
+        <service
+            android:name=".DeviceDiscoveryService"
+            android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
+            android:exported="true">
+        </service>
+
+        <activity
+            android:name=".DeviceChooserActivity"
+            android:theme="@*android:style/Theme.Dialog.NoFrame"
+            android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE">
+            <!--TODO include url scheme filter similar to PrintSpooler -->
+            <intent-filter>
+                <action android:name="android.companiondevice.START_DISCOVERY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+    </application>
+
+</manifest>
diff --git a/packages/CompanionDeviceManager/MODULE_LICENSE_APACHE2 b/packages/CompanionDeviceManager/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/CompanionDeviceManager/MODULE_LICENSE_APACHE2
diff --git a/packages/CompanionDeviceManager/NOTICE b/packages/CompanionDeviceManager/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/packages/CompanionDeviceManager/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, 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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/packages/CompanionDeviceManager/res/layout/device_chooser.xml b/packages/CompanionDeviceManager/res/layout/device_chooser.xml
new file mode 100644
index 0000000..ee08582
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/layout/device_chooser.xml
@@ -0,0 +1,67 @@
+<?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.
+-->
+
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_weight="0.1"
+    >
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textColor="@android:color/black"
+        style="@*android:style/TextAppearance.Widget.Toolbar.Title"
+    />
+
+    <ListView
+        android:id="@+id/device_list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@+id/title"
+        android:layout_above="@+id/buttons"
+        style="@android:style/Widget.Material.Light.ListView"
+    />
+
+    <LinearLayout
+        android:id="@+id/buttons"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentEnd="true"
+        android:gravity="end"
+    >
+        <Button
+            android:id="@+id/button_cancel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="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="Pair"
+            style="@android:style/Widget.Material.Light.Button.Borderless.Colored"
+        />
+    </LinearLayout>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/dimens.xml b/packages/CompanionDeviceManager/res/values/dimens.xml
new file mode 100644
index 0000000..da7b0d1
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/values/dimens.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <!--  Padding applied on most UI elements  -->
+    <dimen name="padding">12dp</dimen>
+
+</resources>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
new file mode 100644
index 0000000..c4195b50
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Title of the CompanionDeviceManager application. [CHAR LIMIT=50] -->
+    <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>
+
+</resources>
diff --git a/core/res/res/values-ldrtl/dimens.xml b/packages/CompanionDeviceManager/res/values/themes.xml
similarity index 62%
rename from core/res/res/values-ldrtl/dimens.xml
rename to packages/CompanionDeviceManager/res/values/themes.xml
index 807c042..465f8fc 100644
--- a/core/res/res/values-ldrtl/dimens.xml
+++ b/packages/CompanionDeviceManager/res/values/themes.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
@@ -15,6 +15,11 @@
 -->
 
 <resources>
-    <item type="dimen" format="integer" name="time_picker_column_start_material">1</item>
-    <item type="dimen" format="integer" name="time_picker_column_end_material">0</item>
+
+    <!--TODO-->
+    <!--<style name="Theme.ChooserActivity" parent="@*android:style/Theme.Dialog.NoFrame">-->
+        <!--&lt;!&ndash;<item name="android:windowBackground">@android:color/light_grey</item>&ndash;&gt;-->
+        <!--<item name="android:backgroundColor">@android:color/light_grey</item>-->
+    <!--</style>-->
+
 </resources>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
new file mode 100644
index 0000000..c95f940
--- /dev/null
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceChooserActivity.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.companiondevicemanager;
+
+import android.app.Activity;
+import android.bluetooth.BluetoothDevice;
+import android.companion.CompanionDeviceManager;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.Html;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class DeviceChooserActivity extends Activity {
+
+    private static final boolean DEBUG = false;
+    private static final String LOG_TAG = "DeviceChooserActivity";
+
+    private ListView mDeviceListView;
+    private View mPairButton;
+    private View mCancelButton;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        if (DEBUG) Log.i(LOG_TAG, "Started with intent " + getIntent());
+
+        setContentView(R.layout.device_chooser);
+        setTitle(Html.fromHtml(getString(R.string.chooser_title, getCallingAppName()), 0));
+        getWindow().getDecorView().getRootView().setBackgroundColor(Color.LTGRAY); //TODO theme
+
+        if (getService().mDevicesFound.isEmpty()) {
+            Log.e(LOG_TAG, "About to show UI, but no devices to show");
+        }
+
+        final DeviceDiscoveryService.DevicesAdapter adapter = getService().mDevicesAdapter;
+        mDeviceListView = (ListView) findViewById(R.id.device_list);
+        mDeviceListView.setAdapter(adapter);
+        mDeviceListView.addFooterView(getProgressBar(), null, false);
+
+        mPairButton = findViewById(R.id.button_pair);
+        mPairButton.setOnClickListener((view) ->
+                onPairTapped(getService().mSelectedDevice));
+        adapter.registerDataSetObserver(new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                updatePairButtonEnabled();
+            }
+        });
+        updatePairButtonEnabled();
+        mCancelButton = findViewById(R.id.button_cancel);
+        mCancelButton.setOnClickListener((view) -> {
+            setResult(RESULT_CANCELED);
+            finish();
+        });
+    }
+
+    private CharSequence getCallingAppName() {
+        try {
+            final PackageManager packageManager = getPackageManager();
+            return packageManager.getApplicationLabel(
+                    packageManager.getApplicationInfo(getService().mCallingPackage, 0));
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void setTitle(CharSequence title) {
+        final TextView titleView = (TextView) findViewById(R.id.title);
+        final int padding = getPadding(getResources());
+        titleView.setPadding(padding, padding, padding, padding);
+        titleView.setText(title);
+    }
+
+    //TODO put in resources xmls
+    private ProgressBar getProgressBar() {
+        final ProgressBar progressBar = new ProgressBar(this);
+        progressBar.setForegroundGravity(Gravity.CENTER_HORIZONTAL);
+        final int padding = getPadding(getResources());
+        progressBar.setPadding(padding, padding, padding, padding);
+        return progressBar;
+    }
+
+    static int getPadding(Resources r) {
+        return r.getDimensionPixelSize(R.dimen.padding);
+        //TODO
+//        final float dp = r.getDisplayMetrics().density;
+//        return (int)(12 * dp);
+    }
+
+    private void updatePairButtonEnabled() {
+        mPairButton.setEnabled(getService().mSelectedDevice != null);
+    }
+
+    private DeviceDiscoveryService getService() {
+        return DeviceDiscoveryService.sInstance;
+    }
+
+    protected void onPairTapped(BluetoothDevice selectedDevice) {
+        setResult(RESULT_OK,
+                new Intent().putExtra(CompanionDeviceManager.EXTRA_DEVICE, selectedDevice));
+        finish();
+    }
+
+    private void toast(String msg) {
+        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
+    }
+}
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
new file mode 100644
index 0000000..a3eec0d
--- /dev/null
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.companiondevicemanager;
+
+import static android.companion.BluetoothDeviceFilterUtils.getDeviceDisplayName;
+import static android.companion.BluetoothLEDeviceFilter.nullsafe;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.companion.AssociationRequest;
+import android.companion.BluetoothDeviceFilterUtils;
+import android.companion.BluetoothLEDeviceFilter;
+import android.companion.ICompanionDeviceManagerService;
+import android.companion.IOnAssociateCallback;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class DeviceDiscoveryService extends Service {
+
+    private static final boolean DEBUG = false;
+    private static final String LOG_TAG = "DeviceDiscoveryService";
+
+    static DeviceDiscoveryService sInstance;
+
+    private BluetoothAdapter mBluetoothAdapter;
+    private BluetoothLEDeviceFilter mFilter;
+    private ScanFilter mScanFilter;
+    private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
+    List<BluetoothDevice> mDevicesFound;
+    BluetoothDevice mSelectedDevice;
+    DevicesAdapter mDevicesAdapter;
+    IOnAssociateCallback mCallback;
+    String mCallingPackage;
+
+    private final ICompanionDeviceManagerService mBinder =
+            new ICompanionDeviceManagerService.Stub() {
+        @Override
+        public void startDiscovery(AssociationRequest request,
+                IOnAssociateCallback callback,
+                String callingPackage) throws RemoteException {
+            if (DEBUG) {
+                Log.i(LOG_TAG,
+                        "startDiscovery() called with: filter = [" + request + "], callback = ["
+                                + callback + "]");
+            }
+            mCallback = callback;
+            mCallingPackage = callingPackage;
+            DeviceDiscoveryService.this.startDiscovery(request);
+        }
+    };
+
+    private final ScanCallback mBLEScanCallback = new ScanCallback() {
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            final BluetoothDevice device = result.getDevice();
+            if (callbackType == ScanSettings.CALLBACK_TYPE_MATCH_LOST) {
+                onDeviceLost(device);
+            } else {
+                onDeviceFound(device);
+            }
+        }
+    };
+
+    private BluetoothLeScanner mBLEScanner;
+
+    private BroadcastReceiver mBluetoothDeviceFoundBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final BluetoothDevice device = intent.getParcelableExtra(
+                    BluetoothDevice.EXTRA_DEVICE);
+            if (!mFilter.matches(device)) return; // ignore device
+
+            if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
+                onDeviceFound(device);
+            } else {
+                onDeviceLost(device);
+            }
+        }
+    };
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (DEBUG) Log.i(LOG_TAG, "onBind(" + intent + ")");
+        return mBinder.asBinder();
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        if (DEBUG) Log.i(LOG_TAG, "onCreate()");
+
+        mBluetoothAdapter = getSystemService(BluetoothManager.class).getAdapter();
+        mBLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
+
+        mDevicesFound = new ArrayList<>();
+        mDevicesAdapter = new DevicesAdapter();
+
+        sInstance = this;
+    }
+
+    private void startDiscovery(AssociationRequest<?> request) {
+        //TODO support other protocols as well
+        mFilter = nullsafe((BluetoothLEDeviceFilter) request.getDeviceFilter());
+        mScanFilter = mFilter.getScanFilter();
+
+        reset();
+
+        final IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
+        intentFilter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
+
+        registerReceiver(mBluetoothDeviceFoundBroadcastReceiver, intentFilter);
+        mBluetoothAdapter.startDiscovery();
+
+        mBLEScanner.startScan(
+                Collections.singletonList(mScanFilter), mDefaultScanSettings, mBLEScanCallback);
+    }
+
+    private void reset() {
+        mDevicesFound.clear();
+        mSelectedDevice = null;
+        mDevicesAdapter.notifyDataSetChanged();
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        stopScan();
+        return super.onUnbind(intent);
+    }
+
+    private void stopScan() {
+        if (DEBUG) Log.i(LOG_TAG, "stopScan() called");
+        mBluetoothAdapter.cancelDiscovery();
+        mBLEScanner.stopScan(mBLEScanCallback);
+        unregisterReceiver(mBluetoothDeviceFoundBroadcastReceiver);
+        stopSelf();
+    }
+
+    private void onDeviceFound(BluetoothDevice device) {
+        if (mDevicesFound.contains(device)) {
+            return;
+        }
+
+        if (DEBUG) {
+            Log.i(LOG_TAG, "Considering device " + getDeviceDisplayName(device));
+        }
+
+        if (!mFilter.matches(device)) {
+            return;
+        }
+
+        if (DEBUG) {
+            Log.i(LOG_TAG, "Found device " + getDeviceDisplayName(device));
+        }
+        if (mDevicesFound.isEmpty()) {
+            onReadyToShowUI();
+        }
+        mDevicesFound.add(device);
+        mDevicesAdapter.notifyDataSetChanged();
+    }
+
+    //TODO also, on timeout -> call onFailure
+    private void onReadyToShowUI() {
+        try {
+            mCallback.onSuccess(PendingIntent.getActivity(
+                    this, 0,
+                    new Intent(this, DeviceChooserActivity.class),
+                    PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_CANCEL_CURRENT
+                            | PendingIntent.FLAG_IMMUTABLE));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void onDeviceLost(BluetoothDevice device) {
+        mDevicesFound.remove(device);
+        mDevicesAdapter.notifyDataSetChanged();
+        if (DEBUG) {
+            Log.i(LOG_TAG, "Lost device " + getDeviceDisplayName(device));
+        }
+    }
+
+    class DevicesAdapter extends ArrayAdapter<BluetoothDevice> {
+        private Drawable BLUETOOTH_ICON = icon(android.R.drawable.stat_sys_data_bluetooth);
+
+        private Drawable icon(int drawableRes) {
+            Drawable icon = getResources().getDrawable(drawableRes, null);
+            icon.setTint(Color.DKGRAY);
+            return icon;
+        }
+
+        public DevicesAdapter() {
+            super(DeviceDiscoveryService.this, 0, mDevicesFound);
+        }
+
+        @Override
+        public View getView(
+                int position,
+                @Nullable View convertView,
+                @NonNull ViewGroup parent) {
+            TextView view = convertView instanceof TextView
+                    ? (TextView) convertView
+                    : newView();
+            bind(view, getItem(position));
+            return view;
+        }
+
+        private void bind(TextView textView, BluetoothDevice device) {
+            textView.setText(getDeviceDisplayName(device));
+            textView.setBackgroundColor(
+                    device.equals(mSelectedDevice)
+                            ? Color.GRAY
+                            : Color.TRANSPARENT);
+            textView.setOnClickListener((view) -> {
+                mSelectedDevice = device;
+                notifyDataSetChanged();
+            });
+        }
+
+        //TODO move to a layout file
+        private TextView newView() {
+            final TextView textView = new TextView(DeviceDiscoveryService.this);
+            textView.setTextColor(Color.BLACK);
+            final int padding = DeviceChooserActivity.getPadding(getResources());
+            textView.setPadding(padding, padding, padding, padding);
+            textView.setCompoundDrawablesWithIntrinsicBounds(
+                    BLUETOOTH_ICON, null, null, null);
+            textView.setCompoundDrawablePadding(padding);
+            return textView;
+        }
+    }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 8bbc8c9..4ddafac 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1399,9 +1399,6 @@
                 Settings.Secure.NIGHT_DISPLAY_CUSTOM_END_TIME,
                 SecureSettingsProto.NIGHT_DISPLAY_CUSTOM_END_TIME);
         dumpSetting(s, p,
-                Settings.Secure.BRIGHTNESS_USE_TWILIGHT,
-                SecureSettingsProto.BRIGHTNESS_USE_TWILIGHT);
-        dumpSetting(s, p,
                 Settings.Secure.ENABLED_VR_LISTENERS,
                 SecureSettingsProto.ENABLED_VR_LISTENERS);
         dumpSetting(s, p,
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
index d71b6bd..dd1614b 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginInstanceManager.java
@@ -51,9 +51,6 @@
     private static final String TAG = "PluginInstanceManager";
     private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
 
-    // must be one of the channels created in NotificationChannels.java
-    private static final String NOTIFICATION_CHANNEL_ID = "ALR";
-
     private final Context mContext;
     private final PluginListener<T> mListener;
     private final String mAction;
@@ -310,14 +307,14 @@
                             mContext.getPackageName());
                     final int color = Resources.getSystem().getIdentifier(
                             "system_notification_accent_color", "color", "android");
-                    final Notification.Builder nb = new Notification.Builder(mContext)
-                            .setStyle(new Notification.BigTextStyle())
-                            .setSmallIcon(icon)
-                            .setWhen(0)
-                            .setShowWhen(false)
-                            .setChannel(NOTIFICATION_CHANNEL_ID)
-                            .setVisibility(Notification.VISIBILITY_PUBLIC)
-                            .setColor(mContext.getColor(color));
+                    final Notification.Builder nb = new Notification.Builder(mContext,
+                            PluginManager.NOTIFICATION_CHANNEL_ID)
+                                    .setStyle(new Notification.BigTextStyle())
+                                    .setSmallIcon(icon)
+                                    .setWhen(0)
+                                    .setShowWhen(false)
+                                    .setVisibility(Notification.VISIBILITY_PUBLIC)
+                                    .setColor(mContext.getColor(color));
                     String label = cls;
                     try {
                         label = mPm.getServiceInfo(component, 0).loadLabel(mPm).toString();
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
index 4714547..cef485e 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginManager.java
@@ -55,6 +55,9 @@
 
     static final String DISABLE_PLUGIN = "com.android.systemui.action.DISABLE_PLUGIN";
 
+    // must be one of the channels created in NotificationChannels.java
+    static final String NOTIFICATION_CHANNEL_ID = "ALR";
+
     private static PluginManager sInstance;
 
     private final HandlerThread mBackgroundThread;
@@ -70,7 +73,7 @@
     private boolean mListening;
     private boolean mHasOneShot;
 
-    private PluginManager(Context context) {
+    public PluginManager(Context context) {
         this(context, new PluginInstanceManagerFactory(),
                 Build.IS_DEBUGGABLE, Thread.getDefaultUncaughtExceptionHandler());
     }
@@ -191,15 +194,16 @@
                 } catch (NameNotFoundException e) {
                 }
                 // Localization not required as this will never ever appear in a user build.
-                final Notification.Builder nb = new Notification.Builder(mContext)
-                        .setSmallIcon(icon)
-                        .setWhen(0)
-                        .setShowWhen(false)
-                        .setPriority(Notification.PRIORITY_MAX)
-                        .setVisibility(Notification.VISIBILITY_PUBLIC)
-                        .setColor(mContext.getColor(color))
-                        .setContentTitle("Plugin \"" + label + "\" has updated")
-                        .setContentText("Restart SysUI for changes to take effect.");
+                final Notification.Builder nb =
+                        new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
+                                .setSmallIcon(icon)
+                                .setWhen(0)
+                                .setShowWhen(false)
+                                .setPriority(Notification.PRIORITY_MAX)
+                                .setVisibility(Notification.VISIBILITY_PUBLIC)
+                                .setColor(mContext.getColor(color))
+                                .setContentTitle("Plugin \"" + label + "\" has updated")
+                                .setContentText("Restart SysUI for changes to take effect.");
                 Intent i = new Intent("com.android.systemui.action.RESTART").setData(
                             Uri.parse("package://" + pkg));
                 PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, 0);
@@ -252,13 +256,6 @@
         return new PluginContextWrapper(mContext.createApplicationContext(info, 0), classLoader);
     }
 
-    public static PluginManager getInstance(Context context) {
-        if (sInstance == null) {
-            sInstance = new PluginManager(context.getApplicationContext());
-        }
-        return sInstance;
-    }
-
     private class AllPluginClassLoader extends ClassLoader {
         public AllPluginClassLoader(ClassLoader classLoader) {
             super(classLoader);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
index 0728482..918d6e9 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
@@ -32,6 +32,8 @@
         public boolean onInterceptTouchEvent(MotionEvent event);
 
         public void setBarState(boolean vertical, boolean isRtl);
+
+        public default void destroy() { }
     }
 
 }
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..0615668
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..839e5ed
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..1480c865
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..66e11fb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..d2fe0c3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..5923269
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..d0196e5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..d3a2b39
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button.png
new file mode 100644
index 0000000..726643c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button_dark.png
new file mode 100644
index 0000000..31078f6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_accessibility_button_dark.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/pip_dismiss_background.xml b/packages/SystemUI/res/drawable/pip_dismiss_background.xml
index 3a75296..8f50231 100644
--- a/packages/SystemUI/res/drawable/pip_dismiss_background.xml
+++ b/packages/SystemUI/res/drawable/pip_dismiss_background.xml
@@ -1,22 +1,22 @@
 <!--
-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
+     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,
-    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.
+     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.
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="oval">
-    <corners
-        android:radius="100dp" />
-    <solid
-        android:color="#66000000" />
+    android:shape="rectangle">
+    <gradient
+        android:startColor="#B3000000"
+        android:endColor="#00000000"
+        android:angle="90"/>
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index 5e85ba0..6bd79a4 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -39,4 +39,13 @@
         android:contentDescription="@string/accessibility_ime_switch_button"
         android:scaleType="centerInside"
         />
+    <com.android.systemui.statusbar.policy.KeyButtonView
+        android:id="@+id/accessibility_button"
+        android:layout_width="@dimen/navigation_extra_key_width"
+        android:layout_height="match_parent"
+        android:layout_marginEnd="2dp"
+        android:visibility="invisible"
+        android:contentDescription="@string/accessibility_accessibility_button"
+        android:scaleType="centerInside"
+    />
 </FrameLayout>
diff --git a/packages/SystemUI/res/layout/pip_dismiss_view.xml b/packages/SystemUI/res/layout/pip_dismiss_view.xml
index 141e610..f02a56c 100644
--- a/packages/SystemUI/res/layout/pip_dismiss_view.xml
+++ b/packages/SystemUI/res/layout/pip_dismiss_view.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
+<!--
+     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.
@@ -13,12 +14,44 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/pip_dismiss_view"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@drawable/pip_dismiss_background"
-    android:foreground="@drawable/pip_dismiss"
-    android:alpha="0"
-    android:forceHasOverlappingRendering="false" />
+    android:alpha="0">
+
+    <!-- The height of the below view needs to be animated from a window
+         so it needs to be in a container to resize smoothly -->
+    <View
+        android:id="@+id/gradient_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="bottom"
+        android:background="@drawable/pip_dismiss_background" />
+
+    <LinearLayout
+        android:id="@+id/pip_dismiss_container"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|center_horizontal"
+        android:orientation="horizontal"
+        android:paddingBottom="32dp" >
+
+        <ImageView
+            android:id="@+id/pip_dismiss_icon"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:padding="2dp"
+            android:src="@drawable/pip_dismiss"
+            android:tint="#FFFFFFFF" />
+
+        <TextView
+            android:id="@+id/pip_dismiss_text"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/pip_phone_close"
+            android:textColor="#FFFFFFFF"
+            android:textSize="16sp" />
+    </LinearLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/pip_menu_activity.xml b/packages/SystemUI/res/layout/pip_menu_activity.xml
index cf65f4a..0f5ca9b 100644
--- a/packages/SystemUI/res/layout/pip_menu_activity.xml
+++ b/packages/SystemUI/res/layout/pip_menu_activity.xml
@@ -27,7 +27,7 @@
         android:layout_height="48dp"
         android:layout_gravity="top|end"
         android:padding="10dp"
-        android:contentDescription="@string/pip_phone_dismiss"
+        android:contentDescription="@string/pip_phone_close"
         android:src="@drawable/ic_close_white"
         android:background="?android:selectableItemBackgroundBorderless" />
 
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 174776c..3e8e72a 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -2,23 +2,22 @@
 <!--
 ** Copyright 2012, 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 
+** 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, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** 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.
 -->
 
 <!-- Extends RelativeLayout -->
 <com.android.systemui.statusbar.phone.QuickStatusBarHeader
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/header"
     android:layout_width="match_parent"
     android:layout_height="@dimen/status_bar_header_height"
@@ -29,8 +28,7 @@
     android:clipToPadding="false"
     android:paddingTop="0dp"
     android:paddingEnd="0dp"
-    android:paddingStart="0dp"
-    >
+    android:paddingStart="0dp">
 
     <LinearLayout
         android:layout_width="wrap_content"
@@ -190,8 +188,7 @@
         android:layout_alignParentBottom="true"
         android:alpha="0"
         android:background="@color/qs_detail_progress_track"
-        android:src="@drawable/indeterminate_anim"
-        />
+        android:src="@drawable/indeterminate_anim"/>
 
     <TextView
         android:id="@+id/header_debug_info"
@@ -203,7 +200,6 @@
         android:textColor="#00A040"
         android:textSize="11dp"
         android:textStyle="bold"
-        android:visibility="invisible"
-        />
+        android:visibility="invisible"/>
 
 </com.android.systemui.statusbar.phone.QuickStatusBarHeader>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index f09657f..0852020 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -3,28 +3,27 @@
 **
 ** Copyright 2006, 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 
+** 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, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
+** 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.
 */
 -->
 
-<com.android.systemui.statusbar.phone.NotificationPanelView 
+<com.android.systemui.statusbar.phone.NotificationPanelView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/notification_panel"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@android:color/transparent"
-    >
+    android:background="@android:color/transparent" >
 
     <include
         layout="@layout/keyguard_status_view"
@@ -77,8 +76,8 @@
     </com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
 
     <include
-            layout="@layout/keyguard_bottom_area"
-            android:visibility="gone" />
+        layout="@layout/keyguard_bottom_area"
+        android:visibility="gone" />
 
     <com.android.systemui.statusbar.AlphaOptimizedView
         android:id="@+id/qs_navbar_scrim"
@@ -88,4 +87,4 @@
         android:visibility="invisible"
         android:background="@drawable/qs_navbar_scrim" />
 
-</com.android.systemui.statusbar.phone.NotificationPanelView><!-- end of sliding panel -->
+</com.android.systemui.statusbar.phone.NotificationPanelView>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 285a8ec..c2686f8 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -48,6 +48,7 @@
         android:layout_height="match_parent"
         android:importantForAccessibility="no"
         sysui:ignoreRightInset="true"
+        sysui:scrimColor="@color/scrim_behind_color"
         />
 
     <com.android.systemui.statusbar.AlphaOptimizedView
@@ -72,7 +73,7 @@
     <include layout="@layout/status_bar_expanded"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:visibility="gone" />
+        android:visibility="invisible" />
 
     <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_in_front"
         android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 7fb513c..7632f87 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -115,5 +115,9 @@
     <declare-styleable name="PluginInflateContainer">
         <attr name="viewType" format="string" />
     </declare-styleable>
+    <declare-styleable name="ScrimView">
+        <!-- The initial color for the scrim. -->
+        <attr name="scrimColor" format="color" />
+    </declare-styleable>
 </resources>
 
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 1ec611a..ad5b108 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -36,6 +36,7 @@
     <color name="qs_detail_button">@*android:color/quaternary_device_default_settings</color>
     <color name="qs_detail_button_white">#B3FFFFFF</color><!-- 70% white -->
     <color name="qs_detail_transition">#66FFFFFF</color>
+    <color name="scrim_behind_color">@android:color/black</color>
     <color name="status_bar_clock_color">#FFFFFFFF</color>
     <color name="qs_user_detail_icon_muted">#FFFFFFFF</color> <!-- not so muted after all -->
     <color name="qs_tile_disabled_color">#9E9E9E</color> <!-- 38% black -->
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index d9407ab..64cac3c 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -302,4 +302,34 @@
     <item type="id" name="action_split_task_to_right" />
     <item type="id" name="action_split_task_to_top" />
 
+    <!-- Whether or not the gear icon on notifications should be shown. The gear is shown when the
+         the notification is not swiped enough to dismiss it. -->
+    <bool name="config_showNotificationGear">true</bool>
+
+    <!-- Whether or not a background should be drawn behind a notification. -->
+    <bool name="config_drawNotificationBackground">true</bool>
+
+    <!-- Whether or not the edit icon on the quick settings header is shown. -->
+    <bool name="config_showQuickSettingsEditingIcon">true</bool>
+
+    <!-- Whether or not the multi-user switcher should be visible even if the quick settings are
+         not expanded. If there are not multiple users on the system, the switcher will still
+         hide itself. -->
+    <bool name="config_alwaysShowMultiUserSwitcher">false</bool>
+
+    <!-- Whether or not the expand indicator is visible for manually expanding the quick settings
+         panel. -->
+    <bool name="config_showQuickSettingsExpandIndicator">true</bool>
+
+    <!-- Whether or not to display the row of quick settings icons separate from the full quick
+         settings panel. -->
+    <bool name="config_showQuickSettingsRow">true</bool>
+
+    <!-- Whether or not the quick settings should be revealed on an overscroll of the
+         notifications panel. -->
+    <bool name="config_enableQuickSettingsOverscrollExpansion">true</bool>
+
+    <!-- Whether or the notifications can be shown and dismissed with a drag. -->
+    <bool name="config_enableNotificationShadeDrag">true</bool>
+
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ddcc4ba..b768f90 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -69,6 +69,9 @@
     <!-- Height of a small notification in the status bar-->
     <dimen name="notification_min_height">92dp</dimen>
 
+    <!-- Height of a small notification in the status bar if it is a large (like messaging)-->
+    <dimen name="notification_min_height_large">132dp</dimen>
+
     <!-- Height of a small notification in the status bar which was used before android N -->
     <dimen name="notification_min_height_legacy">64dp</dimen>
 
@@ -347,6 +350,8 @@
     <dimen name="keyguard_clock_notifications_margin_max">42dp</dimen>
     <dimen name="heads_up_scrim_height">250dp</dimen>
 
+    <item name="scrim_behind_alpha" format="float" type="dimen">0.62</item>
+
     <!-- The minimum amount the user needs to swipe to go to the camera / phone. -->
     <dimen name="keyguard_min_swipe_amount">110dp</dimen>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d3e965a..2cc2621 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -207,6 +207,8 @@
     <string name="accessibility_home">Home</string>
     <!-- Content description of the menu button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_menu">Menu</string>
+    <!-- Content description of the accessibility button in the navigation bar (not shown on the screen). [CHAR LIMIT=NONE] -->
+    <string name="accessibility_accessibility_button">Accessibility</string>
     <!-- Content description of the recents button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_recent">Overview</string>
     <!-- Content description of the search button for accessibility. [CHAR LIMIT=NONE] -->
@@ -1746,8 +1748,8 @@
     <!-- Label for PIP action to Minimize the PIP [CHAR LIMIT=25] -->
     <string name="pip_phone_minimize">Minimize</string>
 
-    <!-- Label for PIP action to Dismiss the PIP -->
-    <string name="pip_phone_dismiss">Dismiss</string>
+    <!-- Label for PIP the drag to close zone [CHAR LIMIT=NONE]-->
+    <string name="pip_phone_close">Close</string>
 
     <!-- PIP section of the tuner. Non-translatable since it should
         not appear on production builds ever. -->
@@ -1802,10 +1804,8 @@
     <string name="notification_channel_alerts">Alerts</string>
     <!-- Title for the notification channel dedicated to screenshot progress. [CHAR LIMIT=NONE] -->
     <string name="notification_channel_screenshot">Screenshots</string>
-    <!-- Title for the notification channel for urgent security issues. [CHAR LIMIT=NONE] -->
-    <string name="notification_channel_security">Security</string>
-    <!-- Title for the notification channel containing multi-user status information. [CHAR LIMIT=NONE] -->
-    <string name="notification_channel_user_status">User status</string>
+    <!-- Title for the notification channel for miscellaneous notices. [CHAR LIMIT=NONE] -->
+    <string name="notification_channel_general">General Messages</string>
     <!-- Title for the notification channel for problems with storage (i.e. low disk). [CHAR LIMIT=NONE] -->
     <string name="notification_channel_storage">Storage</string>
 
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index b30b596..29a8da0 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -76,7 +76,7 @@
         mDrawable.setBatteryController(mBatteryController);
         mBatteryController.addCallback(this);
         mDrawable.startListening();
-        TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+        Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
     }
 
     @Override
@@ -84,7 +84,7 @@
         super.onDetachedFromWindow();
         mBatteryController.removeCallback(this);
         mDrawable.stopListening();
-        TunerService.get(getContext()).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 135b129..e1f3176 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -14,6 +14,7 @@
 
 package com.android.systemui;
 
+import android.content.Context;
 import android.content.res.Configuration;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -23,6 +24,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.assist.AssistManager;
+import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
 import com.android.systemui.statusbar.policy.AccessibilityController;
@@ -56,9 +58,11 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
+import com.android.systemui.tuner.TunerService;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.HashMap;
 
 /**
  * Class to handle ugly dependencies throughout sysui until we determine the
@@ -167,12 +171,18 @@
         mProviders.put(DeviceProvisionedController.class.getName(), () ->
                 new DeviceProvisionedControllerImpl(mContext));
 
+        mProviders.put(PluginManager.class.getName(), () ->
+                new PluginManager(mContext));
+
         mProviders.put(AssistManager.class.getName(), () ->
                 new AssistManager(getDependency(DeviceProvisionedController.class), mContext));
 
         mProviders.put(SecurityController.class.getName(), () ->
                 new SecurityControllerImpl(mContext));
 
+        mProviders.put(TunerService.class.getName(), () ->
+                new TunerService(mContext));
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
@@ -220,6 +230,17 @@
         T createDependency();
     }
 
+    /**
+     * Used in separate processes (like tuner settings) to init the dependencies.
+     */
+    public static void initDependencies(Context context) {
+        if (sDependency != null) return;
+        Dependency d = new Dependency();
+        d.mContext = context.getApplicationContext();
+        d.mComponents = new HashMap<>();
+        d.start();
+    }
+
     public static <T> T get(Class<T> cls) {
         return sDependency.getDependency(cls.getName());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/EventLogConstants.java b/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
index 9238928..def3c40 100644
--- a/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
+++ b/packages/SystemUI/src/com/android/systemui/EventLogConstants.java
@@ -16,30 +16,46 @@
 
 package com.android.systemui;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
 /**
  * Constants to be passed as sysui_* eventlog parameters.
  */
 public class EventLogConstants {
     /** The user swiped up on the lockscreen, unlocking the device. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK = 1;
     /** The user swiped down on the lockscreen, going to the full shade. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE = 2;
     /** The user tapped in an empty area, causing the unlock hint to be shown. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT = 3;
     /** The user swiped inward on the camera icon, launching the camera. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA = 4;
     /** The user swiped inward on the dialer icon, launching the dialer. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER = 5;
     /** The user tapped the lock, locking the device. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK = 6;
     /** The user tapped a notification, needs to tap again to launch. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE = 7;
     /** The user swiped down to open quick settings, from keyguard. */
-    public static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8;
+    private static final int SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS = 8;
     /** The user swiped down to open quick settings, from shade. */
-    public static final int SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9;
+    private static final int SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS = 9;
     /** The user tapped on the status bar to open quick settings, from shade. */
-    public static final int SYSUI_TAP_TO_OPEN_QS = 10;
+    private static final int SYSUI_TAP_TO_OPEN_QS = 10;
+
+    public static final int[] METRICS_GESTURE_TYPE_MAP = {
+            MetricsEvent.VIEW_UNKNOWN,         // there is no type 0
+            MetricsEvent.ACTION_LS_UNLOCK,     // SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK
+            MetricsEvent.ACTION_LS_SHADE,      // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE
+            MetricsEvent.ACTION_LS_HINT,       // SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT
+            MetricsEvent.ACTION_LS_CAMERA,     // SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA
+            MetricsEvent.ACTION_LS_DIALER,     // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER
+            MetricsEvent.ACTION_LS_LOCK,       // SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK
+            MetricsEvent.ACTION_LS_NOTE,       // SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE
+            MetricsEvent.ACTION_LS_QS,         // SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS
+            MetricsEvent.ACTION_SHADE_QS_PULL, // SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS
+            MetricsEvent.ACTION_SHADE_QS_TAP   // SYSUI_TAP_TO_OPEN_QS
+    };
 
     /** Secondary user tries binding to the system sysui service */
     public static final int SYSUI_RECENTS_CONNECTION_USER_BIND_SERVICE = 1;
diff --git a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
index efddf20..9cc6613 100644
--- a/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/PluginInflateContainer.java
@@ -76,7 +76,7 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         if (mAction != null) {
-            PluginManager.getInstance(getContext()).addPluginListener(mAction, this, mVersion);
+            Dependency.get(PluginManager.class).addPluginListener(mAction, this, mVersion);
         }
     }
 
@@ -84,7 +84,7 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         if (mAction != null) {
-            PluginManager.getInstance(getContext()).removePluginListener(this);
+            Dependency.get(PluginManager.class).removePluginListener(this);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
index 94b2fdb..9b74cd6 100644
--- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java
@@ -21,11 +21,10 @@
 import android.view.View;
 
 public interface RecentsComponent {
-    void showRecents(boolean triggeredFromAltTab, boolean fromHome);
-    void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
+    void showRecentApps(boolean triggeredFromAltTab, boolean fromHome);
+    void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
     void toggleRecents(Display display);
     void preloadRecents();
-    void cancelPreloadingRecents();
     void showNextAffiliatedTask();
     void showPrevAffiliatedTask();
 
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 9515585..27070ed 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -65,7 +65,6 @@
     private final Class<?>[] SERVICES = new Class[] {
             Dependency.class,
             FragmentService.class,
-            TunerService.class,
             NotificationChannels.class,
             CommandQueue.CommandQueueStart.class,
             KeyguardViewMediator.class,
@@ -88,6 +87,7 @@
      * above.
      */
     private final Class<?>[] SERVICES_PER_USER = new Class[] {
+            Dependency.class,
             Recents.class,
             PipUI.class
     };
@@ -205,7 +205,7 @@
                 mServices[i].onBootCompleted();
             }
         }
-        PluginManager.getInstance(this).addPluginListener(OverlayPlugin.ACTION,
+        Dependency.get(PluginManager.class).addPluginListener(OverlayPlugin.ACTION,
                 new PluginListener<OverlayPlugin>() {
             @Override
             public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index aa22618..7c15096 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.doze;
 
+import android.app.AlarmManager;
 import android.app.Application;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -25,10 +26,7 @@
 import android.os.SystemClock;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
-import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIApplication;
-import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.doze.DozeProvider;
 import com.android.systemui.statusbar.phone.DozeParameters;
 
@@ -45,6 +43,7 @@
         Context context = dozeService;
         SensorManager sensorManager = context.getSystemService(SensorManager.class);
         PowerManager powerManager = context.getSystemService(PowerManager.class);
+        AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
 
         DozeHost host = getHost(dozeService);
         AmbientDisplayConfiguration config = new AmbientDisplayConfiguration(context);
@@ -57,7 +56,7 @@
         machine.setParts(new DozeMachine.Part[]{
                 createDozeTriggers(context, sensorManager, host, config, params, handler, wakeLock,
                         machine),
-                createDozeUi(context, host, wakeLock, machine),
+                createDozeUi(context, host, wakeLock, machine, handler, alarmManager),
         });
 
         return machine;
@@ -72,7 +71,7 @@
     }
 
     private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock,
-            DozeMachine machine) {
+            DozeMachine machine, Handler handler, AlarmManager alarmManager) {
         if (mDozePlugin != null) {
             DozeProvider.DozeUi dozeUi = mDozePlugin.provideDozeUi(context,
                     pluginMachine(context, machine, host),
@@ -82,7 +81,7 @@
                         pluginState(newState));
             };
         } else {
-            return new DozeUi(context, machine, wakeLock, host);
+            return new DozeUi(context, alarmManager, machine, wakeLock, host, handler);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 00d2298..f3fb1ef 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -30,15 +30,12 @@
     void stopDozing();
     void dozeTimeTick();
     boolean isPowerSaveActive();
-    boolean isNotificationLightOn();
     boolean isPulsingBlocked();
 
     void startPendingIntentDismissingKeyguard(PendingIntent intent);
 
     interface Callback {
-        default void onNewNotifications() {}
         default void onNotificationHeadsUp() {}
-        default void onNotificationLight(boolean on) {}
         default void onPowerSaveChanged(boolean active) {}
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 828728f..94dc9a3 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -19,6 +19,7 @@
 import android.service.dreams.DreamService;
 import android.util.Log;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.doze.DozeProvider;
@@ -47,7 +48,7 @@
             return;
         }
 
-        DozeProvider provider = PluginManager.getInstance(this)
+        DozeProvider provider = Dependency.get(PluginManager.class)
                 .getOneShotPlugin(DozeProvider.ACTION, DozeProvider.VERSION);
         mDozeMachine = new DozeFactory(provider).assembleMachine(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 95e49ce..76e0283 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -16,7 +16,13 @@
 
 package com.android.systemui.doze;
 
+import android.app.AlarmManager;
 import android.content.Context;
+import android.os.Handler;
+import android.os.SystemClock;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
 
 /**
  * The policy controlling doze.
@@ -24,16 +30,25 @@
 public class DozeUi implements DozeMachine.Part {
 
     private final Context mContext;
+    private final AlarmManager mAlarmManager;
     private final DozeHost mHost;
-    private DozeFactory.WakeLock mWakeLock;
-    private DozeMachine mMachine;
+    private final Handler mHandler;
+    private final DozeFactory.WakeLock mWakeLock;
+    private final DozeMachine mMachine;
+    private final AlarmManager.OnAlarmListener mTimeTick;
 
-    public DozeUi(Context context, DozeMachine machine, DozeFactory.WakeLock wakeLock,
-            DozeHost host) {
+    private boolean mTimeTickScheduled = false;
+
+    public DozeUi(Context context, AlarmManager alarmManager, DozeMachine machine,
+            DozeFactory.WakeLock wakeLock, DozeHost host, Handler handler) {
         mContext = context;
+        mAlarmManager = alarmManager;
         mMachine = machine;
         mWakeLock = wakeLock;
         mHost = host;
+        mHandler = handler;
+
+        mTimeTick = this::onTimeTick;
     }
 
     private void pulseWhileDozing(int reason) {
@@ -54,6 +69,12 @@
     @Override
     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
         switch (newState) {
+            case DOZE_AOD:
+                scheduleTimeTick();
+                break;
+            case DOZE:
+                unscheduleTimeTick();
+                break;
             case DOZE_REQUEST_PULSE:
                 pulseWhileDozing(DozeLog.PULSE_REASON_NOTIFICATION /* TODO */);
                 break;
@@ -62,7 +83,52 @@
                 break;
             case FINISH:
                 mHost.stopDozing();
+                unscheduleTimeTick();
                 break;
         }
     }
+
+    private void scheduleTimeTick() {
+        if (mTimeTickScheduled) {
+            return;
+        }
+
+        long delta = roundToNextMinute(System.currentTimeMillis()) - System.currentTimeMillis();
+        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                SystemClock.elapsedRealtime() + delta, "doze_time_tick", mTimeTick, mHandler);
+
+        mTimeTickScheduled = true;
+    }
+
+    private void unscheduleTimeTick() {
+        if (!mTimeTickScheduled) {
+            return;
+        }
+        mAlarmManager.cancel(mTimeTick);
+    }
+
+    private long roundToNextMinute(long timeInMillis) {
+        Calendar calendar = GregorianCalendar.getInstance();
+        calendar.setTimeInMillis(timeInMillis);
+        calendar.set(Calendar.MILLISECOND, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.add(Calendar.MINUTE, 1);
+
+        return calendar.getTimeInMillis();
+    }
+
+    private void onTimeTick() {
+        if (!mTimeTickScheduled) {
+            // Alarm was canceled, but we still got the callback. Ignore.
+            return;
+        }
+
+        mHost.dozeTimeTick();
+
+        // Keep wakelock until a frame has been pushed.
+        mHandler.post(mWakeLock.wrap(() -> {}));
+
+        mTimeTickScheduled = false;
+        scheduleTimeTick();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java b/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
index 2e6de4a..1eaca6f 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/PluginFragmentListener.java
@@ -19,6 +19,7 @@
 import android.util.Log;
 import android.view.View;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.plugins.FragmentBase;
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.PluginListener;
@@ -38,7 +39,7 @@
             Class<? extends FragmentBase> expectedInterface) {
         mTag = tag;
         mFragmentHostManager = FragmentHostManager.get(view);
-        mPluginManager = PluginManager.getInstance(view.getContext());
+        mPluginManager = Dependency.get(PluginManager.class);
         mExpectedInterface = expectedInterface;
         mDefaultClass = defaultFragment;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
index a7ac719..e182176 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipDismissViewController.java
@@ -17,13 +17,19 @@
 package com.android.systemui.pip.phone;
 
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.view.Gravity;
 import android.view.LayoutInflater;
+import android.view.TouchDelegate;
 import android.view.View;
 import android.view.View.OnLayoutChangeListener;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.widget.FrameLayout;
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -35,12 +41,22 @@
     private static final int SHOW_TARGET_DELAY = 100;
     private static final int SHOW_TARGET_DURATION = 200;
 
+    private static final float DISMISS_TEXT_MAX_SCALE = 2f;
+    private static final float DISMISS_GRADIENT_MIN_HEIGHT_PERCENT = 0.33f;
+    private static final float DISMISS_GRADIENT_MAX_HEIGHT_PERCENT = 0.5f;
+    private static final float DISMISS_THRESHOLD = 0.55f;
+
     private Context mContext;
     private WindowManager mWindowManager;
 
     private View mDismissView;
     private Rect mDismissTargetScreenBounds = new Rect();
 
+    private View mDismissContainer;
+    private View mGradientView;
+    private float mMinHeight;
+    private float mMaxHeight;
+
     public PipDismissViewController(Context context) {
         mContext = context;
         mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
@@ -51,25 +67,37 @@
      */
     public void createDismissTarget() {
         if (mDismissView == null) {
+            // Determine sizes for the gradient
+            Point windowSize = new Point();
+            mWindowManager.getDefaultDisplay().getSize(windowSize);
+            mMinHeight = windowSize.y * DISMISS_GRADIENT_MIN_HEIGHT_PERCENT;
+            mMaxHeight = windowSize.y * DISMISS_GRADIENT_MAX_HEIGHT_PERCENT;
+
             // Create a new view for the dismiss target
-            int dismissTargetSize = mContext.getResources().getDimensionPixelSize(
-                    R.dimen.pip_dismiss_target_size);
             LayoutInflater inflater = LayoutInflater.from(mContext);
             mDismissView = inflater.inflate(R.layout.pip_dismiss_view, null);
-            mDismissView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+            mGradientView = mDismissView.findViewById(R.id.gradient_view);
+            FrameLayout.LayoutParams glp = (android.widget.FrameLayout.LayoutParams) mGradientView
+                    .getLayoutParams();
+            glp.height = (int) mMaxHeight;
+            mGradientView.setLayoutParams(glp);
+            mGradientView.setPivotY(windowSize.y);
+            mGradientView.setScaleY(mMaxHeight / mMinHeight); // Set to min height via scaling
+            mDismissContainer = mDismissView.findViewById(R.id.pip_dismiss_container);
+            mDismissContainer.addOnLayoutChangeListener(new OnLayoutChangeListener() {
                 @Override
                 public void onLayoutChange(View v, int left, int top, int right, int bottom,
                         int oldLeft, int oldTop, int oldRight, int oldBottom) {
-                    if (mDismissView != null) {
-                        mDismissView.getBoundsOnScreen(mDismissTargetScreenBounds);
+                    if (mDismissContainer != null) {
+                        mDismissContainer.getBoundsOnScreen(mDismissTargetScreenBounds);
                     }
                 }
             });
 
             // Add the target to the window
             WindowManager.LayoutParams lp =  new WindowManager.LayoutParams(
-                    dismissTargetSize,
-                    dismissTargetSize,
+                    windowSize.x,
+                    (int) mMaxHeight,
                     WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG,
                     WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                             | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
@@ -84,7 +112,8 @@
     /**
      * Shows the dismiss target.
      */
-    public void showDismissTarget() {
+    public void showDismissTarget(Rect pinnedStack) {
+        updateDismissTarget(pinnedStack);
         mDismissView.animate()
                 .alpha(1f)
                 .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
@@ -115,10 +144,46 @@
     }
 
     /**
+     * Updates the appearance of the dismiss target based on how close the PIP is.
+     */
+    public void updateDismissTarget(Rect pinnedStack) {
+        // As PIP moves over / away from delete target it grows / shrinks
+        final float scalePercent = calculateDistancePercent(pinnedStack);
+        final float newScale = 1 + (DISMISS_TEXT_MAX_SCALE - 1) * scalePercent;
+        final float minGradientScale = mMinHeight / mMaxHeight;
+        final float newHeight = Math.max(minGradientScale, scalePercent);
+        mGradientView.setScaleY(newHeight);
+        mDismissContainer.setScaleX(newScale);
+        mDismissContainer.setScaleY(newScale);
+    }
+
+    /**
+     * @return the percentage of distance the PIP is away from the dismiss target point.
+     */
+    private float calculateDistancePercent(Rect pinnedStack) {
+        final int distance = mDismissTargetScreenBounds.height();
+        final int textX = mDismissTargetScreenBounds.centerX();
+        final int textY = mDismissTargetScreenBounds.bottom;
+        final float pipCurrX = pinnedStack.centerX();
+        final float pipCurrY = pinnedStack.bottom;
+        final float currentDistance = PointF.length(pipCurrX - textX, pipCurrY - textY);
+        if (currentDistance <= distance) {
+            return 1 - (currentDistance / distance);
+        }
+        return 0;
+    }
+
+    /**
      * @return the dismiss target screen bounds.
      */
     public Rect getDismissBounds() {
         return mDismissTargetScreenBounds;
     }
 
+    /**
+     * @return whether the PIP is positioned on the dismiss target enough to be dismissed.
+     */
+    public boolean shouldDismiss(Rect pinnedStack) {
+        return calculateDistancePercent(pinnedStack) >= DISMISS_THRESHOLD;
+    }
 }
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 30aa03c..10393c6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -33,6 +33,7 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
+import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.util.Log;
@@ -49,6 +50,7 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.policy.PipMotionHelper;
 import com.android.internal.policy.PipSnapAlgorithm;
+import com.android.systemui.Dependency;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.tuner.TunerService;
 
@@ -71,6 +73,7 @@
     private static final int DISMISS_STACK_DURATION = 375;
     private static final int EXPAND_STACK_DURATION = 225;
     private static final int MINIMIZE_STACK_MAX_DURATION = 200;
+    private static final int SHOW_DISMISS_AFFORDANCE_DELAY = 200;
 
     // The fraction of the stack width that the user has to drag offscreen to minimize the PIP
     private static final float MINIMIZE_OFFSCREEN_FRACTION = 0.2f;
@@ -105,6 +108,16 @@
         }
     };
 
+    private Handler mHandler = new Handler();
+    private Runnable mShowDismissAffordance = new Runnable() {
+        @Override
+        public void run() {
+            if (mEnableDragToDismiss) {
+                mDismissViewController.showDismissTarget(mPinnedStackBounds);
+            }
+        }
+    };
+
     // Behaviour states
     private boolean mIsTappingThrough;
     private boolean mIsMinimized;
@@ -193,14 +206,14 @@
         mTouchState = new PipTouchState(mViewConfig);
         mFlingAnimationUtils = new FlingAnimationUtils(context, 2f);
         mGestures = new PipTouchGesture[] {
-                mDragToDismissGesture, mDefaultMovementGesture
+                mDefaultMovementGesture
         };
         mMotionHelper = new PipMotionHelper(BackgroundThread.getHandler());
         registerInputConsumer();
         setSnapToEdge(true);
 
         // Register any tuner settings changes
-        TunerService.get(context).addTunable(this, TUNER_KEY_DRAG_TO_DISMISS,
+        Dependency.get(TunerService.class).addTunable(this, TUNER_KEY_DRAG_TO_DISMISS,
                 TUNER_KEY_ALLOW_MINIMIZE);
     }
 
@@ -521,6 +534,9 @@
     private void movePinnedStack(Rect bounds) {
         if (!bounds.equals(mPinnedStackBounds)) {
             mPinnedStackBounds.set(bounds);
+            if (mEnableDragToDismiss) {
+                mDismissViewController.updateDismissTarget(bounds);
+            }
             mMotionHelper.resizeToBounds(mPinnedStackBounds);
         }
     }
@@ -563,57 +579,25 @@
     }
 
     /**
-     * Gesture controlling dragging over a target to dismiss the PIP.
-     */
-    private PipTouchGesture mDragToDismissGesture = new PipTouchGesture() {
-        @Override
-        public void onDown(PipTouchState touchState) {
-            if (mEnableDragToDismiss) {
-                // TODO: Consider setting a timer such at after X time, we show the dismiss
-                //       target if the user hasn't already dragged some distance
-                mDismissViewController.createDismissTarget();
-            }
-        }
-
-        @Override
-        boolean onMove(PipTouchState touchState) {
-            if (mEnableDragToDismiss && touchState.startedDragging()) {
-                mDismissViewController.showDismissTarget();
-            }
-            return false;
-        }
-
-        @Override
-        public boolean onUp(PipTouchState touchState) {
-            if (mEnableDragToDismiss) {
-                try {
-                    if (touchState.isDragging()) {
-                        Rect dismissBounds = mDismissViewController.getDismissBounds();
-                        PointF lastTouch = touchState.getLastTouchPosition();
-                        if (dismissBounds.contains((int) lastTouch.x, (int) lastTouch.y)) {
-                            animateDismissPinnedStack(dismissBounds);
-                            MetricsLogger.action(mContext,
-                                    MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
-                                            METRIC_VALUE_DISMISSED_BY_DRAG);
-                            return true;
-                        }
-                    }
-                } finally {
-                    mDismissViewController.destroyDismissTarget();
-                }
-            }
-            return false;
-        }
-    };
-
-    /**** Gestures ****/
-
-    /**
      * Gesture controlling normal movement of the PIP.
      */
     private PipTouchGesture mDefaultMovementGesture = new PipTouchGesture() {
+
+        @Override
+        public void onDown(PipTouchState touchState) {
+            if (mEnableDragToDismiss) {
+                mDismissViewController.createDismissTarget();
+                mHandler.postDelayed(mShowDismissAffordance, SHOW_DISMISS_AFFORDANCE_DELAY);
+            }
+        }
+
         @Override
         boolean onMove(PipTouchState touchState) {
+            if (touchState.startedDragging() && mEnableDragToDismiss) {
+                mHandler.removeCallbacks(mShowDismissAffordance);
+                mDismissViewController.showDismissTarget(mPinnedStackBounds);
+            }
+
             if (touchState.isDragging()) {
                 // Move the pinned stack freely
                 PointF lastDelta = touchState.getLastTouchDelta();
@@ -635,6 +619,23 @@
 
         @Override
         public boolean onUp(PipTouchState touchState) {
+            try {
+                if (mEnableDragToDismiss) {
+                    mHandler.removeCallbacks(mShowDismissAffordance);
+                    PointF vel = mTouchState.getVelocity();
+                    final float velocity = PointF.length(vel.x, vel.y);
+                    if (touchState.isDragging()
+                            && velocity < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
+                        if (mDismissViewController.shouldDismiss(mPinnedStackBounds)) {
+                            Rect dismissBounds = mDismissViewController.getDismissBounds();
+                            animateDismissPinnedStack(dismissBounds);
+                            return true;
+                        }
+                    }
+                }
+            } finally {
+                mDismissViewController.destroyDismissTarget();
+            }
             if (touchState.isDragging()) {
                 PointF vel = mTouchState.getVelocity();
                 if (!mIsMinimized && (shouldMinimizedPinnedStack()
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 82ec69d..09ce2ad 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -145,16 +145,16 @@
     }
 
     private void showInvalidChargerNotification() {
-        final Notification.Builder nb = new Notification.Builder(mContext)
-                .setSmallIcon(R.drawable.ic_power_low)
-                .setWhen(0)
-                .setShowWhen(false)
-                .setOngoing(true)
-                .setContentTitle(mContext.getString(R.string.invalid_charger_title))
-                .setContentText(mContext.getString(R.string.invalid_charger_text))
-                .setChannel(NotificationChannels.ALERTS)
-                .setColor(mContext.getColor(
-                        com.android.internal.R.color.system_notification_accent_color));
+        final Notification.Builder nb =
+                new Notification.Builder(mContext, NotificationChannels.ALERTS)
+                        .setSmallIcon(R.drawable.ic_power_low)
+                        .setWhen(0)
+                        .setShowWhen(false)
+                        .setOngoing(true)
+                        .setContentTitle(mContext.getString(R.string.invalid_charger_title))
+                        .setContentText(mContext.getString(R.string.invalid_charger_text))
+                        .setColor(mContext.getColor(
+                                com.android.internal.R.color.system_notification_accent_color));
         SystemUI.overrideNotificationAppName(mContext, nb);
         final Notification n = nb.build();
         mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, UserHandle.ALL);
@@ -164,19 +164,19 @@
     private void showWarningNotification() {
         final int textRes = R.string.battery_low_percent_format;
         final String percentage = NumberFormat.getPercentInstance().format((double) mBatteryLevel / 100.0);
-        final Notification.Builder nb = new Notification.Builder(mContext)
-                .setSmallIcon(R.drawable.ic_power_low)
-                // Bump the notification when the bucket dropped.
-                .setWhen(mBucketDroppedNegativeTimeMs)
-                .setShowWhen(false)
-                .setContentTitle(mContext.getString(R.string.battery_low_title))
-                .setContentText(mContext.getString(textRes, percentage))
-                .setOnlyAlertOnce(true)
-                .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
-                .setChannel(NotificationChannels.ALERTS)
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setColor(mContext.getColor(
-                        com.android.internal.R.color.battery_saver_mode_color));
+        final Notification.Builder nb =
+                new Notification.Builder(mContext, NotificationChannels.ALERTS)
+                        .setSmallIcon(R.drawable.ic_power_low)
+                        // Bump the notification when the bucket dropped.
+                        .setWhen(mBucketDroppedNegativeTimeMs)
+                        .setShowWhen(false)
+                        .setContentTitle(mContext.getString(R.string.battery_low_title))
+                        .setContentText(mContext.getString(textRes, percentage))
+                        .setOnlyAlertOnce(true)
+                        .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_WARNING))
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setColor(mContext.getColor(
+                                com.android.internal.R.color.battery_saver_mode_color));
         if (hasBatterySettings()) {
             nb.setContentIntent(pendingBroadcast(ACTION_SHOW_BATTERY_SETTINGS));
         }
@@ -235,18 +235,18 @@
             return;
         }
         mTempWarning = true;
-        final Notification.Builder nb = new Notification.Builder(mContext)
-                .setSmallIcon(R.drawable.ic_device_thermostat_24)
-                .setWhen(0)
-                .setShowWhen(false)
-                .setContentTitle(mContext.getString(R.string.high_temp_title))
-                .setContentText(mContext.getString(R.string.high_temp_notif_message))
-                .setChannel(NotificationChannels.ALERTS)
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setContentIntent(pendingBroadcast(ACTION_CLICKED_TEMP_WARNING))
-                .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_TEMP_WARNING))
-                .setColor(mContext.getColor(
-                        com.android.internal.R.color.battery_saver_mode_color));
+        final Notification.Builder nb =
+                new Notification.Builder(mContext, NotificationChannels.ALERTS)
+                        .setSmallIcon(R.drawable.ic_device_thermostat_24)
+                        .setWhen(0)
+                        .setShowWhen(false)
+                        .setContentTitle(mContext.getString(R.string.high_temp_title))
+                        .setContentText(mContext.getString(R.string.high_temp_notif_message))
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setContentIntent(pendingBroadcast(ACTION_CLICKED_TEMP_WARNING))
+                        .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_TEMP_WARNING))
+                        .setColor(mContext.getColor(
+                                com.android.internal.R.color.battery_saver_mode_color));
         SystemUI.overrideNotificationAppName(mContext, nb);
         final Notification n = nb.build();
         mNoMan.notifyAsUser(TAG_TEMPERATURE, SystemMessage.NOTE_HIGH_TEMP, n, UserHandle.ALL);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 615063c..c85f83b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -20,6 +20,7 @@
 import android.view.View.OnLayoutChangeListener;
 import android.widget.TextView;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.PagedTileLayout.PageListener;
 import com.android.systemui.qs.QSPanel.QSTileLayout;
@@ -105,7 +106,7 @@
 
     @Override
     public void onViewAttachedToWindow(View v) {
-        TunerService.get(mQs.getContext()).addTunable(this, ALLOW_FANCY_ANIMATION,
+        Dependency.get(TunerService.class).addTunable(this, ALLOW_FANCY_ANIMATION,
                 MOVE_FULL_ROWS, QuickQSPanel.NUM_QUICK_TILES);
     }
 
@@ -114,7 +115,7 @@
         if (mHost != null) {
             mHost.removeCallback(this);
         }
-        TunerService.get(mQs.getContext()).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index c8f1670..95e0301 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -74,8 +74,14 @@
         mContainer = (QSContainerImpl) view;
 
         mQSDetail.setQsPanel(mQSPanel, mHeader);
-        mQSAnimator = new QSAnimator(this, (QuickQSPanel) mHeader.findViewById(R.id.quick_qs_panel),
-                mQSPanel);
+
+        // If the quick settings row is not shown, then there is no need for the animation from
+        // the row to the full QS panel.
+        if (getResources().getBoolean(R.bool.config_showQuickSettingsRow)) {
+            mQSAnimator = new QSAnimator(this,
+                    (QuickQSPanel) mHeader.findViewById(R.id.quick_qs_panel), mQSPanel);
+        }
+
         mQSCustomizer = (QSCustomizer) view.findViewById(R.id.qs_customize);
         mQSCustomizer.setQs(this);
     }
@@ -89,7 +95,10 @@
         super.onConfigurationChanged(newConfig);
         if (newConfig.getLayoutDirection() != mLayoutDirection) {
             mLayoutDirection = newConfig.getLayoutDirection();
-            mQSAnimator.onRtlChanged();
+
+            if (mQSAnimator != null) {
+                mQSAnimator.onRtlChanged();
+            }
         }
     }
 
@@ -108,7 +117,10 @@
         mQSPanel.setHost(qsh, mQSCustomizer);
         mHeader.setQSPanel(mQSPanel);
         mQSDetail.setHost(qsh);
-        mQSAnimator.setHost(qsh);
+
+        if (mQSAnimator != null) {
+            mQSAnimator.setHost(qsh);
+        }
     }
 
     private void updateQsState() {
@@ -155,7 +167,11 @@
     public void setKeyguardShowing(boolean keyguardShowing) {
         if (DEBUG) Log.d(TAG, "setKeyguardShowing " + keyguardShowing);
         mKeyguardShowing = keyguardShowing;
-        mQSAnimator.setOnKeyguard(keyguardShowing);
+
+        if (mQSAnimator != null) {
+            mQSAnimator.setOnKeyguard(keyguardShowing);
+        }
+
         updateQsState();
     }
 
@@ -187,7 +203,10 @@
         mHeader.setExpansion(mKeyguardShowing ? 1 : expansion);
         mQSPanel.setTranslationY(translationScaleY * mQSPanel.getHeight());
         mQSDetail.setFullyExpanded(expansion == 1);
-        mQSAnimator.setPosition(expansion);
+
+        if (mQSAnimator != null) {
+            mQSAnimator.setPosition(expansion);
+        }
 
         // Set bounds on the QS panel so it doesn't run over the header.
         mQsBounds.top = (int) (mQSPanel.getHeight() * (1 - expansion));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index e004828..504678c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -29,6 +29,7 @@
 import android.widget.LinearLayout;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
@@ -126,7 +127,7 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        TunerService.get(mContext).addTunable(this, QS_SHOW_BRIGHTNESS);
+        Dependency.get(TunerService.class).addTunable(this, QS_SHOW_BRIGHTNESS);
         if (mHost != null) {
             setTiles(mHost.getTiles());
         }
@@ -134,8 +135,10 @@
 
     @Override
     protected void onDetachedFromWindow() {
-        TunerService.get(mContext).removeTunable(this);
-        mHost.removeCallback(this);
+        Dependency.get(TunerService.class).removeTunable(this);
+        if (mHost != null) {
+            mHost.removeCallback(this);
+        }
         for (TileRecord record : mRecords) {
             record.tile.removeCallbacks();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 16b351e..d789b44 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -24,6 +24,7 @@
 import android.widget.LinearLayout;
 import android.widget.Space;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.qs.QSTile.SignalState;
 import com.android.systemui.qs.QSTile.State;
@@ -62,13 +63,13 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        TunerService.get(mContext).addTunable(mNumTiles, NUM_QUICK_TILES);
+        Dependency.get(TunerService.class).addTunable(mNumTiles, NUM_QUICK_TILES);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        TunerService.get(mContext).removeTunable(mNumTiles);
+        Dependency.get(TunerService.class).removeTunable(mNumTiles);
     }
 
     public void setQSPanelAndHeader(QSPanel fullPanel, View header) {
@@ -141,7 +142,7 @@
     };
 
     public int getNumQuickTiles(Context context) {
-        return TunerService.get(context).getValue(NUM_QUICK_TILES, 6);
+        return Dependency.get(TunerService.class).getValue(NUM_QUICK_TILES, 6);
     }
 
     private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index 3afbc35..dea56aa1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -237,6 +237,8 @@
         i.setPackage(mComponent.getPackageName());
         i = resolveIntent(i);
         if (i != null) {
+            i.putExtra(TileService.EXTRA_COMPONENT, mComponent);
+            i.putExtra(TileService.EXTRA_STATE, mTile.getState());
             return i;
         }
         return new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 8d18a75..e635162 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.recents;
 
+import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS;
+
 import android.app.ActivityManager;
 import android.app.UiModeManager;
 import android.content.ComponentName;
@@ -38,6 +40,7 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.view.Display;
+import android.view.WindowManager;
 import android.widget.Toast;
 
 import com.android.internal.logging.MetricsLogger;
@@ -59,6 +62,7 @@
 import com.android.systemui.recents.model.RecentsTaskLoader;
 import com.android.systemui.recents.tv.RecentsTvImpl;
 import com.android.systemui.stackdivider.Divider;
+import com.android.systemui.statusbar.CommandQueue;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -70,7 +74,7 @@
  * users.
  */
 public class Recents extends SystemUI
-        implements RecentsComponent {
+        implements RecentsComponent, CommandQueue.Callbacks {
 
     private final static String TAG = "Recents";
     private final static boolean DEBUG = false;
@@ -229,6 +233,7 @@
         if (sSystemServicesProxy.isSystemUser(processUser)) {
             // For the system user, initialize an instance of the interface that we can pass to the
             // secondary user
+            getComponent(CommandQueue.class).addCallbacks(this);
             mSystemToUserCallbacks = new RecentsSystemUser(mContext, mImpl);
         } else {
             // For the secondary user, bind to the primary user's service to get a persistent
@@ -247,7 +252,7 @@
      * Shows the Recents.
      */
     @Override
-    public void showRecents(boolean triggeredFromAltTab, boolean fromHome) {
+    public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
         if (!isUserSetup()) {
@@ -257,6 +262,10 @@
         if (proxyToOverridePackage(ACTION_SHOW_RECENTS)) {
             return;
         }
+        try {
+            ActivityManager.getService().closeSystemDialogs(SYSTEM_DIALOG_REASON_RECENT_APPS);
+        } catch (RemoteException e) {
+        }
 
         int recentsGrowTarget = getComponent(Divider.class).getView().growsRecents();
 
@@ -287,7 +296,7 @@
      * Hides the Recents.
      */
     @Override
-    public void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+    public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
         if (!isUserSetup()) {
@@ -318,6 +327,11 @@
         }
     }
 
+    @Override
+    public void toggleRecentApps() {
+        toggleRecents(mContext.getSystemService(WindowManager.class).getDefaultDisplay());
+    }
+
     /**
      * Toggles the Recents activity.
      */
@@ -387,7 +401,7 @@
     }
 
     @Override
-    public void cancelPreloadingRecents() {
+    public void cancelPreloadRecentApps() {
         // Ensure the device has been provisioned before allowing the user to interact with
         // recents
         if (!isUserSetup()) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 9a8b267..8091199 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -53,6 +53,7 @@
 import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.IterateRecentsEvent;
+import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestEvent;
 import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
 import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
 import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
@@ -75,6 +76,7 @@
 import com.android.systemui.recents.views.TaskStackViewScroller;
 import com.android.systemui.recents.views.TaskViewHeader;
 import com.android.systemui.recents.views.TaskViewTransform;
+import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
 import com.android.systemui.stackdivider.DividerView;
 import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -311,15 +313,23 @@
                 RecentsConfiguration config = Recents.getConfiguration();
                 RecentsActivityLaunchState launchState = config.getLaunchState();
                 if (!launchState.launchedWithAltTab) {
-                    // If the user taps quickly
-                    if (!debugFlags.isPagingEnabled() ||
-                            (ViewConfiguration.getDoubleTapMinTime() < elapsedTime &&
-                                    elapsedTime < ViewConfiguration.getDoubleTapTimeout())) {
-                        // Launch the next focused task
-                        EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
+                    // Has the user tapped quickly?
+                    boolean isQuickTap = ViewConfiguration.getDoubleTapMinTime() < elapsedTime &&
+                            elapsedTime < ViewConfiguration.getDoubleTapTimeout();
+                    if (Recents.getConfiguration().isGridEnabled) {
+                        if (isQuickTap) {
+                            EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
+                        } else {
+                            EventBus.getDefault().post(new LaunchMostRecentTaskRequestEvent());
+                        }
                     } else {
-                        // Notify recents to move onto the next task
-                        EventBus.getDefault().post(new IterateRecentsEvent());
+                        if (!debugFlags.isPagingEnabled() || isQuickTap) {
+                            // Launch the next focused task
+                            EventBus.getDefault().post(new LaunchNextTaskRequestEvent());
+                        } else {
+                            // Notify recents to move onto the next task
+                            EventBus.getDefault().post(new IterateRecentsEvent());
+                        }
                     }
                 } else {
                     // If the user has toggled it too quickly, then just eat up the event here (it's
@@ -628,10 +638,21 @@
             stackLayout.initialize(displayRect, windowRect, mTaskStackBounds,
                     TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
             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();
+                }
+            }
 
-            Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
-            if (!taskViewBounds.isEmpty()) {
-                int taskViewWidth = taskViewBounds.width();
+            if (taskViewWidth > 0) {
                 synchronized (mHeaderBarLock) {
                     if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
                             mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
@@ -743,11 +764,7 @@
             Task toTask = new Task();
             TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask,
                     windowOverrideRect);
-            // When using a grid layout, the header is already visible on screen at the target
-            // location, making it unnecessary to draw it in the transition thumbnail.
-            Bitmap thumbnail = stackView.useGridLayout()
-                    ? mThumbTransitionBitmapCache.createAshmemBitmap()
-                    : drawThumbnailTransitionBitmap(toTask, toTransform,
+            Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform,
                             mThumbTransitionBitmapCache);
             if (thumbnail != null) {
                 RectF toTaskRect = toTransform.rect;
diff --git a/core/java/android/service/autofill/CallbackHelper.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchMostRecentTaskRequestEvent.java
similarity index 68%
copy from core/java/android/service/autofill/CallbackHelper.java
copy to packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchMostRecentTaskRequestEvent.java
index ded8f97..24913a4 100644
--- a/core/java/android/service/autofill/CallbackHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/LaunchMostRecentTaskRequestEvent.java
@@ -13,18 +13,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.service.autofill;
 
-import java.io.PrintWriter;
+package com.android.systemui.recents.events.activity;
 
-final class CallbackHelper {
+import com.android.systemui.recents.events.EventBus;
 
-    static interface Dumpable {
-        void dump(String prefix, PrintWriter pw);
-        void setFinalizer(Finalizer f);
-    }
-
-    static interface Finalizer {
-        void gone();
-    }
+/**
+ * This event is sent to request that the most recent task is launched.
+ */
+public class LaunchMostRecentTaskRequestEvent extends EventBus.Event {
+    // Simple event
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index a2ee4c5..f1314aba 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -619,7 +619,7 @@
         postAnimationTrigger.addLastDecrementRunnable(() -> {
             mStackView.getTouchHandler().onChildDismissed(deleteTaskView);
         });
-        deleteTaskView.animate().setDuration(300).scaleX(0).scaleY(0).alpha(0).setListener(
+        deleteTaskView.animate().setDuration(300).scaleX(0.9f).scaleY(0.9f).alpha(0).setListener(
                 new AnimatorListenerAdapter() {
                     @Override
                     public void onAnimationEnd(Animator animation) {
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 8ae7a83..0160eb7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -64,6 +64,7 @@
 import com.android.systemui.recents.events.activity.HideRecentsEvent;
 import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
 import com.android.systemui.recents.events.activity.IterateRecentsEvent;
+import com.android.systemui.recents.events.activity.LaunchMostRecentTaskRequestEvent;
 import com.android.systemui.recents.events.activity.LaunchNextTaskRequestEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskEvent;
 import com.android.systemui.recents.events.activity.LaunchTaskStartedEvent;
@@ -95,6 +96,7 @@
 import com.android.systemui.recents.model.TaskStack;
 
 import com.android.systemui.recents.views.grid.GridTaskView;
+import com.android.systemui.recents.views.grid.TaskGridLayoutAlgorithm;
 import com.android.systemui.recents.views.grid.TaskViewFocusFrame;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -446,6 +448,11 @@
         return mLayoutAlgorithm;
     }
 
+    /** Returns the grid algorithm for this task stack. */
+    public TaskGridLayoutAlgorithm getGridAlgorithm() {
+        return mLayoutAlgorithm.mTaskGridLayoutAlgorithm;
+    }
+
     /**
      * Returns the touch handler for this task stack.
      */
@@ -1733,6 +1740,13 @@
         mUIDozeTrigger.stopDozing();
     }
 
+    public final void onBusEvent(LaunchMostRecentTaskRequestEvent event) {
+        if (mStack.getTaskCount() > 0) {
+            Task mostRecentTask = mStack.getStackFrontMostTask(true /* includeFreefromTasks */);
+            launchTask(mostRecentTask);
+        }
+    }
+
     public final void onBusEvent(LaunchNextTaskRequestEvent event) {
         if (mAwaitingFirstLayout) {
             mLaunchNextAfterFirstMeasure = true;
@@ -1741,29 +1755,7 @@
 
         final Task launchTask = mStack.getNextLaunchTarget();
         if (launchTask != null) {
-            // Stop all animations
-            cancelAllTaskViewAnimations();
-
-            float curScroll = mStackScroller.getStackScroll();
-            float targetScroll = mLayoutAlgorithm.getStackScrollForTaskAtInitialOffset(launchTask);
-            float absScrollDiff = Math.abs(targetScroll - curScroll);
-            if (getChildViewForTask(launchTask) == null || absScrollDiff > 0.35f) {
-                int duration = (int) (LAUNCH_NEXT_SCROLL_BASE_DURATION +
-                        absScrollDiff * LAUNCH_NEXT_SCROLL_INCR_DURATION);
-                mStackScroller.animateScroll(targetScroll,
-                        duration, new Runnable() {
-                            @Override
-                            public void run() {
-                                EventBus.getDefault().send(new LaunchTaskEvent(
-                                        getChildViewForTask(launchTask), launchTask, null,
-                                        INVALID_STACK_ID, false /* screenPinningRequested */));
-                            }
-                        });
-            } else {
-                EventBus.getDefault().send(new LaunchTaskEvent(getChildViewForTask(launchTask),
-                        launchTask, null, INVALID_STACK_ID, false /* screenPinningRequested */));
-            }
-
+            launchTask(launchTask);
             MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_LAUNCH_PREVIOUS_TASK,
                     launchTask.key.getComponent().toString());
         } else if (mStack.getTaskCount() == 0) {
@@ -2215,6 +2207,31 @@
         return -1;
     }
 
+    private void launchTask(Task task) {
+        // Stop all animations
+        cancelAllTaskViewAnimations();
+
+        float curScroll = mStackScroller.getStackScroll();
+        float targetScroll = mLayoutAlgorithm.getStackScrollForTaskAtInitialOffset(task);
+        float absScrollDiff = Math.abs(targetScroll - curScroll);
+        if (getChildViewForTask(task) == null || absScrollDiff > 0.35f) {
+            int duration = (int) (LAUNCH_NEXT_SCROLL_BASE_DURATION +
+                    absScrollDiff * LAUNCH_NEXT_SCROLL_INCR_DURATION);
+            mStackScroller.animateScroll(targetScroll,
+                    duration, new Runnable() {
+                        @Override
+                        public void run() {
+                            EventBus.getDefault().send(new LaunchTaskEvent(
+                                    getChildViewForTask(task), task, null,
+                                    INVALID_STACK_ID, false /* screenPinningRequested */));
+                        }
+                    });
+        } else {
+            EventBus.getDefault().send(new LaunchTaskEvent(getChildViewForTask(task),
+                    task, null, INVALID_STACK_ID, false /* screenPinningRequested */));
+        }
+    }
+
     /**
      * Check whether we should use the grid layout.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 7135caf..9a4b45a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -178,20 +178,19 @@
                 .bigPicture(picture.createAshmemBitmap());
 
         // The public notification will show similar info but with the actual screenshot omitted
-        mPublicNotificationBuilder = new Notification.Builder(context)
-                .setChannel(NotificationChannels.SCREENSHOTS)
-                .setContentTitle(r.getString(R.string.screenshot_saving_title))
-                .setContentText(r.getString(R.string.screenshot_saving_text))
-                .setSmallIcon(R.drawable.stat_notify_image)
-                .setCategory(Notification.CATEGORY_PROGRESS)
-                .setWhen(now)
-                .setShowWhen(true)
-                .setColor(r.getColor(
-                        com.android.internal.R.color.system_notification_accent_color));
+        mPublicNotificationBuilder =
+                new Notification.Builder(context, NotificationChannels.SCREENSHOTS)
+                        .setContentTitle(r.getString(R.string.screenshot_saving_title))
+                        .setContentText(r.getString(R.string.screenshot_saving_text))
+                        .setSmallIcon(R.drawable.stat_notify_image)
+                        .setCategory(Notification.CATEGORY_PROGRESS)
+                        .setWhen(now)
+                        .setShowWhen(true)
+                        .setColor(r.getColor(
+                                com.android.internal.R.color.system_notification_accent_color));
         SystemUI.overrideNotificationAppName(context, mPublicNotificationBuilder);
 
-        mNotificationBuilder = new Notification.Builder(context)
-            .setChannel(NotificationChannels.SCREENSHOTS)
+        mNotificationBuilder = new Notification.Builder(context, NotificationChannels.SCREENSHOTS)
             .setTicker(r.getString(R.string.screenshot_saving_ticker)
                     + (mTickerAddSpace ? " " : ""))
             .setContentTitle(r.getString(R.string.screenshot_saving_title))
@@ -335,7 +334,6 @@
 
             // Update the text and the icon for the existing notification
             mPublicNotificationBuilder
-                    .setChannel(NotificationChannels.SCREENSHOTS)
                     .setContentTitle(r.getString(R.string.screenshot_saved_title))
                     .setContentText(r.getString(R.string.screenshot_saved_text))
                     .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0))
@@ -344,7 +342,6 @@
                     .setColor(context.getColor(
                             com.android.internal.R.color.system_notification_accent_color));
             mNotificationBuilder
-                .setChannel(NotificationChannels.SCREENSHOTS)
                 .setContentTitle(r.getString(R.string.screenshot_saved_title))
                 .setContentText(r.getString(R.string.screenshot_saved_text))
                 .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0))
@@ -858,7 +855,7 @@
         String errorMsg = r.getString(msgResId);
 
         // Repurpose the existing notification to notify the user of the error
-        Notification.Builder b = new Notification.Builder(context)
+        Notification.Builder b = new Notification.Builder(context, NotificationChannels.ALERTS)
             .setTicker(r.getString(R.string.screenshot_failed_title))
             .setContentTitle(r.getString(R.string.screenshot_failed_title))
             .setContentText(errorMsg)
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 19eefec..7699bb9 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -107,7 +107,7 @@
                 List<ActivityManager.RecentTaskInfo> taskList =
                         SystemServicesProxy.getInstance(mContext).getRecentTasks(1,
                                 UserHandle.USER_CURRENT, false, new ArraySet<>());
-                recents.showRecents(
+                recents.showRecentApps(
                         false /* triggeredFromAltTab */,
                         false /* fromHome */);
                 if (!taskList.isEmpty()) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index b9a0f74..0b09acc 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -72,6 +72,10 @@
         return mMinimized;
     }
 
+    public boolean isHomeStackResizable() {
+        return mHomeStackResizable;
+    }
+
     private void addDivider(Configuration configuration) {
         mView = (DividerView)
                 LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null);
@@ -119,6 +123,7 @@
         mView.post(new Runnable() {
             @Override
             public void run() {
+                mHomeStackResizable = isHomeStackResizable;
                 if (mMinimized != minimized) {
                     mMinimized = minimized;
                     updateTouchable();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 49035ba..6f59fe2 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -1241,7 +1241,8 @@
 
     public final void onBusEvent(UndockingTaskEvent undockingTaskEvent) {
         int dockSide = mWindowManagerProxy.getDockSide();
-        if (dockSide != WindowManager.DOCKED_INVALID && !mDockedStackMinimized) {
+        if (dockSide != WindowManager.DOCKED_INVALID && (mHomeStackResizable
+                || !mDockedStackMinimized)) {
             startDragging(false /* animate */, false /* touching */);
             SnapTarget target = dockSideTopLeft(dockSide)
                     ? mSnapAlgorithm.getDismissEndTarget()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index b9ed725..0bd6491 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -38,7 +38,6 @@
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.statusbar.notification.FakeShadowView;
 import com.android.systemui.statusbar.notification.NotificationUtils;
-import com.android.systemui.statusbar.policy.AccessibilityController;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 
@@ -106,7 +105,7 @@
     private boolean mDimmed;
     private boolean mDark;
 
-    private int mBgTint = NO_COLOR;
+    protected int mBgTint = NO_COLOR;
     private float mBgAlpha = 1f;
 
     /**
@@ -140,8 +139,6 @@
     private ValueAnimator mBackgroundColorAnimator;
     private float mAppearAnimationFraction = -1.0f;
     private float mAppearAnimationTranslation;
-    private boolean mShowingLegacyBackground;
-    private final int mLegacyColor;
     private final int mNormalColor;
     private final int mLowPriorityColor;
     private boolean mIsBelowSpeedBump;
@@ -192,7 +189,6 @@
         mSlowOutLinearInInterpolator = new PathInterpolator(0.8f, 0.0f, 1.0f, 1.0f);
         setClipChildren(false);
         setClipToPadding(false);
-        mLegacyColor = context.getColor(R.color.notification_legacy_background_color);
         mNormalColor = context.getColor(R.color.notification_material_background_color);
         mLowPriorityColor = context.getColor(
                 R.color.notification_material_background_low_priority_color);
@@ -489,11 +485,6 @@
         updateOutlineAlpha();
     }
 
-    public void setShowingLegacyBackground(boolean showing) {
-        mShowingLegacyBackground = showing;
-        updateBackgroundTint();
-    }
-
     @Override
     public void setBelowSpeedBump(boolean below) {
         super.setBelowSpeedBump(below);
@@ -950,8 +941,6 @@
         }
         if (withTint && mBgTint != NO_COLOR) {
             return mBgTint;
-        } else if (mShowingLegacyBackground) {
-            return mLegacyColor;
         } else if (mIsBelowSpeedBump) {
             return mLowPriorityColor;
         } else {
@@ -962,8 +951,6 @@
     protected int getRippleColor() {
         if (mBgTint != 0) {
             return mTintedRippleColor;
-        } else if (mShowingLegacyBackground) {
-            return mTintedRippleColor;
         } else if (mIsBelowSpeedBump) {
             return mLowPriorityRippleColor;
         } else {
@@ -1009,7 +996,6 @@
     public void reset() {
         setTintColor(0);
         resetBackgroundAlpha();
-        setShowingLegacyBackground(false);
         setBelowSpeedBump(false);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 477701c..9245df0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -63,9 +63,6 @@
     private static final int MSG_SET_WINDOW_STATE              = 12 << MSG_SHIFT;
     private static final int MSG_SHOW_RECENT_APPS              = 13 << MSG_SHIFT;
     private static final int MSG_HIDE_RECENT_APPS              = 14 << MSG_SHIFT;
-    private static final int MSG_BUZZ_BEEP_BLINKED             = 15 << MSG_SHIFT;
-    private static final int MSG_NOTIFICATION_LIGHT_OFF        = 16 << MSG_SHIFT;
-    private static final int MSG_NOTIFICATION_LIGHT_PULSE      = 17 << MSG_SHIFT;
     private static final int MSG_SHOW_SCREEN_PIN_REQUEST       = 18 << MSG_SHIFT;
     private static final int MSG_APP_TRANSITION_PENDING        = 19 << MSG_SHIFT;
     private static final int MSG_APP_TRANSITION_CANCELLED      = 20 << MSG_SHIFT;
@@ -121,9 +118,6 @@
         default void toggleKeyboardShortcutsMenu(int deviceId) { }
         default void cancelPreloadRecentApps() { }
         default void setWindowState(int window, int state) { }
-        default void buzzBeepBlinked() { }
-        default void notificationLightOff() { }
-        default void notificationLightPulse(int argb, int onMillis, int offMillis) { }
         default void showScreenPinningRequest(int taskId) { }
         default void appTransitionPending() { }
         default void appTransitionCancelled() { }
@@ -313,26 +307,6 @@
         }
     }
 
-    public void buzzBeepBlinked() {
-        synchronized (mLock) {
-            mHandler.removeMessages(MSG_BUZZ_BEEP_BLINKED);
-            mHandler.sendEmptyMessage(MSG_BUZZ_BEEP_BLINKED);
-        }
-    }
-
-    public void notificationLightOff() {
-        synchronized (mLock) {
-            mHandler.sendEmptyMessage(MSG_NOTIFICATION_LIGHT_OFF);
-        }
-    }
-
-    public void notificationLightPulse(int argb, int onMillis, int offMillis) {
-        synchronized (mLock) {
-            mHandler.obtainMessage(MSG_NOTIFICATION_LIGHT_PULSE, onMillis, offMillis, argb)
-                    .sendToTarget();
-        }
-    }
-
     public void showScreenPinningRequest(int taskId) {
         synchronized (mLock) {
             mHandler.obtainMessage(MSG_SHOW_SCREEN_PIN_REQUEST, taskId, 0, null)
@@ -524,21 +498,6 @@
                         mCallbacks.get(i).setWindowState(msg.arg1, msg.arg2);
                     }
                     break;
-                case MSG_BUZZ_BEEP_BLINKED:
-                    for (int i = 0; i < mCallbacks.size(); i++) {
-                        mCallbacks.get(i).buzzBeepBlinked();
-                    }
-                    break;
-                case MSG_NOTIFICATION_LIGHT_OFF:
-                    for (int i = 0; i < mCallbacks.size(); i++) {
-                        mCallbacks.get(i).notificationLightOff();
-                    }
-                    break;
-                case MSG_NOTIFICATION_LIGHT_PULSE:
-                    for (int i = 0; i < mCallbacks.size(); i++) {
-                        mCallbacks.get(i).notificationLightPulse((Integer) msg.obj, msg.arg1, msg.arg2);
-                    }
-                    break;
                 case MSG_SHOW_SCREEN_PIN_REQUEST:
                     for (int i = 0; i < mCallbacks.size(); i++) {
                         mCallbacks.get(i).showScreenPinningRequest(msg.arg1);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index d1245b1..2e9c7fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -77,6 +77,7 @@
     private int mMaxHeadsUpHeightLegacy;
     private int mMaxHeadsUpHeight;
     private int mNotificationMinHeight;
+    private int mNotificationMinHeightLarge;
     private int mNotificationMaxHeight;
     private int mNotificationAmbientHeight;
     private int mIncreasedPaddingBetweenElements;
@@ -207,6 +208,7 @@
     private Runnable mOnDismissRunnable;
     private boolean mIsLowPriority;
     private boolean mIsColorized;
+    private boolean mUseIncreasedCollapsedHeight;
 
     @Override
     public boolean isGroupExpansionChanging() {
@@ -341,8 +343,14 @@
         boolean customView = layout.getContractedChild().getId()
                 != com.android.internal.R.id.status_bar_latest_event_content;
         boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
-        int minHeight = customView && beforeN && !mIsSummaryWithChildren ?
-                mNotificationMinHeightLegacy : mNotificationMinHeight;
+        int minHeight;
+        if (customView && beforeN && !mIsSummaryWithChildren) {
+            minHeight = mNotificationMinHeightLegacy;
+        } else if (mUseIncreasedCollapsedHeight && layout == mPrivateLayout) {
+            minHeight = mNotificationMinHeightLarge;
+        } else {
+            minHeight = mNotificationMinHeight;
+        }
         boolean headsUpCustom = layout.getHeadsUpChild() != null &&
                 layout.getHeadsUpChild().getId()
                         != com.android.internal.R.id.status_bar_latest_event_content;
@@ -979,6 +987,10 @@
         }
     }
 
+    public void setUseIncreasedCollapsedHeight(boolean use) {
+        mUseIncreasedCollapsedHeight = use;
+    }
+
     public interface ExpansionLogger {
         public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
     }
@@ -992,6 +1004,8 @@
     private void initDimens() {
         mNotificationMinHeightLegacy = getFontScaledHeight(R.dimen.notification_min_height_legacy);
         mNotificationMinHeight = getFontScaledHeight(R.dimen.notification_min_height);
+        mNotificationMinHeightLarge = getFontScaledHeight(
+                R.dimen.notification_min_height_large);
         mNotificationMaxHeight = getFontScaledHeight(R.dimen.notification_max_height);
         mNotificationAmbientHeight = getFontScaledHeight(R.dimen.notification_ambient_height);
         mMaxHeadsUpHeightLegacy = getFontScaledHeight(
@@ -1782,9 +1796,7 @@
         return mShowingPublic ? mPublicLayout : mPrivateLayout;
     }
 
-    @Override
     public void setShowingLegacyBackground(boolean showing) {
-        super.setShowingLegacyBackground(showing);
         for (NotificationContentView l : mLayouts) {
             l.setShowingLegacyBackground(showing);
         }
@@ -1868,14 +1880,14 @@
             } else if (isUserLocked()) {
                 return mChildrenContainer.getGroupExpandFraction();
             }
-        } else if (isColorized()) {
+        } else if (isColorized() && (!mIsLowPriority || isExpanded())) {
             return -1.0f;
         }
         return 0.0f;
     }
 
     private boolean isColorized() {
-        return mIsColorized;
+        return mIsColorized && mBgTint != NO_COLOR;
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index e0ddf13..57d2e1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -505,7 +505,8 @@
                     isTransitioningFromTo(VISIBLE_TYPE_HEADSUP, VISIBLE_TYPE_EXPANDED) ||
                     isTransitioningFromTo(VISIBLE_TYPE_EXPANDED, VISIBLE_TYPE_HEADSUP);
             boolean pinned = !isVisibleOrTransitioning(VISIBLE_TYPE_CONTRACTED)
-                    && (mIsHeadsUp || mHeadsUpAnimatingAway);
+                    && (mIsHeadsUp || mHeadsUpAnimatingAway)
+                    && !mContainingNotification.isOnKeyguard();
             if (transitioningBetweenHunAndExpanded || pinned) {
                 return Math.min(mHeadsUpChild.getHeight(), mExpandedChild.getHeight());
             }
@@ -611,7 +612,7 @@
     public int getMaxHeight() {
         if (mExpandedChild != null) {
             return mExpandedChild.getHeight();
-        } else if (mIsHeadsUp && mHeadsUpChild != null) {
+        } else if (mIsHeadsUp && mHeadsUpChild != null && !mContainingNotification.isOnKeyguard()) {
             return mHeadsUpChild.getHeight();
         }
         return mContractedChild.getHeight();
@@ -921,7 +922,8 @@
             return VISIBLE_TYPE_SINGLELINE;
         }
 
-        if ((mIsHeadsUp || mHeadsUpAnimatingAway) && mHeadsUpChild != null) {
+        if ((mIsHeadsUp || mHeadsUpAnimatingAway) && mHeadsUpChild != null
+                && !mContainingNotification.isOnKeyguard()) {
             if (viewHeight <= mHeadsUpChild.getHeight() || noExpandedChild) {
                 return VISIBLE_TYPE_HEADSUP;
             } else {
@@ -1174,7 +1176,7 @@
         mExpandable = expandable;
         // if the expanded child has the same height as the collapsed one we hide it.
         if (mExpandedChild != null && mExpandedChild.getHeight() != 0) {
-            if ((!mIsHeadsUp || mHeadsUpChild == null)) {
+            if (!mIsHeadsUp || mHeadsUpChild == null || mContainingNotification.isOnKeyguard()) {
                 if (mExpandedChild.getHeight() == mContractedChild.getHeight()) {
                     expandable = false;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index b49ba0c..f73a5ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -126,13 +126,13 @@
         }
 
         public boolean cacheContentViews(Context ctx, Notification updatedNotification,
-                boolean isLowPriority) {
+                boolean isLowPriority, boolean useIncreasedCollapsedView) {
             boolean applyInPlace = false;
             if (updatedNotification != null) {
                 final Notification.Builder updatedNotificationBuilder
                         = Notification.Builder.recoverBuilder(ctx, updatedNotification);
                 final RemoteViews newContentView = createContentView(updatedNotificationBuilder,
-                        isLowPriority);
+                        isLowPriority, useIncreasedCollapsedView);
                 final RemoteViews newBigContentView = createBigContentView(
                         updatedNotificationBuilder, isLowPriority);
                 final RemoteViews newHeadsUpContentView =
@@ -162,7 +162,8 @@
                 final Notification.Builder builder
                         = Notification.Builder.recoverBuilder(ctx, notification.getNotification());
 
-                cachedContentView = createContentView(builder, isLowPriority);
+                cachedContentView = createContentView(builder, isLowPriority,
+                        useIncreasedCollapsedView);
                 cachedBigContentView = createBigContentView(builder, isLowPriority);
                 cachedHeadsUpContentView = builder.createHeadsUpContentView();
                 cachedPublicContentView = builder.makePublicContentView();
@@ -188,11 +189,11 @@
         }
 
         private RemoteViews createContentView(Notification.Builder builder,
-                boolean isAmbient) {
-            if (isAmbient) {
+                boolean isLowPriority, boolean useLarge) {
+            if (isLowPriority) {
                 return builder.makeLowPriorityContentView(false /* useRegularSubtext */);
             }
-            return builder.createContentView();
+            return builder.createContentView(useLarge);
         }
 
         // Returns true if the RemoteViews are the same.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index fad63dd..355022f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -30,6 +30,7 @@
 
 import java.util.ArrayList;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.plugins.PluginListener;
@@ -82,10 +83,21 @@
     public NotificationMenuRow(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs);
-        PluginManager.getInstance(getContext()).addPluginListener(
+        mMenuItems.addAll(getDefaultNotificationMenuItems());
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        Dependency.get(PluginManager.class).addPluginListener(
                 NotificationMenuRowProvider.ACTION, this,
                 NotificationMenuRowProvider.VERSION, false /* Allow multiple */);
-        mMenuItems.addAll(getDefaultNotificationMenuItems());
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        Dependency.get(PluginManager.class).removePluginListener(this);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index e8e9d4e..2425076 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -68,6 +68,7 @@
     private float mMaxShelfEnd;
     private int mRelativeOffset;
     private boolean mInteractive;
+    private boolean mAnimationsEnabled = true;
 
     public NotificationShelf(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -388,12 +389,13 @@
 
         View rowIcon = row.getNotificationIcon();
         float notificationIconPosition = row.getTranslationY() + row.getContentTranslation();
-        if (usingLinearInterpolation) {
+        boolean stayingInShelf = row.isInShelf() && !row.isTransformingIntoShelf();
+        if (usingLinearInterpolation && !stayingInShelf) {
             // If we interpolate from the notification position, this might lead to a slightly
             // odd interpolation, since the notification position changes as well. Let's interpolate
             // from a fixed distance. We can only do this if we don't animate and the icon is
             // always in the interpolated positon.
-            notificationIconPosition = mMaxShelfEnd - getIntrinsicHeight() - iconTransformDistance;
+            notificationIconPosition = getTranslationY() - iconTransformDistance;
         }
         float notificationIconSize = 0.0f;
         int iconTopPadding;
@@ -426,7 +428,7 @@
             iconState.hidden = transitionAmount == 0.0f;
             iconState.alpha = alpha;
             iconState.yTranslation = iconYTranslation;
-            if (row.isInShelf() && !row.isTransformingIntoShelf()) {
+            if (stayingInShelf) {
                 iconState.iconAppearAmount = 1.0f;
                 iconState.alpha = 1.0f;
                 iconState.scaleX = 1.0f;
@@ -573,6 +575,15 @@
         mMaxShelfEnd = maxShelfEnd;
     }
 
+    public void setAnimationsEnabled(boolean enabled) {
+        mAnimationsEnabled = enabled;
+        mCollapsedIcons.setAnimationsEnabled(enabled);
+        if (!enabled) {
+            // we need to wait with enabling the animations until the first frame has passed
+            mShelfIcons.setAnimationsEnabled(false);
+        }
+    }
+
     private class ShelfState extends ExpandableViewState {
         private float openedAmount;
         private boolean hasItemsInStableShelf;
@@ -585,6 +596,7 @@
             setOpenedAmount(openedAmount);
             updateAppearance();
             setHasItemsInStableShelf(hasItemsInStableShelf);
+            mShelfIcons.setAnimationsEnabled(mAnimationsEnabled);
         }
 
         @Override
@@ -594,6 +606,7 @@
             setOpenedAmount(openedAmount);
             updateAppearance();
             setHasItemsInStableShelf(hasItemsInStableShelf);
+            mShelfIcons.setAnimationsEnabled(mAnimationsEnabled);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
index dba7130..f9d0cd6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScrimView.java
@@ -20,6 +20,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.content.Context;
+import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -29,6 +30,7 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.Interpolator;
+import com.android.systemui.R;
 
 /**
  * A view which can draw a scrim
@@ -73,6 +75,14 @@
 
     public ScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ScrimView);
+
+        try {
+            mScrimColor = ta.getColor(R.styleable.ScrimView_scrimColor, Color.BLACK);
+        } finally {
+            ta.recycle();
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 9a76ad6..45eb5df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -220,7 +220,7 @@
         int endPadding = mMobileSignalGroup.getChildCount() > 0 ? mMobileSignalGroupEndPadding : 0;
         mMobileSignalGroup.setPaddingRelative(0, 0, endPadding, 0);
 
-        TunerService.get(mContext).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+        Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
 
         apply();
         applyIconTint();
@@ -231,7 +231,7 @@
     @Override
     protected void onDetachedFromWindow() {
         mMobileSignalGroup.removeAllViews();
-        TunerService.get(mContext).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
         mSecurityController.removeCallback(this);
         mNetworkController.removeCallback(this);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 399b0d2..6283148 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -256,9 +256,16 @@
         if (mIcon == null) {
             return false;
         }
-        Drawable drawable = getIcon(mIcon);
+        Drawable drawable;
+        try {
+            drawable = getIcon(mIcon);
+        } catch (OutOfMemoryError e) {
+            Log.w(TAG, "OOM while inflating " + mIcon.icon + " for slot " + mSlot);
+            return false;
+        }
+
         if (drawable == null) {
-            Log.w(TAG, "No icon for slot " + mSlot);
+            Log.w(TAG, "No icon for slot " + mSlot + "; " + mIcon.icon);
             return false;
         }
         if (withClear) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
index 3bbda4b..7e08d56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java
@@ -24,24 +24,22 @@
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.support.v4.util.SimpleArrayMap;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseBooleanArray;
 import android.view.View;
 import android.widget.LinearLayout;
-
 import com.android.systemui.R;
-import com.android.systemui.ActivityStarter;
 
 import java.net.URISyntaxException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
  * A controller to populate data for CarNavigationBarView and handle user interactions.
- * <p/>
- * Each button inside the navigation bar is defined by data in arrays_car.xml. OEMs can customize
- * the navigation buttons by updating arrays_car.xml appropriately in an overlay.
+ *
+ * <p>Each button inside the navigation bar is defined by data in arrays_car.xml. OEMs can
+ * customize the navigation buttons by updating arrays_car.xml appropriately in an overlay.
  */
 class CarNavigationBarController {
     private static final String TAG = "CarNavBarController";
@@ -51,48 +49,49 @@
     private static final String EXTRA_FACET_ID = "filter_id";
     private static final String EXTRA_FACET_LAUNCH_PICKER = "launch_picker";
 
-    // Each facet of the navigation bar maps to a set of package names or categories defined in
-    // arrays_car.xml. Package names for a given facet are delimited by ";"
-    private static final String FACET_FILTER_DEMILITER = ";";
+    /**
+     * Each facet of the navigation bar maps to a set of package names or categories defined in
+     * arrays_car.xml. Package names for a given facet are delimited by ";".
+     */
+    private static final String FACET_FILTER_DELIMITER = ";";
 
-    private Context mContext;
-    private CarNavigationBarView mNavBar;
-    private CarStatusBar mStatusBar;
+    private final Context mContext;
+    private final CarNavigationBarView mNavBar;
+    private final CarStatusBar mStatusBar;
 
-    // Set of categories each facet will filter on.
-    private List<String[]> mFacetCategories = new ArrayList<String[]>();
-    // Set of package names each facet will filter on.
-    private List<String[]> mFacetPackages = new ArrayList<String[]>();
+    /**
+     * Set of categories each facet will filter on.
+     */
+    private final List<String[]> mFacetCategories = new ArrayList<>();
 
-    private SimpleArrayMap<String, Integer> mFacetCategoryMap
-            = new SimpleArrayMap<String, Integer>();
-    private SimpleArrayMap<String, Integer> mFacetPackageMap
-            = new SimpleArrayMap<String, Integer>();
+    /**
+     * Set of package names each facet will filter on.
+     */
+    private final List<String[]> mFacetPackages = new ArrayList<>();
 
-    private List<Intent> mIntents;
-    private List<Intent> mLongPressIntents;
+    private final SimpleArrayMap<String, Integer> mFacetCategoryMap = new SimpleArrayMap<>();
+    private final SimpleArrayMap<String, Integer> mFacetPackageMap = new SimpleArrayMap<>();
 
-    private List<CarNavigationButton> mNavButtons = new ArrayList<CarNavigationButton>();
+    private final List<CarNavigationButton> mNavButtons = new ArrayList<>();
+
+    private final SparseBooleanArray mFacetHasMultipleAppsCache = new SparseBooleanArray();
 
     private int mCurrentFacetIndex;
-    private SparseBooleanArray mFacetHasMultipleAppsCache = new SparseBooleanArray();
-
     private Intent mPersistentTaskIntent;
 
-    public CarNavigationBarController(Context context,
-                                      CarNavigationBarView navBar,
-                                      CarStatusBar activityStarter) {
+    public CarNavigationBarController(Context context, CarNavigationBarView navBar,
+            CarStatusBar activityStarter) {
         mContext = context;
         mNavBar = navBar;
         mStatusBar = activityStarter;
         bind();
 
         if (context.getResources().getBoolean(R.bool.config_enablePersistentDockedActivity)) {
-            setupPersistentDockedTask(context);
+            setupPersistentDockedTask();
         }
     }
 
-    private void setupPersistentDockedTask(Context context) {
+    private void setupPersistentDockedTask() {
         try {
             mPersistentTaskIntent = Intent.parseUri(
                     mContext.getString(R.string.config_persistentDockedActivityIntentUri),
@@ -137,64 +136,85 @@
         }
     }
 
+    /**
+     * Iterates through the items in arrays_car.xml and sets up the facet bar buttons to
+     * perform the task in that configuration file when clicked or long-pressed.
+     */
     private void bind() {
-        // Read up arrays_car.xml and populate the navigation bar here.
-        Resources r = mContext.getResources();
-        TypedArray icons = r.obtainTypedArray(R.array.car_facet_icons);
-        TypedArray intents = r.obtainTypedArray(R.array.car_facet_intent_uris);
-        TypedArray longpressIntents =
-                r.obtainTypedArray(R.array.car_facet_longpress_intent_uris);
-        TypedArray facetPackageNames = r.obtainTypedArray(R.array.car_facet_package_filters);
+        Resources res = mContext.getResources();
 
-        TypedArray facetCategories = r.obtainTypedArray(R.array.car_facet_category_filters);
+        TypedArray icons = res.obtainTypedArray(R.array.car_facet_icons);
+        TypedArray intents = res.obtainTypedArray(R.array.car_facet_intent_uris);
+        TypedArray longPressIntents = res.obtainTypedArray(R.array.car_facet_longpress_intent_uris);
+        TypedArray facetPackageNames = res.obtainTypedArray(R.array.car_facet_package_filters);
+        TypedArray facetCategories = res.obtainTypedArray(R.array.car_facet_category_filters);
 
-        if (icons.length() != intents.length()
-                || icons.length() != longpressIntents.length()
-                || icons.length() != facetPackageNames.length()
-                || icons.length() != facetCategories.length()) {
-            throw new RuntimeException("car_facet array lengths do not match");
-        }
-
-        mIntents = createEmptyIntentList(icons.length());
-        mLongPressIntents = createEmptyIntentList(icons.length());
-
-        for (int i = 0; i < icons.length(); i++) {
-            Drawable icon = icons.getDrawable(i);
-            try {
-                mIntents.set(i,
-                        Intent.parseUri(intents.getString(i), Intent.URI_INTENT_SCHEME));
-
-                String longpressUri = longpressIntents.getString(i);
-                boolean hasLongpress = !longpressUri.isEmpty();
-                if (hasLongpress) {
-                    mLongPressIntents.set(i,
-                            Intent.parseUri(longpressUri, Intent.URI_INTENT_SCHEME));
-                }
-
-                CarNavigationButton button = createNavButton(icon, i, hasLongpress);
-                mNavButtons.add(button);
-                mNavBar.addButton(button,
-                        createNavButton(icon, i, hasLongpress) /* lightsOutButton */);
-
-                initFacetFilterMaps(i,
-                        facetPackageNames.getString(i).split(FACET_FILTER_DEMILITER),
-                        facetCategories.getString(i).split(FACET_FILTER_DEMILITER));
-                        mFacetHasMultipleAppsCache.put(i, facetHasMultiplePackages(i));
-            } catch (URISyntaxException e) {
-                throw new RuntimeException("Malformed intent uri", e);
+        try {
+            if (icons.length() != intents.length()
+                    || icons.length() != longPressIntents.length()
+                    || icons.length() != facetPackageNames.length()
+                    || icons.length() != facetCategories.length()) {
+                throw new RuntimeException("car_facet array lengths do not match");
             }
+
+            for (int i = 0, size = icons.length(); i < size; i++) {
+                Drawable icon = icons.getDrawable(i);
+                CarNavigationButton button = createNavButton(icon);
+                initClickListeners(button, i, intents.getString(i), longPressIntents.getString(i));
+
+                mNavButtons.add(button);
+                mNavBar.addButton(button, createNavButton(icon) /* lightsOutButton */);
+
+                initFacetFilterMaps(i, facetPackageNames.getString(i).split(FACET_FILTER_DELIMITER),
+                        facetCategories.getString(i).split(FACET_FILTER_DELIMITER));
+                mFacetHasMultipleAppsCache.put(i, facetHasMultiplePackages(i));
+            }
+        } finally {
+            // Clean up all the TypedArrays.
+            icons.recycle();
+            intents.recycle();
+            longPressIntents.recycle();
+            facetPackageNames.recycle();
+            facetCategories.recycle();
+        }
+    }
+
+    /**
+     * Recreates each of the buttons on a density or font scale change. This manual process is
+     * necessary since this class is not part of an activity that automatically gets recreated.
+     */
+    public void onDensityOrFontScaleChanged() {
+        TypedArray icons = mContext.getResources().obtainTypedArray(R.array.car_facet_icons);
+
+        try {
+            int length = icons.length();
+            if (length != mNavButtons.size()) {
+                // This should not happen since the mNavButtons list is created from the length
+                // of the icons array in bind().
+                throw new RuntimeException("car_facet array lengths do not match number of "
+                        + "created buttons.");
+            }
+
+            for (int i = 0; i < length; i++) {
+                Drawable icon = icons.getDrawable(i);
+
+                // Setting a new icon will trigger a requestLayout() call if necessary.
+                mNavButtons.get(i).setResources(icon);
+            }
+        } finally {
+            icons.recycle();
         }
     }
 
     private void initFacetFilterMaps(int id, String[] packageNames, String[] categories) {
         mFacetCategories.add(categories);
-        for (int i = 0; i < categories.length; i++) {
-            mFacetCategoryMap.put(categories[i], id);
+        for (String category : categories) {
+            mFacetCategoryMap.put(category, id);
         }
 
         mFacetPackages.add(packageNames);
-        for (int i = 0; i < packageNames.length; i++) {
-            mFacetPackageMap.put(packageNames[i], id);
+        for (String packageName : packageNames) {
+            mFacetPackageMap.put(packageName, id);
         }
     }
 
@@ -223,8 +243,10 @@
     }
 
     /**
-     * Helper method to check if a given facet has multiple packages associated with it.
-     * This can be resource defined package names or package names filtered by facet category.
+     * Helper method to check if a given facet has multiple packages associated with it. This can
+     * be resource defined package names or package names filtered by facet category.
+     *
+     * @return {@code true} if the facet at the given index has more than one package.
      */
     private boolean facetHasMultiplePackages(int index) {
         PackageManager pm = mContext.getPackageManager();
@@ -259,6 +281,10 @@
         return false;
     }
 
+    /**
+     * Sets the facet at the given index to be the facet that is currently active. The button will
+     * be highlighted appropriately.
+     */
     private void setCurrentFacet(int index) {
         if (index == mCurrentFacetIndex) {
             return;
@@ -273,11 +299,16 @@
             mNavButtons.get(index).setSelected(true /* selected */,
                     mFacetHasMultipleAppsCache.get(index)  /* showMoreIcon */);
         }
+
         mCurrentFacetIndex = index;
     }
 
-    private CarNavigationButton createNavButton(Drawable icon, final int id,
-                                                boolean longClickEnabled) {
+    /**
+     * Creates the View that is used for the buttons along the navigation bar.
+     *
+     * @param icon The icon to be used for the button.
+     */
+    private CarNavigationButton createNavButton(Drawable icon) {
         CarNavigationButton button = (CarNavigationButton) View.inflate(mContext,
                 R.layout.car_navigation_button, null);
         button.setResources(icon);
@@ -285,37 +316,49 @@
                 new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
         button.setLayoutParams(lp);
 
-        button.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                onFacetClicked(id);
-            }
-        });
-
-        if (longClickEnabled) {
-            button.setLongClickable(true);
-            button.setOnLongClickListener(new View.OnLongClickListener() {
-                @Override
-                public boolean onLongClick(View v) {
-                    onFacetLongClicked(id);
-                    return true;
-                }
-            });
-        } else {
-            button.setLongClickable(false);
-        }
-
         return button;
     }
 
-    private void startActivity(Intent intent, ActivityStarter.Callback callback) {
-        if (mStatusBar != null && intent != null) {
-            mStatusBar.startActivity(intent, false, callback);
+    /**
+     * Initializes the click and long click listeners that correspond to the given command string.
+     * The click listeners are attached to the given button.
+     */
+    private void initClickListeners(View button, int index, String clickString,
+            String longPressString) {
+        // Each button at least have an action when pressed.
+        if (TextUtils.isEmpty(clickString)) {
+            throw new RuntimeException("Facet at index " + index + " does not have click action.");
+        }
+
+        try {
+            Intent intent = Intent.parseUri(clickString, Intent.URI_INTENT_SCHEME);
+            button.setOnClickListener(v -> onFacetClicked(intent, index));
+        } catch (URISyntaxException e) {
+            throw new RuntimeException("Malformed intent uri", e);
+        }
+
+        if (TextUtils.isEmpty(longPressString)) {
+            button.setLongClickable(false);
+            return;
+        }
+
+        try {
+            Intent intent = Intent.parseUri(longPressString, Intent.URI_INTENT_SCHEME);
+            button.setOnLongClickListener(v -> {
+                onFacetLongClicked(intent, index);
+                return true;
+            });
+        } catch (URISyntaxException e) {
+            throw new RuntimeException("Malformed long-press intent uri", e);
         }
     }
 
-    private void onFacetClicked(int index) {
-        Intent intent = mIntents.get(index);
+    /**
+     * Handles a click on a facet. A click will trigger the given Intent.
+     *
+     * @param index The index of the facet that was clicked.
+     */
+    private void onFacetClicked(Intent intent, int index) {
         String packageName = intent.getPackage();
 
         if (packageName == null) {
@@ -341,13 +384,13 @@
         mStatusBar.startActivityOnStack(intent, stackId);
     }
 
-    private void onFacetLongClicked(int index) {
+    /**
+     * Handles a long-press on a facet. The long-press will trigger the given Intent.
+     *
+     * @param index The index of the facet that was clicked.
+     */
+    private void onFacetLongClicked(Intent intent, int index) {
         setCurrentFacet(index);
-        mStatusBar.startActivityOnStack(mLongPressIntents.get(index),
-                StackId.FULLSCREEN_WORKSPACE_STACK_ID);
-    }
-
-    private List<Intent> createEmptyIntentList(int size) {
-        return Arrays.asList(new Intent[size]);
+        mStatusBar.startActivityOnStack(intent, StackId.FULLSCREEN_WORKSPACE_STACK_ID);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index f6a5687..4161389 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -35,10 +35,12 @@
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.SwipeHelper;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.phone.NavigationBarView;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
 import com.android.systemui.statusbar.policy.BatteryController;
@@ -51,10 +53,8 @@
         CarBatteryController.BatteryViewHandler {
     private static final String TAG = "CarStatusBar";
 
-    private SystemServicesProxy mSystemServicesProxy;
     private TaskStackListenerImpl mTaskStackListener;
 
-    private CarNavigationBarView mCarNavigationBar;
     private CarNavigationBarController mController;
     private FullscreenUserSwitcher mFullscreenUserSwitcher;
 
@@ -62,7 +62,6 @@
     private BatteryMeterView mBatteryMeterView;
 
     private ConnectedDeviceSignalController mConnectedDeviceSignalController;
-    private View mSignalsView;
     private CarNavigationBarView mNavigationBarView;
 
     @Override
@@ -72,6 +71,8 @@
         SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskStackListener);
         registerPackageChangeReceivers();
 
+        mStackScroller.setScrollingEnabled(true);
+
         createBatteryController();
         mCarBatteryController.startListening();
         mConnectedDeviceSignalController.startListening();
@@ -96,16 +97,16 @@
         mBatteryMeterView.setVisibility(View.GONE);
 
         ViewStub stub = (ViewStub) statusBarView.findViewById(R.id.connected_device_signals_stub);
-        mSignalsView = stub.inflate();
+        View signalsView = stub.inflate();
 
         // When a ViewStub if inflated, it does not respect the margins on the inflated view.
         // As a result, manually add the ending margin.
-        ((LinearLayout.LayoutParams) mSignalsView.getLayoutParams()).setMarginEnd(
+        ((LinearLayout.LayoutParams) signalsView.getLayoutParams()).setMarginEnd(
                 mContext.getResources().getDimensionPixelOffset(
                         R.dimen.status_bar_connected_device_signal_margin_end));
 
         mConnectedDeviceSignalController = new ConnectedDeviceSignalController(mContext,
-                mSignalsView);
+                signalsView);
 
         if (Log.isLoggable(TAG, Log.DEBUG)) {
             Log.d(TAG, "makeStatusBarView(). mBatteryMeterView: " + mBatteryMeterView);
@@ -126,12 +127,11 @@
             return;
         }
 
-        mCarNavigationBar =
-                (CarNavigationBarView) View.inflate(mContext, R.layout.car_navigation_bar, null);
-        mController = new CarNavigationBarController(mContext, mCarNavigationBar,
+        mNavigationBarView = (CarNavigationBarView) View.inflate(mContext,
+                R.layout.car_navigation_bar, null);
+        mController = new CarNavigationBarController(mContext, mNavigationBarView,
                 this /* ActivityStarter*/);
-        mNavigationBarView = mCarNavigationBar;
-        mCarNavigationBar.getBarTransitions().setAlwaysOpaque(true);
+        mNavigationBarView.getBarTransitions().setAlwaysOpaque(true);
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
                 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
@@ -148,6 +148,31 @@
     }
 
     @Override
+    public NavigationBarView getNavigationBarView() {
+        return mNavigationBarView;
+    }
+
+    @Override
+    protected View.OnTouchListener getStatusBarWindowTouchListener() {
+        // Usually, a touch on the background window will dismiss the notification shade. However,
+        // for the car use-case, the shade should remain unless the user switches to a different
+        // facet (e.g. phone).
+        return null;
+    }
+
+    /**
+     * Returns the {@link com.android.systemui.SwipeHelper.LongPressListener} that will be
+     * triggered when a notification card is long-pressed.
+     */
+    @Override
+    protected SwipeHelper.LongPressListener getNotificationLongClicker() {
+        // For the automative use case, we do not want to the user to be able to interact with
+        // a notification other than a regular click. As a result, just return null for the
+        // long click listener.
+        return null;
+    }
+
+    @Override
     public void showBatteryView() {
         if (Log.isLoggable(TAG, Log.DEBUG)) {
             Log.d(TAG, "showBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
@@ -272,4 +297,14 @@
         options.setLaunchStackId(stackId);
         return startActivityWithOptions(intent, options.toBundle());
     }
+
+    /**
+     * Ensures that relevant child views are appropriately recreated when the device's density
+     * changes.
+     */
+    @Override
+    protected void onDensityOrFontScaleChanged() {
+        super.onDensityOrFontScaleChanged();
+        mController.onDensityOrFontScaleChanged();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index 3b18886..e5f32df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -41,10 +41,12 @@
     private final ViewInvertHelper mInvertHelper;
     private final Paint mGreyPaint = new Paint();
     private boolean mShowingLegacyBackground;
+    private int mLegacyColor;
 
     protected NotificationCustomViewWrapper(View view, ExpandableNotificationRow row) {
         super(view, row);
         mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION);
+        mLegacyColor = row.getContext().getColor(R.color.notification_legacy_background_color);
     }
 
     @Override
@@ -103,6 +105,20 @@
     }
 
     @Override
+    protected boolean shouldClearBackgroundOnReapply() {
+        return false;
+    }
+
+    @Override
+    public int getCustomBackgroundColor() {
+        int customBackgroundColor = super.getCustomBackgroundColor();
+        if (customBackgroundColor == 0 && mShowingLegacyBackground) {
+            return mLegacyColor;
+        }
+        return customBackgroundColor;
+    }
+
+    @Override
     public void setShowingLegacyBackground(boolean showing) {
         super.setShowingLegacyBackground(showing);
         mShowingLegacyBackground = showing;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 836482a..5f5e1e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -93,7 +93,9 @@
     public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
         mDarkInitialized = false;
         Drawable background = mView.getBackground();
-        mBackgroundColor = 0;
+        if (shouldClearBackgroundOnReapply()) {
+            mBackgroundColor = 0;
+        }
         if (background instanceof ColorDrawable) {
             mBackgroundColor = ((ColorDrawable) background).getColor();
             mView.setBackground(null);
@@ -101,6 +103,10 @@
         mShouldInvertDark = mBackgroundColor == 0 || isColorLight(mBackgroundColor);
     }
 
+    protected boolean shouldClearBackgroundOnReapply() {
+        return true;
+    }
+
     private boolean isColorLight(int backgroundColor) {
         return Color.alpha(backgroundColor) == 0
                 || ColorUtils.calculateLuminance(backgroundColor) > 0.5;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index bfc0a80..14f9919 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -35,6 +35,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.res.AssetFileDescriptor.AutoCloseOutputStream;
 import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
@@ -58,6 +59,7 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -164,6 +166,7 @@
     private IntentButton mLeftDefault = mLeftButton;
     private IntentButton mLeftPlugin;
     private String mLeftButtonStr;
+    private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
 
     public KeyguardBottomAreaView(Context context) {
         this(context, null);
@@ -257,11 +260,11 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mAccessibilityController.addStateChangedCallback(this);
-        PluginManager.getInstance(getContext()).addPluginListener(RIGHT_BUTTON_PLUGIN,
+        Dependency.get(PluginManager.class).addPluginListener(RIGHT_BUTTON_PLUGIN,
                 mRightListener, IntentButtonProvider.VERSION, false /* Only allow one */);
-        PluginManager.getInstance(getContext()).addPluginListener(LEFT_BUTTON_PLUGIN,
+        Dependency.get(PluginManager.class).addPluginListener(LEFT_BUTTON_PLUGIN,
                 mLeftListener, IntentButtonProvider.VERSION, false /* Only allow one */);
-        TunerService.get(getContext()).addTunable(this, LockscreenFragment.LOCKSCREEN_LEFT_BUTTON,
+        Dependency.get(TunerService.class).addTunable(this, LockscreenFragment.LOCKSCREEN_LEFT_BUTTON,
                 LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON);
     }
 
@@ -269,9 +272,9 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         mAccessibilityController.removeStateChangedCallback(this);
-        PluginManager.getInstance(getContext()).removePluginListener(mRightListener);
-        PluginManager.getInstance(getContext()).removePluginListener(mLeftListener);
-        TunerService.get(getContext()).removeTunable(this);
+        Dependency.get(PluginManager.class).removePluginListener(mRightListener);
+        Dependency.get(PluginManager.class).removePluginListener(mLeftListener);
+        Dependency.get(TunerService.class).removeTunable(this);
     }
 
     private void initAccessibility() {
@@ -445,8 +448,7 @@
     }
 
     private void handleTrustCircleClick() {
-        EventLogTags.writeSysuiLockscreenGesture(
-                EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_LOCK, 0 /* lengthDp - N/A */,
+        mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_LOCK, 0 /* lengthDp - N/A */,
                 0 /* velocityDp - N/A */);
         mIndicationController.showTransientIndication(
                 R.string.keyguard_indication_trust_disabled);
@@ -573,7 +575,7 @@
             AsyncTask.execute(runnable);
         } else {
             boolean dismissShade = !TextUtils.isEmpty(mRightButtonStr)
-                    && TunerService.get(getContext()).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
+                    && Dependency.get(TunerService.class).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
             mStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
                     dismissShade, false /* afterKeyguardGone */, true /* deferred */);
         }
@@ -594,7 +596,7 @@
             });
         } else {
             boolean dismissShade = !TextUtils.isEmpty(mLeftButtonStr)
-                    && TunerService.get(getContext()).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0;
+                    && Dependency.get(TunerService.class).getValue(LOCKSCREEN_LEFT_UNLOCK, 1) != 0;
             mActivityStarter.startActivity(mLeftButton.getIntent(), dismissShade);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
index 4535992..7c458898 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java
@@ -20,15 +20,19 @@
 import android.view.View;
 
 import com.android.systemui.Dependency;
+import com.android.systemui.Dumpable;
 import com.android.systemui.statusbar.policy.BatteryController;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 
 /**
  * Controls how light status bar flag applies to the icons.
  */
-public class LightBarController implements BatteryController.BatteryStateChangeCallback {
+public class LightBarController implements BatteryController.BatteryStateChangeCallback, Dumpable {
 
     private static final float NAV_BAR_INVERSION_SCRIM_ALPHA_THRESHOLD = 0.1f;
 
@@ -203,4 +207,37 @@
     public void onPowerSaveChanged(boolean isPowerSave) {
         reevaluate();
     }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("LightBarController: ");
+        pw.print(" mSystemUiVisibility=0x"); pw.print(
+                Integer.toHexString(mSystemUiVisibility));
+        pw.print(" mFullscreenStackVisibility=0x"); pw.print(
+                Integer.toHexString(mFullscreenStackVisibility));
+        pw.print(" mDockedStackVisibility=0x"); pw.println(
+                Integer.toHexString(mDockedStackVisibility));
+
+        pw.print(" mFullscreenLight="); pw.print(mFullscreenLight);
+        pw.print(" mDockedLight="); pw.println(mDockedLight);
+
+        pw.print(" mLastFullscreenBounds="); pw.print(mLastFullscreenBounds);
+        pw.print(" mLastDockedBounds="); pw.println(mLastDockedBounds);
+
+        pw.print(" mNavigationLight="); pw.print(mNavigationLight);
+        pw.print(" mHasLightNavigationBar="); pw.println(mHasLightNavigationBar);
+
+        pw.print(" mLastStatusBarMode="); pw.print(mLastStatusBarMode);
+        pw.print(" mLastNavigationBarMode="); pw.println(mLastNavigationBarMode);
+
+        pw.print(" mScrimAlpha="); pw.print(mScrimAlpha);
+        pw.print(" mScrimAlphaBelowThreshold="); pw.println(mScrimAlphaBelowThreshold);
+        pw.println();
+        pw.println(" StatusBarTransitionsController:");
+        mStatusBarIconController.getTransitionsController().dump(fd, pw, args);
+        pw.println();
+        pw.println(" NavigationBarTransitionsController:");
+        mNavigationBarController.dump(fd, pw, args);
+        pw.println();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index 0f9f056..07f37ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -20,13 +20,18 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.SystemClock;
+import android.util.TimeUtils;
 
+import com.android.systemui.Dumpable;
 import com.android.systemui.Interpolators;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 /**
  * Class to control all aspects about light bar changes.
  */
-public class LightBarTransitionsController {
+public class LightBarTransitionsController implements Dumpable {
 
     public static final long DEFAULT_TINT_ANIMATION_DURATION = 120;
     private static final String EXTRA_DARK_INTENSITY = "dark_intensity";
@@ -147,6 +152,26 @@
         mApplier.applyDarkIntensity(darkIntensity);
     }
 
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.print("  mTransitionDeferring="); pw.print(mTransitionDeferring);
+        if (mTransitionDeferring) {
+            pw.println();
+            pw.print("   mTransitionDeferringStartTime=");
+            pw.println(TimeUtils.formatUptime(mTransitionDeferringStartTime));
+
+            pw.print("   mTransitionDeferringDuration=");
+            TimeUtils.formatDuration(mTransitionDeferringDuration, pw);
+            pw.println();
+        }
+        pw.print("  mTransitionPending="); pw.print(mTransitionPending);
+        pw.print(" mTintChangePending="); pw.println(mTintChangePending);
+
+        pw.print("  mPendingDarkIntensity="); pw.print(mPendingDarkIntensity);
+        pw.print(" mDarkIntensity="); pw.print(mDarkIntensity);
+        pw.print(" mNextDarkIntensity="); pw.println(mNextDarkIntensity);
+    }
+
     /**
      * Interface to apply a specific dark intensity.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
new file mode 100644
index 0000000..83b96bf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenGestureLogger.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.metrics.LogMaker;
+import android.util.ArrayMap;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.EventLogConstants;
+import com.android.systemui.EventLogTags;
+
+/**
+ * Wrapper that emits both new- and old-style gesture logs.
+ * TODO: delete this once the old logs are no longer needed.
+ */
+public class LockscreenGestureLogger {
+    private ArrayMap<Integer, Integer> mLegacyMap;
+    private LogMaker mLogMaker = new LogMaker(MetricsEvent.VIEW_UNKNOWN)
+            .setType(MetricsEvent.TYPE_ACTION);
+
+    public LockscreenGestureLogger() {
+        mLegacyMap = new ArrayMap<>(EventLogConstants.METRICS_GESTURE_TYPE_MAP.length);
+        for (int i = 0; i < EventLogConstants.METRICS_GESTURE_TYPE_MAP.length ; i++) {
+            mLegacyMap.put(EventLogConstants.METRICS_GESTURE_TYPE_MAP[i], i);
+        }
+    }
+
+    public void write(int gesture, int length, int velocity) {
+        MetricsLogger.action(mLogMaker.setCategory(gesture)
+                .setType(MetricsEvent.TYPE_ACTION)
+                .addTaggedData(MetricsEvent.FIELD_GESTURE_LENGTH, length)
+                .addTaggedData(MetricsEvent.FIELD_GESTURE_VELOCITY, velocity));
+        // also write old-style logs for backward-0compatibility
+        EventLogTags.writeSysuiLockscreenGesture(safeLookup(gesture), length, velocity);
+    }
+
+    private int safeLookup(int gesture) {
+        Integer value = mLegacyMap.get(gesture);
+        if (value == null) {
+            return MetricsEvent.VIEW_UNKNOWN;
+        }
+        return value;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 62b536e..808cd21 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -23,6 +23,7 @@
 import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE;
 import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions;
 
+import android.accessibilityservice.AccessibilityServiceInfo;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
@@ -79,6 +80,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -101,7 +103,7 @@
 
     private int mNavigationIconHints = 0;
     private int mNavigationBarMode;
-    protected AccessibilityManager mAccessibilityManager;
+    private AccessibilityManager mAccessibilityManager;
 
     private int mDisabledFlags1;
     private StatusBar mStatusBar;
@@ -132,6 +134,8 @@
         mDivider = SysUiServiceProvider.getComponent(getContext(), Divider.class);
         mWindowManager = getContext().getSystemService(WindowManager.class);
         mAccessibilityManager = getContext().getSystemService(AccessibilityManager.class);
+        mAccessibilityManager.addAccessibilityServicesStateChangeListener(
+                this::updateAccessibilityServicesState);
         if (savedInstanceState != null) {
             mDisabledFlags1 = savedInstanceState.getInt(EXTRA_DISABLE_STATE, 0);
         }
@@ -149,6 +153,8 @@
     public void onDestroy() {
         super.onDestroy();
         mCommandQueue.removeCallbacks(this);
+        mAccessibilityManager.removeAccessibilityServicesStateChangeListener(
+                this::updateAccessibilityServicesState);
         try {
             WindowManagerGlobal.getWindowManagerService()
                     .removeRotationWatcher(mRotationWatcher);
@@ -402,6 +408,10 @@
         ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
         homeButton.setOnTouchListener(this::onHomeTouch);
         homeButton.setOnLongClickListener(this::onHomeLongClick);
+
+        ButtonDispatcher accessibilityButton = mNavigationBarView.getAccessibilityButton();
+        accessibilityButton.setOnClickListener(this::onAccessibilityClick);
+        accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
     }
 
     private boolean onHomeTouch(View v, MotionEvent event) {
@@ -553,6 +563,34 @@
                 MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
     }
 
+    private void onAccessibilityClick(View v) {
+        mAccessibilityManager.notifyAccessibilityButtonClicked();
+    }
+
+    private boolean onAccessibilityLongClick(View v) {
+        // TODO(b/34720082): Target service selection via long click
+        android.widget.Toast.makeText(getContext(), "Service selection coming soon...",
+                android.widget.Toast.LENGTH_LONG).show();
+        return true;
+    }
+
+    private void updateAccessibilityServicesState() {
+        final List<AccessibilityServiceInfo> services =
+                mAccessibilityManager.getEnabledAccessibilityServiceList(
+                        AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
+        int requestingServices = 0;
+        for (int i = services.size() - 1; i >= 0; --i) {
+            AccessibilityServiceInfo info = services.get(i);
+            if ((info.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0) {
+                requestingServices++;
+            }
+        }
+
+        final boolean showAccessibilityButton = requestingServices >= 1;
+        final boolean targetSelection = requestingServices >= 2;
+        mNavigationBarView.setAccessibilityButtonState(showAccessibilityButton, targetSelection);
+    }
+
     // ----- Methods that StatusBar talks to (should be minimized) -----
 
     public void setLightBarController(LightBarController lightBarController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index 228e8ea..ee9a791 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -29,6 +29,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
@@ -87,7 +88,11 @@
         mScrollTouchSlop = r.getDimensionPixelSize(R.dimen.navigation_bar_min_swipe_distance);
         mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
         mTaskSwitcherDetector = new GestureDetector(context, this);
-        TunerService.get(context).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
+        Dependency.get(TunerService.class).addTunable(this, KEY_DOCK_WINDOW_GESTURE);
+    }
+
+    public void destroy() {
+        Dependency.get(TunerService.class).removeTunable(this);
     }
 
     public void setComponents(RecentsComponent recentsComponent, Divider divider,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 9b4867e..5fb99da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -30,6 +30,7 @@
 import android.widget.LinearLayout;
 import android.widget.Space;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
@@ -135,15 +136,16 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        TunerService.get(getContext()).addTunable(this, NAV_BAR_VIEWS, NAV_BAR_LEFT,
+        Dependency.get(TunerService.class).addTunable(this, NAV_BAR_VIEWS, NAV_BAR_LEFT,
                 NAV_BAR_RIGHT);
-        PluginManager.getInstance(getContext()).addPluginListener(NavBarButtonProvider.ACTION, this,
+        Dependency.get(PluginManager.class).addPluginListener(NavBarButtonProvider.ACTION, this,
                 NavBarButtonProvider.VERSION, true /* Allow multiple */);
     }
 
     @Override
     protected void onDetachedFromWindow() {
-        TunerService.get(getContext()).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
+        Dependency.get(PluginManager.class).removePluginListener(this);
         super.onDetachedFromWindow();
     }
 
@@ -278,10 +280,10 @@
         View v = null;
         String button = extractButton(buttonSpec);
         if (LEFT.equals(button)) {
-            buttonSpec = TunerService.get(mContext).getValue(NAV_BAR_LEFT, NAVSPACE);
+            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_LEFT, NAVSPACE);
             button = extractButton(buttonSpec);
         } else if (RIGHT.equals(button)) {
-            buttonSpec = TunerService.get(mContext).getValue(NAV_BAR_RIGHT, MENU_IME);
+            buttonSpec = Dependency.get(TunerService.class).getValue(NAV_BAR_RIGHT, MENU_IME);
             button = extractButton(buttonSpec);
         }
         // Let plugins go first so they can override a standard view if they want.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 5e988fc..5d13289 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -46,6 +46,7 @@
 import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.plugins.PluginListener;
@@ -77,6 +78,8 @@
     private int mCurrentRotation = -1;
 
     boolean mShowMenu;
+    boolean mShowAccessibilityButton;
+    boolean mLongClickableAccessibilityButton;
     int mDisabledFlags = 0;
     int mNavigationIconHints = 0;
 
@@ -88,6 +91,7 @@
     private KeyButtonDrawable mDockedIcon;
     private KeyButtonDrawable mImeIcon;
     private KeyButtonDrawable mMenuIcon;
+    private KeyButtonDrawable mAccessibilityIcon;
 
     private GestureHelper mGestureHelper;
     private DeadZone mDeadZone;
@@ -200,7 +204,9 @@
 
         mVertical = false;
         mShowMenu = false;
-        mGestureHelper = new NavigationBarGestureHelper(context);
+
+        mShowAccessibilityButton = false;
+        mLongClickableAccessibilityButton = false;
 
         mConfiguration = new Configuration();
         mConfiguration.updateFrom(context.getResources().getConfiguration());
@@ -213,6 +219,8 @@
         mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
         mButtonDispatchers.put(R.id.menu, new ButtonDispatcher(R.id.menu));
         mButtonDispatchers.put(R.id.ime_switcher, new ButtonDispatcher(R.id.ime_switcher));
+        mButtonDispatchers.put(R.id.accessibility_button,
+                new ButtonDispatcher(R.id.accessibility_button));
     }
 
     public BarTransitions getBarTransitions() {
@@ -287,6 +295,10 @@
         return mButtonDispatchers.get(R.id.ime_switcher);
     }
 
+    public ButtonDispatcher getAccessibilityButton() {
+        return mButtonDispatchers.get(R.id.accessibility_button);
+    }
+
     public SparseArray<ButtonDispatcher> getButtonDispatchers() {
         return mButtonDispatchers;
     }
@@ -320,6 +332,8 @@
             mRecentIcon = getDrawable(ctx,
                     R.drawable.ic_sysbar_recent, R.drawable.ic_sysbar_recent_dark);
             mMenuIcon = getDrawable(ctx, R.drawable.ic_sysbar_menu, R.drawable.ic_sysbar_menu_dark);
+            mAccessibilityIcon = getDrawable(ctx, R.drawable.ic_sysbar_accessibility_button,
+                    R.drawable.ic_sysbar_accessibility_button_dark);
 
             Context darkContext = new ContextThemeWrapper(ctx, R.style.DualToneDarkTheme);
             Context lightContext = new ContextThemeWrapper(ctx, R.style.DualToneLightTheme);
@@ -411,6 +425,9 @@
         setMenuVisibility(mShowMenu, true);
         getMenuButton().setImageDrawable(mMenuIcon);
 
+        setAccessibilityButtonState(mShowAccessibilityButton, mLongClickableAccessibilityButton);
+        getAccessibilityButton().setImageDrawable(mAccessibilityIcon);
+
         setDisabledFlags(mDisabledFlags, true);
 
         mBarTransitions.reapplyDarkIntensity();
@@ -517,13 +534,25 @@
 
         mShowMenu = show;
 
-        // Only show Menu if IME switcher not shown.
-        final boolean shouldShow = mShowMenu &&
+        // Only show Menu if IME switcher and Accessibility button not shown.
+        final boolean shouldShow = mShowMenu && !mShowAccessibilityButton &&
                 ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) == 0);
 
         getMenuButton().setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
     }
 
+    public void setAccessibilityButtonState(final boolean visible, final boolean longClickable) {
+        mShowAccessibilityButton = visible;
+        mLongClickableAccessibilityButton = longClickable;
+        if (visible) {
+            // Accessibility button overrides Menu button.
+            setMenuVisibility(false, true);
+        }
+
+        getAccessibilityButton().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+        getAccessibilityButton().setLongClickable(longClickable);
+    }
+
     @Override
     public void onFinishInflate() {
         mNavigationInflaterView = (NavigationBarInflaterView) findViewById(
@@ -633,6 +662,7 @@
     }
 
     private void updateTaskSwitchHelper() {
+        if (mGestureHelper == null) return;
         boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
         mGestureHelper.setBarState(mVertical, isRtl);
     }
@@ -752,14 +782,18 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        PluginManager.getInstance(getContext()).addPluginListener(NavGesture.ACTION, this,
+        onPluginDisconnected(null); // Create default gesture helper
+        Dependency.get(PluginManager.class).addPluginListener(NavGesture.ACTION, this,
                 NavGesture.VERSION, false /* Only one */);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        PluginManager.getInstance(getContext()).removePluginListener(this);
+        Dependency.get(PluginManager.class).removePluginListener(this);
+        if (mGestureHelper != null) {
+            mGestureHelper.destroy();
+        }
     }
 
     @Override
@@ -772,6 +806,9 @@
     public void onPluginDisconnected(NavGesture plugin) {
         NavigationBarGestureHelper defaultHelper = new NavigationBarGestureHelper(getContext());
         defaultHelper.setComponents(mRecentsComponent, mDivider, this);
+        if (mGestureHelper != null) {
+            mGestureHelper.destroy();
+        }
         mGestureHelper = defaultHelper;
         updateTaskSwitchHelper();
     }
@@ -806,6 +843,7 @@
         dumpButton(pw, "home", getHomeButton());
         dumpButton(pw, "rcnt", getRecentsButton());
         dumpButton(pw, "menu", getMenuButton());
+        dumpButton(pw, "a11y", getAccessibilityButton());
 
         pw.println("    }");
     }
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 c25a45c..571ae26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -104,6 +104,7 @@
     private float mOpenedAmount = 0.0f;
     private float mVisualOverflowAdaption;
     private boolean mDisallowNextAnimation;
+    private boolean mAnimationsEnabled = true;
 
     public NotificationIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -255,7 +256,7 @@
             iconState.visibleState = StatusBarIconView.STATE_ICON;
             if (firstOverflowIndex == -1 && (isAmbient
                     || (translationX >= (noOverflowAfter ? layoutEnd - mIconSize : overflowStart)))) {
-                firstOverflowIndex = noOverflowAfter ? i - 1 : i;
+                firstOverflowIndex = noOverflowAfter && !isAmbient ? i - 1 : i;
                 int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
                 visualOverflowStart = overflowStart + mIconSize * (1 + OVERFLOW_EARLY_AMOUNT)
                         - totalDotLength / 2
@@ -422,6 +423,20 @@
         return mIconSize;
     }
 
+    public void setAnimationsEnabled(boolean enabled) {
+        if (!enabled && mAnimationsEnabled) {
+            for (int i = 0; i < getChildCount(); i++) {
+                View child = getChildAt(i);
+                ViewState childState = mIconStates.get(child);
+                if (childState != null) {
+                    childState.cancelAnimations(child);
+                    childState.applyToView(child);
+                }
+            }
+        }
+        mAnimationsEnabled = enabled;
+    }
+
     public class IconState extends ViewState {
         public float iconAppearAmount = 1.0f;
         public float clampedAppearAmount = 1.0f;
@@ -438,52 +453,59 @@
                 StatusBarIconView icon = (StatusBarIconView) view;
                 boolean animate = false;
                 AnimationProperties animationProperties = null;
-                if (justAdded) {
-                    super.applyToView(icon);
-                    icon.setAlpha(0.0f);
-                    icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, false /* animate */);
-                    animationProperties = ADD_ICON_PROPERTIES;
-                    animate = true;
-                } else if (visibleState != icon.getVisibleState()) {
-                    animationProperties = DOT_ANIMATION_PROPERTIES;
-                    animate = true;
-                }
-                if (!animate && mAddAnimationStartIndex >= 0
-                        && indexOfChild(view) >= mAddAnimationStartIndex
-                        && (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
-                            || visibleState != StatusBarIconView.STATE_HIDDEN)) {
-                    animationProperties = DOT_ANIMATION_PROPERTIES;
-                    animate = true;
-                }
-                if (needsCannedAnimation) {
-                    AnimationFilter animationFilter = mTempProperties.getAnimationFilter();
-                    animationFilter.reset();
-                    animationFilter.combineFilter(ICON_ANIMATION_PROPERTIES.getAnimationFilter());
-                    mTempProperties.resetCustomInterpolators();
-                    mTempProperties.combineCustomInterpolators(ICON_ANIMATION_PROPERTIES);
-                    if (animationProperties != null) {
-                        animationFilter.combineFilter(animationProperties.getAnimationFilter());
-                        mTempProperties.combineCustomInterpolators(animationProperties);
+                boolean animationsAllowed = mAnimationsEnabled && !mDisallowNextAnimation;
+                if (animationsAllowed) {
+                    if (justAdded) {
+                        super.applyToView(icon);
+                        if (iconAppearAmount != 0.0f) {
+                            icon.setAlpha(0.0f);
+                            icon.setVisibleState(StatusBarIconView.STATE_HIDDEN,
+                                    false /* animate */);
+                            animationProperties = ADD_ICON_PROPERTIES;
+                            animate = true;
+                        }
+                    } else if (visibleState != icon.getVisibleState()) {
+                        animationProperties = DOT_ANIMATION_PROPERTIES;
+                        animate = true;
                     }
-                    animationProperties = mTempProperties;
-                    animationProperties.setDuration(CANNED_ANIMATION_DURATION);
-                    animate = true;
-                    mCannedAnimationStartIndex = indexOfChild(view);
+                    if (!animate && mAddAnimationStartIndex >= 0
+                            && indexOfChild(view) >= mAddAnimationStartIndex
+                            && (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
+                            || visibleState != StatusBarIconView.STATE_HIDDEN)) {
+                        animationProperties = DOT_ANIMATION_PROPERTIES;
+                        animate = true;
+                    }
+                    if (needsCannedAnimation) {
+                        AnimationFilter animationFilter = mTempProperties.getAnimationFilter();
+                        animationFilter.reset();
+                        animationFilter.combineFilter(
+                                ICON_ANIMATION_PROPERTIES.getAnimationFilter());
+                        mTempProperties.resetCustomInterpolators();
+                        mTempProperties.combineCustomInterpolators(ICON_ANIMATION_PROPERTIES);
+                        if (animationProperties != null) {
+                            animationFilter.combineFilter(animationProperties.getAnimationFilter());
+                            mTempProperties.combineCustomInterpolators(animationProperties);
+                        }
+                        animationProperties = mTempProperties;
+                        animationProperties.setDuration(CANNED_ANIMATION_DURATION);
+                        animate = true;
+                        mCannedAnimationStartIndex = indexOfChild(view);
+                    }
+                    if (!animate && mCannedAnimationStartIndex >= 0
+                            && indexOfChild(view) > mCannedAnimationStartIndex
+                            && (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
+                            || visibleState != StatusBarIconView.STATE_HIDDEN)) {
+                        AnimationFilter animationFilter = mTempProperties.getAnimationFilter();
+                        animationFilter.reset();
+                        animationFilter.animateX();
+                        mTempProperties.resetCustomInterpolators();
+                        animationProperties = mTempProperties;
+                        animationProperties.setDuration(CANNED_ANIMATION_DURATION);
+                        animate = true;
+                    }
                 }
-                if (!animate && mCannedAnimationStartIndex >= 0
-                        && indexOfChild(view) > mCannedAnimationStartIndex
-                        && (icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
-                        || visibleState != StatusBarIconView.STATE_HIDDEN)) {
-                    AnimationFilter animationFilter = mTempProperties.getAnimationFilter();
-                    animationFilter.reset();
-                    animationFilter.animateX();
-                    mTempProperties.resetCustomInterpolators();
-                    animationProperties = mTempProperties;
-                    animationProperties.setDuration(CANNED_ANIMATION_DURATION);
-                    animate = true;
-                }
-                icon.setVisibleState(visibleState);
-                if (animate && !mDisallowNextAnimation) {
+                icon.setVisibleState(visibleState, animationsAllowed);
+                if (animate) {
                     animateTo(icon, animationProperties);
                 } else {
                     super.applyToView(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index fe7e915..5da3a10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -26,6 +26,7 @@
 import android.content.Context;
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -43,6 +44,7 @@
 import android.widget.TextView;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.EventLogConstants;
@@ -137,6 +139,7 @@
     protected int mQsMinExpansionHeight;
     protected int mQsMaxExpansionHeight;
     private int mQsPeekHeight;
+    private boolean mQsOverscrollExpansionEnabled;
     private boolean mStackScrollerOverscrolling;
     private boolean mQsExpansionFromOverscroll;
     private float mLastOverscroll;
@@ -212,11 +215,14 @@
     private int mIndicationBottomPadding;
     private boolean mIsFullWidth;
     private boolean mDark;
+    private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
         setWillNotDraw(!DEBUG);
         mFalsingManager = FalsingManager.getInstance(context);
+        mQsOverscrollExpansionEnabled =
+                getResources().getBoolean(R.bool.config_enableQuickSettingsOverscrollExpansion);
     }
 
     public void setStatusBar(StatusBar bar) {
@@ -596,7 +602,8 @@
             MetricsLogger.count(mContext, COUNTER_PANEL_OPEN_PEEK, 1);
             return true;
         }
-        if (!isFullyCollapsed() && onQsIntercept(event)) {
+
+        if (mQsOverscrollExpansionEnabled && !isFullyCollapsed() && onQsIntercept(event)) {
             return true;
         }
         return super.onInterceptTouchEvent(event);
@@ -710,10 +717,9 @@
     private void logQsSwipeDown(float y) {
         float vel = getCurrentQSVelocity();
         final int gesture = mStatusBarState == StatusBarState.KEYGUARD
-                ? EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_QS
-                : EventLogConstants.SYSUI_SHADE_GESTURE_SWIPE_DOWN_QS;
-        EventLogTags.writeSysuiLockscreenGesture(
-                gesture,
+                ? MetricsEvent.ACTION_LS_QS
+                : MetricsEvent.ACTION_SHADE_QS_PULL;
+        mLockscreenGestureLogger.write(gesture,
                 (int) ((y - mInitialTouchY) / mStatusBar.getDisplayDensity()),
                 (int) (vel / mStatusBar.getDisplayDensity()));
     }
@@ -770,7 +776,9 @@
             return true;
         }
         mHeadsUpTouchHelper.onTouchEvent(event);
-        if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
+
+        if (mQsOverscrollExpansionEnabled && !mHeadsUpTouchHelper.isTrackingHeadsUp()
+                && handleQsTouch(event)) {
             return true;
         }
         if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
@@ -953,6 +961,10 @@
 
     @Override
     public void onOverscrollTopChanged(float amount, boolean isRubberbanded) {
+        if (!mQsOverscrollExpansionEnabled) {
+            return;
+        }
+
         cancelQsAnimation();
         if (!mQsExpansionEnabled) {
             amount = 0f;
@@ -967,6 +979,10 @@
 
     @Override
     public void flingTopOverscroll(float velocity, boolean open) {
+        if (!mQsOverscrollExpansionEnabled) {
+            return;
+        }
+
         mLastOverscroll = 0f;
         mQsExpansionFromOverscroll = false;
         setQsExpansion(mQsExpansionHeight);
@@ -1819,9 +1835,7 @@
             if (mQsExpanded) {
                 flingSettings(0 /* vel */, false /* expand */, null, true /* isClick */);
             } else if (mQsExpansionEnabled) {
-                EventLogTags.writeSysuiLockscreenGesture(
-                        EventLogConstants.SYSUI_TAP_TO_OPEN_QS,
-                        0, 0);
+                mLockscreenGestureLogger.write(MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0);
                 flingSettings(0 /* vel */, true /* expand */, null, true /* isClick */);
             }
         }
@@ -1836,8 +1850,7 @@
         int lengthDp = Math.abs((int) (translation / displayDensity));
         int velocityDp = Math.abs((int) (vel / displayDensity));
         if (start) {
-            EventLogTags.writeSysuiLockscreenGesture(
-                    EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DIALER, lengthDp, velocityDp);
+            mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_DIALER, lengthDp, velocityDp);
 
             mFalsingManager.onLeftAffordanceOn();
             if (mFalsingManager.shouldEnforceBouncer()) {
@@ -1855,9 +1868,7 @@
         } else {
             if (KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE.equals(
                     mLastCameraLaunchSource)) {
-                EventLogTags.writeSysuiLockscreenGesture(
-                        EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_CAMERA,
-                        lengthDp, velocityDp);
+                mLockscreenGestureLogger.write(MetricsEvent.ACTION_LS_CAMERA, lengthDp, velocityDp);
             }
             mFalsingManager.onCameraOn();
             if (mFalsingManager.shouldEnforceBouncer()) {
@@ -2152,8 +2163,8 @@
         switch (mStatusBar.getBarState()) {
             case StatusBarState.KEYGUARD:
                 if (!mDozingOnDown) {
-                    EventLogTags.writeSysuiLockscreenGesture(
-                            EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_UNLOCK_HINT,
+                    mLockscreenGestureLogger.write(
+                            MetricsEvent.ACTION_LS_HINT,
                             0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
                     startUnlockHintAnimation();
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 5f67468..48a8329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -33,6 +33,7 @@
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.DejankUtils;
 import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
@@ -55,6 +56,7 @@
     private static final int PEEK_ANIMATION_DURATION = 360;
     private long mDownTime;
     private float mMinExpandHeight;
+    private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
 
     private final void logf(String fmt, Object... args) {
         Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
@@ -110,6 +112,11 @@
     private float mInitialTouchX;
     private boolean mTouchDisabled;
 
+    /**
+     * Whether or not the PanelView can be expanded or collapsed with a drag.
+     */
+    private boolean mNotificationsDragEnabled;
+
     private Interpolator mBounceInterpolator;
     protected KeyguardBottomAreaView mKeyguardBottomArea;
 
@@ -190,6 +197,8 @@
                 0.84f /* y2 */);
         mBounceInterpolator = new BounceInterpolator();
         mFalsingManager = FalsingManager.getInstance(context);
+        mNotificationsDragEnabled =
+                getResources().getBoolean(R.bool.config_enableNotificationShadeDrag);
     }
 
     protected void loadDimens() {
@@ -232,6 +241,15 @@
             return false;
         }
 
+        // If dragging should not expand the notifications shade, then return false.
+        if (!mNotificationsDragEnabled) {
+            if (mTracking) {
+                // Turn off tracking if it's on or the shade can get stuck in the down position.
+                onTrackingStopped(true /* expand */);
+            }
+            return false;
+        }
+
         // On expanding, single mouse click expands the panel instead of dragging.
         if (isFullyCollapsed() && event.isFromSource(InputDevice.SOURCE_MOUSE)) {
             if (event.getAction() == MotionEvent.ACTION_UP) {
@@ -423,8 +441,8 @@
                         float displayDensity = mStatusBar.getDisplayDensity();
                         int heightDp = (int) Math.abs((y - mInitialTouchY) / displayDensity);
                         int velocityDp = (int) Math.abs(vel / displayDensity);
-                        EventLogTags.writeSysuiLockscreenGesture(
-                                EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_UP_UNLOCK,
+                        mLockscreenGestureLogger.write(
+                                MetricsEvent.ACTION_LS_UNLOCK,
                                 heightDp, velocityDp);
                     }
             fling(vel, expand, isFalseTouch(x, y));
@@ -487,7 +505,7 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent event) {
-        if (mInstantExpanding
+        if (mInstantExpanding || !mNotificationsDragEnabled
                 || (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) {
             return false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index dd567e8..a1022c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -89,7 +89,7 @@
 
         mServices = new TileServices(this, Dependency.get(Dependency.BG_LOOPER));
 
-        TunerService.get(mContext).addTunable(this, TILES_SETTING);
+        Dependency.get(TunerService.class).addTunable(this, TILES_SETTING);
         // AutoTileManager can modify mTiles so make sure mTiles has already been initialized.
         mAutoTiles = new AutoTileManager(context, this);
     }
@@ -101,7 +101,7 @@
     public void destroy() {
         mTiles.values().forEach(tile -> tile.destroy());
         mAutoTiles.destroy();
-        TunerService.get(mContext).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
         mServices.destroy();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index c0e9653..4307a2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -21,12 +21,14 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.RippleDrawable;
 import android.icu.text.NumberFormat;
 import android.os.UserManager;
+import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
 import android.util.AttributeSet;
 import android.util.SparseBooleanArray;
@@ -67,9 +69,6 @@
 public class QuickStatusBarHeader extends BaseStatusBarHeader implements
         NextAlarmChangeCallback, OnClickListener, OnUserInfoChangedListener, EmergencyListener,
         BatteryStateChangeCallback, SignalCallback {
-
-    private static final String TAG = "QuickStatusBarHeader";
-
     private static final float EXPAND_INDICATOR_THRESHOLD = .93f;
 
     private ActivityStarter mActivityStarter;
@@ -99,13 +98,16 @@
     private boolean mShowEmergencyCallsOnly;
     protected MultiUserSwitch mMultiUserSwitch;
     private ImageView mMultiUserAvatar;
-
+    private boolean mAlwaysShowMultiUserSwitch;
 
     private TouchAnimator mAnimator;
     protected TouchAnimator mSettingsAlpha;
     private float mExpansionAmount;
     protected QSTileHost mHost;
+
     protected View mEdit;
+    private boolean mShowEditIcon;
+
     private boolean mShowFullAlarm;
     private float mDateTimeTranslation;
     private TextView mBatteryLevel;
@@ -119,25 +121,37 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
+        Resources res = getResources();
 
         mEmergencyOnly = (TextView) findViewById(R.id.header_emergency_calls_only);
 
+        mShowEditIcon = res.getBoolean(R.bool.config_showQuickSettingsEditingIcon);
+
         mEdit = findViewById(android.R.id.edit);
-        findViewById(android.R.id.edit).setOnClickListener(view ->
-                Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() ->
-                        mQsPanel.showEdit(view)));
+        mEdit.setVisibility(mShowEditIcon ? VISIBLE : GONE);
+
+        if (mShowEditIcon) {
+            findViewById(android.R.id.edit).setOnClickListener(view ->
+                    Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() ->
+                            mQsPanel.showEdit(view)));
+        }
 
         mDateTimeAlarmGroup = (ViewGroup) findViewById(R.id.date_time_alarm_group);
         mDateTimeAlarmGroup.findViewById(R.id.empty_time_view).setVisibility(View.GONE);
         mDateTimeGroup = (ViewGroup) findViewById(R.id.date_time_group);
         mDateTimeGroup.setPivotX(0);
         mDateTimeGroup.setPivotY(0);
-        mDateTimeTranslation = getResources().getDimension(R.dimen.qs_date_time_translation);
-        mShowFullAlarm = getResources().getBoolean(R.bool.quick_settings_show_full_alarm);
+        mDateTimeTranslation = res.getDimension(R.dimen.qs_date_time_translation);
+        mShowFullAlarm = res.getBoolean(R.bool.quick_settings_show_full_alarm);
 
         mExpandIndicator = (ExpandableIndicator) findViewById(R.id.expand_indicator);
+        mExpandIndicator.setVisibility(
+                res.getBoolean(R.bool.config_showQuickSettingsExpandIndicator)
+                ? VISIBLE : GONE);
 
         mHeaderQsPanel = (QuickQSPanel) findViewById(R.id.quick_qs_panel);
+        mHeaderQsPanel.setVisibility(res.getBoolean(R.bool.config_showQuickSettingsRow)
+                ? VISIBLE : GONE);
 
         mSettingsButton = (SettingsButton) findViewById(R.id.settings_button);
         mSettingsContainer = findViewById(R.id.settings_button_container);
@@ -151,6 +165,7 @@
 
         mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
         mMultiUserAvatar = (ImageView) mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
+        mAlwaysShowMultiUserSwitch = res.getBoolean(R.bool.config_alwaysShowMultiUserSwitcher);
 
         // RenderThread is doing more harm than good when touching the header (to expand quick
         // settings), so disable it for this view
@@ -200,11 +215,8 @@
         updateSettingsAnimator();
     }
 
-    protected void updateSettingsAnimator() {
-        mSettingsAlpha = new TouchAnimator.Builder()
-                .addFloat(mEdit, "alpha", 0, 1)
-                .addFloat(mMultiUserSwitch, "alpha", 0, 1)
-                .build();
+    private void updateSettingsAnimator() {
+        mSettingsAlpha = createSettingsAlphaAnimator();
 
         final boolean isRtl = isLayoutRtl();
         if (isRtl && mDateTimeGroup.getWidth() == 0) {
@@ -221,6 +233,27 @@
         }
     }
 
+    @Nullable
+    private TouchAnimator createSettingsAlphaAnimator() {
+        // If the settings icon is not shown and the user switcher is always shown, then there
+        // is nothing to animate.
+        if (!mShowEditIcon && mAlwaysShowMultiUserSwitch) {
+            return null;
+        }
+
+        TouchAnimator.Builder animatorBuilder = new TouchAnimator.Builder();
+
+        if (mShowEditIcon) {
+            animatorBuilder.addFloat(mEdit, "alpha", 0, 1);
+        }
+
+        if (!mAlwaysShowMultiUserSwitch) {
+            animatorBuilder.addFloat(mMultiUserSwitch, "alpha", 0, 1);
+        }
+
+        return animatorBuilder.build();
+    }
+
     @Override
     public int getCollapsedHeight() {
         return getHeight();
@@ -261,7 +294,10 @@
         mExpansionAmount = headerExpansionFraction;
         updateDateTimePosition();
         mAnimator.setPosition(headerExpansionFraction);
-        mSettingsAlpha.setPosition(headerExpansionFraction);
+
+        if (mSettingsAlpha != null) {
+            mSettingsAlpha.setPosition(headerExpansionFraction);
+        }
 
         updateAlarmVisibilities();
 
@@ -302,7 +338,7 @@
         });
     }
 
-    protected void updateVisibilities() {
+    private void updateVisibilities() {
         updateAlarmVisibilities();
         updateDateTimePosition();
         mEmergencyOnly.setVisibility(mExpanded && (mShowEmergencyCallsOnly || mIsRoaming)
@@ -310,9 +346,14 @@
         mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
                 TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
         final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
-        mMultiUserSwitch.setVisibility(mExpanded && mMultiUserSwitch.hasMultipleUsers() && !isDemo
+
+        mMultiUserSwitch.setVisibility((mExpanded || mAlwaysShowMultiUserSwitch)
+                && mMultiUserSwitch.hasMultipleUsers() && !isDemo
                 ? View.VISIBLE : View.INVISIBLE);
-        mEdit.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
+
+        if (mShowEditIcon) {
+            mEdit.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
+        }
     }
 
     private void updateDateTimePosition() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 8fcbf38..b30d3ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -23,13 +23,13 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.support.v4.graphics.ColorUtils;
+import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
-
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -49,7 +49,6 @@
             = new PathInterpolator(0f, 0, 0.7f, 1f);
     public static final Interpolator KEYGUARD_FADE_OUT_INTERPOLATOR_LOCKED
             = new PathInterpolator(0.3f, 0f, 0.8f, 1f);
-    private static final float SCRIM_BEHIND_ALPHA = 0.62f;
     protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
     protected static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
     private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
@@ -66,7 +65,7 @@
     private final View mHeadsUpScrim;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
 
-    protected float mScrimBehindAlpha = SCRIM_BEHIND_ALPHA;
+    protected float mScrimBehindAlpha;
     protected float mScrimBehindAlphaKeyguard = SCRIM_BEHIND_ALPHA_KEYGUARD;
     protected float mScrimBehindAlphaUnlocking = SCRIM_BEHIND_ALPHA_UNLOCKING;
 
@@ -109,6 +108,8 @@
         mUnlockMethodCache = UnlockMethodCache.getInstance(context);
         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
         mLightBarController = lightBarController;
+        mScrimBehindAlpha = context.getResources().getFloat(R.dimen.scrim_behind_alpha);
+
         updateHeadsUpScrim(false);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 270476e..54c67d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1,3 +1,5 @@
+
+
 /*
  * Copyright (C) 2010 The Android Open Source Project
  *
@@ -69,6 +71,7 @@
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.media.session.PlaybackState;
+import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -112,6 +115,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.NotificationMessagingUtil;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -269,8 +273,6 @@
     protected static final int MSG_TOGGLE_RECENTS_APPS = 1021;
     protected static final int MSG_PRELOAD_RECENT_APPS = 1022;
     protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
-    protected static final int MSG_SHOW_NEXT_AFFILIATED_TASK = 1024;
-    protected static final int MSG_SHOW_PREV_AFFILIATED_TASK = 1025;
     protected static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU = 1026;
     protected static final int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
 
@@ -280,8 +282,8 @@
     private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
 
     // Should match the values in PhoneWindowManager
-    public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
     public static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
+    public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
 
     private static final String BANNER_ACTION_CANCEL =
             "com.android.systemui.statusbar.banner_action_cancel";
@@ -406,7 +408,7 @@
     protected PhoneStatusBarView mStatusBarView;
     private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
     protected StatusBarWindowManager mStatusBarWindowManager;
-    private UnlockMethodCache mUnlockMethodCache;
+    protected UnlockMethodCache mUnlockMethodCache;
     private DozeServiceHost mDozeServiceHost;
     private boolean mWakeUpComingFromTouch;
     private PointF mWakeUpTouchLocation;
@@ -601,8 +603,6 @@
             new ArraySet<>();
     private long mLastVisibilityReportUptimeMs;
 
-    private final ShadeUpdates mShadeUpdates = new ShadeUpdates();
-
     private Runnable mLaunchTransitionEndRunnable;
     protected boolean mLaunchTransitionFadingAway;
     private ExpandableNotificationRow mDraggedDownRow;
@@ -701,11 +701,14 @@
         }
     };
 
+    private NotificationMessagingUtil mMessagingUtil;
     private KeyguardUserSwitcher mKeyguardUserSwitcher;
     private UserSwitcherController mUserSwitcherController;
     private NetworkController mNetworkController;
     private KeyguardMonitorImpl mKeyguardMonitor;
     private BatteryController mBatteryController;
+    private LogMaker mStatusBarStateLog;
+    private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
 
     private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
         final int N = array.size();
@@ -763,6 +766,7 @@
                 Context.DEVICE_POLICY_SERVICE);
 
         mNotificationData = new NotificationData(this);
+        mMessagingUtil = new NotificationMessagingUtil(mContext);
 
         mAccessibilityManager = (AccessibilityManager)
                 mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
@@ -948,19 +952,7 @@
 
         inflateStatusBarWindow(context);
         mStatusBarWindow.setService(this);
-        mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() {
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                checkUserAutohide(v, event);
-                checkRemoteInputOutside(event);
-                if (event.getAction() == MotionEvent.ACTION_DOWN) {
-                    if (mExpandedVisible) {
-                        animateCollapsePanels();
-                    }
-                }
-                return mStatusBarWindow.onTouchEvent(event);
-            }
-        });
+        mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
 
         mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
                 R.id.notification_panel);
@@ -1223,6 +1215,23 @@
         }
     }
 
+    /**
+     * Returns the {@link android.view.View.OnTouchListener} that will be invoked when the
+     * background window of the status bar is clicked.
+     */
+    protected View.OnTouchListener getStatusBarWindowTouchListener() {
+        return (v, event) -> {
+            checkUserAutohide(v, event);
+            checkRemoteInputOutside(event);
+            if (event.getAction() == MotionEvent.ACTION_DOWN) {
+                if (mExpandedVisible) {
+                    animateCollapsePanels();
+                }
+            }
+            return mStatusBarWindow.onTouchEvent(event);
+        };
+    }
+
     private void inflateShelf() {
         mNotificationShelf =
                 (NotificationShelf) LayoutInflater.from(mContext).inflate(
@@ -1490,7 +1499,7 @@
                     ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null, metricsDockAction);
         } else {
             Divider divider = getComponent(Divider.class);
-            if (divider != null && divider.isMinimized()) {
+            if (divider != null && divider.isMinimized() && !divider.isHomeStackResizable()) {
                 // Undocking from the minimized state is not supported
                 return false;
             } else {
@@ -1883,7 +1892,6 @@
         updateEmptyShadeView();
 
         updateQsExpansionEnabled();
-        mShadeUpdates.check();
 
         // Let's also update the icons
         mIconController.updateNotificationIcons(mNotificationData);
@@ -2752,28 +2760,6 @@
         @Override
         public void handleMessage(Message m) {
             switch (m.what) {
-                // start old BaseStatusBar.H handling.
-                case MSG_SHOW_RECENT_APPS:
-                    showRecents(m.arg1 > 0, m.arg2 != 0);
-                    break;
-                case MSG_HIDE_RECENT_APPS:
-                    hideRecents(m.arg1 > 0, m.arg2 > 0);
-                    break;
-                case MSG_TOGGLE_RECENTS_APPS:
-                    toggleRecents();
-                    break;
-                case MSG_PRELOAD_RECENT_APPS:
-                    preloadRecents();
-                    break;
-                case MSG_CANCEL_PRELOAD_RECENT_APPS:
-                    cancelPreloadingRecents();
-                    break;
-                case MSG_SHOW_NEXT_AFFILIATED_TASK:
-                    showRecentsNextAffiliatedTask();
-                    break;
-                case MSG_SHOW_PREV_AFFILIATED_TASK:
-                    showRecentsPreviousAffiliatedTask();
-                    break;
                 case MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU:
                     toggleKeyboardShortcuts(m.arg1);
                     break;
@@ -3082,24 +3068,6 @@
     }
 
     @Override // CommandQueue
-    public void buzzBeepBlinked() {
-    }
-
-    @Override
-    public void notificationLightOff() {
-        if (mDozeServiceHost != null) {
-            mDozeServiceHost.fireNotificationLight(false);
-        }
-    }
-
-    @Override
-    public void notificationLightPulse(int argb, int onMillis, int offMillis) {
-        if (mDozeServiceHost != null) {
-            mDozeServiceHost.fireNotificationLight(true);
-        }
-    }
-
-    @Override // CommandQueue
     public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
             int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
         final int oldVal = mSystemUiVisibility;
@@ -3427,6 +3395,9 @@
         } else {
             pw.println("  mGroupManager: null");
         }
+
+        mLightBarController.dump(fd, pw, args);
+
         if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
             KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
         }
@@ -3828,6 +3799,13 @@
                 isSecure,
                 canSkipBouncer);
         if (stateFingerprint != mLastLoggedStateFingerprint) {
+            if (mStatusBarStateLog == null) {
+                mStatusBarStateLog = new LogMaker(MetricsEvent.VIEW_UNKNOWN);
+            }
+            MetricsLogger.action(mStatusBarStateLog
+                    .setCategory(isBouncerShowing ? MetricsEvent.BOUNCER : MetricsEvent.LOCKSCREEN)
+                    .setType(isShowing ? MetricsEvent.TYPE_OPEN : MetricsEvent.TYPE_CLOSE)
+                    .setSubtype(isSecure ? 1 : 0));
             EventLogTags.writeSysuiStatusBarState(mState,
                     isShowing ? 1 : 0,
                     isOccluded ? 1 : 0,
@@ -4508,8 +4486,8 @@
 
     @Override
     public void onActivated(ActivatableNotificationView view) {
-        EventLogTags.writeSysuiLockscreenGesture(
-                EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_TAP_NOTIFICATION_ACTIVATE,
+        mLockscreenGestureLogger.write(
+                MetricsEvent.ACTION_LS_NOTE,
                 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
         mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
         ActivatableNotificationView previousView = mStackScroller.getActivatedChild();
@@ -4626,8 +4604,8 @@
     @Override
     public boolean onDraggedDown(View startingChild, int dragLengthY) {
         if (hasActiveNotifications() && (!isDozing() || isPulsing())) {
-            EventLogTags.writeSysuiLockscreenGesture(
-                    EventLogConstants.SYSUI_LOCKSCREEN_GESTURE_SWIPE_DOWN_FULL_SHADE,
+            mLockscreenGestureLogger.write(
+                    MetricsEvent.ACTION_LS_SHADE,
                     (int) (dragLengthY / mDisplayMetrics.density),
                     0 /* velocityDp - N/A */);
 
@@ -5060,44 +5038,9 @@
         return mStatusBarKeyguardViewManager.isShowing();
     }
 
-    private final class ShadeUpdates {
-        private final ArraySet<String> mVisibleNotifications = new ArraySet<String>();
-        private final ArraySet<String> mNewVisibleNotifications = new ArraySet<String>();
-
-        public void check() {
-            mNewVisibleNotifications.clear();
-            ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
-            for (int i = 0; i < activeNotifications.size(); i++) {
-                final Entry entry = activeNotifications.get(i);
-                final boolean visible = entry.row != null
-                        && entry.row.getVisibility() == View.VISIBLE;
-                if (visible) {
-                    mNewVisibleNotifications.add(entry.key + entry.notification.getPostTime());
-                }
-            }
-            final boolean updates = !mVisibleNotifications.containsAll(mNewVisibleNotifications);
-            mVisibleNotifications.clear();
-            mVisibleNotifications.addAll(mNewVisibleNotifications);
-
-            // We have new notifications
-            if (updates && mDozeServiceHost != null) {
-                mDozeServiceHost.fireNewNotifications();
-            }
-        }
-    }
-
     private final class DozeServiceHost implements DozeHost {
-        // Amount of time to allow to update the time shown on the screen before releasing
-        // the wakelock.  This timeout is design to compensate for the fact that we don't
-        // currently have a way to know when time display contents have actually been
-        // refreshed once we've finished rendering a new frame.
-        private static final long PROCESSING_TIME = 500;
-
         private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
 
-        // Keeps the last reported state by fireNotificationLight.
-        private boolean mNotificationLightOn;
-
         @Override
         public String toString() {
             return "PSB.DozeServiceHost[mCallbacks=" + mCallbacks.size() + "]";
@@ -5115,19 +5058,6 @@
             }
         }
 
-        public void fireNotificationLight(boolean on) {
-            mNotificationLightOn = on;
-            for (Callback callback : mCallbacks) {
-                callback.onNotificationLight(on);
-            }
-        }
-
-        public void fireNewNotifications() {
-            for (Callback callback : mCallbacks) {
-                callback.onNewNotifications();
-            }
-        }
-
         @Override
         public void addCallback(@NonNull Callback callback) {
             mCallbacks.add(callback);
@@ -5193,11 +5123,6 @@
         }
 
         @Override
-        public boolean isNotificationLightOn() {
-            return mNotificationLightOn;
-        }
-
-        @Override
         public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
             StatusBar.this.startPendingIntentDismissingKeyguard(intent);
         }
@@ -5779,20 +5704,21 @@
                     PendingIntent.FLAG_CANCEL_CURRENT);
 
             final int colorRes = com.android.internal.R.color.system_notification_accent_color;
-            Notification.Builder note = new Notification.Builder(mContext)
-                    .setSmallIcon(R.drawable.ic_android)
-                    .setContentTitle(mContext.getString(R.string.hidden_notifications_title))
-                    .setContentText(mContext.getString(R.string.hidden_notifications_text))
-                    .setChannel(NotificationChannels.SECURITY)
-                    .setOngoing(true)
-                    .setColor(mContext.getColor(colorRes))
-                    .setContentIntent(setupIntent)
-                    .addAction(R.drawable.ic_close,
-                            mContext.getString(R.string.hidden_notifications_cancel),
-                            cancelIntent)
-                    .addAction(R.drawable.ic_settings,
-                            mContext.getString(R.string.hidden_notifications_setup),
-                            setupIntent);
+            Notification.Builder note =
+                    new Notification.Builder(mContext, NotificationChannels.GENERAL)
+                            .setSmallIcon(R.drawable.ic_android)
+                            .setContentTitle(mContext.getString(
+                                    R.string.hidden_notifications_title))
+                            .setContentText(mContext.getString(R.string.hidden_notifications_text))
+                            .setOngoing(true)
+                            .setColor(mContext.getColor(colorRes))
+                            .setContentIntent(setupIntent)
+                            .addAction(R.drawable.ic_close,
+                                    mContext.getString(R.string.hidden_notifications_cancel),
+                                    cancelIntent)
+                            .addAction(R.drawable.ic_settings,
+                                    mContext.getString(R.string.hidden_notifications_setup),
+                                    setupIntent);
             overrideNotificationAppName(mContext, note);
 
             NotificationManager noMan =
@@ -6072,26 +5998,6 @@
     }
 
     @Override
-    public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
-        int msg = MSG_SHOW_RECENT_APPS;
-        mHandler.removeMessages(msg);
-        mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0, fromHome ? 1 : 0).sendToTarget();
-    }
-
-    @Override
-    public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
-        int msg = MSG_HIDE_RECENT_APPS;
-        mHandler.removeMessages(msg);
-        mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0,
-                triggeredFromHomeKey ? 1 : 0).sendToTarget();
-    }
-
-    @Override
-    public void toggleRecentApps() {
-        toggleRecents();
-    }
-
-    @Override
     public void toggleSplitScreen() {
         toggleSplitScreenMode(-1 /* metricsDockAction */, -1 /* metricsUndockAction */);
     }
@@ -6124,20 +6030,6 @@
         mHandler.obtainMessage(msg, deviceId, 0).sendToTarget();
     }
 
-    /** Jumps to the next affiliated task in the group. */
-    public void showNextAffiliatedTask() {
-        int msg = MSG_SHOW_NEXT_AFFILIATED_TASK;
-        mHandler.removeMessages(msg);
-        mHandler.sendEmptyMessage(msg);
-    }
-
-    /** Jumps to the previous affiliated task in the group. */
-    public void showPreviousAffiliatedTask() {
-        int msg = MSG_SHOW_PREV_AFFILIATED_TASK;
-        mHandler.removeMessages(msg);
-        mHandler.sendEmptyMessage(msg);
-    }
-
     protected void sendCloseSystemWindows(String reason) {
         try {
             ActivityManager.getService().closeSystemDialogs(reason);
@@ -6145,33 +6037,6 @@
         }
     }
 
-    /** Proxy for RecentsComponent */
-
-    protected void showRecents(boolean triggeredFromAltTab, boolean fromHome) {
-        if (mRecents != null) {
-            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
-            mRecents.showRecents(triggeredFromAltTab, fromHome);
-        }
-    }
-
-    protected void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
-        if (mRecents != null) {
-            mRecents.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
-        }
-    }
-
-    protected void toggleRecents() {
-        if (mRecents != null) {
-            mRecents.toggleRecents(mDisplay);
-        }
-    }
-
-    protected void preloadRecents() {
-        if (mRecents != null) {
-            mRecents.preloadRecents();
-        }
-    }
-
     protected void toggleKeyboardShortcuts(int deviceId) {
         KeyboardShortcuts.toggle(mContext, deviceId);
     }
@@ -6180,24 +6045,6 @@
         KeyboardShortcuts.dismiss();
     }
 
-    protected void cancelPreloadingRecents() {
-        if (mRecents != null) {
-            mRecents.cancelPreloadingRecents();
-        }
-    }
-
-    protected void showRecentsNextAffiliatedTask() {
-        if (mRecents != null) {
-            mRecents.showNextAffiliatedTask();
-        }
-    }
-
-    protected void showRecentsPreviousAffiliatedTask() {
-        if (mRecents != null) {
-            mRecents.showPrevAffiliatedTask();
-        }
-    }
-
     /**
      * Save the current "public" (locked and secure) state of the lockscreen.
      */
@@ -6321,8 +6168,10 @@
 
         final StatusBarNotification sbn = entry.notification;
         boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
+        boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(sbn,
+                mNotificationData.getImportance(sbn.getKey()));
         try {
-            entry.cacheContentViews(mContext, null, isLowPriority);
+            entry.cacheContentViews(mContext, null, isLowPriority, useIncreasedCollapsedHeight);
         } catch (RuntimeException e) {
             Log.e(TAG, "Unable to get notification remote views", e);
             return false;
@@ -6492,6 +6341,7 @@
             row.setUserExpanded(userExpanded);
         }
         row.setUserLocked(userLocked);
+        row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
         row.onNotificationUpdated(entry);
         return true;
     }
@@ -6981,10 +6831,13 @@
         Notification n = notification.getNotification();
         mNotificationData.updateRanking(ranking);
 
+        boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(notification,
+                mNotificationData.getImportance(notification.getKey()));
+        entry.row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
         boolean applyInPlace;
         try {
             applyInPlace = entry.cacheContentViews(mContext, notification.getNotification(),
-                    mNotificationData.isAmbient(key));
+                    mNotificationData.isAmbient(key), useIncreasedCollapsedHeight);
         } catch (RuntimeException e) {
             Log.e(TAG, "Unable to get notification remote views", e);
             applyInPlace = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 46ca3c6..41f8a91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -36,6 +36,7 @@
 import android.widget.TextView;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.BatteryMeterView;
+import com.android.systemui.Dependency;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -127,7 +128,7 @@
         mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone);
         loadDimens();
 
-        TunerService.get(mContext).addTunable(this, ICON_BLACKLIST);
+        Dependency.get(TunerService.class).addTunable(this, ICON_BLACKLIST);
 
         mTransitionsController = new LightBarTransitionsController(this::setIconTintInternal);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 9cc9749..ffc0d97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -108,7 +108,7 @@
 
             getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter,
                     null, Dependency.get(Dependency.TIME_TICK_HANDLER));
-            TunerService.get(getContext()).addTunable(this, CLOCK_SECONDS,
+            Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
                     StatusBarIconController.ICON_BLACKLIST);
         }
 
@@ -129,7 +129,7 @@
         if (mAttached) {
             getContext().unregisterReceiver(mIntentReceiver);
             mAttached = false;
-            TunerService.get(getContext()).removeTunable(this);
+            Dependency.get(TunerService.class).removeTunable(this);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index fd71f43..7a32bf1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -560,18 +560,20 @@
         private void showLogoutNotification(int userId) {
             PendingIntent logoutPI = PendingIntent.getBroadcastAsUser(mContext,
                     0, new Intent(ACTION_LOGOUT_USER), 0, UserHandle.SYSTEM);
-            Notification.Builder builder = new Notification.Builder(mContext)
-                    .setVisibility(Notification.VISIBILITY_SECRET)
-                    .setChannel(NotificationChannels.USER)
-                    .setSmallIcon(R.drawable.ic_person)
-                    .setContentTitle(mContext.getString(R.string.user_logout_notification_title))
-                    .setContentText(mContext.getString(R.string.user_logout_notification_text))
-                    .setContentIntent(logoutPI)
-                    .setOngoing(true)
-                    .setShowWhen(false)
-                    .addAction(R.drawable.ic_delete,
-                            mContext.getString(R.string.user_logout_notification_action),
-                            logoutPI);
+            Notification.Builder builder =
+                    new Notification.Builder(mContext, NotificationChannels.GENERAL)
+                            .setVisibility(Notification.VISIBILITY_SECRET)
+                            .setSmallIcon(R.drawable.ic_person)
+                            .setContentTitle(mContext.getString(
+                                    R.string.user_logout_notification_title))
+                            .setContentText(mContext.getString(
+                                    R.string.user_logout_notification_text))
+                            .setContentIntent(logoutPI)
+                            .setOngoing(true)
+                            .setShowWhen(false)
+                            .addAction(R.drawable.ic_delete,
+                                    mContext.getString(R.string.user_logout_notification_action),
+                                    logoutPI);
             SystemUI.overrideNotificationAppName(mContext, builder);
             NotificationManager.from(mContext).notifyAsUser(TAG_LOGOUT_USER,
                     SystemMessage.NOTE_LOGOUT_USER, builder.build(), new UserHandle(userId));
@@ -584,17 +586,17 @@
         PendingIntent removeGuestPI = canSwitchUsers ? PendingIntent.getBroadcastAsUser(mContext,
                 0, new Intent(ACTION_REMOVE_GUEST), 0, UserHandle.SYSTEM) : null;
 
-        Notification.Builder builder = new Notification.Builder(mContext)
-                .setVisibility(Notification.VISIBILITY_SECRET)
-                .setChannel(NotificationChannels.USER)
-                .setSmallIcon(R.drawable.ic_person)
-                .setContentTitle(mContext.getString(R.string.guest_notification_title))
-                .setContentText(mContext.getString(R.string.guest_notification_text))
-                .setContentIntent(removeGuestPI)
-                .setShowWhen(false)
-                .addAction(R.drawable.ic_delete,
-                        mContext.getString(R.string.guest_notification_remove_action),
-                        removeGuestPI);
+        Notification.Builder builder =
+                new Notification.Builder(mContext, NotificationChannels.GENERAL)
+                        .setVisibility(Notification.VISIBILITY_SECRET)
+                        .setSmallIcon(R.drawable.ic_person)
+                        .setContentTitle(mContext.getString(R.string.guest_notification_title))
+                        .setContentText(mContext.getString(R.string.guest_notification_text))
+                        .setContentIntent(removeGuestPI)
+                        .setShowWhen(false)
+                        .addAction(R.drawable.ic_delete,
+                                mContext.getString(R.string.guest_notification_remove_action),
+                                removeGuestPI);
         SystemUI.overrideNotificationAppName(mContext, builder);
         NotificationManager.from(mContext).notifyAsUser(TAG_REMOVE_GUEST,
                 SystemMessage.NOTE_REMOVE_GUEST, builder.build(), new UserHandle(guestUserId));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 85b1c32..11927729 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -27,6 +27,7 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -55,7 +56,6 @@
 import android.view.animation.Interpolator;
 import android.widget.OverScroller;
 import android.widget.ScrollView;
-
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.ExpandHelper;
@@ -114,6 +114,7 @@
     private boolean mSwipingInProgress;
     private int mCurrentStackHeight = Integer.MAX_VALUE;
     private final Paint mBackgroundPaint = new Paint();
+    private boolean mShouldDrawNotificationBackground;
 
     private float mExpandedHeight;
     private int mOwnScrollY;
@@ -229,6 +230,7 @@
     private NotificationMenuRow mCurrIconRow;
     private View mTranslatingParentView;
     private View mGearExposedView;
+    private boolean mShouldShowGear;
 
     /**
      * Should in this touch motion only be scrolling allowed? It's true when the scroller was
@@ -378,10 +380,12 @@
     public NotificationStackScrollLayout(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
+        Resources res = getResources();
+
         mAmbientState = new AmbientState(context);
         mBgColor = context.getColor(R.color.notification_shade_background_color);
-        int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
-        int maxHeight = getResources().getDimensionPixelSize(R.dimen.notification_max_height);
+        int minHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
+        int maxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
         mExpandHelper = new ExpandHelper(getContext(), this,
                 minHeight, maxHeight);
         mExpandHelper.setEventSource(this);
@@ -390,14 +394,18 @@
         mSwipeHelper.setLongPressListener(mLongPressListener);
         mStackScrollAlgorithm = createStackScrollAlgorithm(context);
         initView(context);
-        setWillNotDraw(false);
+        mFalsingManager = FalsingManager.getInstance(context);
+        mShouldShowGear = res.getBoolean(R.bool.config_showNotificationGear);
+        mShouldDrawNotificationBackground =
+                res.getBoolean(R.bool.config_drawNotificationBackground);
+
+        updateWillNotDraw();
         if (DEBUG) {
             mDebugPaint = new Paint();
             mDebugPaint.setColor(0xffff0000);
             mDebugPaint.setStrokeWidth(2);
             mDebugPaint.setStyle(Paint.Style.STROKE);
         }
-        mFalsingManager = FalsingManager.getInstance(context);
     }
 
     @Override
@@ -424,10 +432,11 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        if (mCurrentBounds.top < mCurrentBounds.bottom) {
+        if (mShouldDrawNotificationBackground && mCurrentBounds.top < mCurrentBounds.bottom) {
             canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom,
                     mBackgroundPaint);
         }
+
         if (DEBUG) {
             int y = mTopPadding;
             canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
@@ -439,6 +448,11 @@
     }
 
     private void updateBackgroundDimming() {
+        // No need to update the background color if it's not being drawn.
+        if (!mShouldDrawNotificationBackground) {
+            return;
+        }
+
         float alpha = BACKGROUND_ALPHA_DIMMED + (1 - BACKGROUND_ALPHA_DIMMED) * (1.0f - mDimAmount);
         alpha *= mBackgroundFadeAmount;
         // We need to manually blend in the background color
@@ -487,6 +501,10 @@
     }
 
     private void updateSrcDrawing() {
+        if (!mShouldDrawNotificationBackground) {
+            return;
+        }
+
         mBackgroundPaint.setXfermode(mDrawBackgroundAsSrc && !mFadingOut && !mParentNotFullyVisible
                 ? mSrcMode : null);
         invalidate();
@@ -1967,9 +1985,11 @@
     }
 
     private void updateBackground() {
-        if (mAmbientState.isDark()) {
+        // No need to update the background color if it's not being drawn.
+        if (!mShouldDrawNotificationBackground || mAmbientState.isDark()) {
             return;
         }
+
         updateBackgroundBounds();
         if (!mCurrentBounds.equals(mBackgroundBounds)) {
             boolean animate = mAnimateNextBackgroundTop || mAnimateNextBackgroundBottom
@@ -2119,6 +2139,12 @@
     }
 
     private void applyCurrentBackgroundBounds() {
+        // If the background of the notification is not being drawn, then there is no need to
+        // exclude an area in the scrim. Rather, the scrim's color should serve as the background.
+        if (!mShouldDrawNotificationBackground) {
+            return;
+        }
+
         mScrimController.setExcludedBackgroundArea(
                 mFadingOut || mParentNotFullyVisible || mAmbientState.isDark() || mIsClipped ? null
                         : mCurrentBounds);
@@ -2740,6 +2766,7 @@
 
     private void updateNotificationAnimationStates() {
         boolean running = mAnimationsEnabled || mPulsing;
+        mShelf.setAnimationsEnabled(running);
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             View child = getChildAt(i);
@@ -3545,16 +3572,29 @@
         }
         requestChildrenUpdate();
         if (dark) {
-            setWillNotDraw(!DEBUG);
             mScrimController.setExcludedBackgroundArea(null);
         } else {
             updateBackground();
-            setWillNotDraw(false);
         }
+
+        updateWillNotDraw();
         updateContentHeight();
         notifyHeightChangeListener(mShelf);
     }
 
+    /**
+     * Updates whether or not this Layout will perform its own custom drawing (i.e. whether or
+     * not {@link #onDraw(Canvas)} is called). This method should be called whenever the
+     * {@link #mAmbientState}'s dark mode is toggled.
+     */
+    private void updateWillNotDraw() {
+       if (mAmbientState.isDark()) {
+           setWillNotDraw(!DEBUG);
+       } else {
+           setWillNotDraw(!mShouldDrawNotificationBackground && !DEBUG);
+       }
+    }
+
     private void setBackgroundFadeAmount(float fadeAmount) {
         mBackgroundFadeAmount = fadeAmount;
         updateBackgroundDimming();
@@ -4106,14 +4146,14 @@
      * A listener that is notified when some child locations might have changed.
      */
     public interface OnChildLocationsChangedListener {
-        public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout);
+        void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout);
     }
 
     /**
      * A listener that is notified when the empty space below the notifications is clicked on
      */
     public interface OnEmptySpaceClickListener {
-        public void onEmptySpaceClicked(float x, float y);
+        void onEmptySpaceClicked(float x, float y);
     }
 
     /**
@@ -4129,7 +4169,7 @@
          *                     unrubberbanded motion to directly expand overscroll view (e.g expand
          *                     QS)
          */
-        public void onOverscrollTopChanged(float amount, boolean isRubberbanded);
+        void onOverscrollTopChanged(float amount, boolean isRubberbanded);
 
         /**
          * Notify a listener that the scroller wants to escape from the scrolling motion and
@@ -4138,7 +4178,7 @@
          * @param velocity The velocity that the Scroller had when over flinging
          * @param open Should the fling open or close the overscroll view.
          */
-        public void flingTopOverscroll(float velocity, boolean open);
+        void flingTopOverscroll(float velocity, boolean open);
     }
 
     private class NotificationSwipeHelper extends SwipeHelper {
@@ -4216,7 +4256,7 @@
             final boolean gutsExposed = (view instanceof ExpandableNotificationRow)
                     && ((ExpandableNotificationRow) view).areGutsExposed();
 
-            if (!isPinnedHeadsUp(view) && !gutsExposed) {
+            if (mShouldShowGear && !isPinnedHeadsUp(view) && !gutsExposed) {
                 // Only show the gear if we're not a heads up view and guts aren't exposed.
                 checkForDrag();
             }
@@ -4259,11 +4299,19 @@
                 return false; // Let SwipeHelper handle it.
             }
 
+            // If the gear icon should not be shown, then there is no need to check if the a swipe
+            // should result in a snapping to the gear icon. As a result, just check if the swipe
+            // was enough to dismiss the notification.
+            if (!mShouldShowGear) {
+                dismissOrSnapBack(animView, velocity, ev);
+                return true;
+            }
+
             boolean gestureTowardsGear = isTowardsGear(velocity, mCurrIconRow.isMenuOnLeft());
             boolean gestureFastEnough = Math.abs(velocity) > getEscapeVelocity();
             final double timeForGesture = ev.getEventTime() - ev.getDownTime();
             final boolean showGearForSlowOnGoing = !canChildBeDismissed(animView)
-                && timeForGesture >= SWIPE_GEAR_TIMING;
+                    && timeForGesture >= SWIPE_GEAR_TIMING;
 
             if (mGearSnappedTo && mCurrIconRow.isVisible()) {
                 if (mGearSnappedOnLeft == mCurrIconRow.isMenuOnLeft()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index ab562d1..5d11ef3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -42,104 +42,11 @@
     private IStatusBarService mBarService;
 
     @Override
-    public void setIcon(String slot, StatusBarIcon icon) {
-    }
-
-    @Override
-    public void removeIcon(String slot) {
-    }
-
-    public void removeNotification(String key, RankingMap ranking) {
-    }
-
-    @Override
-    public void disable(int state1, int state2, boolean animate) {
-    }
-
-    @Override
-    public void animateExpandNotificationsPanel() {
-    }
-
-    @Override
-    public void animateCollapsePanels(int flags) {
-    }
-
-    @Override
-    public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
-            int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
-    }
-
-    @Override
-    public void topAppWindowChanged(boolean visible) {
-    }
-
-    @Override
-    public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
-            boolean showImeSwitcher) {
-    }
-
-    @Override // CommandQueue
-    public void setWindowState(int window, int state) {
-    }
-
-    @Override // CommandQueue
-    public void buzzBeepBlinked() {
-    }
-
-    @Override // CommandQueue
-    public void notificationLightOff() {
-    }
-
-    @Override // CommandQueue
-    public void notificationLightPulse(int argb, int onMillis, int offMillis) {
-    }
-
-    @Override
-    public void animateExpandSettingsPanel(String subPanel) {
-    }
-
-    @Override
-    public void showScreenPinningRequest(int taskId) {
-    }
-
-    @Override
-    public void appTransitionPending() {
-    }
-
-    @Override
-    public void appTransitionCancelled() {
-    }
-
-    @Override
-    public void appTransitionStarting(long startTime, long duration) {
-    }
-
-    @Override
-    public void appTransitionFinished() {
-    }
-
-    @Override
-    public void onCameraLaunchGestureDetected(int source) {
-    }
-
-    @Override
     public void showTvPictureInPictureMenu() {
         PipManager.getInstance().showTvPictureInPictureMenu();
     }
 
     @Override
-    public void addQsTile(ComponentName tile) {
-    }
-
-    @Override
-    public void remQsTile(ComponentName tile) {
-    }
-
-    @Override
-    public void clickTile(ComponentName tile) {
-    }
-
-    @Override
     public void start() {
         putComponent(TvStatusBar.class, this);
         CommandQueue commandQueue = getComponent(CommandQueue.class);
@@ -160,8 +67,4 @@
         }
     }
 
-    @Override
-    public void handleSystemNavigationKey(int arg1) {
-        // Not implemented
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
index 9998283..3058c0a 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/BatteryPreference.java
@@ -22,6 +22,7 @@
 import android.util.AttributeSet;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 
 import static com.android.systemui.BatteryMeterDrawable.SHOW_PERCENT_SETTING;
@@ -49,12 +50,12 @@
         super.onAttached();
         mHasPercentage = Settings.System.getInt(getContext().getContentResolver(),
                 SHOW_PERCENT_SETTING, 0) != 0;
-        TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+        Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
     }
 
     @Override
     public void onDetached() {
-        TunerService.get(getContext()).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
         super.onDetached();
     }
 
@@ -89,7 +90,7 @@
         } else {
             mBlacklist.remove(mBattery);
         }
-        TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
+        Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_BLACKLIST,
                 TextUtils.join(",", mBlacklist));
         return true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
index caa0527..014ec92 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/ClockPreference.java
@@ -18,6 +18,8 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.AttributeSet;
+
+import com.android.systemui.Dependency;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.Clock;
 
@@ -44,13 +46,13 @@
     @Override
     public void onAttached() {
         super.onAttached();
-        TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
+        Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST,
                 Clock.CLOCK_SECONDS);
     }
 
     @Override
     public void onDetached() {
-        TunerService.get(getContext()).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
         super.onDetached();
     }
 
@@ -81,13 +83,14 @@
 
     @Override
     protected boolean persistString(String value) {
-        TunerService.get(getContext()).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1 : 0);
+        Dependency.get(TunerService.class).setValue(Clock.CLOCK_SECONDS, SECONDS.equals(value) ? 1
+                : 0);
         if (DISABLED.equals(value)) {
             mBlacklist.add(mClock);
         } else {
             mBlacklist.remove(mClock);
         }
-        TunerService.get(getContext()).setValue(StatusBarIconController.ICON_BLACKLIST,
+        Dependency.get(TunerService.class).setValue(StatusBarIconController.ICON_BLACKLIST,
                 TextUtils.join(",", mBlacklist));
         return true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
index 41786b5..9d579f5 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/LockscreenFragment.java
@@ -43,6 +43,7 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
 import com.android.systemui.statusbar.phone.ExpandableIndicator;
@@ -71,7 +72,7 @@
 
     @Override
     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-        mTunerService = TunerService.get(getContext());
+        mTunerService = Dependency.get(TunerService.class);
         mHandler = new Handler();
         addPreferencesFromResource(R.xml.lockscreen_settings);
         setupGroup((PreferenceGroup) findPreference(KEY_LEFT), LOCKSCREEN_LEFT_BUTTON,
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
index 9593c45..28a0057 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/NavBarTuner.java
@@ -51,6 +51,7 @@
 import android.view.KeyEvent;
 import android.widget.EditText;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.NavigationBarInflaterView;
 import com.android.systemui.tuner.TunerService.Tunable;
@@ -104,12 +105,12 @@
     @Override
     public void onDestroy() {
         super.onDestroy();
-        mTunables.forEach(t -> TunerService.get(getContext()).removeTunable(t));
+        mTunables.forEach(t -> Dependency.get(TunerService.class).removeTunable(t));
     }
 
     private void addTunable(Tunable tunable, String... keys) {
         mTunables.add(tunable);
-        TunerService.get(getContext()).addTunable(tunable, keys);
+        Dependency.get(TunerService.class).addTunable(tunable, keys);
     }
 
     private void bindLayout(ListPreference preference) {
@@ -123,7 +124,7 @@
         preference.setOnPreferenceChangeListener((preference1, newValue) -> {
             String val = (String) newValue;
             if ("default".equals(val)) val = null;
-            TunerService.get(getContext()).setValue(NAV_BAR_VIEWS, val);
+            Dependency.get(TunerService.class).setValue(NAV_BAR_VIEWS, val);
             return true;
         });
     }
@@ -215,7 +216,7 @@
             }
             button = button + KEY_CODE_START + code + KEY_IMAGE_DELIM + uri + KEY_CODE_END;
         }
-        TunerService.get(getContext()).setValue(setting, button);
+        Dependency.get(TunerService.class).setValue(setting, button);
     }
 
     private void setupIcons(ListPreference icon) {
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PreviewNavInflater.java b/packages/SystemUI/src/com/android/systemui/tuner/PreviewNavInflater.java
index e6e8f4e..e7a695f 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/PreviewNavInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/PreviewNavInflater.java
@@ -18,6 +18,7 @@
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.statusbar.phone.NavigationBarInflaterView;
 
 public class PreviewNavInflater extends NavigationBarInflaterView {
@@ -31,7 +32,7 @@
         super.onAttachedToWindow();
         // Immediately remove tuner listening, since this is a preview, all values will be injected
         // manually.
-        TunerService.get(getContext()).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
index dea2f50..8a2407a 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
@@ -25,6 +25,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.Dependency;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.tuner.TunerService.Tunable;
 
@@ -41,12 +42,12 @@
     @Override
     public void onAttached() {
         super.onAttached();
-        TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+        Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
     }
 
     @Override
     public void onDetached() {
-        TunerService.get(getContext()).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
         super.onDetached();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 3b14e60..74280a3 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -24,6 +24,7 @@
 import android.util.Log;
 
 import com.android.settingslib.drawer.SettingsDrawerActivity;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 
 public class TunerActivity extends SettingsDrawerActivity implements
@@ -36,6 +37,7 @@
 
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        Dependency.initDependencies(this);
 
         if (getFragmentManager().findFragmentByTag(TAG_TUNER) == null) {
             final String action = getIntent().getAction();
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
index fb94061..ca582b3 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerService.java
@@ -40,6 +40,7 @@
 
 import com.android.systemui.BatteryMeterDrawable;
 import com.android.systemui.DemoMode;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIApplication;
@@ -51,7 +52,7 @@
 import java.util.Set;
 
 
-public class TunerService extends SystemUI {
+public class TunerService {
 
     public static final String ACTION_CLEAR = "com.android.systemui.action.CLEAR_TUNER";
 
@@ -64,13 +65,14 @@
     private final ArrayMap<Uri, String> mListeningUris = new ArrayMap<>();
     // Map of settings keys to the listener.
     private final HashMap<String, Set<Tunable>> mTunableLookup = new HashMap<>();
+    private final Context mContext;
 
     private ContentResolver mContentResolver;
     private int mCurrentUser;
     private CurrentUserTracker mUserTracker;
 
-    @Override
-    public void start() {
+    public TunerService(Context context) {
+        mContext = context;
         mContentResolver = mContext.getContentResolver();
 
         for (UserInfo user : UserManager.get(mContext).getUsers()) {
@@ -79,7 +81,6 @@
                 upgradeTuner(getValue(TUNER_VERSION, 0), CURRENT_TUNER_VERSION);
             }
         }
-        putComponent(TunerService.class, this);
 
         mCurrentUser = ActivityManager.getCurrentUser();
         mUserTracker = new CurrentUserTracker(mContext) {
@@ -209,32 +210,6 @@
         }
     }
 
-    // Only used in other processes, such as the tuner.
-    private static TunerService sInstance;
-
-    public static TunerService get(Context context) {
-        TunerService service = null;
-        if (context.getApplicationContext() instanceof SystemUIApplication) {
-            SystemUIApplication sysUi = (SystemUIApplication) context.getApplicationContext();
-            service = sysUi.getComponent(TunerService.class);
-        }
-        if (service == null) {
-            // Can't get it as a component, must in the tuner, lets just create one for now.
-            return getStaticService(context);
-        }
-        return service;
-    }
-
-    private static TunerService getStaticService(Context context) {
-        if (sInstance == null) {
-            sInstance = new TunerService();
-            sInstance.mContext = context.getApplicationContext();
-            sInstance.mComponents = new HashMap<>();
-            sInstance.start();
-        }
-        return sInstance;
-    }
-
     public static final void showResetRequest(final Context context, final Runnable onDisabled) {
         SystemUIDialog dialog = new SystemUIDialog(context);
         dialog.setShowForAllUsers(true);
@@ -310,7 +285,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             if (ACTION_CLEAR.equals(intent.getAction())) {
-                get(context).clearAll();
+                Dependency.get(TunerService.class).clearAll();
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
index 5b9ebd7..d5b6ccd 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
@@ -7,6 +7,7 @@
 import android.util.AttributeSet;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.tuner.TunerService.Tunable;
 
@@ -26,12 +27,12 @@
     @Override
     public void onAttached() {
         super.onAttached();
-        TunerService.get(getContext()).addTunable(this, getKey().split(","));
+        Dependency.get(TunerService.class).addTunable(this, getKey().split(","));
     }
 
     @Override
     public void onDetached() {
-        TunerService.get(getContext()).removeTunable(this);
+        Dependency.get(TunerService.class).removeTunable(this);
         super.onDetached();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 9a16d6d..43727e0 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -198,18 +198,19 @@
                         rec.getNickname());
                 final CharSequence text = mContext.getString(R.string.ext_media_missing_message);
 
-                Notification.Builder builder = new Notification.Builder(mContext)
-                        .setSmallIcon(R.drawable.ic_sd_card_48dp)
-                        .setColor(mContext.getColor(R.color.system_notification_accent_color))
-                        .setContentTitle(title)
-                        .setContentText(text)
-                        .setContentIntent(buildForgetPendingIntent(rec))
-                        .setStyle(new Notification.BigTextStyle().bigText(text))
-                        .setVisibility(Notification.VISIBILITY_PUBLIC)
-                        .setLocalOnly(true)
-                        .setChannel(NotificationChannels.STORAGE)
-                        .setCategory(Notification.CATEGORY_SYSTEM)
-                        .setDeleteIntent(buildSnoozeIntent(fsUuid));
+                Notification.Builder builder =
+                        new Notification.Builder(mContext, NotificationChannels.STORAGE)
+                                .setSmallIcon(R.drawable.ic_sd_card_48dp)
+                                .setColor(mContext.getColor(
+                                        R.color.system_notification_accent_color))
+                                .setContentTitle(title)
+                                .setContentText(text)
+                                .setContentIntent(buildForgetPendingIntent(rec))
+                                .setStyle(new Notification.BigTextStyle().bigText(text))
+                                .setVisibility(Notification.VISIBILITY_PUBLIC)
+                                .setLocalOnly(true)
+                                .setCategory(Notification.CATEGORY_SYSTEM)
+                                .setDeleteIntent(buildSnoozeIntent(fsUuid));
                 SystemUI.overrideNotificationAppName(mContext, builder);
 
                 mNotificationManager.notifyAsUser(fsUuid, SystemMessage.NOTE_STORAGE_PRIVATE,
@@ -226,17 +227,17 @@
             final CharSequence text = mContext.getString(
                     R.string.ext_media_unsupported_notification_message, disk.getDescription());
 
-            Notification.Builder builder = new Notification.Builder(mContext)
-                    .setChannel(NotificationChannels.STORAGE)
-                    .setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE))
-                    .setColor(mContext.getColor(R.color.system_notification_accent_color))
-                    .setContentTitle(title)
-                    .setContentText(text)
-                    .setContentIntent(buildInitPendingIntent(disk))
-                    .setStyle(new Notification.BigTextStyle().bigText(text))
-                    .setVisibility(Notification.VISIBILITY_PUBLIC)
-                    .setLocalOnly(true)
-                    .setCategory(Notification.CATEGORY_ERROR);
+            Notification.Builder builder =
+                    new Notification.Builder(mContext, NotificationChannels.STORAGE)
+                            .setSmallIcon(getSmallIcon(disk, VolumeInfo.STATE_UNMOUNTABLE))
+                            .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                            .setContentTitle(title)
+                            .setContentText(text)
+                            .setContentIntent(buildInitPendingIntent(disk))
+                            .setStyle(new Notification.BigTextStyle().bigText(text))
+                            .setVisibility(Notification.VISIBILITY_PUBLIC)
+                            .setLocalOnly(true)
+                            .setCategory(Notification.CATEGORY_ERROR);
             SystemUI.overrideNotificationAppName(mContext, builder);
 
             mNotificationManager.notifyAsUser(disk.getId(), SystemMessage.NOTE_STORAGE_DISK,
@@ -475,19 +476,19 @@
             intent = buildWizardMigratePendingIntent(move);
         }
 
-        Notification.Builder builder = new Notification.Builder(mContext)
-                .setSmallIcon(R.drawable.ic_sd_card_48dp)
-                .setColor(mContext.getColor(R.color.system_notification_accent_color))
-                .setContentTitle(title)
-                .setContentText(text)
-                .setContentIntent(intent)
-                .setStyle(new Notification.BigTextStyle().bigText(text))
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setLocalOnly(true)
-                .setChannel(NotificationChannels.STORAGE)
-                .setCategory(Notification.CATEGORY_PROGRESS)
-                .setProgress(100, status, false)
-                .setOngoing(true);
+        Notification.Builder builder =
+                new Notification.Builder(mContext, NotificationChannels.STORAGE)
+                        .setSmallIcon(R.drawable.ic_sd_card_48dp)
+                        .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(text)
+                        .setContentIntent(intent)
+                        .setStyle(new Notification.BigTextStyle().bigText(text))
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setLocalOnly(true)
+                        .setCategory(Notification.CATEGORY_PROGRESS)
+                        .setProgress(100, status, false)
+                        .setOngoing(true);
         SystemUI.overrideNotificationAppName(mContext, builder);
 
         mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
@@ -526,18 +527,18 @@
             intent = null;
         }
 
-        Notification.Builder builder = new Notification.Builder(mContext)
-                .setSmallIcon(R.drawable.ic_sd_card_48dp)
-                .setColor(mContext.getColor(R.color.system_notification_accent_color))
-                .setContentTitle(title)
-                .setContentText(text)
-                .setContentIntent(intent)
-                .setStyle(new Notification.BigTextStyle().bigText(text))
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setLocalOnly(true)
-                .setCategory(Notification.CATEGORY_SYSTEM)
-                .setChannel(NotificationChannels.STORAGE)
-                .setAutoCancel(true);
+        Notification.Builder builder =
+                new Notification.Builder(mContext, NotificationChannels.STORAGE)
+                        .setSmallIcon(R.drawable.ic_sd_card_48dp)
+                        .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(text)
+                        .setContentIntent(intent)
+                        .setStyle(new Notification.BigTextStyle().bigText(text))
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setLocalOnly(true)
+                        .setCategory(Notification.CATEGORY_SYSTEM)
+                        .setAutoCancel(true);
         SystemUI.overrideNotificationAppName(mContext, builder);
 
         mNotificationManager.notifyAsUser(move.packageName, SystemMessage.NOTE_STORAGE_MOVE,
@@ -562,15 +563,15 @@
 
     private Notification.Builder buildNotificationBuilder(VolumeInfo vol, CharSequence title,
             CharSequence text) {
-        Notification.Builder builder = new Notification.Builder(mContext)
-                .setChannel(NotificationChannels.STORAGE)
-                .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
-                .setColor(mContext.getColor(R.color.system_notification_accent_color))
-                .setContentTitle(title)
-                .setContentText(text)
-                .setStyle(new Notification.BigTextStyle().bigText(text))
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setLocalOnly(true);
+        Notification.Builder builder =
+                new Notification.Builder(mContext, NotificationChannels.STORAGE)
+                        .setSmallIcon(getSmallIcon(vol.getDisk(), vol.getState()))
+                        .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(text)
+                        .setStyle(new Notification.BigTextStyle().bigText(text))
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setLocalOnly(true);
         overrideNotificationAppName(mContext, builder);
         return builder;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index 6bb8aea..15ad0ce 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -27,8 +27,7 @@
 public class NotificationChannels extends SystemUI {
     public static String ALERTS      = "ALR";
     public static String SCREENSHOTS = "SCN";
-    public static String SECURITY    = "SEC";
-    public static String USER        = "USR";
+    public static String GENERAL     = "GEN";
     public static String STORAGE     = "DSK";
 
     @VisibleForTesting
@@ -42,14 +41,10 @@
                 new NotificationChannel(
                         SCREENSHOTS,
                         context.getString(R.string.notification_channel_screenshot),
-                        NotificationManager.IMPORTANCE_DEFAULT),
+                        NotificationManager.IMPORTANCE_LOW),
                 new NotificationChannel(
-                        SECURITY,
-                        context.getString(R.string.notification_channel_security),
-                        NotificationManager.IMPORTANCE_HIGH),
-                new NotificationChannel(
-                        USER,
-                        context.getString(R.string.notification_channel_user_status),
+                        GENERAL,
+                        context.getString(R.string.notification_channel_general),
                         NotificationManager.IMPORTANCE_MIN),
                 new NotificationChannel(
                         STORAGE,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index d057d863..b9cb575 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -69,6 +69,7 @@
 import android.widget.TextView;
 
 import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.ZenModeController;
@@ -165,7 +166,7 @@
 
         controller.addCallback(mControllerCallbackH, mHandler);
         controller.getState();
-        TunerService.get(mContext).addTunable(this, SHOW_FULL_ZEN);
+        Dependency.get(TunerService.class).addTunable(this, SHOW_FULL_ZEN);
 
         final Configuration currentConfig = mContext.getResources().getConfiguration();
         mDensity = currentConfig.densityDpi;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 78145fe..0a1d34f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -72,7 +72,7 @@
         mDialog = new VolumeDialog(context, WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY,
                 mController, mZenModeController, mVolumeDialogCallback);
         applyConfiguration();
-        TunerService.get(mContext).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
+        Dependency.get(TunerService.class).addTunable(this, VOLUME_DOWN_SILENT, VOLUME_UP_SILENT,
                 VOLUME_SILENT_DO_NOT_DISTURB);
     }
 
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index c627e22..cefade0 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -43,6 +43,7 @@
     android-support-v17-leanback
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
+    metrics-helper-lib \
     android-support-test \
     mockito-updated-target-minus-junit4 \
     SystemUI-proto \
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 408e8f3..6d62435 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -17,6 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.systemui.tests">
 
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
     <uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE" />
     <uses-permission android:name="android.permission.INJECT_EVENTS" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
diff --git a/packages/SystemUI/tests/res/layout/custom_view_dark.xml b/packages/SystemUI/tests/res/layout/custom_view_dark.xml
new file mode 100644
index 0000000..9e460a5
--- /dev/null
+++ b/packages/SystemUI/tests/res/layout/custom_view_dark.xml
@@ -0,0 +1,20 @@
+<?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.
+-->
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#ff000000"
+    />
diff --git a/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java
index 447edac..f8f67bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/FragmentTestCase.java
@@ -19,13 +19,17 @@
 import android.app.FragmentController;
 import android.app.FragmentHostCallback;
 import android.app.FragmentManagerNonConfig;
+import android.graphics.PixelFormat;
 import android.os.Handler;
-import android.os.HandlerThread;
+import android.os.Looper;
 import android.os.Parcelable;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
 import android.widget.FrameLayout;
 
+import com.android.systemui.utils.ViewUtils;
 import com.android.systemui.utils.leaks.LeakCheckedTest;
 
 import org.junit.After;
@@ -45,7 +49,6 @@
 
     private static final int VIEW_ID = 42;
     private final Class<? extends Fragment> mCls;
-    private HandlerThread mHandlerThread;
     private Handler mHandler;
     private FrameLayout mView;
     protected FragmentController mFragments;
@@ -59,9 +62,7 @@
     public void setupFragment() throws IllegalAccessException, InstantiationException {
         mView = new FrameLayout(mContext);
         mView.setId(VIEW_ID);
-        mHandlerThread = new HandlerThread("FragmentTestThread");
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
+        mHandler = new Handler(Looper.getMainLooper());
         mFragment = mCls.newInstance();
         postAndWait(() -> {
             mFragments = FragmentController.createController(new HostCallbacks());
@@ -78,7 +79,6 @@
             // Set mFragments to null to let it know not to destroy.
             postAndWait(() -> mFragments.dispatchDestroy());
         }
-        mHandlerThread.quit();
     }
 
     @Test
@@ -100,6 +100,26 @@
     }
 
     @Test
+    public void testAttachDetach() {
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
+                LayoutParams.TYPE_SYSTEM_ALERT,
+                0, PixelFormat.TRANSLUCENT);
+        postAndWait(() -> mFragments.dispatchResume());
+        attachFragmentToWindow();
+        detachFragmentToWindow();
+        postAndWait(() -> mFragments.dispatchPause());
+    }
+
+    protected void attachFragmentToWindow() {
+        ViewUtils.attachView(mView);
+    }
+
+    protected void detachFragmentToWindow() {
+        ViewUtils.detachView(mView);
+    }
+
+    @Test
     public void testRecreate() {
         postAndWait(() -> mFragments.dispatchResume());
         postAndWait(() -> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index f258e5d..81a50d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -65,7 +65,7 @@
         waitForIdleSync(mHandler);
     }
 
-    protected void waitForIdleSync(Handler h) {
+    public static void waitForIdleSync(Handler h) {
         validateThread(h.getLooper());
         Idler idler = new Idler(null);
         h.getLooper().getQueue().addIdleHandler(idler);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index 5345031..29d5a36 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -42,6 +42,7 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.tuner.TunerService;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -60,11 +61,7 @@
     public void addLeakCheckDependencies() {
         injectTestDependency(Dependency.BG_LOOPER, Looper.getMainLooper());
         injectMockDependency(UserSwitcherController.class);
-        injectLeakCheckedDependencies(BluetoothController.class, LocationController.class,
-                RotationLockController.class, NetworkController.class, ZenModeController.class,
-                HotspotController.class, CastController.class, FlashlightController.class,
-                UserInfoController.class, KeyguardMonitor.class, SecurityController.class,
-                BatteryController.class, NextAlarmController.class);
+        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
     }
 
     @Test
@@ -88,6 +85,6 @@
 
         host.destroy();
         // Ensure the tuner cleans up its persistent listeners.
-        TunerService.get(mContext).destroy();
+        Dependency.get(TunerService.class).destroy();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index 43f8629..5b22986 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -171,27 +171,6 @@
     }
 
     @Test
-    public void testBuzzBeepBlink() {
-        mCommandQueue.buzzBeepBlinked();
-        waitForIdleSync();
-        verify(mCallbacks).buzzBeepBlinked();
-    }
-
-    @Test
-    public void testNotificationLightOff() {
-        mCommandQueue.notificationLightOff();
-        waitForIdleSync();
-        verify(mCallbacks).notificationLightOff();
-    }
-
-    @Test
-    public void testNotificationLightPulse() {
-        mCommandQueue.notificationLightPulse(1, 2, 3);
-        waitForIdleSync();
-        verify(mCallbacks).notificationLightPulse(eq(1), eq(2), eq(3));
-    }
-
-    @Test
     public void testScreenPinRequest() {
         mCommandQueue.showScreenPinningRequest(1);
         waitForIdleSync();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
index 3bb9f5f..77f96b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationContentViewTest.java
@@ -16,9 +16,6 @@
 
 package com.android.systemui.statusbar;
 
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 import android.content.Context;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.annotation.UiThreadTest;
@@ -31,6 +28,11 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class NotificationContentViewTest {
@@ -39,13 +41,16 @@
     Context mContext;
 
     @Before
+    @UiThreadTest
     public void setup() {
-        ExpandableNotificationRow rowMock = mock(ExpandableNotificationRow.class);
-        when(rowMock.getIntrinsicHeight()).thenReturn(10);
-
         mContext = InstrumentationRegistry.getTargetContext();
         mView = new NotificationContentView(mContext, null);
-        mView.setContainingNotification(rowMock);
+        ExpandableNotificationRow row = new ExpandableNotificationRow(mContext, null);
+        ExpandableNotificationRow mockRow = spy(row);
+        doNothing().when(mockRow).updateBackgroundAlpha(anyFloat());
+        doReturn(10).when(mockRow).getIntrinsicHeight();
+
+        mView.setContainingNotification(mockRow);
         mView.setHeights(10, 20, 30, 40);
 
         mView.setContractedChild(createViewWithHeight(10));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
new file mode 100644
index 0000000..d07cea1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+import android.widget.RemoteViews;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.NotificationCustomViewWrapper;
+import com.android.systemui.statusbar.notification.NotificationViewWrapper;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NotificationCustomViewWrapperTest {
+
+    private Context mContext;
+    private ExpandableNotificationRow mRow;
+
+    @Before
+    @UiThreadTest
+    public void setUp() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mRow = new ExpandableNotificationRow(mContext, null);
+    }
+
+    @Test
+    public void testBackgroundPersists() {
+        RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.custom_view_dark);
+        View v = views.apply(mContext, null);
+        NotificationViewWrapper wrap = NotificationCustomViewWrapper.wrap(mContext, v, mRow);
+        wrap.notifyContentUpdated(null, false /* isLowPriority */);
+        Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
+        views.reapply(mContext, v);
+        wrap.notifyContentUpdated(null, false /* isLowPriority */);
+        Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
+    }
+
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
new file mode 100644
index 0000000..7141170
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar;
+
+import com.android.systemui.utils.ViewUtils;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class NotificationMenuRowTest extends LeakCheckedTest {
+
+    @Before
+    public void setup() {
+        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+    }
+
+    @Test
+    public void testAttachDetach() {
+        NotificationMenuRow row = new NotificationMenuRow(mContext);
+        ViewUtils.attachView(row);
+        ViewUtils.detachView(row);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
index 7d9e073..68f9cb05 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarIconViewTest.java
@@ -16,36 +16,74 @@
 
 package com.android.systemui.statusbar;
 
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNull;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.graphics.drawable.Icon;
-import android.os.Debug;
 import android.os.UserHandle;
+import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.junit.runner.RunWith;
-
-import static junit.framework.Assert.assertNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
+import org.mockito.ArgumentMatcher;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class StatusBarIconViewTest extends SysuiTestCase {
 
+    @Rule
+    public ExpectedException mThrown = ExpectedException.none();
+
     private StatusBarIconView mIconView;
     private StatusBarIcon mStatusBarIcon = mock(StatusBarIcon.class);
 
+    private PackageManager mPackageManagerSpy;
+    private Context mContext;
+    private Resources mMockResources;
+
     @Before
-    public void setUp() {
-        mIconView = new StatusBarIconView(getContext(), "slot", null);
-        mStatusBarIcon = new StatusBarIcon(UserHandle.ALL, getContext().getPackageName(),
-                Icon.createWithResource(getContext(), R.drawable.ic_android), 0, 0, "");
+    public void setUp() throws Exception {
+        // Set up context such that asking for "mockPackage" resources returns mMockResources.
+        mMockResources = mock(Resources.class);
+        mPackageManagerSpy = spy(getContext().getPackageManager());
+        doReturn(mMockResources).when(mPackageManagerSpy)
+                .getResourcesForApplicationAsUser(eq("mockPackage"), anyInt());
+        doReturn(mMockResources).when(mPackageManagerSpy)
+                .getResourcesForApplication(eq("mockPackage"));
+        doReturn(mMockResources).when(mPackageManagerSpy).getResourcesForApplication(argThat(
+                (ArgumentMatcher<ApplicationInfo>) o -> "mockPackage".equals(o.packageName)));
+        mContext = new ContextWrapper(getContext()) {
+            @Override
+            public PackageManager getPackageManager() {
+                return mPackageManagerSpy;
+            }
+        };
+
+        mIconView = new StatusBarIconView(mContext, "test_slot", null);
+        mStatusBarIcon = new StatusBarIcon(UserHandle.ALL, "mockPackage",
+                Icon.createWithResource(mContext, R.drawable.ic_android), 0, 0, "");
     }
 
     @Test
@@ -55,4 +93,11 @@
         assertNull(mIconView.getTag(R.id.icon_is_grayscale));
     }
 
+    @Test
+    public void testSettingOomingIconDoesNotThrowOom() {
+        when(mMockResources.getDrawable(anyInt(), any())).thenThrow(new OutOfMemoryError("mocked"));
+        mStatusBarIcon.icon = Icon.createWithResource("mockPackage", R.drawable.ic_android);
+
+        assertFalse(mIconView.set(mStatusBarIcon));
+    }
 }
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index e28d077..a9d6df7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -40,6 +40,7 @@
         mContext.putComponent(Recents.class, mock(Recents.class));
         mContext.putComponent(Divider.class, mock(Divider.class));
         mContext.addMockSystemService(Context.WINDOW_SERVICE, mock(WindowManager.class));
+        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 309559b..21c7fce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -22,11 +22,20 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.metrics.LogMaker;
+import android.metrics.MetricsReader;
 import android.support.test.filters.SmallTest;
+import android.support.test.metricshelper.MetricsAsserts;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.DisplayMetrics;
 
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.keyguard.KeyguardHostView.OnDismissAction;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.ActivatableNotificationView;
+import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -37,12 +46,22 @@
 public class StatusBarTest extends SysuiTestCase {
 
     StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+    UnlockMethodCache mUnlockMethodCache;
+    KeyguardIndicationController mKeyguardIndicationController;
+    NotificationStackScrollLayout mStackScroller;
     StatusBar mStatusBar;
 
+    private MetricsReader mMetricsReader;
+    private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+
     @Before
     public void setup() {
         mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
-        mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager);
+        mUnlockMethodCache = mock(UnlockMethodCache.class);
+        mKeyguardIndicationController = mock(KeyguardIndicationController.class);
+        mStackScroller = mock(NotificationStackScrollLayout.class);
+        mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
+                mKeyguardIndicationController, mStackScroller);
 
         doAnswer(invocation -> {
             OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
@@ -55,6 +74,11 @@
             runnable.run();
             return null;
         }).when(mStatusBarKeyguardViewManager).addAfterKeyguardGoneRunnable(any());
+
+        when(mStackScroller.getActivatedChild()).thenReturn(null);
+
+        mMetricsReader = new MetricsReader();
+        mMetricsReader.checkpoint(); // clear out old logs
     }
 
     @Test
@@ -81,9 +105,114 @@
         mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
     }
 
+    @Test
+    public void lockscreenStateMetrics_notShowing() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(false);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing hidden insecure lockscreen log", mMetricsReader,
+                new LogMaker(MetricsEvent.LOCKSCREEN)
+                        .setType(MetricsEvent.TYPE_CLOSE)
+                        .setSubtype(0));
+    }
+
+    @Test
+    public void lockscreenStateMetrics_notShowing_secure() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing hidden secure lockscreen log", mMetricsReader,
+                new LogMaker(MetricsEvent.LOCKSCREEN)
+                        .setType(MetricsEvent.TYPE_CLOSE)
+                        .setSubtype(1));
+    }
+
+    @Test
+    public void lockscreenStateMetrics_isShowing() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(false);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing insecure lockscreen showing", mMetricsReader,
+                new LogMaker(MetricsEvent.LOCKSCREEN)
+                        .setType(MetricsEvent.TYPE_OPEN)
+                        .setSubtype(0));
+    }
+
+    @Test
+    public void lockscreenStateMetrics_isShowing_secure() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing secure lockscreen showing log", mMetricsReader,
+                new LogMaker(MetricsEvent.LOCKSCREEN)
+                        .setType(MetricsEvent.TYPE_OPEN)
+                        .setSubtype(1));
+    }
+
+    @Test
+    public void lockscreenStateMetrics_isShowingBouncer() {
+        // uninteresting state, except that fingerprint must be non-zero
+        when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
+        when(mUnlockMethodCache.canSkipBouncer()).thenReturn(true);
+        // interesting state
+        when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
+        when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+        when(mUnlockMethodCache.isMethodSecure()).thenReturn(true);
+
+        mStatusBar.onKeyguardViewManagerStatesUpdated();
+
+        MetricsAsserts.assertHasLog("missing bouncer log", mMetricsReader,
+                new LogMaker(MetricsEvent.BOUNCER)
+                        .setType(MetricsEvent.TYPE_OPEN)
+                        .setSubtype(1));
+    }
+
+    @Test
+    public void onActivatedMetrics() {
+        ActivatableNotificationView view =  mock(ActivatableNotificationView.class);
+        mStatusBar.onActivated(view);
+
+        MetricsAsserts.assertHasLog("missing lockscreen note tap log", mMetricsReader,
+                new LogMaker(MetricsEvent.ACTION_LS_NOTE)
+                        .setType(MetricsEvent.TYPE_ACTION));
+    }
+
     static class TestableStatusBar extends StatusBar {
-        public TestableStatusBar(StatusBarKeyguardViewManager man) {
+        public TestableStatusBar(StatusBarKeyguardViewManager man,
+                UnlockMethodCache unlock, KeyguardIndicationController key,
+                NotificationStackScrollLayout stack) {
             mStatusBarKeyguardViewManager = man;
+            mUnlockMethodCache = unlock;
+            mKeyguardIndicationController = key;
+            mStackScroller = stack;
         }
 
         @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
index 8949598..f67296d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
@@ -55,9 +55,8 @@
         Set<String> ALL_CHANNELS = new ArraySet<>(Arrays.asList(
                 NotificationChannels.ALERTS,
                 NotificationChannels.SCREENSHOTS,
-                NotificationChannels.SECURITY,
-                NotificationChannels.USER,
-                NotificationChannels.STORAGE
+                NotificationChannels.STORAGE,
+                NotificationChannels.GENERAL
         ));
         NotificationChannels.createAll(mContext);
         ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java b/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java
new file mode 100644
index 0000000..202c4cf
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/ViewUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.utils;
+
+import android.graphics.PixelFormat;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.support.test.InstrumentationRegistry;
+
+import com.android.systemui.SysuiTestCase;
+
+public class ViewUtils {
+
+    public static void attachView(View view) {
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
+                LayoutParams.TYPE_APPLICATION_OVERLAY,
+                0, PixelFormat.TRANSLUCENT);
+        Handler handler = new Handler(Looper.getMainLooper());
+        handler.post(() -> InstrumentationRegistry.getContext()
+                .getSystemService(WindowManager.class).addView(view, lp));
+        SysuiTestCase.waitForIdleSync(handler);
+    }
+
+    public static void detachView(View view) {
+        Handler handler = new Handler(Looper.getMainLooper());
+        handler.post(() -> InstrumentationRegistry.getContext()
+                .getSystemService(WindowManager.class).removeView(view));
+        SysuiTestCase.waitForIdleSync(handler);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
new file mode 100644
index 0000000..d1abcca
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakePluginManager.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.utils.leaks;
+
+import android.content.Context;
+
+import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
+
+public class FakePluginManager extends PluginManager {
+
+    private final BaseLeakChecker<PluginListener> mLeakChecker;
+
+    public FakePluginManager(Context context, LeakCheckedTest test) {
+        super(context);
+        mLeakChecker = new BaseLeakChecker<>(test, "Plugin");
+    }
+
+    @Override
+    public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
+            int version) {
+        mLeakChecker.addCallback(listener);
+    }
+
+    @Override
+    public <T extends Plugin> void addPluginListener(String action, PluginListener<T> listener,
+            int version, boolean allowMultiple) {
+        mLeakChecker.addCallback(listener);
+    }
+
+    @Override
+    public void removePluginListener(PluginListener<?> listener) {
+        mLeakChecker.removeCallback(listener);
+    }
+
+    @Override
+    public <T extends Plugin> T getOneShotPlugin(String action, int version) {
+        return null;
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java
new file mode 100644
index 0000000..f553277
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeTunerService.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.utils.leaks;
+
+import android.content.Context;
+
+import com.android.systemui.tuner.TunerService;
+
+public class FakeTunerService extends TunerService {
+
+    private final BaseLeakChecker<Tunable> mBaseLeakChecker;
+
+    public FakeTunerService(Context context, LeakCheckedTest test) {
+        super(context);
+        mBaseLeakChecker = new BaseLeakChecker<>(test, "tunable");
+    }
+
+    @Override
+    public void addTunable(Tunable tunable, String... keys) {
+        for (String key : keys) {
+            tunable.onTuningChanged(key, null);
+        }
+        mBaseLeakChecker.addCallback(tunable);
+    }
+
+    @Override
+    public void removeTunable(Tunable tunable) {
+        mBaseLeakChecker.removeCallback(tunable);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
index c182493..c2048c7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java
@@ -20,6 +20,7 @@
 import android.util.ArrayMap;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.statusbar.policy.BluetoothController;
@@ -35,6 +36,7 @@
 import com.android.systemui.statusbar.policy.SecurityController;
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.tuner.TunerService;
 
 import org.junit.Assert;
 import org.junit.Rule;
@@ -56,6 +58,25 @@
     private final Map<String, Tracker> mTrackers = new HashMap<>();
     private final Map<Class, Object> mLeakCheckers = new ArrayMap<>();
 
+    public static final Class<?>[] ALL_SUPPORTED_CLASSES = new Class[] {
+            BluetoothController.class,
+            LocationController.class,
+            RotationLockController.class,
+            ZenModeController.class,
+            CastController.class,
+            HotspotController.class,
+            FlashlightController.class,
+            UserInfoController.class,
+            KeyguardMonitor.class,
+            BatteryController.class,
+            SecurityController.class,
+            ManagedProfileController.class,
+            NextAlarmController.class,
+            NetworkController.class,
+            PluginManager.class,
+            TunerService.class,
+    };
+
     @Rule
     public TestWatcher successWatcher = new TestWatcher() {
         @Override
@@ -96,6 +117,10 @@
                 obj = new FakeNextAlarmController(this);
             } else if (cls == NetworkController.class) {
                 obj = new FakeNetworkController(this);
+            } else if (cls == PluginManager.class) {
+                obj = new FakePluginManager(mContext, this);
+            } else if (cls == TunerService.class) {
+                obj = new FakeTunerService(mContext, this);
             } else {
                 Assert.fail(cls.getName() + " is not supported by LeakCheckedTest yet");
             }
diff --git a/preloaded-classes b/preloaded-classes
index 2fad5dd..7dc5a25 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1,3 +1,28 @@
+#
+# 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.
+#
+#
+#
+# Preloaded-classes filter file for phones.
+#
+# Classes in this file will be allocated into the boot image, and forcibly initialized in
+# the zygote during initialization. This is a trade-off, using virtual address space to share
+# common heap between apps.
+#
+# This file has been derived for mainline phone (and tablet) usage.
+#
 [B
 [C
 [D
@@ -9,7 +34,6 @@
 [Landroid.animation.Keyframe$FloatKeyframe;
 [Landroid.animation.Keyframe$IntKeyframe;
 [Landroid.animation.Keyframe$ObjectKeyframe;
-[Landroid.animation.Keyframe;
 [Landroid.animation.PropertyValuesHolder;
 [Landroid.app.LoaderManagerImpl;
 [Landroid.content.ContentProviderResult;
@@ -57,45 +81,45 @@
 [Landroid.hardware.soundtrigger.SoundTrigger$Keyphrase;
 [Landroid.hardware.soundtrigger.SoundTrigger$KeyphraseRecognitionExtra;
 [Landroid.icu.impl.CacheValue$Strength;
+[Landroid.icu.impl.CacheValue;
+[Landroid.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern;
+[Landroid.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType;
 [Landroid.icu.impl.ICUResourceBundle$OpenType;
 [Landroid.icu.impl.StandardPlural;
 [Landroid.icu.impl.Trie2$ValueWidth;
 [Landroid.icu.impl.UCharacterProperty$BinaryProperty;
 [Landroid.icu.impl.UCharacterProperty$IntProperty;
-[Landroid.icu.lang.UScript$ScriptUsage;
-[Landroid.icu.text.DateFormat$BooleanAttribute;
-[Landroid.icu.text.DateFormat$Field;
+[Landroid.icu.text.DateFormatSymbols$CalendarDataSink$AliasType;
 [Landroid.icu.text.DateFormatSymbols$CapitalizationContextUsage;
-[Landroid.icu.text.DateTimePatternGenerator$DTPGflags;
 [Landroid.icu.text.DisplayContext$Type;
 [Landroid.icu.text.DisplayContext;
-[Landroid.icu.text.MessagePattern$ApostropheMode;
-[Landroid.icu.text.MessagePattern$ArgType;
-[Landroid.icu.text.MessagePattern$Part$Type;
 [Landroid.icu.text.PluralRules$Operand;
 [Landroid.icu.text.PluralRules$PluralType;
 [Landroid.icu.text.PluralRules$SampleType;
+[Landroid.icu.text.TimeZoneNames$NameType;
 [Landroid.icu.text.UnicodeSet;
 [Landroid.icu.util.BytesTrie$Result;
-[Landroid.icu.util.Calendar$CalType;
 [Landroid.icu.util.Currency$CurrencyUsage;
 [Landroid.icu.util.ULocale$Category;
 [Landroid.icu.util.ULocale;
+[Landroid.icu.util.UResourceBundle$RootType;
 [Landroid.media.AudioGain;
+[Landroid.media.MediaCodecInfo$CodecProfileLevel;
 [Landroid.net.Network;
 [Landroid.net.NetworkInfo$DetailedState;
 [Landroid.net.NetworkInfo$State;
+[Landroid.net.NetworkRequest$Type;
 [Landroid.net.Uri;
 [Landroid.net.wifi.SupplicantState;
 [Landroid.os.AsyncTask$Status;
-[Landroid.os.Bundle;
+[Landroid.os.IBinder;
 [Landroid.os.MessageQueue$IdleHandler;
 [Landroid.os.Parcel;
-[Landroid.os.ParcelFileDescriptor;
 [Landroid.os.Parcelable;
 [Landroid.os.PatternMatcher;
 [Landroid.os.storage.StorageVolume;
 [Landroid.system.StructPollfd;
+[Landroid.telephony.TelephonyManager$MultiSimVariants;
 [Landroid.text.DynamicLayout$ChangeWatcher;
 [Landroid.text.InputFilter;
 [Landroid.text.Layout$Alignment;
@@ -124,9 +148,7 @@
 [Landroid.util.Range;
 [Landroid.util.Rational;
 [Landroid.view.Choreographer$CallbackQueue;
-[Landroid.view.Display$ColorTransform;
 [Landroid.view.Display$Mode;
-[Landroid.view.Display;
 [Landroid.view.HandlerActionQueue$HandlerAction;
 [Landroid.view.MenuItem;
 [Landroid.view.View;
@@ -146,18 +168,22 @@
 [Lcom.android.org.bouncycastle.asn1.ASN1ObjectIdentifier;
 [Lcom.android.org.conscrypt.OpenSSLX509CertPath$Encoding;
 [Lcom.android.org.conscrypt.OpenSSLX509Certificate;
+[Lcom.android.org.conscrypt.ct.CTLogInfo;
 [Ldalvik.system.DexPathList$Element;
-[Ljava.beans.PropertyChangeListener;
+[Ldalvik.system.DexPathList$NativeLibraryElement;
 [Ljava.io.File$PathStatus;
 [Ljava.io.File;
 [Ljava.io.FileDescriptor;
 [Ljava.io.IOException;
+[Ljava.io.ObjectInputStream$HandleTable$HandleList;
 [Ljava.io.ObjectStreamField;
+[Ljava.lang.Boolean;
 [Ljava.lang.Byte;
 [Ljava.lang.CharSequence;
 [Ljava.lang.Character$UnicodeBlock;
 [Ljava.lang.Character;
 [Ljava.lang.Class;
+[Ljava.lang.Comparable;
 [Ljava.lang.Enum;
 [Ljava.lang.Integer;
 [Ljava.lang.Long;
@@ -174,21 +200,20 @@
 [Ljava.lang.Throwable;
 [Ljava.lang.Void;
 [Ljava.lang.annotation.Annotation;
-[Ljava.lang.ref.SoftReference;
+[Ljava.lang.invoke.MethodType;
 [Ljava.lang.ref.WeakReference;
 [Ljava.lang.reflect.AccessibleObject;
 [Ljava.lang.reflect.Constructor;
 [Ljava.lang.reflect.Field;
 [Ljava.lang.reflect.Method;
+[Ljava.lang.reflect.Parameter;
 [Ljava.lang.reflect.Type;
 [Ljava.lang.reflect.TypeVariable;
-[Ljava.math.BigDecimal;
 [Ljava.math.BigInteger;
 [Ljava.math.RoundingMode;
 [Ljava.net.InetAddress;
-[Ljava.net.InterfaceAddress;
-[Ljava.net.NetworkInterface;
 [Ljava.net.Proxy$Type;
+[Ljava.nio.file.attribute.FileAttribute;
 [Ljava.security.CryptoPrimitive;
 [Ljava.security.Provider;
 [Ljava.security.cert.Certificate;
@@ -200,30 +225,31 @@
 [Ljava.util.Enumeration;
 [Ljava.util.Formatter$Flags;
 [Ljava.util.Formatter$FormatString;
-[Ljava.util.HashMap$HashMapEntry;
+[Ljava.util.HashMap$Node;
 [Ljava.util.Hashtable$HashtableEntry;
-[Ljava.util.List;
 [Ljava.util.Locale$Category;
 [Ljava.util.Locale;
 [Ljava.util.Map$Entry;
 [Ljava.util.WeakHashMap$Entry;
+[Ljava.util.concurrent.ConcurrentHashMap$CounterCell;
 [Ljava.util.concurrent.ConcurrentHashMap$Node;
 [Ljava.util.concurrent.ConcurrentHashMap$Segment;
+[Ljava.util.concurrent.ForkJoinTask$ExceptionNode;
 [Ljava.util.concurrent.RunnableScheduledFuture;
 [Ljava.util.concurrent.TimeUnit;
 [Ljava.util.logging.Handler;
 [Ljava.util.regex.Pattern;
-[Ljavax.crypto.Cipher$InitType;
-[Ljavax.crypto.Cipher$NeedToSet;
 [Ljavax.net.ssl.KeyManager;
 [Ljavax.net.ssl.TrustManager;
 [Ljavax.security.cert.X509Certificate;
 [Llibcore.io.ClassPathURLStreamHandler;
+[Llibcore.io.IoTracker$Mode;
 [Llibcore.reflect.AnnotationMember$DefaultValues;
 [Llibcore.reflect.AnnotationMember;
 [Lorg.apache.http.Header;
 [Lorg.json.JSONStringer$Scope;
 [Lorg.kxml2.io.KXmlParser$ValueContext;
+[Lsun.misc.FDBigInteger;
 [Lsun.misc.FormattedFloatingDecimal$Form;
 [Lsun.security.jca.ProviderConfig;
 [Lsun.security.jca.ServiceId;
@@ -244,31 +270,22 @@
 [[Ljava.lang.Object;
 [[Ljava.lang.String;
 [[Ljava.lang.annotation.Annotation;
-[[S
 [[[I
 android.R$styleable
 android.accounts.Account
 android.accounts.Account$1
 android.accounts.AccountManager
 android.accounts.AccountManager$1
-android.accounts.AccountManager$11
-android.accounts.AccountManager$AmsTask
-android.accounts.AccountManager$AmsTask$1
-android.accounts.AccountManager$AmsTask$Response
-android.accounts.AccountManagerCallback
 android.accounts.AccountManagerFuture
 android.accounts.AccountsException
 android.accounts.AuthenticatorException
 android.accounts.IAccountManager
 android.accounts.IAccountManager$Stub
 android.accounts.IAccountManager$Stub$Proxy
-android.accounts.IAccountManagerResponse
-android.accounts.IAccountManagerResponse$Stub
 android.accounts.OnAccountsUpdateListener
 android.accounts.OperationCanceledException
 android.animation.AnimationHandler
 android.animation.AnimationHandler$1
-android.animation.AnimationHandler$2
 android.animation.AnimationHandler$AnimationFrameCallback
 android.animation.AnimationHandler$AnimationFrameCallbackProvider
 android.animation.AnimationHandler$MyFrameCallbackProvider
@@ -277,12 +294,15 @@
 android.animation.Animator$AnimatorListener
 android.animation.Animator$AnimatorPauseListener
 android.animation.AnimatorInflater
-android.animation.AnimatorInflater$PathDataEvaluator
 android.animation.AnimatorListenerAdapter
 android.animation.AnimatorSet
-android.animation.AnimatorSet$AnimatorSetListener
+android.animation.AnimatorSet$1
+android.animation.AnimatorSet$2
+android.animation.AnimatorSet$3
+android.animation.AnimatorSet$AnimationEvent
 android.animation.AnimatorSet$Builder
 android.animation.AnimatorSet$Node
+android.animation.AnimatorSet$SeekState
 android.animation.ArgbEvaluator
 android.animation.FloatEvaluator
 android.animation.FloatKeyframeSet
@@ -299,14 +319,13 @@
 android.animation.LayoutTransition
 android.animation.LayoutTransition$TransitionListener
 android.animation.ObjectAnimator
-android.animation.PathKeyframes
-android.animation.PathKeyframes$1
-android.animation.PathKeyframes$2
 android.animation.PathKeyframes$FloatKeyframesBase
+android.animation.PathKeyframes$IntKeyframesBase
 android.animation.PathKeyframes$SimpleKeyframes
 android.animation.PropertyValuesHolder
 android.animation.PropertyValuesHolder$FloatPropertyValuesHolder
 android.animation.PropertyValuesHolder$IntPropertyValuesHolder
+android.animation.PropertyValuesHolder$PropertyValues
 android.animation.RectEvaluator
 android.animation.StateListAnimator
 android.animation.StateListAnimator$1
@@ -316,12 +335,15 @@
 android.animation.TypeEvaluator
 android.animation.ValueAnimator
 android.animation.ValueAnimator$AnimatorUpdateListener
+android.app.-$Lambda$36$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$39$c44uHH2WE4sJvw5tZZB6gRzEaHI
+android.app.-$Lambda$7$u_rp3dnwvfyMTggc6hVftcuYJ3E
 android.app.ActionBar
 android.app.ActionBar$LayoutParams
 android.app.Activity
 android.app.Activity$HostCallbacks
 android.app.ActivityManager
-android.app.ActivityManager$MemoryInfo
+android.app.ActivityManager$1
 android.app.ActivityManager$RunningAppProcessInfo
 android.app.ActivityManager$RunningAppProcessInfo$1
 android.app.ActivityManager$StackId
@@ -357,20 +379,17 @@
 android.app.AppOpsManager
 android.app.Application
 android.app.Application$ActivityLifecycleCallbacks
-android.app.ApplicationErrorReport
 android.app.ApplicationErrorReport$CrashInfo
 android.app.ApplicationLoaders
 android.app.ApplicationPackageManager
 android.app.ApplicationPackageManager$ResourceName
 android.app.BackStackRecord
 android.app.BackStackRecord$Op
-android.app.BackStackRecord$TransitionState
 android.app.ContentProviderHolder
 android.app.ContentProviderHolder$1
 android.app.ContextImpl
 android.app.ContextImpl$ApplicationContentResolver
 android.app.Dialog
-android.app.Dialog$-void__init__android_content_Context_context_int_themeResId_boolean_createContextThemeWrapper_LambdaImpl0
 android.app.Dialog$ListenersHandler
 android.app.DialogFragment
 android.app.DownloadManager
@@ -383,7 +402,10 @@
 android.app.FragmentManager$BackStackEntry
 android.app.FragmentManagerImpl
 android.app.FragmentManagerImpl$1
+android.app.FragmentManagerImpl$OpGenerator
 android.app.FragmentTransaction
+android.app.FragmentTransition
+android.app.FragmentTransition$FragmentContainerTransition
 android.app.IActivityManager
 android.app.IActivityManager$Stub
 android.app.IActivityManager$Stub$Proxy
@@ -392,7 +414,6 @@
 android.app.IAlarmManager$Stub$Proxy
 android.app.IApplicationThread
 android.app.IApplicationThread$Stub
-android.app.IApplicationThread$Stub$Proxy
 android.app.IInstrumentationWatcher
 android.app.IInstrumentationWatcher$Stub
 android.app.INotificationManager
@@ -409,10 +430,10 @@
 android.app.IntentReceiverLeaked
 android.app.IntentService
 android.app.IntentService$ServiceHandler
-android.app.JobSchedulerImpl
 android.app.KeyguardManager
 android.app.ListActivity
 android.app.LoadedApk
+android.app.LoadedApk$DexLoadReporter
 android.app.LoadedApk$ReceiverDispatcher
 android.app.LoadedApk$ReceiverDispatcher$Args
 android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
@@ -426,19 +447,17 @@
 android.app.LoaderManagerImpl
 android.app.NativeActivity
 android.app.Notification
-android.app.Notification$1
 android.app.Notification$Action
 android.app.Notification$BigTextStyle
 android.app.Notification$Builder
-android.app.Notification$BuilderRemoteViews
 android.app.Notification$Style
 android.app.NotificationManager
-android.app.OnActivityPausedListener
 android.app.PendingIntent
 android.app.PendingIntent$1
 android.app.PendingIntent$CanceledException
-android.app.ProgressDialog
+android.app.PendingIntent$OnMarshaledListener
 android.app.QueuedWork
+android.app.QueuedWork$QueuedWorkHandler
 android.app.ReceiverRestrictedContext
 android.app.ResourcesManager
 android.app.ResourcesManager$1
@@ -530,6 +549,11 @@
 android.app.SystemServiceRegistry$72
 android.app.SystemServiceRegistry$73
 android.app.SystemServiceRegistry$74
+android.app.SystemServiceRegistry$75
+android.app.SystemServiceRegistry$76
+android.app.SystemServiceRegistry$77
+android.app.SystemServiceRegistry$78
+android.app.SystemServiceRegistry$79
 android.app.SystemServiceRegistry$8
 android.app.SystemServiceRegistry$9
 android.app.SystemServiceRegistry$CachedServiceFetcher
@@ -550,13 +574,11 @@
 android.app.backup.BackupDataOutput
 android.app.backup.BackupHelperDispatcher
 android.app.backup.BackupHelperDispatcher$Header
+android.app.backup.BackupManager
 android.app.backup.FileBackupHelperBase
 android.app.backup.FullBackup
 android.app.backup.FullBackupDataOutput
-android.app.job.IJobScheduler
-android.app.job.IJobScheduler$Stub
 android.app.job.JobInfo
-android.app.job.JobInfo$Builder
 android.app.job.JobScheduler
 android.app.job.JobService
 android.app.trust.ITrustManager
@@ -564,14 +586,15 @@
 android.app.trust.ITrustManager$Stub$Proxy
 android.app.trust.TrustManager
 android.app.usage.NetworkStatsManager
+android.app.usage.StorageStatsManager
 android.app.usage.UsageStatsManager
 android.appwidget.AppWidgetManager
-android.appwidget.AppWidgetProvider
 android.bluetooth.BluetoothAdapter
 android.bluetooth.BluetoothAdapter$1
 android.bluetooth.BluetoothManager
 android.bluetooth.IBluetooth
 android.bluetooth.IBluetooth$Stub
+android.bluetooth.IBluetooth$Stub$Proxy
 android.bluetooth.IBluetoothManager
 android.bluetooth.IBluetoothManager$Stub
 android.bluetooth.IBluetoothManager$Stub$Proxy
@@ -582,8 +605,6 @@
 android.content.BroadcastReceiver$PendingResult
 android.content.BroadcastReceiver$PendingResult$1
 android.content.ClipData
-android.content.ClipData$Item
-android.content.ClipDescription
 android.content.ClipboardManager
 android.content.ComponentCallbacks
 android.content.ComponentCallbacks2
@@ -594,7 +615,6 @@
 android.content.ContentProviderClient
 android.content.ContentProviderNative
 android.content.ContentProviderOperation
-android.content.ContentProviderOperation$Builder
 android.content.ContentProviderProxy
 android.content.ContentProviderResult
 android.content.ContentResolver
@@ -618,10 +638,6 @@
 android.content.IIntentSender
 android.content.IIntentSender$Stub
 android.content.IIntentSender$Stub$Proxy
-android.content.ISyncAdapter
-android.content.ISyncAdapter$Stub
-android.content.ISyncContext
-android.content.ISyncContext$Stub
 android.content.Intent
 android.content.Intent$1
 android.content.IntentFilter
@@ -635,13 +651,7 @@
 android.content.SharedPreferences
 android.content.SharedPreferences$Editor
 android.content.SharedPreferences$OnSharedPreferenceChangeListener
-android.content.SyncResult
-android.content.SyncResult$1
-android.content.SyncStats
-android.content.SyncStats$1
 android.content.UndoManager
-android.content.UndoManager$UndoState
-android.content.UndoOperation
 android.content.UndoOwner
 android.content.UriMatcher
 android.content.pm.ActivityInfo
@@ -714,7 +724,6 @@
 android.content.res.ResourcesImpl$ThemeImpl
 android.content.res.ResourcesKey
 android.content.res.StringBlock
-android.content.res.StringBlock$StyleIDs
 android.content.res.ThemedResourceCache
 android.content.res.TypedArray
 android.content.res.XmlBlock
@@ -752,7 +761,6 @@
 android.database.IContentObserver$Stub
 android.database.IContentObserver$Stub$Proxy
 android.database.MatrixCursor
-android.database.MatrixCursor$RowBuilder
 android.database.Observable
 android.database.SQLException
 android.database.sqlite.DatabaseObjectNotClosedException
@@ -796,6 +804,7 @@
 android.ddm.DdmHandleThread
 android.ddm.DdmHandleViewDebug
 android.ddm.DdmRegister
+android.graphics.BaseCanvas
 android.graphics.Bitmap
 android.graphics.Bitmap$1
 android.graphics.Bitmap$CompressFormat
@@ -812,7 +821,6 @@
 android.graphics.CanvasProperty
 android.graphics.Color
 android.graphics.ColorFilter
-android.graphics.ColorMatrix
 android.graphics.ColorMatrixColorFilter
 android.graphics.ComposePathEffect
 android.graphics.ComposeShader
@@ -823,15 +831,17 @@
 android.graphics.EmbossMaskFilter
 android.graphics.FontFamily
 android.graphics.FontListParser
+android.graphics.GraphicBuffer
+android.graphics.GraphicBuffer$1
 android.graphics.Insets
 android.graphics.Interpolator
 android.graphics.Interpolator$Result
-android.graphics.LayerRasterizer
 android.graphics.LightingColorFilter
 android.graphics.LinearGradient
 android.graphics.MaskFilter
 android.graphics.Matrix
 android.graphics.Matrix$1
+android.graphics.Matrix$NoImagePreloadHolder
 android.graphics.Matrix$ScaleToFit
 android.graphics.Movie
 android.graphics.NinePatch
@@ -863,7 +873,6 @@
 android.graphics.PorterDuffColorFilter
 android.graphics.PorterDuffXfermode
 android.graphics.RadialGradient
-android.graphics.Rasterizer
 android.graphics.Rect
 android.graphics.Rect$1
 android.graphics.RectF
@@ -876,7 +885,6 @@
 android.graphics.Shader$TileMode
 android.graphics.SumPathEffect
 android.graphics.SurfaceTexture
-android.graphics.SurfaceTexture$OnFrameAvailableListener
 android.graphics.SweepGradient
 android.graphics.TableMaskFilter
 android.graphics.TemporaryBuffer
@@ -893,7 +901,6 @@
 android.graphics.drawable.AnimatedVectorDrawable$AnimatedVectorDrawableState$PendingAnimator
 android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimator
 android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT
-android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorUI
 android.graphics.drawable.AnimationDrawable
 android.graphics.drawable.AnimationDrawable$AnimationState
 android.graphics.drawable.BitmapDrawable
@@ -904,6 +911,7 @@
 android.graphics.drawable.Drawable$Callback
 android.graphics.drawable.Drawable$ConstantState
 android.graphics.drawable.DrawableContainer
+android.graphics.drawable.DrawableContainer$BlockInvalidateCallback
 android.graphics.drawable.DrawableContainer$DrawableContainerState
 android.graphics.drawable.DrawableInflater
 android.graphics.drawable.DrawableWrapper
@@ -943,11 +951,30 @@
 android.graphics.drawable.VectorDrawable
 android.graphics.drawable.VectorDrawable$VFullPath
 android.graphics.drawable.VectorDrawable$VFullPath$1
+android.graphics.drawable.VectorDrawable$VFullPath$10
+android.graphics.drawable.VectorDrawable$VFullPath$2
+android.graphics.drawable.VectorDrawable$VFullPath$3
+android.graphics.drawable.VectorDrawable$VFullPath$4
+android.graphics.drawable.VectorDrawable$VFullPath$5
+android.graphics.drawable.VectorDrawable$VFullPath$6
+android.graphics.drawable.VectorDrawable$VFullPath$7
+android.graphics.drawable.VectorDrawable$VFullPath$8
+android.graphics.drawable.VectorDrawable$VFullPath$9
 android.graphics.drawable.VectorDrawable$VGroup
 android.graphics.drawable.VectorDrawable$VGroup$1
+android.graphics.drawable.VectorDrawable$VGroup$2
+android.graphics.drawable.VectorDrawable$VGroup$3
+android.graphics.drawable.VectorDrawable$VGroup$4
+android.graphics.drawable.VectorDrawable$VGroup$5
+android.graphics.drawable.VectorDrawable$VGroup$6
+android.graphics.drawable.VectorDrawable$VGroup$7
+android.graphics.drawable.VectorDrawable$VGroup$8
+android.graphics.drawable.VectorDrawable$VGroup$9
 android.graphics.drawable.VectorDrawable$VObject
 android.graphics.drawable.VectorDrawable$VPath
+android.graphics.drawable.VectorDrawable$VPath$1
 android.graphics.drawable.VectorDrawable$VectorDrawableState
+android.graphics.drawable.VectorDrawable$VectorDrawableState$1
 android.graphics.drawable.shapes.OvalShape
 android.graphics.drawable.shapes.RectShape
 android.graphics.drawable.shapes.Shape
@@ -958,6 +985,8 @@
 android.hardware.Camera$CameraInfo
 android.hardware.Camera$Face
 android.hardware.ConsumerIrManager
+android.hardware.HardwareBuffer
+android.hardware.HardwareBuffer$1
 android.hardware.Sensor
 android.hardware.SensorEvent
 android.hardware.SensorEventListener
@@ -966,7 +995,6 @@
 android.hardware.SerialPort
 android.hardware.SystemSensorManager
 android.hardware.SystemSensorManager$BaseEventQueue
-android.hardware.SystemSensorManager$SensorEventQueue
 android.hardware.camera2.CameraCharacteristics$Key
 android.hardware.camera2.CameraManager
 android.hardware.camera2.CaptureRequest$Key
@@ -996,9 +1024,10 @@
 android.hardware.input.InputDeviceIdentifier$1
 android.hardware.input.InputManager
 android.hardware.input.InputManager$InputDevicesChangedListener
+android.hardware.location.ActivityRecognitionHardware
 android.hardware.location.ContextHubManager
-android.hardware.location.IContextHubService
-android.hardware.location.IContextHubService$Stub
+android.hardware.location.IActivityRecognitionHardware
+android.hardware.location.IActivityRecognitionHardware$Stub
 android.hardware.radio.RadioManager
 android.hardware.radio.RadioManager$AmBandConfig
 android.hardware.radio.RadioManager$AmBandConfig$1
@@ -1044,8 +1073,6 @@
 android.hardware.soundtrigger.SoundTrigger$SoundModelEvent
 android.hardware.soundtrigger.SoundTrigger$SoundModelEvent$1
 android.hardware.soundtrigger.SoundTriggerModule
-android.hardware.usb.IUsbManager
-android.hardware.usb.IUsbManager$Stub
 android.hardware.usb.UsbDevice
 android.hardware.usb.UsbDeviceConnection
 android.hardware.usb.UsbManager
@@ -1056,16 +1083,16 @@
 android.icu.impl.CacheValue$NullValue
 android.icu.impl.CacheValue$SoftValue
 android.icu.impl.CacheValue$Strength
-android.icu.impl.CalendarData
 android.icu.impl.CalendarUtil
+android.icu.impl.CalendarUtil$CalendarPreferences
 android.icu.impl.CharTrie
 android.icu.impl.ClassLoaderUtil
 android.icu.impl.CurrencyData
 android.icu.impl.CurrencyData$CurrencyDisplayInfo
 android.icu.impl.CurrencyData$CurrencyDisplayInfoProvider
 android.icu.impl.CurrencyData$CurrencySpacingInfo
-android.icu.impl.DateNumberFormat
-android.icu.impl.Grego
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingPattern
+android.icu.impl.CurrencyData$CurrencySpacingInfo$SpacingType
 android.icu.impl.ICUBinary
 android.icu.impl.ICUBinary$Authenticate
 android.icu.impl.ICUBinary$DatPackageReader
@@ -1076,6 +1103,7 @@
 android.icu.impl.ICUConfig
 android.icu.impl.ICUCurrencyDisplayInfoProvider
 android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo
+android.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo$SpacingInfoSink
 android.icu.impl.ICUCurrencyMetaInfo
 android.icu.impl.ICUCurrencyMetaInfo$Collector
 android.icu.impl.ICUCurrencyMetaInfo$CurrencyCollector
@@ -1091,13 +1119,15 @@
 android.icu.impl.ICUResourceBundle
 android.icu.impl.ICUResourceBundle$1
 android.icu.impl.ICUResourceBundle$2
-android.icu.impl.ICUResourceBundle$2$1
+android.icu.impl.ICUResourceBundle$3
+android.icu.impl.ICUResourceBundle$3$1
+android.icu.impl.ICUResourceBundle$4
 android.icu.impl.ICUResourceBundle$AvailEntry
+android.icu.impl.ICUResourceBundle$Loader
 android.icu.impl.ICUResourceBundle$OpenType
 android.icu.impl.ICUResourceBundle$WholeBundle
 android.icu.impl.ICUResourceBundleImpl
 android.icu.impl.ICUResourceBundleImpl$ResourceArray
-android.icu.impl.ICUResourceBundleImpl$ResourceBinary
 android.icu.impl.ICUResourceBundleImpl$ResourceContainer
 android.icu.impl.ICUResourceBundleImpl$ResourceInt
 android.icu.impl.ICUResourceBundleImpl$ResourceIntVector
@@ -1111,6 +1141,7 @@
 android.icu.impl.ICUResourceBundleReader$IsAcceptable
 android.icu.impl.ICUResourceBundleReader$ReaderCache
 android.icu.impl.ICUResourceBundleReader$ReaderCacheKey
+android.icu.impl.ICUResourceBundleReader$ReaderValue
 android.icu.impl.ICUResourceBundleReader$ResourceCache
 android.icu.impl.ICUResourceBundleReader$ResourceCache$Level
 android.icu.impl.ICUResourceBundleReader$Table
@@ -1121,7 +1152,6 @@
 android.icu.impl.ICUService$Factory
 android.icu.impl.ICUService$Key
 android.icu.impl.IDNA2003
-android.icu.impl.JavaTimeZone
 android.icu.impl.LocaleIDParser
 android.icu.impl.LocaleIDs
 android.icu.impl.Norm2AllModes
@@ -1129,7 +1159,6 @@
 android.icu.impl.Norm2AllModes$ComposeNormalizer2
 android.icu.impl.Norm2AllModes$DecomposeNormalizer2
 android.icu.impl.Norm2AllModes$FCDNormalizer2
-android.icu.impl.Norm2AllModes$NFCSingleton
 android.icu.impl.Norm2AllModes$NFKCSingleton
 android.icu.impl.Norm2AllModes$NoopNormalizer2
 android.icu.impl.Norm2AllModes$Norm2AllModesSingleton
@@ -1137,14 +1166,13 @@
 android.icu.impl.Normalizer2Impl
 android.icu.impl.Normalizer2Impl$1
 android.icu.impl.Normalizer2Impl$IsAcceptable
-android.icu.impl.OlsonTimeZone
 android.icu.impl.Pair
 android.icu.impl.PatternProps
-android.icu.impl.PatternTokenizer
 android.icu.impl.PluralRulesLoader
 android.icu.impl.ReplaceableUCharacterIterator
 android.icu.impl.RuleCharacterIterator
 android.icu.impl.SimpleCache
+android.icu.impl.SimpleFormatterImpl
 android.icu.impl.SoftCache
 android.icu.impl.StandardPlural
 android.icu.impl.StringPrepDataReader
@@ -1159,7 +1187,6 @@
 android.icu.impl.Trie2$ValueMapper
 android.icu.impl.Trie2$ValueWidth
 android.icu.impl.Trie2_16
-android.icu.impl.Trie2_32
 android.icu.impl.UBiDiProps
 android.icu.impl.UBiDiProps$IsAcceptable
 android.icu.impl.UCharacterProperty
@@ -1194,24 +1221,13 @@
 android.icu.impl.UCharacterProperty$IsAcceptable
 android.icu.impl.UCharacterProperty$NormInertBinaryProperty
 android.icu.impl.UCharacterProperty$NormQuickCheckIntProperty
-android.icu.impl.UPropertyAliases
-android.icu.impl.UPropertyAliases$IsAcceptable
 android.icu.impl.URLHandler$URLVisitor
-android.icu.impl.USerializedSet
+android.icu.impl.UResource$Array
+android.icu.impl.UResource$Key
+android.icu.impl.UResource$Sink
+android.icu.impl.UResource$Table
+android.icu.impl.UResource$Value
 android.icu.impl.Utility
-android.icu.impl.ZoneMeta
-android.icu.impl.ZoneMeta$CustomTimeZoneCache
-android.icu.impl.ZoneMeta$SystemTimeZoneCache
-android.icu.impl.coll.CollationData
-android.icu.impl.coll.CollationDataReader
-android.icu.impl.coll.CollationDataReader$IsAcceptable
-android.icu.impl.coll.CollationFastLatin
-android.icu.impl.coll.CollationLoader
-android.icu.impl.coll.CollationRoot
-android.icu.impl.coll.CollationSettings
-android.icu.impl.coll.CollationTailoring
-android.icu.impl.coll.SharedObject
-android.icu.impl.coll.SharedObject$Reference
 android.icu.impl.locale.AsciiUtil
 android.icu.impl.locale.BaseLocale
 android.icu.impl.locale.BaseLocale$Cache
@@ -1222,8 +1238,6 @@
 android.icu.lang.UCharacter
 android.icu.lang.UCharacterEnums$ECharacterCategory
 android.icu.lang.UCharacterEnums$ECharacterDirection
-android.icu.lang.UScript
-android.icu.lang.UScript$ScriptUsage
 android.icu.math.BigDecimal
 android.icu.math.MathContext
 android.icu.text.BreakIterator
@@ -1232,51 +1246,26 @@
 android.icu.text.BreakIteratorFactory
 android.icu.text.BreakIteratorFactory$BFService
 android.icu.text.BreakIteratorFactory$BFService$1RBBreakIteratorFactory
-android.icu.text.Collator
-android.icu.text.Collator$ServiceShim
-android.icu.text.CollatorServiceShim
-android.icu.text.CollatorServiceShim$CService
-android.icu.text.CollatorServiceShim$CService$1CollatorFactory
 android.icu.text.CurrencyDisplayNames
 android.icu.text.CurrencyMetaInfo
 android.icu.text.CurrencyMetaInfo$CurrencyDigits
 android.icu.text.CurrencyMetaInfo$CurrencyFilter
-android.icu.text.DateFormat
-android.icu.text.DateFormat$BooleanAttribute
-android.icu.text.DateFormat$Field
 android.icu.text.DateFormatSymbols
+android.icu.text.DateFormatSymbols$1
+android.icu.text.DateFormatSymbols$CalendarDataSink
+android.icu.text.DateFormatSymbols$CalendarDataSink$AliasType
 android.icu.text.DateFormatSymbols$CapitalizationContextUsage
-android.icu.text.DateIntervalFormat
-android.icu.text.DateIntervalFormat$BestMatchInfo
-android.icu.text.DateIntervalInfo
-android.icu.text.DateIntervalInfo$PatternInfo
-android.icu.text.DateTimePatternGenerator
-android.icu.text.DateTimePatternGenerator$DTPGflags
-android.icu.text.DateTimePatternGenerator$DateTimeMatcher
-android.icu.text.DateTimePatternGenerator$DistanceInfo
-android.icu.text.DateTimePatternGenerator$FormatParser
-android.icu.text.DateTimePatternGenerator$PatternInfo
-android.icu.text.DateTimePatternGenerator$PatternWithMatcher
-android.icu.text.DateTimePatternGenerator$PatternWithSkeletonFlag
-android.icu.text.DateTimePatternGenerator$VariableField
 android.icu.text.DecimalFormat
 android.icu.text.DecimalFormat$Unit
 android.icu.text.DecimalFormatSymbols
 android.icu.text.DecimalFormatSymbols$1
 android.icu.text.DecimalFormatSymbols$CacheData
+android.icu.text.DecimalFormatSymbols$DecFmtDataSink
 android.icu.text.DigitList
 android.icu.text.DisplayContext
 android.icu.text.DisplayContext$Type
 android.icu.text.IDNA
 android.icu.text.LanguageBreakEngine
-android.icu.text.MessageFormat
-android.icu.text.MessageFormat$AppendableWrapper
-android.icu.text.MessageFormat$Field
-android.icu.text.MessagePattern
-android.icu.text.MessagePattern$ApostropheMode
-android.icu.text.MessagePattern$ArgType
-android.icu.text.MessagePattern$Part
-android.icu.text.MessagePattern$Part$Type
 android.icu.text.Normalizer
 android.icu.text.Normalizer$FCDMode
 android.icu.text.Normalizer$Mode
@@ -1292,6 +1281,9 @@
 android.icu.text.NumberFormat
 android.icu.text.NumberFormat$Field
 android.icu.text.NumberingSystem
+android.icu.text.NumberingSystem$1
+android.icu.text.NumberingSystem$2
+android.icu.text.NumberingSystem$LocaleLookupData
 android.icu.text.PluralRanges
 android.icu.text.PluralRanges$Matrix
 android.icu.text.PluralRules
@@ -1317,11 +1309,10 @@
 android.icu.text.Replaceable
 android.icu.text.ReplaceableString
 android.icu.text.RuleBasedBreakIterator
-android.icu.text.RuleBasedCollator
-android.icu.text.SimpleDateFormat
-android.icu.text.SimpleDateFormat$PatternItem
+android.icu.text.RuleBasedBreakIterator$LookAheadResults
 android.icu.text.StringPrep
 android.icu.text.StringPrepParseException
+android.icu.text.TimeZoneNames$NameType
 android.icu.text.UCharacterIterator
 android.icu.text.UFieldPosition
 android.icu.text.UFormat
@@ -1331,48 +1322,36 @@
 android.icu.text.UnicodeFilter
 android.icu.text.UnicodeMatcher
 android.icu.text.UnicodeSet
-android.icu.text.UnicodeSet$Filter
-android.icu.text.UnicodeSet$GeneralCategoryMaskFilter
-android.icu.text.UnicodeSet$IntPropertyFilter
-android.icu.util.BasicTimeZone
-android.icu.util.BytesTrie
 android.icu.util.BytesTrie$Result
-android.icu.util.Calendar
-android.icu.util.Calendar$CalType
-android.icu.util.Calendar$FormatConfiguration
-android.icu.util.Calendar$PatternData
-android.icu.util.Calendar$WeekData
-android.icu.util.Calendar$WeekDataCache
 android.icu.util.Currency
+android.icu.util.Currency$1
 android.icu.util.Currency$CurrencyUsage
 android.icu.util.Currency$EquivalenceRelation
 android.icu.util.Freezable
-android.icu.util.GregorianCalendar
 android.icu.util.MeasureUnit
 android.icu.util.MeasureUnit$1
 android.icu.util.MeasureUnit$2
 android.icu.util.MeasureUnit$3
 android.icu.util.MeasureUnit$Factory
-android.icu.util.Output
-android.icu.util.SimpleTimeZone
 android.icu.util.TimeUnit
 android.icu.util.TimeZone
 android.icu.util.TimeZone$ConstantZone
 android.icu.util.ULocale
+android.icu.util.ULocale$1
+android.icu.util.ULocale$2
 android.icu.util.ULocale$Category
 android.icu.util.ULocale$JDKLocaleHelper
 android.icu.util.ULocale$Type
 android.icu.util.UResourceBundle
-android.icu.util.UResourceBundle$ResourceCacheKey
+android.icu.util.UResourceBundle$RootType
 android.icu.util.UResourceBundleIterator
 android.icu.util.UResourceTypeMismatchException
 android.icu.util.VersionInfo
 android.location.CountryDetector
-android.location.ILocationManager
-android.location.ILocationManager$Stub
 android.location.Location
+android.location.Location$1
+android.location.Location$2
 android.location.LocationManager
-android.media.AmrInputStream
 android.media.AudioAttributes
 android.media.AudioAttributes$1
 android.media.AudioAttributes$Builder
@@ -1386,7 +1365,7 @@
 android.media.AudioManager
 android.media.AudioManager$1
 android.media.AudioManager$2
-android.media.AudioManager$OnAudioFocusChangeListener
+android.media.AudioManager$3
 android.media.AudioManager$ServiceEventHandlerDelegate
 android.media.AudioManager$ServiceEventHandlerDelegate$1
 android.media.AudioMixPort
@@ -1404,7 +1383,6 @@
 android.media.CameraProfile
 android.media.DecoderCapabilities
 android.media.EncoderCapabilities
-android.media.ExifInterface
 android.media.IAudioFocusDispatcher
 android.media.IAudioFocusDispatcher$Stub
 android.media.IAudioService
@@ -1412,6 +1390,10 @@
 android.media.IAudioService$Stub$Proxy
 android.media.IMediaHTTPConnection
 android.media.IMediaHTTPConnection$Stub
+android.media.IPlaybackConfigDispatcher
+android.media.IPlaybackConfigDispatcher$Stub
+android.media.IPlayer
+android.media.IPlayer$Stub
 android.media.IRecordingConfigDispatcher
 android.media.IRecordingConfigDispatcher$Stub
 android.media.Image
@@ -1422,6 +1404,8 @@
 android.media.JetPlayer
 android.media.MediaCodec
 android.media.MediaCodecInfo
+android.media.MediaCodecInfo$CodecCapabilities
+android.media.MediaCodecInfo$CodecProfileLevel
 android.media.MediaCodecList
 android.media.MediaCrypto
 android.media.MediaDrm
@@ -1432,21 +1416,17 @@
 android.media.MediaMuxer
 android.media.MediaPlayer
 android.media.MediaPlayer$OnCompletionListener
-android.media.MediaPlayer$OnErrorListener
-android.media.MediaPlayer$OnPreparedListener
-android.media.MediaPlayer$OnSeekCompleteListener
-android.media.MediaPlayer$OnVideoSizeChangedListener
 android.media.MediaRecorder
 android.media.MediaRouter
-android.media.MediaRouter$Callback
-android.media.MediaRouter$RouteCategory
-android.media.MediaRouter$RouteInfo
 android.media.MediaScanner
 android.media.MediaSync
 android.media.PlaybackParams
 android.media.PlaybackParams$1
 android.media.PlayerBase
 android.media.PlayerBase$1
+android.media.PlayerBase$2
+android.media.PlayerBase$PlayerIdCard
+android.media.PlayerBase$PlayerIdCard$1
 android.media.RemoteDisplay
 android.media.ResampleInputStream
 android.media.SubtitleController$Listener
@@ -1456,12 +1436,10 @@
 android.media.audiopolicy.AudioMixingRule$AudioMixMatchCriterion
 android.media.midi.MidiManager
 android.media.projection.MediaProjectionManager
-android.media.session.MediaController
-android.media.session.MediaController$TransportControls
-android.media.session.MediaSession$Token
 android.media.session.MediaSessionManager
 android.media.soundtrigger.SoundTriggerManager
 android.media.tv.TvInputManager
+android.metrics.LogMaker
 android.mtp.MtpDatabase
 android.mtp.MtpDevice
 android.mtp.MtpDeviceInfo
@@ -1476,6 +1454,8 @@
 android.net.ConnectivityManager$CallbackHandler
 android.net.ConnectivityManager$NetworkCallback
 android.net.ConnectivityThread
+# Must not be initialized, creates a thread.
+# android.net.ConnectivityThread$Singleton
 android.net.Credentials
 android.net.EthernetManager
 android.net.IConnectivityManager
@@ -1504,6 +1484,7 @@
 android.net.NetworkRequest
 android.net.NetworkRequest$1
 android.net.NetworkRequest$Builder
+android.net.NetworkRequest$Type
 android.net.NetworkScoreManager
 android.net.NetworkStats
 android.net.NetworkStats$1
@@ -1512,9 +1493,6 @@
 android.net.ProxyInfo
 android.net.RouteInfo
 android.net.RouteInfo$1
-android.net.SSLCertificateSocketFactory
-android.net.SSLCertificateSocketFactory$1
-android.net.SSLSessionCache
 android.net.TrafficStats
 android.net.Uri
 android.net.Uri$1
@@ -1539,29 +1517,13 @@
 android.net.wifi.WifiInfo
 android.net.wifi.WifiInfo$1
 android.net.wifi.WifiManager
-android.net.wifi.WifiManager$WifiLock
 android.net.wifi.WifiScanner
 android.net.wifi.WifiSsid
 android.net.wifi.WifiSsid$1
-android.net.wifi.nan.WifiNanManager
+android.net.wifi.aware.WifiAwareManager
 android.net.wifi.p2p.WifiP2pManager
-android.nfc.IAppCallback
-android.nfc.IAppCallback$Stub
 android.nfc.INfcAdapter
 android.nfc.INfcAdapter$Stub
-android.nfc.INfcAdapter$Stub$Proxy
-android.nfc.INfcCardEmulation
-android.nfc.INfcCardEmulation$Stub
-android.nfc.INfcCardEmulation$Stub$Proxy
-android.nfc.INfcFCardEmulation
-android.nfc.INfcFCardEmulation$Stub
-android.nfc.INfcFCardEmulation$Stub$Proxy
-android.nfc.INfcTag
-android.nfc.INfcTag$Stub
-android.nfc.INfcTag$Stub$Proxy
-android.nfc.NfcActivityManager
-android.nfc.NfcAdapter
-android.nfc.NfcAdapter$1
 android.nfc.NfcManager
 android.opengl.EGL14
 android.opengl.EGLConfig
@@ -1583,6 +1545,7 @@
 android.opengl.GLUtils
 android.opengl.Matrix
 android.opengl.Visibility
+android.os.-$Lambda$5$6x30vPJhBKUfNY8tswxuZo3DCe0
 android.os.AsyncTask$1
 android.os.AsyncTask$2
 android.os.AsyncTask$3
@@ -1614,17 +1577,24 @@
 android.os.DropBoxManager
 android.os.Environment
 android.os.Environment$UserEnvironment
+android.os.FactoryTest
 android.os.FileObserver$ObserverThread
 android.os.FileUtils
+android.os.GraphicsEnvironment
 android.os.Handler
 android.os.Handler$Callback
 android.os.Handler$MessengerImpl
 android.os.HandlerThread
 android.os.HardwarePropertiesManager
+android.os.HwBinder
+android.os.HwBlob
+android.os.HwParcel
+android.os.HwRemoteBinder
 android.os.IBinder
 android.os.IBinder$DeathRecipient
 android.os.ICancellationSignal
 android.os.ICancellationSignal$Stub
+android.os.IHwBinder
 android.os.IInterface
 android.os.IMessenger
 android.os.IMessenger$Stub
@@ -1641,7 +1611,7 @@
 android.os.IUserManager$Stub$Proxy
 android.os.IVibratorService
 android.os.IVibratorService$Stub
-android.os.IVibratorService$Stub$Proxy
+android.os.IncidentManager
 android.os.LocaleList
 android.os.LocaleList$1
 android.os.Looper
@@ -1658,7 +1628,6 @@
 android.os.ParcelFileDescriptor
 android.os.ParcelFileDescriptor$1
 android.os.ParcelFileDescriptor$AutoCloseInputStream
-android.os.ParcelFileDescriptor$AutoCloseOutputStream
 android.os.Parcelable
 android.os.Parcelable$ClassLoaderCreator
 android.os.Parcelable$Creator
@@ -1677,8 +1646,11 @@
 android.os.ResultReceiver
 android.os.SELinux
 android.os.ServiceManager
+android.os.ServiceManager$ServiceNotFoundException
 android.os.ServiceManagerNative
 android.os.ServiceManagerProxy
+android.os.ServiceSpecificException
+android.os.ShellCallback
 android.os.StatFs
 android.os.StrictMode
 android.os.StrictMode$1
@@ -1704,6 +1676,7 @@
 android.os.StrictMode$ThreadPolicy$Builder
 android.os.StrictMode$ThreadSpanState
 android.os.StrictMode$ViolationInfo
+android.os.StrictMode$ViolationInfo$1
 android.os.StrictMode$VmPolicy
 android.os.StrictMode$VmPolicy$Builder
 android.os.SystemClock
@@ -1716,6 +1689,7 @@
 android.os.UserHandle$1
 android.os.UserManager
 android.os.Vibrator
+android.os.ZygoteProcess
 android.os.ZygoteStartFailedEx
 android.os.health.SystemHealthManager
 android.os.storage.IStorageManager
@@ -1724,17 +1698,16 @@
 android.os.storage.StorageManager
 android.os.storage.StorageVolume
 android.os.storage.StorageVolume$1
-android.preference.Preference$OnPreferenceChangeListener
 android.preference.PreferenceActivity
 android.preference.PreferenceFragment$OnPreferenceStartFragmentCallback
 android.preference.PreferenceManager
 android.preference.PreferenceManager$OnPreferenceTreeClickListener
 android.print.PrintManager
+android.provider.-$Lambda$46$87WmhkvObehVg0OMBzwa_MTVV8g
 android.provider.BaseColumns
 android.provider.ContactsContract
 android.provider.ContactsContract$CommonDataKinds$BaseTypes
 android.provider.ContactsContract$CommonDataKinds$CommonColumns
-android.provider.ContactsContract$CommonDataKinds$Email
 android.provider.ContactsContract$CommonDataKinds$Phone
 android.provider.ContactsContract$ContactCounts
 android.provider.ContactsContract$ContactNameColumns
@@ -1748,13 +1721,12 @@
 android.provider.ContactsContract$DataUsageStatColumns
 android.provider.ContactsContract$RawContactsColumns
 android.provider.ContactsContract$StatusColumns
-android.provider.MediaStore$Images$ImageColumns
-android.provider.MediaStore$Images$Media
 android.provider.MediaStore$MediaColumns
+android.provider.Settings
+android.provider.Settings$ContentProviderHolder
 android.provider.Settings$GenerationTracker
 android.provider.Settings$Global
 android.provider.Settings$NameValueCache
-android.provider.Settings$NameValueCache$-java_lang_String_getStringForUser_android_content_ContentResolver_cr_java_lang_String_name_int_userHandle_LambdaImpl0
 android.provider.Settings$NameValueTable
 android.provider.Settings$Secure
 android.provider.Settings$SettingNotFoundException
@@ -1773,8 +1745,6 @@
 android.provider.Settings$System$InclusiveIntegerRangeValidator
 android.provider.Settings$System$Validator
 android.renderscript.RenderScriptCacheDir
-android.security.FrameworkNetworkSecurityPolicy
-android.security.NetworkSecurityPolicy
 android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
 android.security.keystore.AndroidKeyStoreProvider
 android.security.net.config.ApplicationConfig
@@ -1797,9 +1767,7 @@
 android.security.net.config.RootTrustManager
 android.security.net.config.RootTrustManagerFactorySpi
 android.security.net.config.SystemCertificateSource
-android.security.net.config.TrustAnchor
 android.security.net.config.TrustedCertificateStoreAdapter
-android.security.net.config.UserCertificateSource
 android.service.persistentdata.PersistentDataBlockManager
 android.system.ErrnoException
 android.system.GaiException
@@ -1811,6 +1779,7 @@
 android.system.StructFlock
 android.system.StructGroupReq
 android.system.StructGroupSourceReq
+android.system.StructIfaddrs
 android.system.StructLinger
 android.system.StructPasswd
 android.system.StructPollfd
@@ -1824,11 +1793,11 @@
 android.telephony.CarrierConfigManager
 android.telephony.PhoneNumberUtils
 android.telephony.PhoneStateListener
-android.telephony.PhoneStateListener$1
-android.telephony.PhoneStateListener$IPhoneStateListenerStub
 android.telephony.Rlog
+android.telephony.ServiceState
 android.telephony.SubscriptionManager
 android.telephony.TelephonyManager
+android.telephony.TelephonyManager$MultiSimVariants
 android.text.AndroidBidi
 android.text.AndroidCharacter
 android.text.BoringLayout
@@ -1839,15 +1808,19 @@
 android.text.Editable
 android.text.Editable$Factory
 android.text.FontConfig
+android.text.FontConfig$1
 android.text.FontConfig$Alias
+android.text.FontConfig$Alias$1
 android.text.FontConfig$Axis
+android.text.FontConfig$Axis$1
 android.text.FontConfig$Family
+android.text.FontConfig$Family$1
 android.text.FontConfig$Font
+android.text.FontConfig$Font$1
+android.text.FontManager
 android.text.GetChars
 android.text.GraphicsOperations
 android.text.Html
-android.text.Html$HtmlParser
-android.text.HtmlToSpannedConverter
 android.text.Hyphenator
 android.text.InputFilter
 android.text.InputType
@@ -1889,15 +1862,11 @@
 android.text.TextUtils
 android.text.TextUtils$1
 android.text.TextUtils$EllipsizeCallback
-android.text.TextUtils$SimpleStringSplitter
-android.text.TextUtils$StringSplitter
 android.text.TextUtils$TruncateAt
 android.text.TextWatcher
 android.text.format.DateFormat
 android.text.format.DateUtils
-android.text.format.Formatter
 android.text.format.Time
-android.text.format.Time$TimeCalculator
 android.text.method.AllCapsTransformationMethod
 android.text.method.ArrowKeyMovementMethod
 android.text.method.BaseKeyListener
@@ -1919,10 +1888,8 @@
 android.text.style.AlignmentSpan
 android.text.style.CharacterStyle
 android.text.style.ClickableSpan
-android.text.style.DynamicDrawableSpan
 android.text.style.EasyEditSpan
 android.text.style.ForegroundColorSpan
-android.text.style.ImageSpan
 android.text.style.LeadingMarginSpan
 android.text.style.LineBackgroundSpan
 android.text.style.LineHeightSpan
@@ -1933,9 +1900,7 @@
 android.text.style.StyleSpan
 android.text.style.SuggestionSpan
 android.text.style.TabStopSpan
-android.text.style.TextAppearanceSpan
 android.text.style.URLSpan
-android.text.style.UnderlineSpan
 android.text.style.UpdateAppearance
 android.text.style.UpdateLayout
 android.text.style.WrapTogetherSpan
@@ -1956,7 +1921,6 @@
 android.transition.ChangeTransform$2
 android.transition.Fade
 android.transition.PathMotion
-android.transition.Scene
 android.transition.Transition
 android.transition.Transition$1
 android.transition.Transition$EpicenterCallback
@@ -1976,18 +1940,20 @@
 android.util.Base64$Coder
 android.util.Base64$Decoder
 android.util.Base64$Encoder
+android.util.BootTimingsTraceLog
 android.util.ContainerHelpers
 android.util.DisplayMetrics
 android.util.EventLog
 android.util.EventLog$Event
 android.util.FloatProperty
+android.util.IntArray
 android.util.IntProperty
-android.util.JsonReader
 android.util.Log
 android.util.Log$1
 android.util.Log$ImmediateLogWriter
 android.util.Log$TerribleFailureHandler
 android.util.LogPrinter
+android.util.LongArray
 android.util.LongSparseArray
 android.util.LongSparseLongArray
 android.util.LruCache
@@ -2002,6 +1968,7 @@
 android.util.Pair
 android.util.PathParser
 android.util.PathParser$PathData
+android.util.Patterns
 android.util.Pools$Pool
 android.util.Pools$SimplePool
 android.util.Pools$SynchronizedPool
@@ -2011,24 +1978,24 @@
 android.util.Rational
 android.util.Singleton
 android.util.Size
+android.util.SizeF
 android.util.Slog
 android.util.SparseArray
 android.util.SparseBooleanArray
 android.util.SparseIntArray
-android.util.SparseLongArray
 android.util.StateSet
 android.util.SuperNotCalledException
-android.util.TimeFormatException
 android.util.TypedValue
 android.util.Xml
 android.util.jar.StrictJarFile
+android.view.-$Lambda$48$iU_USrtPm1XIm5H9QYQvXfBGDE4
+android.view.-$Lambda$49$iU_USrtPm1XIm5H9QYQvXfBGDE4
 android.view.AbsSavedState
 android.view.AbsSavedState$1
 android.view.AbsSavedState$2
 android.view.ActionMode
 android.view.ActionMode$Callback
 android.view.ActionProvider
-android.view.ActionProvider$SubUiVisibilityListener
 android.view.Choreographer
 android.view.Choreographer$1
 android.view.Choreographer$2
@@ -2041,8 +2008,6 @@
 android.view.ContextMenu$ContextMenuInfo
 android.view.ContextThemeWrapper
 android.view.Display
-android.view.Display$ColorTransform
-android.view.Display$ColorTransform$1
 android.view.Display$HdrCapabilities
 android.view.Display$HdrCapabilities$1
 android.view.Display$Mode
@@ -2052,6 +2017,7 @@
 android.view.DisplayInfo
 android.view.DisplayInfo$1
 android.view.DisplayListCanvas
+android.view.DragEvent
 android.view.FallbackEventHandler
 android.view.FocusFinder
 android.view.FocusFinder$1
@@ -2066,8 +2032,6 @@
 android.view.GestureDetector$OnDoubleTapListener
 android.view.GestureDetector$OnGestureListener
 android.view.GestureDetector$SimpleOnGestureListener
-android.view.GraphicBuffer
-android.view.GraphicBuffer$1
 android.view.Gravity
 android.view.HandlerActionQueue
 android.view.HandlerActionQueue$HandlerAction
@@ -2092,7 +2056,6 @@
 android.view.InputChannel$1
 android.view.InputDevice
 android.view.InputDevice$1
-android.view.InputDevice$MotionRange
 android.view.InputEvent
 android.view.InputEvent$1
 android.view.InputEventConsistencyVerifier
@@ -2125,9 +2088,12 @@
 android.view.MotionEvent$PointerProperties
 android.view.PointerIcon
 android.view.PointerIcon$1
+android.view.RecordingCanvas
 android.view.RenderNode
+android.view.RenderNode$NoImagePreloadHolder
 android.view.RenderNodeAnimator
 android.view.RenderNodeAnimator$1
+android.view.RenderNodeAnimatorSetHelper
 android.view.SearchEvent
 android.view.SoundEffectConstants
 android.view.SubMenu
@@ -2143,9 +2109,8 @@
 android.view.SurfaceSession
 android.view.SurfaceView
 android.view.TextureView
-android.view.TextureView$SurfaceTextureListener
 android.view.ThreadedRenderer
-android.view.ThreadedRenderer$HardwareDrawCallbacks
+android.view.ThreadedRenderer$DrawCallbacks
 android.view.ThreadedRenderer$ProcessInitializer
 android.view.VelocityTracker
 android.view.VelocityTracker$Estimator
@@ -2182,6 +2147,7 @@
 android.view.View$OnTouchListener
 android.view.View$PerformClick
 android.view.View$ScrollabilityCache
+android.view.View$TooltipInfo
 android.view.View$TransformationInfo
 android.view.View$UnsetPressedState
 android.view.ViewConfiguration
@@ -2193,11 +2159,13 @@
 android.view.ViewGroup$MarginLayoutParams
 android.view.ViewGroup$OnHierarchyChangeListener
 android.view.ViewGroup$TouchTarget
+android.view.ViewGroupOverlay
 android.view.ViewManager
 android.view.ViewOutlineProvider
 android.view.ViewOutlineProvider$1
 android.view.ViewOutlineProvider$2
 android.view.ViewOutlineProvider$3
+android.view.ViewOverlay
 android.view.ViewParent
 android.view.ViewPropertyAnimator
 android.view.ViewPropertyAnimator$1
@@ -2245,6 +2213,7 @@
 android.view.Window
 android.view.Window$Callback
 android.view.Window$OnWindowDismissedCallback
+android.view.Window$OnWindowSwipeDismissedCallback
 android.view.Window$WindowControllerCallback
 android.view.WindowAnimationFrameStats
 android.view.WindowAnimationFrameStats$1
@@ -2254,7 +2223,6 @@
 android.view.WindowInsets
 android.view.WindowLeaked
 android.view.WindowManager
-android.view.WindowManager$BadTokenException
 android.view.WindowManager$LayoutParams
 android.view.WindowManager$LayoutParams$1
 android.view.WindowManagerGlobal
@@ -2272,9 +2240,6 @@
 android.view.accessibility.AccessibilityNodeProvider
 android.view.accessibility.AccessibilityRecord
 android.view.accessibility.CaptioningManager
-android.view.accessibility.CaptioningManager$1
-android.view.accessibility.CaptioningManager$CaptioningChangeListener
-android.view.accessibility.CaptioningManager$MyContentObserver
 android.view.accessibility.IAccessibilityManager
 android.view.accessibility.IAccessibilityManager$Stub
 android.view.accessibility.IAccessibilityManager$Stub$Proxy
@@ -2291,24 +2256,23 @@
 android.view.animation.Animation$NoImagePreloadHolder
 android.view.animation.AnimationSet
 android.view.animation.AnimationUtils
+android.view.animation.AnimationUtils$1
+android.view.animation.AnimationUtils$AnimationState
 android.view.animation.BaseInterpolator
 android.view.animation.DecelerateInterpolator
 android.view.animation.Interpolator
 android.view.animation.LinearInterpolator
-android.view.animation.OvershootInterpolator
 android.view.animation.PathInterpolator
 android.view.animation.ScaleAnimation
 android.view.animation.Transformation
 android.view.animation.TranslateAnimation
+android.view.autofill.AutoFillManager
 android.view.inputmethod.BaseInputConnection
 android.view.inputmethod.ComposingText
 android.view.inputmethod.CursorAnchorInfo$Builder
 android.view.inputmethod.EditorInfo
 android.view.inputmethod.EditorInfo$1
-android.view.inputmethod.ExtractedText
-android.view.inputmethod.ExtractedText$1
 android.view.inputmethod.InputConnection
-android.view.inputmethod.InputConnectionInspector
 android.view.inputmethod.InputMethodManager
 android.view.inputmethod.InputMethodManager$1
 android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
@@ -2316,6 +2280,7 @@
 android.view.inputmethod.InputMethodManager$H
 android.view.inputmethod.InputMethodManager$ImeInputEventSender
 android.view.inputmethod.InputMethodManager$PendingEvent
+android.view.textclassifier.TextClassificationManager
 android.view.textservice.SpellCheckerSubtype
 android.view.textservice.SpellCheckerSubtype$1
 android.view.textservice.TextServicesManager
@@ -2323,7 +2288,6 @@
 android.webkit.IWebViewUpdateService$Stub
 android.webkit.IWebViewUpdateService$Stub$Proxy
 android.webkit.MimeTypeMap
-android.webkit.WebSettings
 android.webkit.WebView
 android.webkit.WebViewFactory
 android.webkit.WebViewFactory$MissingWebViewPackageException
@@ -2339,14 +2303,6 @@
 android.widget.AbsSeekBar
 android.widget.AbsSpinner
 android.widget.AbsoluteLayout
-android.widget.ActionMenuPresenter
-android.widget.ActionMenuPresenter$1
-android.widget.ActionMenuPresenter$2
-android.widget.ActionMenuPresenter$OverflowMenuButton
-android.widget.ActionMenuPresenter$OverflowMenuButton$1
-android.widget.ActionMenuPresenter$PopupPresenterCallback
-android.widget.ActionMenuView
-android.widget.ActionMenuView$ActionMenuChildView
 android.widget.ActionMenuView$OnMenuItemClickListener
 android.widget.Adapter
 android.widget.AdapterView
@@ -2367,24 +2323,16 @@
 android.widget.Editor
 android.widget.Editor$1
 android.widget.Editor$2
-android.widget.Editor$Blink
 android.widget.Editor$CursorAnchorInfoNotifier
-android.widget.Editor$CursorController
-android.widget.Editor$EditOperation
-android.widget.Editor$EditOperation$1
 android.widget.Editor$InputContentType
-android.widget.Editor$InputMethodState
-android.widget.Editor$InsertionPointCursorController
 android.widget.Editor$PositionListener
 android.widget.Editor$ProcessTextIntentActionsHandler
-android.widget.Editor$SelectionModifierCursorController
 android.widget.Editor$SpanController
 android.widget.Editor$SuggestionHelper
 android.widget.Editor$SuggestionHelper$SuggestionSpanComparator
 android.widget.Editor$TextRenderNode
 android.widget.Editor$TextViewPositionListener
 android.widget.Editor$UndoInputFilter
-android.widget.Filter
 android.widget.Filter$FilterListener
 android.widget.Filterable
 android.widget.ForwardingListener
@@ -2392,8 +2340,6 @@
 android.widget.FrameLayout$LayoutParams
 android.widget.HeaderViewListAdapter
 android.widget.HorizontalScrollView
-android.widget.HorizontalScrollView$SavedState
-android.widget.HorizontalScrollView$SavedState$1
 android.widget.ImageButton
 android.widget.ImageView
 android.widget.ImageView$ScaleType
@@ -2402,12 +2348,12 @@
 android.widget.ListAdapter
 android.widget.ListPopupWindow
 android.widget.ListPopupWindow$ListSelectorHider
+android.widget.ListPopupWindow$PopupDataSetObserver
 android.widget.ListPopupWindow$PopupScrollListener
 android.widget.ListPopupWindow$PopupTouchInterceptor
 android.widget.ListPopupWindow$ResizePopupRunnable
 android.widget.ListView
 android.widget.ListView$ArrowScrollFocusResult
-android.widget.ListView$FixedViewInfo
 android.widget.MultiAutoCompleteTextView
 android.widget.OverScroller
 android.widget.OverScroller$SplineOverScroller
@@ -2415,8 +2361,6 @@
 android.widget.PopupWindow$1
 android.widget.PopupWindow$2
 android.widget.PopupWindow$OnDismissListener
-android.widget.PopupWindow$PopupDecorView
-android.widget.PopupWindow$PopupDecorView$1
 android.widget.ProgressBar
 android.widget.ProgressBar$1
 android.widget.ProgressBar$SavedState
@@ -2428,30 +2372,17 @@
 android.widget.RelativeLayout$DependencyGraph$Node
 android.widget.RelativeLayout$LayoutParams
 android.widget.RemoteViews
-android.widget.RemoteViews$1
-android.widget.RemoteViews$2
-android.widget.RemoteViews$3
-android.widget.RemoteViews$Action
-android.widget.RemoteViews$ActionException
-android.widget.RemoteViews$BitmapCache
-android.widget.RemoteViews$MemoryUsageCounter
-android.widget.RemoteViews$MutablePair
-android.widget.RemoteViews$OnClickHandler
-android.widget.RemoteViews$ReflectionAction
-android.widget.RemoteViews$RuntimeAction
-android.widget.RemoteViews$SetOnClickPendingIntent
+android.widget.RemoteViews$RemoteView
 android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
 android.widget.RtlSpacingHelper
 android.widget.ScrollBarDrawable
 android.widget.ScrollView
 android.widget.Scroller
 android.widget.Scroller$ViscousFluidInterpolator
-android.widget.SectionIndexer
 android.widget.SeekBar
 android.widget.Space
 android.widget.Spinner
 android.widget.SpinnerAdapter
-android.widget.Switch
 android.widget.TextView
 android.widget.TextView$BufferType
 android.widget.TextView$ChangeWatcher
@@ -2465,7 +2396,6 @@
 android.widget.Toolbar
 android.widget.Toolbar$1
 android.widget.Toolbar$2
-android.widget.Toolbar$ExpandedActionViewMenuPresenter
 android.widget.Toolbar$LayoutParams
 android.widget.WrapperListAdapter
 com.android.dex.ClassData
@@ -2497,9 +2427,6 @@
 com.android.i18n.phonenumbers.NumberParseException
 com.android.i18n.phonenumbers.PhoneNumberUtil
 com.android.internal.R$styleable
-com.android.internal.app.AlertController
-com.android.internal.app.AlertController$1
-com.android.internal.app.AlertController$ButtonHandler
 com.android.internal.app.IAppOpsCallback
 com.android.internal.app.IAppOpsCallback$Stub
 com.android.internal.app.IAppOpsService
@@ -2507,42 +2434,47 @@
 com.android.internal.app.IAppOpsService$Stub$Proxy
 com.android.internal.app.IBatteryStats
 com.android.internal.app.IBatteryStats$Stub
+com.android.internal.app.IBatteryStats$Stub$Proxy
 com.android.internal.app.IVoiceInteractor
 com.android.internal.app.IVoiceInteractor$Stub
-com.android.internal.appwidget.IAppWidgetService
-com.android.internal.appwidget.IAppWidgetService$Stub
-com.android.internal.appwidget.IAppWidgetService$Stub$Proxy
 com.android.internal.content.NativeLibraryHelper
 com.android.internal.content.ReferrerIntent
 com.android.internal.content.ReferrerIntent$1
+com.android.internal.graphics.drawable.AnimationScaleListDrawable
+com.android.internal.graphics.drawable.AnimationScaleListDrawable$AnimationScaleListState
 com.android.internal.inputmethod.InputMethodUtils
 com.android.internal.inputmethod.InputMethodUtils$1
 com.android.internal.inputmethod.LocaleUtils$LocaleExtractor
 com.android.internal.logging.AndroidConfig
 com.android.internal.logging.AndroidHandler
 com.android.internal.logging.AndroidHandler$1
+com.android.internal.logging.EventLogTags
+com.android.internal.logging.MetricsLogger
 com.android.internal.net.NetworkStatsFactory
 com.android.internal.os.AndroidPrintStream
 com.android.internal.os.BinderInternal
 com.android.internal.os.BinderInternal$GcWatcher
-com.android.internal.os.InstallerConnection$InstallerException
+com.android.internal.os.FuseAppLoop
+com.android.internal.os.FuseAppLoop$1
+com.android.internal.os.FuseAppLoop$UnmountedException
 com.android.internal.os.LoggingPrintStream
 com.android.internal.os.LoggingPrintStream$1
 com.android.internal.os.PathClassLoaderFactory
+com.android.internal.os.RoSystemProperties
 com.android.internal.os.RuntimeInit
 com.android.internal.os.RuntimeInit$1
 com.android.internal.os.RuntimeInit$Arguments
 com.android.internal.os.RuntimeInit$KillApplicationHandler
 com.android.internal.os.RuntimeInit$LoggingHandler
-com.android.internal.os.RoSystemProperties
 com.android.internal.os.SamplingProfilerIntegration
 com.android.internal.os.SomeArgs
 com.android.internal.os.Zygote
+com.android.internal.os.Zygote$MethodAndArgsCaller
 com.android.internal.os.ZygoteConnection
 com.android.internal.os.ZygoteConnection$Arguments
 com.android.internal.os.ZygoteInit
-com.android.internal.os.ZygoteInit$MethodAndArgsCaller
 com.android.internal.os.ZygoteSecurityException
+com.android.internal.os.ZygoteServer
 com.android.internal.policy.DecorContext
 com.android.internal.policy.DecorView
 com.android.internal.policy.DecorView$ColorViewState
@@ -2554,8 +2486,6 @@
 com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback
 com.android.internal.policy.PhoneWindow$RotationWatcher
 com.android.internal.policy.PhoneWindow$RotationWatcher$1
-com.android.internal.telephony.IPhoneStateListener
-com.android.internal.telephony.IPhoneStateListener$Stub
 com.android.internal.telephony.ISub
 com.android.internal.telephony.ISub$Stub
 com.android.internal.telephony.ISub$Stub$Proxy
@@ -2569,6 +2499,8 @@
 com.android.internal.textservice.ITextServicesManager
 com.android.internal.textservice.ITextServicesManager$Stub
 com.android.internal.textservice.ITextServicesManager$Stub$Proxy
+com.android.internal.transition.EpicenterTranslateClipReveal
+com.android.internal.transition.TransitionConstants
 com.android.internal.util.ArrayUtils
 com.android.internal.util.FastPrintWriter
 com.android.internal.util.FastPrintWriter$DummyWriter
@@ -2579,15 +2511,10 @@
 com.android.internal.util.VirtualRefBasePtr
 com.android.internal.util.XmlUtils
 com.android.internal.util.XmlUtils$WriteMapCallback
-com.android.internal.view.ActionBarPolicy
 com.android.internal.view.IInputConnectionWrapper
 com.android.internal.view.IInputConnectionWrapper$MyHandler
-com.android.internal.view.IInputConnectionWrapper$SomeArgs
 com.android.internal.view.IInputContext
 com.android.internal.view.IInputContext$Stub
-com.android.internal.view.IInputContextCallback
-com.android.internal.view.IInputContextCallback$Stub
-com.android.internal.view.IInputContextCallback$Stub$Proxy
 com.android.internal.view.IInputMethodClient
 com.android.internal.view.IInputMethodClient$Stub
 com.android.internal.view.IInputMethodManager
@@ -2603,23 +2530,13 @@
 com.android.internal.view.animation.HasNativeInterpolator
 com.android.internal.view.animation.NativeInterpolatorFactory
 com.android.internal.view.animation.NativeInterpolatorFactoryHelper
-com.android.internal.view.menu.ActionMenuItem
-com.android.internal.view.menu.BaseMenuPresenter
 com.android.internal.view.menu.MenuBuilder
 com.android.internal.view.menu.MenuBuilder$Callback
-com.android.internal.view.menu.MenuBuilder$ItemInvoker
 com.android.internal.view.menu.MenuItemImpl
-com.android.internal.view.menu.MenuPresenter
 com.android.internal.view.menu.MenuPresenter$Callback
-com.android.internal.view.menu.MenuView
 com.android.internal.view.menu.ShowableListMenu
 com.android.internal.widget.BackgroundFallback
 com.android.internal.widget.DecorContentParent
-com.android.internal.widget.DecorToolbar
-com.android.internal.widget.EditableInputConnection
-com.android.internal.widget.ScrollBarUtils
-com.android.internal.widget.ToolbarWidgetWrapper
-com.android.internal.widget.ToolbarWidgetWrapper$1
 com.android.okhttp.Address
 com.android.okhttp.Authenticator
 com.android.okhttp.CacheControl
@@ -2635,6 +2552,8 @@
 com.android.okhttp.ConnectionSpec
 com.android.okhttp.ConnectionSpec$Builder
 com.android.okhttp.Dispatcher
+com.android.okhttp.Dns
+com.android.okhttp.Dns$1
 com.android.okhttp.Handshake
 com.android.okhttp.Headers
 com.android.okhttp.Headers$Builder
@@ -2659,8 +2578,6 @@
 com.android.okhttp.TlsVersion
 com.android.okhttp.internal.ConnectionSpecSelector
 com.android.okhttp.internal.Internal
-com.android.okhttp.internal.Network
-com.android.okhttp.internal.Network$1
 com.android.okhttp.internal.OptionalMethod
 com.android.okhttp.internal.Platform
 com.android.okhttp.internal.RouteDatabase
@@ -2670,14 +2587,14 @@
 com.android.okhttp.internal.http.AuthenticatorAdapter
 com.android.okhttp.internal.http.CacheStrategy
 com.android.okhttp.internal.http.CacheStrategy$Factory
-com.android.okhttp.internal.http.HttpConnection
-com.android.okhttp.internal.http.HttpConnection$AbstractSource
-com.android.okhttp.internal.http.HttpConnection$ChunkedSource
-com.android.okhttp.internal.http.HttpConnection$FixedLengthSource
+com.android.okhttp.internal.http.Http1xStream
+com.android.okhttp.internal.http.Http1xStream$AbstractSource
+com.android.okhttp.internal.http.Http1xStream$ChunkedSource
+com.android.okhttp.internal.http.Http1xStream$FixedLengthSource
 com.android.okhttp.internal.http.HttpEngine
 com.android.okhttp.internal.http.HttpEngine$1
 com.android.okhttp.internal.http.HttpMethod
-com.android.okhttp.internal.http.HttpTransport
+com.android.okhttp.internal.http.HttpStream
 com.android.okhttp.internal.http.OkHeaders
 com.android.okhttp.internal.http.OkHeaders$1
 com.android.okhttp.internal.http.RealResponseBody
@@ -2687,10 +2604,11 @@
 com.android.okhttp.internal.http.RouteException
 com.android.okhttp.internal.http.RouteSelector
 com.android.okhttp.internal.http.StatusLine
-com.android.okhttp.internal.http.Transport
+com.android.okhttp.internal.http.StreamAllocation
 com.android.okhttp.internal.huc.DelegatingHttpsURLConnection
 com.android.okhttp.internal.huc.HttpURLConnectionImpl
 com.android.okhttp.internal.huc.HttpsURLConnectionImpl
+com.android.okhttp.internal.io.RealConnection
 com.android.okhttp.internal.tls.OkHostnameVerifier
 com.android.okhttp.okio.AsyncTimeout
 com.android.okhttp.okio.AsyncTimeout$1
@@ -2771,8 +2689,12 @@
 com.android.org.bouncycastle.jcajce.provider.symmetric.DES$Mappings
 com.android.org.bouncycastle.jcajce.provider.symmetric.DESede
 com.android.org.bouncycastle.jcajce.provider.symmetric.DESede$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPBKDF2$Mappings
 com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12
 com.android.org.bouncycastle.jcajce.provider.symmetric.PBEPKCS12$Mappings
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters
+com.android.org.bouncycastle.jcajce.provider.symmetric.PBES2AlgorithmParameters$Mappings
 com.android.org.bouncycastle.jcajce.provider.symmetric.RC2
 com.android.org.bouncycastle.jcajce.provider.symmetric.RC2$Mappings
 com.android.org.bouncycastle.jcajce.provider.symmetric.SymmetricAlgorithmProvider
@@ -2792,18 +2714,20 @@
 com.android.org.bouncycastle.util.Encodable
 com.android.org.bouncycastle.util.Strings
 com.android.org.bouncycastle.util.Strings$1
+com.android.org.conscrypt.AbstractOpenSSLSession
 com.android.org.conscrypt.AbstractSessionContext
 com.android.org.conscrypt.AbstractSessionContext$1
 com.android.org.conscrypt.AddressUtils
 com.android.org.conscrypt.ByteArray
-com.android.org.conscrypt.CertPinManager
+com.android.org.conscrypt.CertBlacklist
 com.android.org.conscrypt.CertificatePriorityComparator
 com.android.org.conscrypt.ChainStrengthAnalyzer
 com.android.org.conscrypt.ClientSessionContext
 com.android.org.conscrypt.ClientSessionContext$HostAndPort
 com.android.org.conscrypt.CryptoUpcalls
-com.android.org.conscrypt.FileClientSessionCache
-com.android.org.conscrypt.FileClientSessionCache$Impl
+com.android.org.conscrypt.EvpMdRef$MD5
+com.android.org.conscrypt.EvpMdRef$SHA1
+com.android.org.conscrypt.EvpMdRef$SHA256
 com.android.org.conscrypt.Hex
 com.android.org.conscrypt.JSSEProvider
 com.android.org.conscrypt.KeyManagerFactoryImpl
@@ -2817,10 +2741,7 @@
 com.android.org.conscrypt.NativeRef$EVP_MD_CTX
 com.android.org.conscrypt.NativeRef$EVP_PKEY
 com.android.org.conscrypt.OpenSSLBIOInputStream
-com.android.org.conscrypt.OpenSSLContextImpl
-com.android.org.conscrypt.OpenSSLContextImpl$TLSv12
 com.android.org.conscrypt.OpenSSLECGroupContext
-com.android.org.conscrypt.OpenSSLECKeyFactory
 com.android.org.conscrypt.OpenSSLECPointContext
 com.android.org.conscrypt.OpenSSLECPublicKey
 com.android.org.conscrypt.OpenSSLExtendedSessionImpl
@@ -2829,6 +2750,7 @@
 com.android.org.conscrypt.OpenSSLMessageDigestJDK
 com.android.org.conscrypt.OpenSSLMessageDigestJDK$MD5
 com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA1
+com.android.org.conscrypt.OpenSSLMessageDigestJDK$SHA256
 com.android.org.conscrypt.OpenSSLProvider
 com.android.org.conscrypt.OpenSSLRSAKeyFactory
 com.android.org.conscrypt.OpenSSLRSAPublicKey
@@ -2847,11 +2769,7 @@
 com.android.org.conscrypt.OpenSSLX509CertificateFactory$2
 com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
 com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException
-com.android.org.conscrypt.PinEntryException
-com.android.org.conscrypt.PinListEntry
-com.android.org.conscrypt.PinManagerException
 com.android.org.conscrypt.Platform
-com.android.org.conscrypt.SSLClientSessionCache
 com.android.org.conscrypt.SSLParametersImpl
 com.android.org.conscrypt.SSLParametersImpl$AliasChooser
 com.android.org.conscrypt.SSLParametersImpl$PSKCallbacks
@@ -2863,6 +2781,17 @@
 com.android.org.conscrypt.TrustedCertificateIndex
 com.android.org.conscrypt.TrustedCertificateKeyStoreSpi
 com.android.org.conscrypt.TrustedCertificateStore
+com.android.org.conscrypt.TrustedCertificateStore$1
+com.android.org.conscrypt.TrustedCertificateStore$CertSelector
+com.android.org.conscrypt.ct.CTLogInfo
+com.android.org.conscrypt.ct.CTLogStore
+com.android.org.conscrypt.ct.CTLogStoreImpl
+com.android.org.conscrypt.ct.CTLogStoreImpl$InvalidLogFileException
+com.android.org.conscrypt.ct.CTPolicy
+com.android.org.conscrypt.ct.CTPolicyImpl
+com.android.org.conscrypt.ct.CTVerifier
+com.android.org.conscrypt.ct.KnownLogs
+com.android.org.conscrypt.ct.SerializationException
 com.android.org.conscrypt.util.ArrayUtils
 com.android.server.NetworkManagementSocketTagger
 com.android.server.NetworkManagementSocketTagger$1
@@ -2871,20 +2800,31 @@
 com.google.android.collect.Maps
 com.google.android.gles_jni.EGLImpl
 com.google.android.gles_jni.GLImpl
+dalvik.annotation.optimization.CriticalNative
+dalvik.annotation.optimization.FastNative
 dalvik.system.BaseDexClassLoader
+dalvik.system.BaseDexClassLoader$Reporter
 dalvik.system.BlockGuard
 dalvik.system.BlockGuard$1
 dalvik.system.BlockGuard$2
 dalvik.system.BlockGuard$BlockGuardPolicyException
 dalvik.system.BlockGuard$Policy
+dalvik.system.ClassExt
 dalvik.system.CloseGuard
 dalvik.system.CloseGuard$DefaultReporter
+dalvik.system.CloseGuard$DefaultTracker
 dalvik.system.CloseGuard$Reporter
+dalvik.system.CloseGuard$Tracker
 dalvik.system.DalvikLogHandler
+dalvik.system.DexClassLoader
 dalvik.system.DexFile
 dalvik.system.DexFile$DFEnum
 dalvik.system.DexPathList
 dalvik.system.DexPathList$Element
+dalvik.system.DexPathList$NativeLibraryElement
+dalvik.system.EmulatedStackFrame
+dalvik.system.EmulatedStackFrame$Range
+dalvik.system.InMemoryDexClassLoader$DexData
 dalvik.system.PathClassLoader
 dalvik.system.SocketTagger
 dalvik.system.SocketTagger$1
@@ -2892,11 +2832,6 @@
 dalvik.system.VMRuntime
 dalvik.system.VMStack
 dalvik.system.ZygoteHooks
-java.beans.ChangeListenerMap
-java.beans.PropertyChangeEvent
-java.beans.PropertyChangeListener
-java.beans.PropertyChangeSupport
-java.beans.PropertyChangeSupport$PropertyChangeListenerMap
 java.io.Bits
 java.io.BufferedInputStream
 java.io.BufferedOutputStream
@@ -2911,6 +2846,7 @@
 java.io.DataInputStream
 java.io.DataOutput
 java.io.DataOutputStream
+java.io.DefaultFileSystem
 java.io.EOFException
 java.io.ExpiringCache
 java.io.ExpiringCache$1
@@ -2919,6 +2855,7 @@
 java.io.File
 java.io.File$PathStatus
 java.io.FileDescriptor
+java.io.FileDescriptor$1
 java.io.FileFilter
 java.io.FileInputStream
 java.io.FileInputStream$UseManualSkipException
@@ -2930,18 +2867,33 @@
 java.io.FilenameFilter
 java.io.FilterInputStream
 java.io.FilterOutputStream
-java.io.FilterReader
 java.io.Flushable
 java.io.IOException
 java.io.InputStream
 java.io.InputStreamReader
 java.io.InterruptedIOException
+java.io.InvalidClassException
 java.io.InvalidObjectException
 java.io.ObjectInput
 java.io.ObjectInputStream
+java.io.ObjectInputStream$BlockDataInputStream
+java.io.ObjectInputStream$HandleTable
+java.io.ObjectInputStream$HandleTable$HandleList
+java.io.ObjectInputStream$PeekInputStream
+java.io.ObjectInputStream$ValidationList
 java.io.ObjectOutput
 java.io.ObjectOutputStream
+java.io.ObjectOutputStream$BlockDataOutputStream
+java.io.ObjectOutputStream$HandleTable
+java.io.ObjectOutputStream$PutField
+java.io.ObjectOutputStream$ReplaceTable
 java.io.ObjectStreamClass
+java.io.ObjectStreamClass$2
+java.io.ObjectStreamClass$Caches
+java.io.ObjectStreamClass$EntryFuture
+java.io.ObjectStreamClass$FieldReflector
+java.io.ObjectStreamClass$FieldReflectorKey
+java.io.ObjectStreamClass$WeakClassKey
 java.io.ObjectStreamConstants
 java.io.ObjectStreamException
 java.io.ObjectStreamField
@@ -2950,7 +2902,6 @@
 java.io.PrintStream
 java.io.PrintWriter
 java.io.PushbackInputStream
-java.io.PushbackReader
 java.io.RandomAccessFile
 java.io.Reader
 java.io.SequenceInputStream
@@ -2962,10 +2913,13 @@
 java.io.UnixFileSystem
 java.io.UnsupportedEncodingException
 java.io.Writer
+java.lang.-$Lambda$250$S9HjrJh0nDg7IyU6wZdPArnZWRQ
+java.lang.-$Lambda$251$S9HjrJh0nDg7IyU6wZdPArnZWRQ
 java.lang.AbstractMethodError
 java.lang.AbstractStringBuilder
 java.lang.AndroidHardcodedSystemProperties
 java.lang.Appendable
+java.lang.ArithmeticException
 java.lang.ArrayIndexOutOfBoundsException
 java.lang.ArrayStoreException
 java.lang.AssertionError
@@ -2977,8 +2931,6 @@
 java.lang.CaseMapper
 java.lang.CaseMapper$1
 java.lang.CharSequence
-java.lang.CharSequence$-java_util_stream_IntStream_chars__LambdaImpl0
-java.lang.CharSequence$-java_util_stream_IntStream_codePoints__LambdaImpl0
 java.lang.CharSequence$1CharIterator
 java.lang.CharSequence$1CodePointIterator
 java.lang.Character
@@ -3008,9 +2960,7 @@
 java.lang.Error
 java.lang.Exception
 java.lang.Float
-java.lang.FloatingDecimal
-java.lang.FloatingDecimal$1
-java.lang.FloatingDecimal$2
+java.lang.IllegalAccessError
 java.lang.IllegalAccessException
 java.lang.IllegalArgumentException
 java.lang.IllegalStateException
@@ -3029,7 +2979,7 @@
 java.lang.Long
 java.lang.Long$LongCache
 java.lang.Math
-java.lang.Math$NoImagePreloadHolder
+java.lang.Math$RandomNumberGeneratorHolder
 java.lang.NoClassDefFoundError
 java.lang.NoSuchFieldError
 java.lang.NoSuchFieldException
@@ -3042,6 +2992,7 @@
 java.lang.OutOfMemoryError
 java.lang.Package
 java.lang.Process
+java.lang.ProcessBuilder
 java.lang.ProcessEnvironment
 java.lang.Readable
 java.lang.ReflectiveOperationException
@@ -3053,7 +3004,6 @@
 java.lang.SecurityManager
 java.lang.Short
 java.lang.Short$ShortCache
-java.lang.Shutdown
 java.lang.StackOverflowError
 java.lang.StackTraceElement
 java.lang.StrictMath
@@ -3061,7 +3011,6 @@
 java.lang.String$CaseInsensitiveComparator
 java.lang.StringBuffer
 java.lang.StringBuilder
-java.lang.StringCoding
 java.lang.StringFactory
 java.lang.StringIndexOutOfBoundsException
 java.lang.System
@@ -3095,6 +3044,22 @@
 java.lang.annotation.Inherited
 java.lang.annotation.Retention
 java.lang.annotation.Target
+java.lang.invoke.MethodHandle
+java.lang.invoke.MethodHandleImpl
+java.lang.invoke.MethodHandleImpl$HandleInfo
+java.lang.invoke.MethodHandleInfo
+java.lang.invoke.MethodHandleStatics
+java.lang.invoke.MethodHandles
+java.lang.invoke.MethodType
+java.lang.invoke.MethodType$ConcurrentWeakInternSet
+java.lang.invoke.MethodType$ConcurrentWeakInternSet$WeakEntry
+java.lang.invoke.MethodTypeForm
+java.lang.invoke.Transformers$BindTo
+java.lang.invoke.Transformers$Collector
+java.lang.invoke.Transformers$Spreader
+java.lang.invoke.Transformers$Transformer
+java.lang.invoke.Transformers$VarargsCollector
+java.lang.invoke.WrongMethodTypeException
 java.lang.ref.FinalizerReference
 java.lang.ref.FinalizerReference$Sentinel
 java.lang.ref.PhantomReference
@@ -3102,47 +3067,54 @@
 java.lang.ref.ReferenceQueue
 java.lang.ref.SoftReference
 java.lang.ref.WeakReference
-java.lang.reflect.AbstractMethod
-java.lang.reflect.AbstractMethod$GenericInfo
 java.lang.reflect.AccessibleObject
 java.lang.reflect.AnnotatedElement
 java.lang.reflect.Array
 java.lang.reflect.Constructor
+java.lang.reflect.Executable
+java.lang.reflect.Executable$GenericInfo
 java.lang.reflect.Field
-java.lang.reflect.GenericArrayType
 java.lang.reflect.GenericDeclaration
 java.lang.reflect.InvocationHandler
 java.lang.reflect.InvocationTargetException
+java.lang.reflect.MalformedParametersException
 java.lang.reflect.Member
 java.lang.reflect.Method
 java.lang.reflect.Method$1
 java.lang.reflect.Modifier
+java.lang.reflect.Parameter
 java.lang.reflect.ParameterizedType
 java.lang.reflect.Proxy
 java.lang.reflect.Proxy$1
+java.lang.reflect.Proxy$Key1
+java.lang.reflect.Proxy$Key2
+java.lang.reflect.Proxy$KeyFactory
+java.lang.reflect.Proxy$KeyX
+java.lang.reflect.Proxy$ProxyClassFactory
 java.lang.reflect.Type
 java.lang.reflect.TypeVariable
-java.lang.reflect.WildcardType
+java.lang.reflect.WeakCache
+java.lang.reflect.WeakCache$CacheKey
+java.lang.reflect.WeakCache$CacheValue
+java.lang.reflect.WeakCache$Factory
+java.lang.reflect.WeakCache$LookupValue
+java.lang.reflect.WeakCache$Value
 java.math.BigDecimal
 java.math.BigInt
 java.math.BigInteger
-java.math.BitLevel
 java.math.NativeBN
 java.math.RoundingMode
-java.net.AbstractPlainDatagramSocketImpl
 java.net.AbstractPlainSocketImpl
 java.net.AddressCache
 java.net.AddressCache$AddressCacheEntry
 java.net.AddressCache$AddressCacheKey
 java.net.ConnectException
 java.net.CookieHandler
-java.net.DatagramPacket
-java.net.DatagramSocketImpl
-java.net.DefaultInterface
 java.net.HttpURLConnection
 java.net.IDN
 java.net.Inet4Address
 java.net.Inet6Address
+java.net.Inet6Address$Inet6AddressHolder
 java.net.Inet6AddressImpl
 java.net.InetAddress
 java.net.InetAddress$1
@@ -3150,12 +3122,10 @@
 java.net.InetAddressImpl
 java.net.InetSocketAddress
 java.net.InetSocketAddress$InetSocketAddressHolder
-java.net.InterfaceAddress
 java.net.JarURLConnection
 java.net.MalformedURLException
 java.net.NetworkInterface
 java.net.Parts
-java.net.PlainDatagramSocketImpl
 java.net.PlainSocketImpl
 java.net.ProtocolException
 java.net.Proxy
@@ -3164,6 +3134,8 @@
 java.net.ResponseCache
 java.net.ServerSocket
 java.net.Socket
+java.net.Socket$2
+java.net.Socket$3
 java.net.SocketAddress
 java.net.SocketException
 java.net.SocketImpl
@@ -3173,7 +3145,6 @@
 java.net.SocketTimeoutException
 java.net.SocksConsts
 java.net.SocksSocketImpl
-java.net.SocksSocketImpl$3
 java.net.URI
 java.net.URI$Parser
 java.net.URISyntaxException
@@ -3222,6 +3193,7 @@
 java.nio.channels.FileLock
 java.nio.channels.GatheringByteChannel
 java.nio.channels.InterruptibleChannel
+java.nio.channels.MulticastChannel
 java.nio.channels.NetworkChannel
 java.nio.channels.ReadableByteChannel
 java.nio.channels.ScatteringByteChannel
@@ -3248,6 +3220,7 @@
 java.nio.charset.IllegalCharsetNameException
 java.nio.charset.StandardCharsets
 java.nio.charset.UnsupportedCharsetException
+java.nio.file.attribute.FileAttribute
 java.security.AccessControlContext
 java.security.AccessControlException
 java.security.AccessController
@@ -3338,7 +3311,6 @@
 java.security.interfaces.RSAPublicKey
 java.security.spec.AlgorithmParameterSpec
 java.security.spec.ECField
-java.security.spec.ECFieldF2m
 java.security.spec.ECFieldFp
 java.security.spec.ECParameterSpec
 java.security.spec.ECPoint
@@ -3346,15 +3318,12 @@
 java.security.spec.EllipticCurve
 java.security.spec.EncodedKeySpec
 java.security.spec.InvalidKeySpecException
-java.security.spec.InvalidParameterSpecException
 java.security.spec.KeySpec
 java.security.spec.RSAPublicKeySpec
 java.security.spec.X509EncodedKeySpec
-java.sql.Timestamp
 java.text.AttributedCharacterIterator$Attribute
 java.text.CalendarBuilder
 java.text.CharacterIterator
-java.text.Collator
 java.text.DateFormat
 java.text.DateFormat$Field
 java.text.DateFormatSymbols
@@ -3371,13 +3340,19 @@
 java.text.NumberFormat
 java.text.ParseException
 java.text.ParsePosition
-java.text.RuleBasedCollator
 java.text.SimpleDateFormat
 java.text.StringCharacterIterator
-java.text.spi.DateFormatProvider
-java.text.spi.DateFormatSymbolsProvider
-java.text.spi.DecimalFormatSymbolsProvider
-java.text.spi.NumberFormatProvider
+java.time.DateTimeException
+java.util.-$Lambda$181$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$182$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$183$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$184$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$267$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$268$4EqhxufgNKat19m0CB0-toH_lzo
+java.util.-$Lambda$291$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$292$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$293$aUGKT4ItCOku5-JSG-x8Aqj2pJw
+java.util.-$Lambda$294$aUGKT4ItCOku5-JSG-x8Aqj2pJw
 java.util.AbstractCollection
 java.util.AbstractList
 java.util.AbstractList$Itr
@@ -3397,8 +3372,21 @@
 java.util.ArrayList$ListItr
 java.util.ArrayList$SubList
 java.util.ArrayList$SubList$1
+java.util.ArrayPrefixHelpers$CumulateTask
+java.util.ArrayPrefixHelpers$DoubleCumulateTask
+java.util.ArrayPrefixHelpers$IntCumulateTask
+java.util.ArrayPrefixHelpers$LongCumulateTask
 java.util.Arrays
 java.util.Arrays$ArrayList
+java.util.Arrays$NaturalOrder
+java.util.ArraysParallelSortHelpers$FJByte$Sorter
+java.util.ArraysParallelSortHelpers$FJChar$Sorter
+java.util.ArraysParallelSortHelpers$FJDouble$Sorter
+java.util.ArraysParallelSortHelpers$FJFloat$Sorter
+java.util.ArraysParallelSortHelpers$FJInt$Sorter
+java.util.ArraysParallelSortHelpers$FJLong$Sorter
+java.util.ArraysParallelSortHelpers$FJObject$Sorter
+java.util.ArraysParallelSortHelpers$FJShort$Sorter
 java.util.BitSet
 java.util.Calendar
 java.util.Collection
@@ -3410,6 +3398,9 @@
 java.util.Collections$CheckedCollection
 java.util.Collections$CheckedList
 java.util.Collections$CheckedMap
+java.util.Collections$CheckedNavigableMap
+java.util.Collections$CheckedNavigableSet
+java.util.Collections$CheckedQueue
 java.util.Collections$CheckedRandomAccessList
 java.util.Collections$CheckedSet
 java.util.Collections$CheckedSortedMap
@@ -3430,6 +3421,8 @@
 java.util.Collections$SynchronizedCollection
 java.util.Collections$SynchronizedList
 java.util.Collections$SynchronizedMap
+java.util.Collections$SynchronizedNavigableMap
+java.util.Collections$SynchronizedNavigableSet
 java.util.Collections$SynchronizedRandomAccessList
 java.util.Collections$SynchronizedSet
 java.util.Collections$SynchronizedSortedMap
@@ -3442,18 +3435,16 @@
 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet
 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$1
 java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
+java.util.Collections$UnmodifiableNavigableMap
+java.util.Collections$UnmodifiableNavigableMap$EmptyNavigableMap
+java.util.Collections$UnmodifiableNavigableSet
+java.util.Collections$UnmodifiableNavigableSet$EmptyNavigableSet
 java.util.Collections$UnmodifiableRandomAccessList
 java.util.Collections$UnmodifiableSet
 java.util.Collections$UnmodifiableSortedMap
 java.util.Collections$UnmodifiableSortedSet
 java.util.ComparableTimSort
 java.util.Comparator
-java.util.Comparator$-java_util_Comparator_comparingDouble_java_util_function_ToDoubleFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparingInt_java_util_function_ToIntFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparingLong_java_util_function_ToLongFunction_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparing_java_util_function_Function_keyExtractor_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_comparing_java_util_function_Function_keyExtractor_java_util_Comparator_keyComparator_LambdaImpl0
-java.util.Comparator$-java_util_Comparator_thenComparing_java_util_Comparator_other_LambdaImpl0
 java.util.Comparators$NaturalOrderComparator
 java.util.Comparators$NullComparator
 java.util.ConcurrentModificationException
@@ -3467,7 +3458,6 @@
 java.util.EnumSet
 java.util.Enumeration
 java.util.EventListener
-java.util.EventObject
 java.util.Formattable
 java.util.Formatter
 java.util.Formatter$Conversion
@@ -3481,14 +3471,14 @@
 java.util.HashMap$EntryIterator
 java.util.HashMap$EntrySet
 java.util.HashMap$HashIterator
-java.util.HashMap$HashMapEntry
 java.util.HashMap$KeyIterator
 java.util.HashMap$KeySet
+java.util.HashMap$Node
+java.util.HashMap$TreeNode
 java.util.HashMap$ValueIterator
 java.util.HashMap$Values
 java.util.HashSet
 java.util.Hashtable
-java.util.Hashtable$EntrySet
 java.util.Hashtable$Enumerator
 java.util.Hashtable$HashtableEntry
 java.util.IdentityHashMap
@@ -3498,11 +3488,14 @@
 java.util.IllformedLocaleException
 java.util.Iterator
 java.util.LinkedHashMap
-java.util.LinkedHashMap$EntryIterator
-java.util.LinkedHashMap$KeyIterator
+java.util.LinkedHashMap$LinkedEntryIterator
+java.util.LinkedHashMap$LinkedEntrySet
 java.util.LinkedHashMap$LinkedHashIterator
 java.util.LinkedHashMap$LinkedHashMapEntry
-java.util.LinkedHashMap$ValueIterator
+java.util.LinkedHashMap$LinkedKeyIterator
+java.util.LinkedHashMap$LinkedKeySet
+java.util.LinkedHashMap$LinkedValueIterator
+java.util.LinkedHashMap$LinkedValues
 java.util.LinkedHashSet
 java.util.LinkedList
 java.util.LinkedList$ListItr
@@ -3513,6 +3506,8 @@
 java.util.Locale$Builder
 java.util.Locale$Cache
 java.util.Locale$Category
+java.util.Locale$FilteringMode
+java.util.Locale$LanguageRange
 java.util.Locale$LocaleKey
 java.util.Map
 java.util.Map$Entry
@@ -3524,30 +3519,16 @@
 java.util.PrimitiveIterator
 java.util.PrimitiveIterator$OfInt
 java.util.PriorityQueue
-java.util.PriorityQueue$Itr
 java.util.Properties
 java.util.Properties$LineReader
-java.util.PropertyResourceBundle
 java.util.Queue
 java.util.Random
 java.util.RandomAccess
 java.util.RandomAccessSubList
 java.util.RegularEnumSet
-java.util.RegularEnumSet$EnumSetIterator
 java.util.ResourceBundle
 java.util.ResourceBundle$1
-java.util.ResourceBundle$BundleReference
-java.util.ResourceBundle$CacheKey
-java.util.ResourceBundle$CacheKeyReference
-java.util.ResourceBundle$Control
-java.util.ResourceBundle$Control$1
-java.util.ResourceBundle$Control$CandidateListCache
-java.util.ResourceBundle$LoaderReference
-java.util.ResourceBundle$RBClassLoader
-java.util.ResourceBundle$RBClassLoader$1
-java.util.ServiceLoader
-java.util.ServiceLoader$1
-java.util.ServiceLoader$LazyIterator
+java.util.Scanner
 java.util.Set
 java.util.SimpleTimeZone
 java.util.SortedMap
@@ -3564,12 +3545,11 @@
 java.util.Spliterators$EmptySpliterator$OfLong
 java.util.Spliterators$EmptySpliterator$OfRef
 java.util.Stack
+java.util.StringJoiner
 java.util.StringTokenizer
 java.util.SubList
 java.util.TimSort
 java.util.TimeZone
-java.util.Timer
-java.util.TimerTask
 java.util.TreeMap
 java.util.TreeMap$EntryIterator
 java.util.TreeMap$EntrySet
@@ -3591,31 +3571,69 @@
 java.util.WeakHashMap$KeyIterator
 java.util.WeakHashMap$KeySet
 java.util.WeakHashMap$Values
+java.util.concurrent.-$Lambda$269$xR9BLpu6SifNikvFgr4lEiECBsk
 java.util.concurrent.AbstractExecutorService
 java.util.concurrent.BlockingQueue
 java.util.concurrent.Callable
 java.util.concurrent.CancellationException
 java.util.concurrent.ConcurrentHashMap
 java.util.concurrent.ConcurrentHashMap$BaseIterator
+java.util.concurrent.ConcurrentHashMap$BulkTask
 java.util.concurrent.ConcurrentHashMap$CollectionView
+java.util.concurrent.ConcurrentHashMap$CounterCell
 java.util.concurrent.ConcurrentHashMap$EntryIterator
 java.util.concurrent.ConcurrentHashMap$EntrySetView
+java.util.concurrent.ConcurrentHashMap$ForEachEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedEntryTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedKeyTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedMappingTask
+java.util.concurrent.ConcurrentHashMap$ForEachTransformedValueTask
+java.util.concurrent.ConcurrentHashMap$ForEachValueTask
 java.util.concurrent.ConcurrentHashMap$ForwardingNode
 java.util.concurrent.ConcurrentHashMap$KeyIterator
 java.util.concurrent.ConcurrentHashMap$KeySetView
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceEntriesToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceKeysToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceMappingsToLongTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToDoubleTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToIntTask
+java.util.concurrent.ConcurrentHashMap$MapReduceValuesToLongTask
 java.util.concurrent.ConcurrentHashMap$Node
+java.util.concurrent.ConcurrentHashMap$ReduceEntriesTask
+java.util.concurrent.ConcurrentHashMap$ReduceKeysTask
+java.util.concurrent.ConcurrentHashMap$ReduceValuesTask
+java.util.concurrent.ConcurrentHashMap$ReservationNode
+java.util.concurrent.ConcurrentHashMap$SearchEntriesTask
+java.util.concurrent.ConcurrentHashMap$SearchKeysTask
+java.util.concurrent.ConcurrentHashMap$SearchMappingsTask
+java.util.concurrent.ConcurrentHashMap$SearchValuesTask
 java.util.concurrent.ConcurrentHashMap$Segment
 java.util.concurrent.ConcurrentHashMap$Traverser
 java.util.concurrent.ConcurrentHashMap$TreeBin
 java.util.concurrent.ConcurrentHashMap$TreeNode
+java.util.concurrent.ConcurrentHashMap$ValueIterator
+java.util.concurrent.ConcurrentHashMap$ValuesView
 java.util.concurrent.ConcurrentLinkedQueue
 java.util.concurrent.ConcurrentLinkedQueue$Node
 java.util.concurrent.ConcurrentMap
 java.util.concurrent.CopyOnWriteArrayList
-java.util.concurrent.CopyOnWriteArrayList$CowIterator
+java.util.concurrent.CopyOnWriteArrayList$COWIterator
 java.util.concurrent.CopyOnWriteArraySet
 java.util.concurrent.CountDownLatch
 java.util.concurrent.CountDownLatch$Sync
+java.util.concurrent.CountedCompleter
 java.util.concurrent.Delayed
 java.util.concurrent.ExecutionException
 java.util.concurrent.Executor
@@ -3626,6 +3644,9 @@
 java.util.concurrent.Executors$DelegatedScheduledExecutorService
 java.util.concurrent.Executors$FinalizableDelegatedExecutorService
 java.util.concurrent.Executors$RunnableAdapter
+java.util.concurrent.ForkJoinPool
+java.util.concurrent.ForkJoinTask
+java.util.concurrent.ForkJoinTask$ExceptionNode
 java.util.concurrent.Future
 java.util.concurrent.FutureTask
 java.util.concurrent.FutureTask$WaitNode
@@ -3649,6 +3670,7 @@
 java.util.concurrent.SynchronousQueue$TransferStack$SNode
 java.util.concurrent.SynchronousQueue$Transferer
 java.util.concurrent.ThreadFactory
+java.util.concurrent.ThreadLocalRandom
 java.util.concurrent.ThreadPoolExecutor
 java.util.concurrent.ThreadPoolExecutor$AbortPolicy
 java.util.concurrent.ThreadPoolExecutor$Worker
@@ -3684,19 +3706,33 @@
 java.util.concurrent.locks.ReentrantReadWriteLock$Sync
 java.util.concurrent.locks.ReentrantReadWriteLock$Sync$ThreadLocalHoldCounter
 java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock
+java.util.function.-$Lambda$276$1MZdIZ-DL_fjy9l0o8IMJk57T2g
 java.util.function.BiConsumer
 java.util.function.BiFunction
+java.util.function.BinaryOperator
 java.util.function.Consumer
+java.util.function.DoubleBinaryOperator
 java.util.function.Function
+java.util.function.IntBinaryOperator
+java.util.function.IntConsumer
+java.util.function.IntFunction
+java.util.function.IntToDoubleFunction
+java.util.function.IntToLongFunction
+java.util.function.IntUnaryOperator
+java.util.function.LongBinaryOperator
+java.util.function.LongUnaryOperator
 java.util.function.Predicate
 java.util.function.Supplier
+java.util.function.ToDoubleBiFunction
 java.util.function.ToDoubleFunction
+java.util.function.ToIntBiFunction
 java.util.function.ToIntFunction
+java.util.function.ToLongBiFunction
 java.util.function.ToLongFunction
 java.util.function.UnaryOperator
 java.util.jar.JarEntry
 java.util.jar.JarFile
-java.util.jar.JarFile$1
+java.util.jar.JarFile$JarEntryIterator
 java.util.jar.JarFile$JarFileEntry
 java.util.logging.ErrorManager
 java.util.logging.Formatter
@@ -3706,7 +3742,8 @@
 java.util.logging.LogManager
 java.util.logging.LogManager$1
 java.util.logging.LogManager$2
-java.util.logging.LogManager$4
+java.util.logging.LogManager$3
+java.util.logging.LogManager$5
 java.util.logging.LogManager$Cleaner
 java.util.logging.LogManager$LogNode
 java.util.logging.LogManager$LoggerContext
@@ -3714,8 +3751,8 @@
 java.util.logging.LogManager$LoggerWeakRef
 java.util.logging.LogManager$RootLogger
 java.util.logging.LogManager$SystemLoggerContext
-java.util.logging.LogRecord
 java.util.logging.Logger
+java.util.logging.Logger$LoggerBundle
 java.util.logging.LoggingPermission
 java.util.logging.LoggingProxyImpl
 java.util.prefs.AbstractPreferences
@@ -3725,9 +3762,10 @@
 java.util.regex.Matcher
 java.util.regex.Pattern
 java.util.regex.PatternSyntaxException
-java.util.spi.LocaleServiceProvider
 java.util.stream.BaseStream
+java.util.stream.DoubleStream
 java.util.stream.IntStream
+java.util.stream.LongStream
 java.util.stream.Stream
 java.util.stream.StreamSupport
 java.util.zip.Adler32
@@ -3746,24 +3784,15 @@
 java.util.zip.ZipConstants
 java.util.zip.ZipEntry
 java.util.zip.ZipFile
-java.util.zip.ZipFile$1
+java.util.zip.ZipFile$ZipEntryIterator
 java.util.zip.ZipFile$ZipFileInflaterInputStream
 java.util.zip.ZipFile$ZipFileInputStream
+java.util.zip.ZipUtils
 javax.crypto.BadPaddingException
 javax.crypto.Cipher
-javax.crypto.Cipher$CipherSpiAndProvider
-javax.crypto.Cipher$InitParams
-javax.crypto.Cipher$InitType
-javax.crypto.Cipher$NeedToSet
-javax.crypto.Cipher$SpiAndProviderUpdater
-javax.crypto.Cipher$Transform
-javax.crypto.CipherSpi
 javax.crypto.IllegalBlockSizeException
-javax.crypto.JceSecurity
 javax.crypto.NoSuchPaddingException
-javax.crypto.NullCipher
 javax.crypto.SecretKey
-javax.crypto.ShortBufferException
 javax.crypto.spec.IvParameterSpec
 javax.crypto.spec.SecretKeySpec
 javax.microedition.khronos.egl.EGL
@@ -3799,7 +3828,6 @@
 javax.net.ssl.SSLSessionContext
 javax.net.ssl.SSLSocket
 javax.net.ssl.SSLSocketFactory
-javax.net.ssl.SSLSocketFactory$1
 javax.net.ssl.TrustManager
 javax.net.ssl.TrustManagerFactory
 javax.net.ssl.TrustManagerFactory$1
@@ -3808,13 +3836,12 @@
 javax.net.ssl.X509ExtendedTrustManager
 javax.net.ssl.X509KeyManager
 javax.net.ssl.X509TrustManager
+javax.security.auth.Destroyable
 javax.security.auth.callback.UnsupportedCallbackException
 javax.security.auth.x500.X500Principal
 javax.security.cert.Certificate
 javax.security.cert.CertificateException
 javax.security.cert.X509Certificate
-libcore.icu.DateIntervalFormat
-libcore.icu.DateUtilsBridge
 libcore.icu.ICU
 libcore.icu.LocaleData
 libcore.icu.NativeConverter
@@ -3834,8 +3861,9 @@
 libcore.io.EventLogger$Reporter
 libcore.io.ForwardingOs
 libcore.io.IoBridge
+libcore.io.IoTracker
+libcore.io.IoTracker$Mode
 libcore.io.IoUtils
-libcore.io.IoUtils$FileReader
 libcore.io.Libcore
 libcore.io.Memory
 libcore.io.MemoryMappedFile
@@ -3854,8 +3882,6 @@
 libcore.reflect.GenericSignatureParser
 libcore.reflect.InternalNames
 libcore.reflect.ListOfTypes
-libcore.reflect.ListOfVariables
-libcore.reflect.ParameterizedTypeImpl
 libcore.reflect.Types
 libcore.util.BasicLruCache
 libcore.util.CharsetUtils
@@ -3865,8 +3891,6 @@
 libcore.util.NativeAllocationRegistry$CleanerRunner
 libcore.util.NativeAllocationRegistry$CleanerThunk
 libcore.util.ZoneInfo
-libcore.util.ZoneInfo$CheckedArithmeticException
-libcore.util.ZoneInfo$WallTime
 libcore.util.ZoneInfoDB
 libcore.util.ZoneInfoDB$TzData
 libcore.util.ZoneInfoDB$TzData$1
@@ -3879,54 +3903,22 @@
 org.apache.harmony.xml.ExpatAttributes
 org.apache.harmony.xml.ExpatParser
 org.apache.http.Header
-org.apache.http.HeaderIterator
 org.apache.http.HttpEntity
 org.apache.http.HttpEntityEnclosingRequest
-org.apache.http.HttpHost
 org.apache.http.HttpMessage
 org.apache.http.HttpRequest
 org.apache.http.HttpResponse
-org.apache.http.HttpVersion
-org.apache.http.NameValuePair
 org.apache.http.ProtocolVersion
 org.apache.http.StatusLine
 org.apache.http.client.HttpClient
-org.apache.http.client.ResponseHandler
-org.apache.http.client.methods.AbortableHttpRequest
-org.apache.http.client.methods.HttpEntityEnclosingRequestBase
-org.apache.http.client.methods.HttpPost
-org.apache.http.client.methods.HttpRequestBase
 org.apache.http.client.methods.HttpUriRequest
-org.apache.http.client.utils.URLEncodedUtils
-org.apache.http.conn.ClientConnectionManager
 org.apache.http.conn.ConnectTimeoutException
 org.apache.http.entity.AbstractHttpEntity
-org.apache.http.entity.BasicHttpEntity
-org.apache.http.impl.cookie.DateParseException
-org.apache.http.impl.cookie.DateUtils
 org.apache.http.message.AbstractHttpMessage
 org.apache.http.message.BasicHeader
 org.apache.http.message.BasicHttpResponse
 org.apache.http.message.BasicStatusLine
 org.apache.http.message.HeaderGroup
-org.apache.http.params.AbstractHttpParams
-org.apache.http.params.BasicHttpParams
-org.apache.http.params.CoreConnectionPNames
-org.apache.http.params.HttpConnectionParams
-org.apache.http.params.HttpParams
-org.apache.http.protocol.HttpContext
-org.ccil.cowan.tagsoup.AttributesImpl
-org.ccil.cowan.tagsoup.AutoDetector
-org.ccil.cowan.tagsoup.Element
-org.ccil.cowan.tagsoup.ElementType
-org.ccil.cowan.tagsoup.HTMLModels
-org.ccil.cowan.tagsoup.HTMLScanner
-org.ccil.cowan.tagsoup.HTMLSchema
-org.ccil.cowan.tagsoup.Parser
-org.ccil.cowan.tagsoup.Parser$1
-org.ccil.cowan.tagsoup.ScanHandler
-org.ccil.cowan.tagsoup.Scanner
-org.ccil.cowan.tagsoup.Schema
 org.json.JSON
 org.json.JSONArray
 org.json.JSONException
@@ -3938,31 +3930,30 @@
 org.kxml2.io.KXmlParser
 org.kxml2.io.KXmlParser$ValueContext
 org.xml.sax.Attributes
-org.xml.sax.ContentHandler
-org.xml.sax.DTDHandler
-org.xml.sax.EntityResolver
-org.xml.sax.ErrorHandler
-org.xml.sax.InputSource
-org.xml.sax.Locator
 org.xml.sax.SAXException
-org.xml.sax.SAXNotRecognizedException
-org.xml.sax.SAXNotSupportedException
-org.xml.sax.XMLReader
-org.xml.sax.ext.LexicalHandler
-org.xml.sax.helpers.DefaultHandler
 org.xmlpull.v1.XmlPullParser
 org.xmlpull.v1.XmlPullParserException
 org.xmlpull.v1.XmlSerializer
+sun.invoke.util.BytecodeDescriptor
+sun.invoke.util.Wrapper
 sun.misc.Cleaner
 sun.misc.CompoundEnumeration
+sun.misc.FDBigInteger
+sun.misc.FloatingDecimal
+sun.misc.FloatingDecimal$1
+sun.misc.FloatingDecimal$ASCIIToBinaryBuffer
+sun.misc.FloatingDecimal$ASCIIToBinaryConverter
+sun.misc.FloatingDecimal$BinaryToASCIIBuffer
+sun.misc.FloatingDecimal$BinaryToASCIIConverter
+sun.misc.FloatingDecimal$ExceptionalBinaryToASCIIBuffer
+sun.misc.FloatingDecimal$PreparedASCIIToBinaryBuffer
 sun.misc.FormattedFloatingDecimal
 sun.misc.FormattedFloatingDecimal$1
 sun.misc.FormattedFloatingDecimal$Form
-sun.misc.FpUtils
-sun.misc.Hashing
 sun.misc.IOUtils
-sun.misc.IoTrace
+sun.misc.JavaIOFileDescriptorAccess
 sun.misc.REException
+sun.misc.SharedSecrets
 sun.misc.Unsafe
 sun.misc.VM
 sun.misc.Version
@@ -3978,10 +3969,10 @@
 sun.net.www.ParseUtil
 sun.net.www.protocol.file.Handler
 sun.net.www.protocol.jar.Handler
-sun.nio.ch.AbstractPollArrayWrapper
 sun.nio.ch.DatagramChannelImpl
 sun.nio.ch.DatagramDispatcher
 sun.nio.ch.DirectBuffer
+sun.nio.ch.EPollArrayWrapper
 sun.nio.ch.FileChannelImpl
 sun.nio.ch.FileChannelImpl$Unmapper
 sun.nio.ch.FileDispatcher
@@ -3991,13 +3982,11 @@
 sun.nio.ch.FileLockTable
 sun.nio.ch.IOStatus
 sun.nio.ch.IOUtil
-sun.nio.ch.InheritedChannel
 sun.nio.ch.Interruptible
 sun.nio.ch.NativeDispatcher
 sun.nio.ch.NativeThread
 sun.nio.ch.NativeThreadSet
 sun.nio.ch.Net
-sun.nio.ch.PollArrayWrapper
 sun.nio.ch.SelChImpl
 sun.nio.ch.ServerSocketChannelImpl
 sun.nio.ch.SharedFileLockTable
@@ -4006,14 +3995,8 @@
 sun.nio.cs.ArrayEncoder
 sun.nio.cs.StreamDecoder
 sun.nio.cs.StreamEncoder
-sun.reflect.annotation.AnnotationType
 sun.security.action.GetBooleanAction
 sun.security.action.GetPropertyAction
-sun.security.ec.ECKeyFactory
-sun.security.ec.ECKeyFactory$1
-sun.security.ec.ECKeyFactory$2
-sun.security.ec.ECParameters
-sun.security.ec.NamedCurve
 sun.security.jca.GetInstance
 sun.security.jca.GetInstance$Instance
 sun.security.jca.ProviderConfig
@@ -4027,7 +4010,6 @@
 sun.security.jca.Providers
 sun.security.jca.ServiceId
 sun.security.pkcs.PKCS9Attribute
-sun.security.pkcs.ParsingException
 sun.security.pkcs.SignerInfo
 sun.security.provider.CertPathProvider
 sun.security.provider.X509Factory
@@ -4043,7 +4025,9 @@
 sun.security.provider.certpath.PKIXMasterCertPathValidator
 sun.security.provider.certpath.PolicyChecker
 sun.security.provider.certpath.PolicyNodeImpl
-sun.security.provider.certpath.UntrustedChecker
+sun.security.util.-$Lambda$179$Kli5xKA4dAwmFO1sy_hpNWmbfH4
+sun.security.util.AbstractAlgorithmConstraints
+sun.security.util.AlgorithmDecomposer
 sun.security.util.BitArray
 sun.security.util.ByteArrayLexOrder
 sun.security.util.ByteArrayTagOrder
@@ -4057,7 +4041,6 @@
 sun.security.util.DerOutputStream
 sun.security.util.DerValue
 sun.security.util.DisabledAlgorithmConstraints
-sun.security.util.DisabledAlgorithmConstraints$1
 sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint
 sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraint$Operator
 sun.security.util.DisabledAlgorithmConstraints$KeySizeConstraints
@@ -4067,7 +4050,6 @@
 sun.security.util.MemoryCache$CacheEntry
 sun.security.util.MemoryCache$SoftCacheEntry
 sun.security.util.ObjectIdentifier
-sun.security.util.UntrustedCertificates
 sun.security.x509.AVA
 sun.security.x509.AVAKeyword
 sun.security.x509.AccessDescription
@@ -4124,8 +4106,6 @@
 sun.security.x509.X509CertImpl
 sun.security.x509.X509CertInfo
 sun.security.x509.X509Key
-sun.util.LocaleServiceProviderPool
-sun.util.LocaleServiceProviderPool$1
 sun.util.calendar.AbstractCalendar
 sun.util.calendar.BaseCalendar
 sun.util.calendar.BaseCalendar$Date
@@ -4139,18 +4119,15 @@
 sun.util.locale.BaseLocale
 sun.util.locale.BaseLocale$Cache
 sun.util.locale.BaseLocale$Key
-sun.util.locale.Extension
 sun.util.locale.InternalLocaleBuilder
 sun.util.locale.InternalLocaleBuilder$CaseInsensitiveChar
 sun.util.locale.LanguageTag
-sun.util.locale.LocaleExtensions
 sun.util.locale.LocaleObjectCache
 sun.util.locale.LocaleObjectCache$CacheEntry
 sun.util.locale.LocaleSyntaxException
 sun.util.locale.LocaleUtils
 sun.util.locale.ParseStatus
 sun.util.locale.StringTokenIterator
-sun.util.locale.UnicodeLocaleExtension
 sun.util.logging.LoggingProxy
 sun.util.logging.LoggingSupport
 sun.util.logging.LoggingSupport$1
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 59d982a..a590805 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3275,7 +3275,6 @@
     // OPEN: Settings > Apps > Default Apps > Warning dialog to confirm selection
     DEFAULT_APP_PICKER_CONFIRMATION_DIALOG = 791;
 
-
     // OPEN: Settings > Apps > Default Apps > Default autofill app
     DEFAULT_AUTOFILL_PICKER = 792;
 
@@ -3352,7 +3351,8 @@
     BACKUP_SETTINGS = 818;
 
     // ACTION: Picture-in-picture was explicitly entered for an activity
-    // VALUE: true if it was entered while hiding as a result of moving to another task, false otherwise
+    // VALUE: true if it was entered while hiding as a result of moving to
+    // another task, false otherwise
     ACTION_PICTURE_IN_PICTURE_ENTERED = 819;
 
     // ACTION: The activity currently in picture-in-picture was expanded back to fullscreen
@@ -3378,6 +3378,16 @@
     // The current aspect ratio of the PiP, logged when it changes.
     PICTURE_IN_PICTURE_ASPECT_RATIO = 825;
 
+    // FIELD - length in dp of ACTION_LS_* gestures, or zero if not applicable
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O
+    FIELD_GESTURE_LENGTH = 826;
+
+    // FIELD - velocity in dp (per second?) of ACTION_LS_* gestures, or zero if not applicable
+    // CATEGORY: GLOBAL_SYSTEM_UI
+    // OS: O
+    FIELD_GESTURE_VELOCITY = 827;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 3ba8915..3d9ef02 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -70,6 +70,8 @@
 import android.os.UserManagerInternal;
 import android.provider.Settings;
 import android.hardware.fingerprint.IFingerprintService;
+import android.provider.SettingsStringUtil.ComponentNameSet;
+import android.provider.SettingsStringUtil.SettingStringHelper;
 import android.text.TextUtils;
 import android.text.TextUtils.SimpleStringSplitter;
 import android.util.Slog;
@@ -98,9 +100,9 @@
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.SomeArgs;
 import com.android.server.LocalServices;
-
 import com.android.server.policy.AccessibilityShortcutController;
 import com.android.server.statusbar.StatusBarManagerInternal;
+
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.FileDescriptor;
@@ -445,7 +447,7 @@
                 }
                 return userState.getClientState();
             } else {
-                userState.mClients.register(client);
+                userState.mUserClients.register(client);
                 // If this client is not for the current user we do not
                 // return a state since it is not for the foreground user.
                 // We will send the state to the client on a user switch.
@@ -813,6 +815,42 @@
         }
     }
 
+    /**
+     * Invoked remotely over AIDL by SysUi when the accessibility button within the system's
+     * navigation area has been clicked.
+     */
+    @Override
+    public void notifyAccessibilityButtonClicked() {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Caller does not hold permission "
+                    + android.Manifest.permission.STATUS_BAR);
+        }
+        synchronized (mLock) {
+            notifyAccessibilityButtonClickedLocked();
+        }
+    }
+
+    /**
+     * Invoked remotely over AIDL by SysUi when the availability of the accessibility
+     * button within the system's navigation area has changed.
+     *
+     * @param available {@code true} if the accessibility button is available to the
+     *                  user, {@code false} otherwise
+     */
+    @Override
+    public void notifyAccessibilityButtonAvailabilityChanged(boolean available) {
+        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
+                != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Caller does not hold permission "
+                    + android.Manifest.permission.STATUS_BAR);
+        }
+        synchronized (mLock) {
+            notifyAccessibilityButtonAvailabilityChangedLocked(available);
+        }
+    }
+
+
     boolean onGesture(int gestureId) {
         synchronized (mLock) {
             boolean handled = notifyGestureLocked(gestureId, false);
@@ -927,7 +965,7 @@
             oldUserState.onSwitchToAnotherUser();
 
             // Disable the local managers for the old user.
-            if (oldUserState.mClients.getRegisteredCallbackCount() > 0) {
+            if (oldUserState.mUserClients.getRegisteredCallbackCount() > 0) {
                 mMainHandler.obtainMessage(MainHandler.MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER,
                         oldUserState.mUserId, 0).sendToTarget();
             }
@@ -1044,6 +1082,28 @@
         }
     }
 
+    private void notifyAccessibilityButtonClickedLocked() {
+        final UserState state = getCurrentUserStateLocked();
+        for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
+            final Service service = state.mBoundServices.get(i);
+            // TODO(b/34720082): Only notify a single user-defined service
+            if (service.mRequestAccessibilityButton) {
+                service.notifyAccessibilityButtonClickedLocked();
+            }
+        }
+    }
+
+    private void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
+        final UserState state = getCurrentUserStateLocked();
+        state.mIsAccessibilityButtonAvailable = available;
+        for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
+            final Service service = state.mBoundServices.get(i);
+            if (service.mRequestAccessibilityButton) {
+                service.notifyAccessibilityButtonAvailabilityChangedLocked(available);
+            }
+        }
+    }
+
     /**
      * Removes an AccessibilityInteractionConnection.
      *
@@ -1178,7 +1238,7 @@
                 service.onAdded();
                 userState.mBoundServices.add(service);
                 userState.mComponentNameToServiceMap.put(service.mComponentName, service);
-                scheduleNotifyClientsOfServicesStateChange();
+                scheduleNotifyClientsOfServicesStateChange(userState);
             }
         } catch (RemoteException re) {
             /* do nothing */
@@ -1200,7 +1260,7 @@
             Service boundService = userState.mBoundServices.get(i);
             userState.mComponentNameToServiceMap.put(boundService.mComponentName, boundService);
         }
-        scheduleNotifyClientsOfServicesStateChange();
+        scheduleNotifyClientsOfServicesStateChange(userState);
     }
 
     /**
@@ -1362,16 +1422,16 @@
         final int clientState = userState.getClientState();
         if (userState.mLastSentClientState != clientState
                 && (mGlobalClients.getRegisteredCallbackCount() > 0
-                        || userState.mClients.getRegisteredCallbackCount() > 0)) {
+                        || userState.mUserClients.getRegisteredCallbackCount() > 0)) {
             userState.mLastSentClientState = clientState;
             mMainHandler.obtainMessage(MainHandler.MSG_SEND_STATE_TO_CLIENTS,
                     clientState, userState.mUserId).sendToTarget();
         }
     }
 
-    private void scheduleNotifyClientsOfServicesStateChange() {
-        mMainHandler.obtainMessage(MainHandler.MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS)
-                .sendToTarget();
+    private void scheduleNotifyClientsOfServicesStateChange(UserState userState) {
+        mMainHandler.obtainMessage(MainHandler.MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS,
+                userState.mUserId).sendToTarget();
     }
 
     private void scheduleUpdateInputFilter(UserState userState) {
@@ -2013,10 +2073,12 @@
      * Enables accessibility service specified by {@param componentName} for the {@param userId}.
      */
     private void enableAccessibilityServiceLocked(ComponentName componentName, int userId) {
-        SettingsStringHelper settingsHelper = new SettingsStringHelper(
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userId);
-        settingsHelper.addService(componentName);
-        settingsHelper.writeToSettings();
+        final SettingStringHelper setting =
+                new SettingStringHelper(
+                        mContext.getContentResolver(),
+                        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                        userId);
+        setting.write(ComponentNameSet.add(setting.read(), componentName));
 
         UserState userState = getUserStateLocked(userId);
         if (userState.mEnabledServices.add(componentName)) {
@@ -2028,10 +2090,12 @@
      * Disables accessibility service specified by {@param componentName} for the {@param userId}.
      */
     private void disableAccessibilityServiceLocked(ComponentName componentName, int userId) {
-        SettingsStringHelper settingsHelper = new SettingsStringHelper(
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, userId);
-        settingsHelper.deleteService(componentName);
-        settingsHelper.writeToSettings();
+        final SettingStringHelper setting =
+                new SettingStringHelper(
+                        mContext.getContentResolver(),
+                        Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                        userId);
+        setting.write(ComponentNameSet.remove(setting.read(), componentName));
 
         UserState userState = getUserStateLocked(userId);
         if (userState.mEnabledServices.remove(componentName)) {
@@ -2060,45 +2124,6 @@
         return mFingerprintGestureDispatcher.onFingerprintGesture(gestureKeyCode);
     }
 
-    private class SettingsStringHelper {
-        private static final String SETTINGS_DELIMITER = ":";
-        private ContentResolver mContentResolver;
-        private final String mSettingsName;
-        private Set<String> mServices;
-        private final int mUserId;
-
-        public SettingsStringHelper(String name, int userId) {
-            mUserId = userId;
-            mSettingsName = name;
-            mContentResolver = mContext.getContentResolver();
-            String servicesString = Settings.Secure.getStringForUser(
-                    mContentResolver, mSettingsName, userId);
-            mServices = new HashSet();
-            if (!TextUtils.isEmpty(servicesString)) {
-                final TextUtils.SimpleStringSplitter colonSplitter =
-                        new TextUtils.SimpleStringSplitter(SETTINGS_DELIMITER.charAt(0));
-                colonSplitter.setString(servicesString);
-                while (colonSplitter.hasNext()) {
-                    final String serviceName = colonSplitter.next();
-                    mServices.add(serviceName);
-                }
-            }
-        }
-
-        public void addService(ComponentName component) {
-            mServices.add(component.flattenToString());
-        }
-
-        public void deleteService(ComponentName component) {
-            mServices.remove(component.flattenToString());
-        }
-
-        public void writeToSettings() {
-            Settings.Secure.putStringForUser(mContentResolver, mSettingsName,
-                    TextUtils.join(SETTINGS_DELIMITER, mServices), mUserId);
-        }
-    }
-
     @Override
     public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
         mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
@@ -2225,12 +2250,12 @@
                     final int clientState = msg.arg1;
                     final int userId = msg.arg2;
                     sendStateToClients(clientState, mGlobalClients);
-                    sendStateToClientsForUser(clientState, userId);
+                    sendStateToClients(clientState, getUserClientsForId(userId));
                 } break;
 
                 case MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER: {
                     final int userId = msg.arg1;
-                    sendStateToClientsForUser(0, userId);
+                    sendStateToClients(0, getUserClientsForId(userId));
                 } break;
 
                 case MSG_ANNOUNCE_NEW_USER_IF_NEEDED: {
@@ -2257,7 +2282,9 @@
                 } break;
 
                 case MSG_SEND_SERVICES_STATE_CHANGED_TO_CLIENTS: {
-                    notifyClientsOfServicesStateChange();
+                    final int userId = msg.arg1;
+                    notifyClientsOfServicesStateChange(mGlobalClients);
+                    notifyClientsOfServicesStateChange(getUserClientsForId(userId));
                 } break;
 
                 case MSG_UPDATE_FINGERPRINT: {
@@ -2282,12 +2309,12 @@
             }
         }
 
-        private void sendStateToClientsForUser(int clientState, int userId) {
+        private RemoteCallbackList<IAccessibilityManagerClient> getUserClientsForId(int userId) {
             final UserState userState;
             synchronized (mLock) {
                 userState = getUserStateLocked(userId);
             }
-            sendStateToClients(clientState, userState.mClients);
+            return userState.mUserClients;
         }
 
         private void sendStateToClients(int clientState,
@@ -2307,11 +2334,8 @@
             }
         }
 
-        private void notifyClientsOfServicesStateChange() {
-            RemoteCallbackList<IAccessibilityManagerClient> clients;
-            synchronized (mLock) {
-                clients = getCurrentUserStateLocked().mClients;
-            }
+        private void notifyClientsOfServicesStateChange(
+                RemoteCallbackList<IAccessibilityManagerClient> clients) {
             try {
                 final int userClientCount = clients.beginBroadcast();
                 for (int i = 0; i < userClientCount; i++) {
@@ -2426,6 +2450,8 @@
 
         boolean mCaptureFingerprintGestures;
 
+        boolean mRequestAccessibilityButton;
+
         int mFetchFlags;
 
         long mNotificationTimeout;
@@ -2581,6 +2607,8 @@
                     & AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS) != 0;
             mCaptureFingerprintGestures = (info.flags
                     & AccessibilityServiceInfo.FLAG_CAPTURE_FINGERPRINT_GESTURES) != 0;
+            mRequestAccessibilityButton = (info.flags
+                    & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
         }
 
         /**
@@ -2694,7 +2722,7 @@
                     }
                     UserState userState = getUserStateLocked(mUserId);
                     onUserStateChangedLocked(userState);
-                    scheduleNotifyClientsOfServicesStateChange();
+                    scheduleNotifyClientsOfServicesStateChange(userState);
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3332,6 +3360,19 @@
         }
 
         @Override
+        public boolean isAccessibilityButtonAvailable() {
+            final UserState userState;
+            synchronized (mLock) {
+                if (!isCalledForCurrentUserLocked()) {
+                    return false;
+                }
+                userState = getCurrentUserStateLocked();
+            }
+
+            return mRequestAccessibilityButton && userState.mIsAccessibilityButtonAvailable;
+        }
+
+        @Override
         public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
             mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
             synchronized (mLock) {
@@ -3544,6 +3585,14 @@
             mInvocationHandler.notifySoftKeyboardShowModeChangedLocked(showState);
         }
 
+        public void notifyAccessibilityButtonClickedLocked() {
+            mInvocationHandler.notifyAccessibilityButtonClickedLocked();
+        }
+
+        public void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
+            mInvocationHandler.notifyAccessibilityButtonAvailabilityChangedLocked(available);
+        }
+
         /**
          * Called by the invocation handler to notify the service that the
          * state of magnification has changed.
@@ -3582,6 +3631,36 @@
             }
         }
 
+        private void notifyAccessibilityButtonClickedInternal() {
+            final IAccessibilityServiceClient listener;
+            synchronized (mLock) {
+                listener = mServiceInterface;
+            }
+            if (listener != null) {
+                try {
+                    listener.onAccessibilityButtonClicked();
+                } catch (RemoteException re) {
+                    Slog.e(LOG_TAG, "Error sending accessibility button click to " + mService, re);
+                }
+            }
+        }
+
+        private void notifyAccessibilityButtonAvailabilityChangedInternal(boolean available) {
+            final IAccessibilityServiceClient listener;
+            synchronized (mLock) {
+                listener = mServiceInterface;
+            }
+            if (listener != null) {
+                try {
+                    listener.onAccessibilityButtonAvailabilityChanged(available);
+                } catch (RemoteException re) {
+                    Slog.e(LOG_TAG,
+                            "Error sending accessibility button availability change to " + mService,
+                            re);
+                }
+            }
+        }
+
         private void notifyGestureInternal(int gestureId) {
             final IAccessibilityServiceClient listener;
             synchronized (mLock) {
@@ -3723,6 +3802,8 @@
 
             private static final int MSG_ON_MAGNIFICATION_CHANGED = 5;
             private static final int MSG_ON_SOFT_KEYBOARD_STATE_CHANGED = 6;
+            private static final int MSG_ON_ACCESSIBILITY_BUTTON_CLICKED = 7;
+            private static final int MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED = 8;
 
             private boolean mIsMagnificationCallbackEnabled = false;
             private boolean mIsSoftKeyboardCallbackEnabled = false;
@@ -3758,6 +3839,15 @@
                         notifySoftKeyboardShowModeChangedInternal(showState);
                     } break;
 
+                    case MSG_ON_ACCESSIBILITY_BUTTON_CLICKED: {
+                        notifyAccessibilityButtonClickedInternal();
+                    } break;
+
+                    case MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED: {
+                        final boolean available = (message.arg1 != 0);
+                        notifyAccessibilityButtonAvailabilityChangedInternal(available);
+                    } break;
+
                     default: {
                         throw new IllegalArgumentException("Unknown message: " + type);
                     }
@@ -3797,6 +3887,17 @@
             public void setSoftKeyboardCallbackEnabled(boolean enabled) {
                 mIsSoftKeyboardCallbackEnabled = enabled;
             }
+
+            public void notifyAccessibilityButtonClickedLocked() {
+                final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_CLICKED);
+                msg.sendToTarget();
+            }
+
+            public void notifyAccessibilityButtonAvailabilityChangedLocked(boolean available) {
+                final Message msg = obtainMessage(MSG_ON_ACCESSIBILITY_BUTTON_AVAILABILITY_CHANGED,
+                        (available ? 1 : 0), 0);
+                msg.sendToTarget();
+            }
         }
     }
 
@@ -3899,6 +4000,7 @@
                 case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
                 case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
                 case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
+                case WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:
                 case WindowManager.LayoutParams.TYPE_SCREENSHOT: {
                     return AccessibilityWindowInfo.TYPE_SYSTEM;
                 }
@@ -4466,7 +4568,7 @@
 
         // Non-transient state.
 
-        public final RemoteCallbackList<IAccessibilityManagerClient> mClients =
+        public final RemoteCallbackList<IAccessibilityManagerClient> mUserClients =
             new RemoteCallbackList<>();
 
         public final SparseArray<AccessibilityConnectionWrapper> mInteractionConnections =
@@ -4500,6 +4602,8 @@
 
         public int mSoftKeyboardShowMode = 0;
 
+        public boolean mIsAccessibilityButtonAvailable;
+
         public boolean mIsTouchExplorationEnabled;
         public boolean mIsTextHighContrastEnabled;
         public boolean mIsEnhancedWebAccessibilityEnabled;
@@ -4574,6 +4678,9 @@
             mIsDisplayMagnificationEnabled = false;
             mIsAutoclickEnabled = false;
             mSoftKeyboardShowMode = 0;
+
+            // Clear state tracked from system UI
+            mIsAccessibilityButtonAvailable = false;
         }
 
         public void destroyUiAutomationService() {
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
index 78436f7..178a697 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
@@ -34,7 +34,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -43,7 +42,6 @@
 import android.provider.Settings;
 import android.service.autofill.IAutoFillManagerService;
 import android.text.TextUtils;
-import android.text.format.DateUtils;
 import android.util.LocalLog;
 import android.util.Log;
 import android.util.Slog;
@@ -72,66 +70,47 @@
 public final class AutoFillManagerService extends SystemService {
 
     private static final String TAG = "AutoFillManagerService";
-    static final boolean DEBUG = true; // TODO(b/33197203): change to false once stable
+    static final boolean DEBUG = false;
 
-    private static final long SERVICE_BINDING_LIFETIME_MS = 5 * DateUtils.MINUTE_IN_MILLIS;
-
-    private static final int MSG_UNBIND = 1;
-    private static final int MSG_REQUEST_AUTO_FILL_FOR_USER = 2;
-    private static final int MSG_REQUEST_AUTO_FILL = 3;
+    protected static final int MSG_REQUEST_AUTO_FILL_FOR_USER = 1;
+    protected static final int MSG_REQUEST_AUTO_FILL = 2;
+    private static final int MSG_REQUEST_SAVE_FOR_USER = 3;
     private static final int MSG_ON_VALUE_CHANGED = 4;
-    private static final int MSG_REQUEST_SAVE_FOR_USER = 5;
 
-    private final AutoFillManagerServiceStub mServiceStub;
     private final Context mContext;
-    private final ContentResolver mResolver;
+    private final AutoFillUI mUi;
 
     private final Object mLock = new Object();
 
-    private final HandlerCaller.Callback mHandlerCallback = new HandlerCaller.Callback() {
-
-        @Override
-        public void executeMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_UNBIND: {
-                    synchronized (mLock) {
-                        removeCachedServiceLocked(msg.arg1);
-                    }
-                    return;
-                } case MSG_REQUEST_AUTO_FILL_FOR_USER: {
-                    handleAutoFillForUser(msg.arg1);
-                    return;
-                } case MSG_REQUEST_SAVE_FOR_USER: {
-                    handleSaveForUser(msg.arg1);
-                    return;
-                } case MSG_REQUEST_AUTO_FILL: {
-                    final SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        final int userId = msg.arg1;
-                        final int flags = msg.arg2;
-                        final IBinder activityToken = (IBinder) args.arg1;
-                        final AutoFillId autoFillId = (AutoFillId) args.arg2;
-                        final Rect bounds = (Rect) args.arg3;
-                        handleAutoFill(activityToken, userId, autoFillId, bounds, flags);
-                    } finally {
-                        args.recycle();
-                    }
-                    return;
-                } case MSG_ON_VALUE_CHANGED: {
-                    final SomeArgs args = (SomeArgs) msg.obj;
-                    try {
-                        final int userId = msg.arg1;
-                        final IBinder activityToken = (IBinder) args.arg1;
-                        final AutoFillId autoFillId = (AutoFillId) args.arg2;
-                        final AutoFillValue newValue = (AutoFillValue) args.arg3;
-                        handleValueChanged(activityToken, userId, autoFillId, newValue);
-                    } finally {
-                        args.recycle();
-                    }
-                    return;
-                } default: {
-                    Slog.w(TAG, "Invalid message: " + msg);
-                }
+    private final HandlerCaller.Callback mHandlerCallback = (msg) -> {
+        switch (msg.what) {
+            case MSG_REQUEST_AUTO_FILL_FOR_USER: {
+                handleAutoFillForUser(msg.arg1);
+                return;
+            } case MSG_REQUEST_SAVE_FOR_USER: {
+                handleSaveForUser(msg.arg1);
+                return;
+            } case MSG_REQUEST_AUTO_FILL: {
+                final SomeArgs args = (SomeArgs) msg.obj;
+                final int userId = msg.arg1;
+                final int flags = msg.arg2;
+                final IBinder activityToken = (IBinder) args.arg1;
+                final AutoFillId autoFillId = (AutoFillId) args.arg2;
+                final Rect bounds = (Rect) args.arg3;
+                args.recycle();
+                handleAutoFill(activityToken, userId, autoFillId, bounds, flags);
+                return;
+            } case MSG_ON_VALUE_CHANGED: {
+                final SomeArgs args = (SomeArgs) msg.obj;
+                final int userId = msg.arg1;
+                final IBinder activityToken = (IBinder) args.arg1;
+                final AutoFillId autoFillId = (AutoFillId) args.arg2;
+                final AutoFillValue newValue = (AutoFillValue) args.arg3;
+                args.recycle();
+                handleValueChanged(activityToken, userId, autoFillId, newValue);
+                return;
+            } default: {
+                Slog.w(TAG, "Invalid message: " + msg);
             }
         }
     };
@@ -148,10 +127,10 @@
      * Entries on this cache are added on demand and removed when:
      * <ol>
      *   <li>An auto-fill service app is removed.
-     *   <li>The {@link android.provider.Settings.Secure#AUTO_FILL_SERVICE} for an user change.
-     *   <li>It has not been interacted with for {@link #SERVICE_BINDING_LIFETIME_MS} ms.
+     *   <li>The {@link android.provider.Settings.Secure#AUTO_FILL_SERVICE} for an user change.\
      * </ol>
      */
+    // TODO(b/33197203): Update the above comment
     @GuardedBy("mLock")
     private SparseArray<AutoFillManagerServiceImpl> mServicesCache = new SparseArray<>();
 
@@ -160,19 +139,14 @@
 
     public AutoFillManagerService(Context context) {
         super(context);
-
         mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
-
         mContext = context;
-
-        mResolver = context.getContentResolver();
-        mServiceStub = new AutoFillManagerServiceStub();
+        mUi = new AutoFillUI(mContext);
     }
 
     @Override
     public void onStart() {
-        if (DEBUG) Slog.d(TAG, "onStart(): binding as " + AUTO_FILL_MANAGER_SERVICE);
-        publishBinderService(AUTO_FILL_MANAGER_SERVICE, mServiceStub);
+        publishBinderService(AUTO_FILL_MANAGER_SERVICE, new AutoFillManagerServiceStub());
     }
 
     @Override
@@ -186,61 +160,41 @@
         ComponentName serviceComponent = null;
         ServiceInfo serviceInfo = null;
         final String componentName = Settings.Secure.getStringForUser(
-                mResolver, Settings.Secure.AUTO_FILL_SERVICE, userId);
+                mContext.getContentResolver(), Settings.Secure.AUTO_FILL_SERVICE, userId);
         if (!TextUtils.isEmpty(componentName)) {
             try {
                 serviceComponent = ComponentName.unflattenFromString(componentName);
                 serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent, 0,
                         userId);
             } catch (RuntimeException | RemoteException e) {
-                Slog.wtf(TAG, "Bad auto-fill service name " + componentName, e);
+                Slog.e(TAG, "Bad auto-fill service name " + componentName, e);
                 return null;
             }
         }
 
-        if (DEBUG) {
-            Slog.d(TAG, "getServiceComponentForUser(" + userId + "): component="
-                    + serviceComponent + ", info: " + serviceInfo);
-        }
         if (serviceInfo == null) {
-            if (DEBUG) Slog.d(TAG, "no service info for " + serviceComponent);
             return null;
         }
-        return new AutoFillManagerServiceImpl(this, mContext, mLock, mRequestsHistory,
-                userId, serviceInfo.applicationInfo.uid, serviceComponent,
-                SERVICE_BINDING_LIFETIME_MS);
+
+        try {
+            return new AutoFillManagerServiceImpl(mContext, mLock, mRequestsHistory,
+                    userId, serviceComponent, mUi);
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.w(TAG, "Auto-fill service not found: " + serviceComponent, e);
+        }
+
+        return null;
     }
 
     /**
      * Gets the service instance for an user.
-     * <p>
-     * First it tries to return the existing instance from the cache; if it's not cached, it creates
-     * a new instance and caches it.
      */
-    // TODO(b/33197203): make private once AutoFillUi does not uses notifications
-    AutoFillManagerServiceImpl getServiceForUserLocked(int userId) {
+    AutoFillManagerServiceImpl getOrCreateServiceForUserLocked(int userId) {
         AutoFillManagerServiceImpl service = mServicesCache.get(userId);
-        if (service != null) {
-            if (DEBUG)
-                Log.d(TAG, "reusing cached service for userId " + userId);
-            service.setLifeExpectancy(SERVICE_BINDING_LIFETIME_MS);
-        } else {
+        if (service == null) {
             service = newServiceForUser(userId);
-            if (service == null) {
-                // Already logged
-                return null;
-            }
-            if (DEBUG) Log.d(TAG, "creating new cached service for userId " + userId);
-            service.startLocked();
             mServicesCache.put(userId, service);
         }
-        // Keep service connection alive for a while, in case user needs to interact with it
-        // (for example, to save the data that was inputted in)
-        if (mHandlerCaller.hasMessages(MSG_UNBIND)) {
-            mHandlerCaller.removeMessages(MSG_UNBIND);
-        }
-        mHandlerCaller.sendMessageDelayed(mHandlerCaller.obtainMessageI(MSG_UNBIND, userId),
-                SERVICE_BINDING_LIFETIME_MS);
         return service;
     }
 
@@ -248,22 +202,17 @@
      * Removes a cached service for a given user.
      */
     void removeCachedServiceLocked(int userId) {
-        if (DEBUG) Log.d(TAG, "removing cached service for userId " + userId);
         final AutoFillManagerServiceImpl service = mServicesCache.get(userId);
-        if (service == null) {
-            if (DEBUG) {
-                Log.d(TAG, "removeCachedServiceForUser(): no cached service for userId " + userId);
-            }
-            return;
+        if (service != null) {
+            mServicesCache.delete(userId);
+            service.destroyLocked();
         }
-        mServicesCache.delete(userId);
-        service.stopLocked();
     }
 
     private void handleAutoFill(IBinder activityToken, int userId, AutoFillId autoFillId,
             Rect bounds, int flags) {
         synchronized (mLock) {
-            final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+            final AutoFillManagerServiceImpl service = getOrCreateServiceForUserLocked(userId);
             if (service != null) {
                 service.requestAutoFillLocked(activityToken, autoFillId, bounds, flags);
             }
@@ -273,7 +222,7 @@
     private void handleValueChanged(IBinder activityToken, int userId, AutoFillId autoFillId,
             AutoFillValue newValue) {
         synchronized (mLock) {
-            final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+            final AutoFillManagerServiceImpl service = getOrCreateServiceForUserLocked(userId);
             if (service != null) {
                 service.onValueChangeLocked(activityToken, autoFillId, newValue);
             }
@@ -283,45 +232,32 @@
     private IBinder getTopActivityForUser() {
         final List<IBinder> topActivities = LocalServices
                 .getService(ActivityManagerInternal.class).getTopVisibleActivities();
-        if (DEBUG) Slog.d(TAG, "Top activities (" + topActivities.size() + "): " + topActivities);
         if (topActivities.isEmpty()) {
-            Slog.w(TAG, "Could not get top activity");
             return null;
         }
         return topActivities.get(0);
     }
 
     private void handleAutoFillForUser(int userId) {
-        if (DEBUG) Slog.d(TAG, "handler.requestAutoFillForUser(): id=" + userId);
         final IBinder activityToken = getTopActivityForUser();
-        if (activityToken == null) {
-            return;
+        if (activityToken != null) {
+            synchronized (mLock) {
+                final AutoFillManagerServiceImpl service =
+                        getOrCreateServiceForUserLocked(userId);
+                service.requestAutoFillLocked(activityToken, null, null, 0);
+            }
         }
 
-        synchronized (mLock) {
-            final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
-            if (service == null) {
-                Slog.w(TAG, "no service for user " + userId);
-                return;
-            }
-            service.requestAutoFillLocked(activityToken, null, null, 0);
-        }
     }
 
     private void handleSaveForUser(int userId) {
-        if (DEBUG) Slog.d(TAG, "handler.handleSaveForUser(): id=" + userId);
         final IBinder activityToken = getTopActivityForUser();
-        if (activityToken == null) {
-            return;
-        }
-
-        synchronized (mLock) {
-            final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
-            if (service == null) {
-                Slog.w(TAG, "no service for user " + userId);
-                return;
+        if (activityToken != null) {
+            synchronized (mLock) {
+                final AutoFillManagerServiceImpl service =
+                        getOrCreateServiceForUserLocked(userId);
+                service.requestSaveForUserLocked(activityToken);
             }
-            service.requestSaveForUserLocked(activityToken);
         }
     }
 
@@ -347,9 +283,6 @@
 
         @Override
         public void requestAutoFill(AutoFillId id, Rect bounds, int flags) {
-            if (DEBUG) Slog.d(TAG, "requestAutoFill: flags=" + flags + ", autoFillId=" + id
-                    + ", bounds=" + bounds);
-
             final IBinder activityToken = getTopActivity();
             if (activityToken != null) {
                 mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIIOOO(MSG_REQUEST_AUTO_FILL,
@@ -360,25 +293,19 @@
         @Override
         public void requestAutoFillForUser(int userId) {
             mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-
-            mHandlerCaller.sendMessage(
-                    mHandlerCaller.obtainMessageI(MSG_REQUEST_AUTO_FILL_FOR_USER, userId));
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageI(
+                    MSG_REQUEST_AUTO_FILL_FOR_USER, userId));
         }
 
         @Override
         public void requestSaveForUser(int userId) {
             mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-
-            mHandlerCaller.sendMessage(
-                    mHandlerCaller.obtainMessageI(MSG_REQUEST_SAVE_FOR_USER, userId));
+            mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageI(MSG_REQUEST_SAVE_FOR_USER, userId));
         }
 
         @Override
         public void onValueChanged(AutoFillId id, AutoFillValue value) {
-            if (DEBUG) Slog.d(TAG, "onValueChanged(): id=" + id + ", value=" + value);
-
             final IBinder activityToken = getTopActivity();
-
             if (activityToken != null) {
                 mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOOO(MSG_ON_VALUE_CHANGED,
                         UserHandle.getCallingUserId(), activityToken, id, value));
@@ -407,6 +334,7 @@
                         impl.dumpLocked("  ", pw);
                     }
                 }
+                mUi.dump(pw);
             }
             pw.println("Requests history:");
             mRequestsHistory.reverseDump(fd, pw, args);
@@ -430,7 +358,6 @@
 
         @Override
         public void onChange(boolean selfChange, Uri uri, int userId) {
-            if (DEBUG) Slog.d(TAG, "settings (" + uri + " changed for " + userId);
             synchronized (mLock) {
                 removeCachedServiceLocked(userId);
             }
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
index 42e4fd3..e32e21d 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -16,15 +16,11 @@
 
 package com.android.server.autofill;
 
-import static android.service.autofill.AutoFillService.FLAG_AUTHENTICATION_ERROR;
-import static android.service.autofill.AutoFillService.FLAG_AUTHENTICATION_REQUESTED;
-import static android.service.autofill.AutoFillService.FLAG_AUTHENTICATION_SUCCESS;
 import static android.view.autofill.AutoFillManager.FLAG_UPDATE_UI_SHOW;
 import static android.view.autofill.AutoFillManager.FLAG_UPDATE_UI_HIDE;
 
 import static com.android.server.autofill.Helper.DEBUG;
 import static com.android.server.autofill.Helper.VERBOSE;
-import static com.android.server.autofill.Helper.bundleToString;
 
 import android.annotation.Nullable;
 import android.app.Activity;
@@ -38,33 +34,26 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.ServiceConnection;
+import android.content.IntentSender;
 import android.content.pm.PackageManager;
 import android.graphics.Rect;
-import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.IFingerprintService;
-import android.hardware.fingerprint.IFingerprintServiceReceiver;
-import android.os.Binder;
 import android.os.Bundle;
-import android.os.DeadObjectException;
 import android.os.IBinder;
+import android.os.ICancellationSignal;
 import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.UserHandle;
 import android.service.autofill.AutoFillService;
 import android.service.autofill.AutoFillServiceInfo;
+import android.service.autofill.FillCallback;
 import android.service.autofill.IAutoFillAppCallback;
-import android.service.autofill.IAutoFillServerCallback;
 import android.service.autofill.IAutoFillService;
+import android.service.autofill.IFillCallback;
 import android.service.voice.VoiceInteractionSession;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.LocalLog;
-import android.util.Log;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.TimeUtils;
 import android.view.autofill.AutoFillId;
 import android.view.autofill.AutoFillValue;
 import android.view.autofill.Dataset;
@@ -77,8 +66,6 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
@@ -95,24 +82,13 @@
     private static int sSessionIdCounter = 0;
 
     private final int mUserId;
-    private final int mUid;
     private final ComponentName mComponent;
     private final String mComponentName;
     private final Context mContext;
     private final IActivityManager mAm;
     private final Object mLock;
     private final AutoFillServiceInfo mInfo;
-    private final AutoFillManagerService mManagerService;
-
-    // Token used for fingerprint authentication
-    // TODO(b/33197203): create on demand?
-    private final IBinder mAuthToken = new Binder();
-
-    private final IFingerprintService mFingerprintService =
-            IFingerprintService.Stub.asInterface(ServiceManager.getService("fingerprint"));
-
-    @GuardedBy("mLock")
-    private final List<QueuedRequest> mQueuedRequests = new LinkedList<>();
+    private final AutoFillUI mUi;
 
     private final LocalLog mRequestsHistory;
 
@@ -122,15 +98,7 @@
             if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
                 final String reason = intent.getStringExtra("reason");
                 if (DEBUG) Slog.d(TAG, "close system dialogs: " + reason);
-
-                synchronized (mLock) {
-                    final int size = mSessions.size();
-                    for (int i = 0; i < size; i++) {
-                        final Session session = mSessions.valueAt(i);
-                        // TODO(b/33197203): invalidate the sessions instead?
-                        session.mUi.closeAll();
-                    }
-                }
+                mUi.hideAll();
             }
         }
     };
@@ -144,40 +112,7 @@
     // TODO(b/33197203): need to make sure service is bound while callback is pending and/or
     // use WeakReference
     @GuardedBy("mLock")
-    private static final SparseArray<Session> mSessions = new SparseArray<>();
-
-    private final ServiceConnection mConnection = new ServiceConnection() {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            if (DEBUG) Slog.d(TAG, "onServiceConnected():" + name);
-            synchronized (mLock) {
-                mService = IAutoFillService.Stub.asInterface(service);
-                try {
-                    mService.onConnected();
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Exception on service.onConnected(): " + e);
-                    return;
-                }
-                if (!mQueuedRequests.isEmpty()) {
-                    if (DEBUG) Slog.d(TAG, "queued requests:" + mQueuedRequests.size());
-                }
-                for (final QueuedRequest request: mQueuedRequests) {
-                    requestAutoFillLocked(request.activityToken, request.autoFillId,
-                            request.bounds, request.flags, false);
-                }
-                mQueuedRequests.clear();
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            if (DEBUG) Slog.d(TAG, name + " disconnected");
-            synchronized (mLock) {
-                mService = null;
-                mManagerService.removeCachedServiceLocked(mUserId);
-            }
-        }
-    };
+    private final SparseArray<Session> mSessions = new SparseArray<>();
 
     /**
      * Receiver of assist data from the app's {@link Activity}, uses the {@code resultData} as
@@ -193,8 +128,13 @@
                 Slog.w(TAG, "no app callback on mAssistReceiver's resultData");
                 return;
             }
+
             final AssistStructure structure = resultData
                     .getParcelable(VoiceInteractionSession.KEY_STRUCTURE);
+            if (structure == null) {
+                Slog.w(TAG, "no assist structure for id " + resultCode);
+                return;
+            }
 
             final Session session;
             synchronized (mLock) {
@@ -203,91 +143,55 @@
                     Slog.w(TAG, "no server callback for id " + resultCode);
                     return;
                 }
-                session.setAppCallbackLocked(appBinder);
-                // 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.mStructure = 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();
-
-                structure.sanitizeForParceling(true);
-                if (VERBOSE) {
-                    Slog.v(TAG, "Dumping " + structure + " before calling service.autoFill()");
-                    structure.dump();
-                }
-                mService.autoFill(structure, session.mServerCallback);
             }
+
+            // 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...)
+
+            // 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();
+
+            structure.sanitizeForParceling(true);
+
+            if (VERBOSE) {
+                Slog.v(TAG, "Dumping " + structure + " before calling service.autoFill()");
+                structure.dump();
+            }
+
+            session.onApplicationDataAvailable(structure, appBinder);
         }
     };
 
-    @GuardedBy("mLock")
-    private IAutoFillService mService;
-    @GuardedBy("mLock")
-    private boolean mBound;
-    @GuardedBy("mLock")
-    private boolean mValid;
-
-    // Estimated time when the service will be evicted from the cache.
-    long mEstimateTimeOfDeath;
-
-    AutoFillManagerServiceImpl(AutoFillManagerService managerService, Context context, Object lock,
-            LocalLog requestsHistory, int userId, int uid, ComponentName component, long ttl) {
-        mManagerService = managerService;
+    AutoFillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
+            int userId, ComponentName component, AutoFillUI ui)
+            throws PackageManager.NameNotFoundException {
         mContext = context;
         mLock = lock;
         mRequestsHistory = requestsHistory;
         mUserId = userId;
-        mUid = uid;
         mComponent = component;
         mComponentName = mComponent.flattenToShortString();
         mAm = ActivityManager.getService();
-        setLifeExpectancy(ttl);
+        mUi = ui;
+        mInfo = new AutoFillServiceInfo(context.getPackageManager(), component, mUserId);
 
-        final AutoFillServiceInfo info;
-        try {
-            info = new AutoFillServiceInfo(context.getPackageManager(), component, mUserId);
-        } catch (PackageManager.NameNotFoundException e) {
-            Slog.w(TAG, "Auto-fill service not found: " + component, e);
-            mInfo = null;
-            mValid = false;
-            return;
-        }
-        mInfo = info;
-        if (mInfo.getParseError() != null) {
-            Slog.w(TAG, "Bad auto-fill service: " + mInfo.getParseError());
-            mValid = false;
-            return;
-        }
-
-        mValid = true;
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         mContext.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler());
     }
 
-    void setLifeExpectancy(long ttl) {
-        mEstimateTimeOfDeath = SystemClock.uptimeMillis() + ttl;
-    }
 
-    void startLocked() {
-        if (DEBUG) Slog.d(TAG, "startLocked()");
-
-        final Intent intent = new Intent(AutoFillService.SERVICE_INTERFACE);
-        intent.setComponent(mComponent);
-        mBound = mContext.bindServiceAsUser(intent, mConnection,
-                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, new UserHandle(mUserId));
-
-        if (!mBound) {
-            Slog.w(TAG, "Failed binding to auto-fill service " + mComponent);
-            return;
-        }
-        if (DEBUG) Slog.d(TAG, "Bound to " + mComponent);
+    /**
+     * Used by {@link AutoFillManagerServiceShellCommand} to request save for the current top app.
+     */
+    void requestSaveForUserLocked(IBinder activityToken) {
+        final Session session = getOrCreateSessionByTokenLocked(activityToken);
+        session.onSaveLocked();
     }
 
     /**
@@ -299,66 +203,17 @@
      * @param flags optional flags.
      */
     void requestAutoFillLocked(IBinder activityToken, @Nullable AutoFillId autoFillId,
-            @Nullable Rect bounds, int flags) {
-        if (!mBound) {
-            Slog.w(TAG, "requestAutoFillLocked() failed because it's not bound to service");
-            return;
-        }
-
-        requestAutoFillLocked(activityToken, autoFillId, bounds, flags, true);
-    }
-
-    /**
-     * Used by {@link AutoFillManagerServiceShellCommand} to request save for the current top app.
-     */
-    void requestSaveForUserLocked(IBinder activityToken) {
-        if (!mBound) {
-            Slog.w(TAG, "requestSaveForUserLocked() failed because it's not bound to service");
-            return;
-        }
-        if (mService == null) {
-            Slog.w(TAG, "requestSaveForUserLocked: service not set");
-            return;
-        }
-
-        final Session session = getSessionByTokenLocked(activityToken);
-        if (session == null) {
-            Slog.w(TAG, "requestSaveForUserLocked(): no session for " + activityToken);
-            return;
-        }
-
-        session.onSaveLocked();
-    }
-
-    private void requestAutoFillLocked(IBinder activityToken, @Nullable AutoFillId autoFillId,
-            @Nullable Rect bounds, int flags, boolean queueIfNecessary) {
-        if (mService == null) {
-            if (!queueIfNecessary) {
-                Slog.w(TAG, "requestAutoFillLocked(): service is null");
-                return;
-            }
-            if (DEBUG) Slog.d(TAG, "requestAutoFillLocked(): service not set yet, queuing it");
-            mQueuedRequests.add(new QueuedRequest(activityToken, autoFillId, bounds, flags));
-            return;
-        }
-
+          @Nullable Rect bounds, int flags) {
         final String historyItem = "s=" + mComponentName + " u=" + mUserId + " f=" + flags
                 + " a=" + activityToken + " i=" + autoFillId + " b=" + bounds;
         mRequestsHistory.log(historyItem);
 
         // TODO(b/33197203): Handle partitioning
-        Session session = getSessionByTokenLocked(activityToken);
-
-        if (session == null) {
-            session = createSessionByTokenLocked(activityToken);
-        } else {
-            if (DEBUG) Slog.d(TAG, "reusing session for " + activityToken + ": " + session.mId);
-        }
-
+        Session session = getOrCreateSessionByTokenLocked(activityToken);
         session.updateAutoFillInput(flags, autoFillId, null, bounds);
     }
 
-    private Session getSessionByTokenLocked(IBinder activityToken) {
+    private Session getOrCreateSessionByTokenLocked(IBinder activityToken) {
         final int size = mSessions.size();
         for (int i = 0; i < size; i++) {
             final Session session = mSessions.valueAt(i);
@@ -366,14 +221,14 @@
                 return session;
             }
         }
-        return null;
+        return createSessionByTokenLocked(activityToken);
     }
 
     private Session createSessionByTokenLocked(IBinder activityToken) {
         final int sessionId = ++sSessionIdCounter;
         if (DEBUG) Slog.d(TAG, "creating session for " + activityToken + ": " + sessionId);
 
-        final Session newSession = new Session(sessionId, activityToken);
+        final Session newSession = new Session(mContext, activityToken, sessionId);
         mSessions.put(sessionId, newSession);
 
         /*
@@ -401,88 +256,33 @@
      */
     void onValueChangeLocked(IBinder activityToken, AutoFillId autoFillId, AutoFillValue newValue) {
         // TODO(b/33197203): add MetricsLogger call
-        final Session session = getSessionByTokenLocked(activityToken);
-        if (session == null) {
-            Slog.w(TAG, "onValueChangeLocked(): session gone for " + activityToken);
-            return;
-        }
-
+        final Session session = getOrCreateSessionByTokenLocked(activityToken);
         session.updateValueLocked(autoFillId, newValue);
     }
 
-    void stopLocked() {
-        if (DEBUG) Slog.d(TAG, "stopLocked()");
-
-        // Sanity check.
-        if (mService == null) {
-            Slog.w(TAG, "service already null on shutdown");
-            return;
-        }
-        try {
-            mService.onDisconnected();
-        } catch (RemoteException e) {
-            if (! (e instanceof DeadObjectException)) {
-                Slog.w(TAG, "Exception calling service.onDisconnected(): " + e);
-            }
-        } finally {
-            mService = null;
-        }
-
-        if (mBound) {
-            mContext.unbindService(mConnection);
-            mBound = false;
-        }
-        if (mValid) {
-            mContext.unregisterReceiver(mBroadcastReceiver);
-        }
-    }
-
     void removeSessionLocked(int id) {
         if (DEBUG) Slog.d(TAG, "Removing session " + id);
-        mSessions.remove(id);
+        mSessions.get(id);
+    }
 
-        // TODO(b/33197203): notify mService so it can invalidate the FillCallback / SaveCallback
-        // and cached AssistStructures
+    void destroyLocked() {
+        mContext.unregisterReceiver(mBroadcastReceiver);
+        final int sessionCount = mSessions.size();
+        for (int i = sessionCount - 1; i >= 0; i--) {
+            Session session = mSessions.valueAt(i);
+            session.destroy();
+            mSessions.removeAt(i);
+        }
     }
 
     void dumpLocked(String prefix, PrintWriter pw) {
-        if (!mValid) {
-            pw.print("  NOT VALID: ");
-            if (mInfo == null) {
-                pw.println("no info");
-            } else {
-                pw.println(mInfo.getParseError());
-            }
-            return;
-        }
-
         final String prefix2 = prefix + "  ";
-
-        pw.print(prefix); pw.print("mUserId="); pw.println(mUserId);
-        pw.print(prefix); pw.print("mUid="); pw.println(mUid);
-        pw.print(prefix); pw.print("mComponent="); pw.println(mComponentName);
-        pw.print(prefix); pw.print("mService: "); pw.println(mService);
-        pw.print(prefix); pw.print("mBound="); pw.println(mBound);
-        pw.print(prefix); pw.print("mEstimateTimeOfDeath=");
-            TimeUtils.formatDuration(mEstimateTimeOfDeath, SystemClock.uptimeMillis(), pw);
-            pw.println();
-        pw.print(prefix); pw.print("mAuthToken: "); pw.println(mAuthToken);
-
         if (DEBUG) {
             // ServiceInfo dump is too noisy and redundant (it can be obtained through other dumps)
             pw.print(prefix); pw.println("ServiceInfo:");
             mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), prefix + prefix);
         }
 
-        if (mQueuedRequests.isEmpty()) {
-            pw.print(prefix); pw.println("No queued requests");
-        } else {
-            pw.print(prefix); pw.println("Queued requests:");
-            for (int i = 0; i < mQueuedRequests.size(); i++) {
-                pw.print(prefix2); pw.print(i); pw.print(": "); pw.println(mQueuedRequests.get(i));
-            }
-        }
-
         pw.print(prefix); pw.print("sSessionIdCounter="); pw.println(sSessionIdCounter);
         final int size = mSessions.size();
         if (size == 0) {
@@ -498,32 +298,10 @@
 
     @Override
     public String toString() {
-        return "AutoFillManagerServiceImpl: [userId=" + mUserId + ", uid=" + mUid
+        return "AutoFillManagerServiceImpl: [userId=" + mUserId
                 + ", component=" + mComponentName + "]";
     }
 
-    private static final class QueuedRequest {
-        final IBinder activityToken;
-        final AutoFillId autoFillId;
-        final Rect bounds;
-        final int flags;
-
-        QueuedRequest(IBinder activityToken, AutoFillId autoFillId, Rect bounds, int flags) {
-            this.activityToken = activityToken;
-            this.autoFillId = autoFillId;
-            this.bounds = bounds;
-            this.flags = flags;
-        }
-
-        @Override
-        public String toString() {
-            if (!DEBUG) return super.toString();
-
-            return "QueuedRequest: [flags=" + flags + ", token=" + activityToken
-                    + ", id=" + autoFillId + ", bounds=" + bounds;
-        }
-    }
-
     /**
      * State for a given view with a AutoFillId.
      *
@@ -553,12 +331,7 @@
          * Response should only be set once.
          */
         void setResponse(FillResponse response) {
-            if (mResponse != null) {
-                Slog.e(TAG, "ViewState response set more than once");
-                return;
-            }
             mResponse = response;
-
             maybeCallOnFillReady();
         }
 
@@ -608,39 +381,27 @@
     // - On all authentication scenarios.
     // - When user does not interact back after a while.
     // - When service is unbound.
-    final class Session implements ViewState.Listener {
+    final class Session implements RemoteFillService.FillServiceCallbacks, ViewState.Listener,
+            AutoFillUI.AutoFillUiCallback {
+        private final int mId;
 
-        private final AutoFillUI mUi;
         private final WeakReference<IBinder> mActivityToken;
 
         @GuardedBy("mLock")
         private final Map<AutoFillId, ViewState> mViewStates = new ArrayMap<>();
+
         @GuardedBy("mLock")
         @Nullable
         private ViewState mCurrentViewState;
 
         private IAutoFillAppCallback mAppCallback;
 
+        @GuardedBy("mLock")
+        RemoteFillService mRemoteFillService;
+
         // TODO(b/33197203): Get a response per view instead of per activity.
         @GuardedBy("mLock")
         private FillResponse mCurrentResponse;
-        @GuardedBy("mLock")
-        private FillResponse mResponseRequiringAuth;
-        @GuardedBy("mLock")
-        private Dataset mDatasetRequiringAuth;
-
-        /**
-         * Used to auto-fill the activity directly when the FillCallback.onResponse() is called as
-         * the result of a successful user authentication on service's side.
-         */
-        @GuardedBy("mLock")
-        private boolean mAutoFillDirectly;
-
-        /**
-         * Used to remember which {@link Dataset} filled the session.
-         */
-        @GuardedBy("mLock")
-        private Dataset mAutoFilledDataset;
 
         /**
          * Map of ids that must be updated so they're send to {@link #onSaveLocked()}.
@@ -652,168 +413,77 @@
          * Assist structure sent by the app; it will be updated (sanitized, change values for save)
          * before sent to {@link AutoFillService}.
          */
+        @GuardedBy("mLock")
         private AssistStructure mStructure;
 
-        // TODO(b/33197203): use handler to handle results?
-        // TODO(b/33197203): handle all callback methods and/or cancelation?
-        private IFingerprintServiceReceiver mServiceReceiver =
-                new IFingerprintServiceReceiver.Stub() {
+        private Session(Context context, IBinder activityToken, int id) {
+            mActivityToken = new WeakReference<>(activityToken);
+            mRemoteFillService = new RemoteFillService(context, mComponent, mUserId, this);
+            mId = id;
+        }
 
-            @Override
-            public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
-                if (DEBUG) Slog.d(TAG, "onEnrollResult()");
+        // FillServiceCallbacks
+        @Override
+        public void onFillRequestSuccess(FillResponse response) {
+            // TODO(b/33197203): add MetricsLogger call
+            if (response == null) {
+                destroy();
+                return;
             }
-
-            @Override
-            public void onAcquired(long deviceId, int acquiredInfo, int vendorCode) {
-                if (DEBUG) Slog.d(TAG, "onAcquired()");
+            synchronized (mLock) {
+                processResponseLocked(response);
             }
+        }
 
-            @Override
-            public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) {
-                if (DEBUG) Slog.d(TAG, "onAuthenticationSucceeded(): " + fp.getGroupId());
+        // FillServiceCallbacks
+        @Override
+        public void onFillRequestFailure(CharSequence message) {
+            // TODO(b/33197203): add MetricsLogger call
+            getUiForShowing().showError(message);
+            destroy();
+        }
 
-                // First, check what was authenticated, a response or a dataset.
-                // Then, decide how to handle it:
-                // - If service provided data, handle them directly.
-                // - Otherwise, notify service.
+        // FillServiceCallbacks
+        @Override
+        public void onSaveRequestSuccess() {
+            // TODO: Implement
+        }
 
-                mAutoFillDirectly = true;
+        // FillServiceCallbacks
+        @Override
+        public void onSaveRequestFailure(CharSequence message) {
+            // TODO(b/33197203): add MetricsLogger call
+            getUiForShowing().showError(message);
+            destroy();
+        }
 
-                if (mDatasetRequiringAuth != null) {
-                    if (mDatasetRequiringAuth.isEmpty()) {
-                        notifyDatasetAuthenticationResult(mDatasetRequiringAuth.getExtras(),
-                                FLAG_AUTHENTICATION_SUCCESS);
-                    } else {
-                        autoFillApp(mDatasetRequiringAuth);
-                    }
-                } else if (mResponseRequiringAuth != null) {
-                    final List<Dataset> datasets = mResponseRequiringAuth.getDatasets();
-                    if (datasets.isEmpty()) {
-                        notifyResponseAuthenticationResult(mResponseRequiringAuth.getExtras(),
-                                FLAG_AUTHENTICATION_SUCCESS);
-                    } else {
-                        showResponseLocked(mResponseRequiringAuth, true);
-                    }
-                } else {
-                    Slog.w(TAG, "onAuthenticationSucceeded(): no response or dataset");
-                }
+        // FillServiceCallbacks
+        @Override
+        public void authenticate(IntentSender intent, Intent fillInIntent) {
+            startAuthIntent(intent, fillInIntent);
+        }
 
-                mUi.dismissFingerprintRequest(true);
+        // FillServiceCallbacks
+        @Override
+        public void onServiceDied(RemoteFillService service) {
+            // TODO: Implement
+        }
+
+        // AutoFillUiCallback
+        @Override
+        public void fill(Dataset dataset) {
+            autoFill(dataset);
+        }
+
+        // AutoFillUiCallback
+        @Override
+        public void save() {
+            synchronized (mLock) {
+                onSaveLocked();
             }
-
-            @Override
-            public void onAuthenticationFailed(long deviceId) {
-                if (DEBUG) Slog.d(TAG, "onAuthenticationFailed()");
-                // Do nothing - onError() will be called after a few failures...
-            }
-
-            @Override
-            public void onError(long deviceId, int error, int vendorCode) {
-                if (DEBUG) Slog.d(TAG, "onError()");
-
-                // Notify service so it can fallback to its own authentication
-                if (mDatasetRequiringAuth != null) {
-                    notifyDatasetAuthenticationResult(mDatasetRequiringAuth.getExtras(),
-                            FLAG_AUTHENTICATION_ERROR);
-                } else if (mResponseRequiringAuth != null) {
-                    notifyResponseAuthenticationResult(mResponseRequiringAuth.getExtras(),
-                            FLAG_AUTHENTICATION_ERROR);
-                } else {
-                    Slog.w(TAG, "onError(): no response or dataset");
-                }
-
-                mUi.dismissFingerprintRequest(false);
-            }
-
-            @Override
-            public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) {
-                if (DEBUG) Slog.d(TAG, "onRemoved()");
-            }
-
-            @Override
-            public void onEnumerated(long deviceId, int fingerId, int groupId, int remaining) {
-                if (DEBUG) Slog.d(TAG, "onEnumerated()");
-            }
-        };
-
-        private IAutoFillServerCallback mServerCallback = new IAutoFillServerCallback.Stub() {
-            @Override
-            public void showResponse(FillResponse response) {
-                // TODO(b/33197203): add MetricsLogger call
-                if (response == null) {
-                    if (DEBUG) Slog.d(TAG, "showResponse(): null response");
-
-                    removeSelf();
-                    return;
-                }
-
-                synchronized (mLock) {
-                    showResponseLocked(response, response.isAuthRequired());
-                }
-            }
-
-            @Override
-            public void showError(CharSequence message) {
-                // TODO(b/33197203): add MetricsLogger call
-                if (DEBUG) Slog.d(TAG, "showError(): " + message);
-
-                mUi.showError(message);
-                removeSelf();
-            }
-
-            @Override
-            public void onSaved() {
-                // TODO(b/33197203): add MetricsLogger call
-                if (DEBUG) Slog.d(TAG, "onSaved()");
-
-                removeSelf();
-            }
-
-            @Override
-            public void unlockFillResponse(int flags) {
-                // TODO(b/33197203): add proper MetricsLogger calls?
-                if (DEBUG) Log.d(TAG, "unlockUser(): flags=" + flags);
-
-                synchronized (mLock) {
-                    if ((flags & FLAG_AUTHENTICATION_SUCCESS) != 0) {
-                        if (mResponseRequiringAuth == null) {
-                            Log.wtf(TAG, "unlockUser(): no mResponseRequiringAuth on flags "
-                                    + flags);
-                            removeSelf();
-                            return;
-                        }
-                        final List<Dataset> datasets = mResponseRequiringAuth.getDatasets();
-                        if (datasets.isEmpty()) {
-                            Log.w(TAG, "unlockUser(): no dataset on previous response: "
-                                    + mResponseRequiringAuth);
-                            removeSelf();
-                            return;
-                        }
-                        mAutoFillDirectly = true;
-                        showResponseLocked(mResponseRequiringAuth, false);
-                    }
-                    // TODO(b/33197203): show UI error on authentication failure?
-                    // Or let service handle it?
-                }
-            }
-
-            @Override
-            public void unlockDataset(Dataset dataset, int flags) {
-                // TODO(b/33197203): add proper MetricsLogger calls?
-                if (DEBUG) Log.d(TAG, "unlockDataset(): dataset=" + dataset + ", flags=" + flags);
-
-                if ((flags & FLAG_AUTHENTICATION_SUCCESS) != 0) {
-                    autoFillApp(dataset != null ? dataset : mDatasetRequiringAuth);
-                    return;
-                }
-            }
-        };
-
-        final int mId;
+        }
 
         private Session(int id, IBinder activityToken) {
-            mUi = new AutoFillUI(mContext, this);
             mId = id;
             mActivityToken = new WeakReference<>(activityToken);
         }
@@ -826,7 +496,7 @@
 
           // TODO(b/33197203): ignore if not part of the savable ids.
           if (mUpdatedValues == null) {
-                // Lazy intializes it
+                // Lazy initializes it
                 mUpdatedValues = new HashMap<>();
             }
             mUpdatedValues.put(id, newValue);
@@ -847,32 +517,10 @@
             if (mUpdatedValues == null || mUpdatedValues.isEmpty()) {
                 // Nothing changed
                 if (DEBUG) Slog.d(TAG, "onSave(): when no changes, comes no responsibilities");
-
                 return;
             }
 
             // TODO(b/33197203): make sure the extras are tested by CTS
-            final Bundle responseExtras = mCurrentResponse == null ? null
-                    : mCurrentResponse.getExtras();
-            final Bundle datasetExtras = mAutoFilledDataset == null ? null
-                    : mAutoFilledDataset.getExtras();
-            final Bundle extras = (responseExtras == null && datasetExtras == null)
-                    ? null : new Bundle();
-            if (responseExtras != null) {
-                if (DEBUG) {
-                    Slog.d(TAG, "response extras on save extras: "
-                            + bundleToString(responseExtras));
-                }
-                extras.putBundle(AutoFillService.EXTRA_RESPONSE_EXTRAS, responseExtras);
-            }
-            if (datasetExtras != null) {
-                if (DEBUG) {
-                    Slog.d(TAG, "dataset extras on save extras: " + bundleToString(datasetExtras));
-                }
-                extras.putBundle(AutoFillService.EXTRA_DATASET_EXTRAS, datasetExtras);
-            }
-
-
             for (Entry<AutoFillId, AutoFillValue> entry : mUpdatedValues.entrySet()) {
                 final AutoFillId id = entry.getKey();
                 final ViewNode node = findViewNodeByIdLocked(id);
@@ -891,20 +539,24 @@
                 Slog.v(TAG, "Dumping " + mStructure + " before calling service.save()");
                 mStructure.dump();
             }
-            try {
-                mService.save(mStructure, mServerCallback, extras);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Error calling save on service: " + e);
-                // TODO(b/33197203): invalidate session?
-            }
+
+            mRemoteFillService.onSaveRequest(mStructure, mCurrentResponse.getExtras());
         }
 
-        void setAppCallbackLocked(IBinder appBinder) {
+        void onApplicationDataAvailable(AssistStructure structure, IBinder appCallback) {
+            setAppCallback(appCallback);
+            mStructure = structure;
+            // TODO(b/33197203): Need to pipe the bundle
+            mRemoteFillService.onFillRequest(structure, null);
+        }
+
+        private void setAppCallback(IBinder appBinder) {
             try {
                 appBinder.linkToDeath(() -> {
                     if (DEBUG) Slog.d(TAG, "app callback died");
                     // TODO(b/33197203): more cleanup here?
                     mAppCallback = null;
+                    destroy();
                 }, 0);
             } catch (RemoteException e) {
                 Slog.w(TAG, "linkToDeath() failed: " + e);
@@ -957,78 +609,105 @@
                     filterText = text.toString();
                 }
             }
-            mUi.showFillUi(viewState, response.getDatasets(), bounds, filterText);
+            getUiForShowing().showFillUi(viewState, response.getDatasets(), bounds, filterText);
         }
 
-        private void showResponseLocked(FillResponse response, boolean authRequired) {
-            if (DEBUG) Slog.d(TAG, "showResponse(directly=" + mAutoFillDirectly
-                    + ", authRequired=" + authRequired +"):" + response);
+        private void processResponseLocked(FillResponse response) {
+            if (DEBUG) Slog.d(TAG, "showResponse(authRequired="
+                    + response.getAuthentication() +"):" + response);
 
-            if (mAutoFillDirectly && response != null) {
-                final List<Dataset> datasets = response.getDatasets();
-                if (datasets.size() == 1) {
-                    // User authenticated and provider returned just 1 dataset - auto-fill it now!
-                    final Dataset dataset = datasets.get(0);
-                    if (DEBUG) Slog.d(TAG, "auto-filling directly from auth: " + dataset);
+            // TODO(b/33197203): add MetricsLogger calls
 
-                    autoFillApp(dataset);
-                    return;
-                }
-            }
+            mCurrentResponse = response;
 
-            if (!authRequired) {
-                // TODO(b/33197203): add MetricsLogger call
-                mCurrentResponse = response;
+            if (mCurrentResponse.getAuthentication() != null) {
+                // ...or handle authentication.
+                Intent fillInIntent = createAuthFillInIntent(response.getId(), mStructure,
+                        new Bundle(), new FillCallback(new IFillCallback.Stub() {
+                            @Override
+                            public void onCancellable(ICancellationSignal cancellation) {
+                                // TODO(b/33197203): Handle cancellation
+                            }
+
+                            @Override
+                            public void onSuccess(FillResponse response) {
+                                mCurrentResponse = createAuthenticatedResponse(
+                                        mCurrentResponse, response);
+                                processResponseLocked(mCurrentResponse);
+                            }
+
+                            @Override
+                            public void onFailure(CharSequence message) {
+                                getUiForShowing().showError(message);
+                                destroy();
+                            }
+                        }));
+
+                 getUiForShowing().showFillResponseAuthRequest(
+                         mCurrentResponse.getAuthentication(), fillInIntent);
+            } else {
                 // TODO(b/33197203): Consider using mCurrentResponse, depends on partitioning design
                 if (mCurrentViewState != null) {
                     mCurrentViewState.setResponse(mCurrentResponse);
                 }
-                return;
             }
-
-            // Handles response that requires authentication.
-            // TODO(b/33197203): add MetricsLogger call, including if fingerprint requested
-
-            mResponseRequiringAuth = response;
-            final boolean requiresFingerprint = response.hasCryptoObject();
-            if (requiresFingerprint) {
-                // TODO(b/33197203): check if fingerprint is available first and call error callback
-                // with FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE if it's not.
-                // Start scanning for the fingerprint.
-                scanFingerprint(response.getCryptoObjectOpId());
-            }
-            // Displays the message asking the user to tap (or fingerprint) for AutoFill.
-            mUi.showFillResponseAuthenticationRequest(requiresFingerprint,
-                    response.getExtras(), response.getFlags());
         }
 
         void autoFill(Dataset dataset) {
             synchronized (mLock) {
                 // Autofill it directly...
-                if (!dataset.isAuthRequired()) {
+                if (dataset.getAuthentication() == null) {
                     autoFillApp(dataset);
+                    // For now just show this on every fill
+                    getUiForShowing().showSaveUi();
                     return;
                 }
 
                 // ...or handle authentication.
-
-                mDatasetRequiringAuth = dataset;
-                final boolean requiresFingerprint = dataset.hasCryptoObject();
-                if (requiresFingerprint) {
-                    // TODO(b/33197203): check if fingerprint is available first and call error
-                    // callback with FLAG_FINGERPRINT_AUTHENTICATION_NOT_AVAILABLE if it's not.
-                    // Start scanning for the fingerprint.
-                    scanFingerprint(dataset.getCryptoObjectOpId());
-                    // Displays the message asking the user to tap (or fingerprint) for AutoFill.
-                    mUi.showDatasetFingerprintAuthenticationRequest(dataset);
-                } else {
-                    try {
-                        mService.authenticateDataset(dataset.getExtras(),
-                                FLAG_AUTHENTICATION_REQUESTED);
-                    } catch (RemoteException e) {
-                        Slog.w(TAG, "Error authenticating dataset: " + e);
+                Intent fillInIntent = createAuthFillInIntent(dataset.getId(), mStructure,
+                        new Bundle(), new FillCallback(new IFillCallback.Stub() {
+                    @Override
+                    public void onCancellable(ICancellationSignal cancellation) {
+                        // TODO(b/33197203): Handle cancellation
                     }
-                }
+
+                    @Override
+                    public void onSuccess(FillResponse response) {
+                        mCurrentResponse = createAuthenticatedResponse(
+                                mCurrentResponse, response);
+                        Dataset augmentedDataset = Helper.findDatasetById(dataset.getId(),
+                                mCurrentResponse);
+                        if (augmentedDataset != null) {
+                            autoFill(augmentedDataset);
+                        }
+                    }
+
+                    @Override
+                    public void onFailure(CharSequence message) {
+                        getUiForShowing().showError(message);
+                        destroy();
+                    }
+                }));
+
+                startAuthIntent(dataset.getAuthentication(), fillInIntent);
+            }
+        }
+
+        private Intent createAuthFillInIntent(String itemId, AssistStructure structure,
+                Bundle extras, FillCallback fillCallback) {
+            Intent fillInIntent = new Intent();
+            fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_ITEM_ID, itemId);
+            fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_ASSIST_STRUCTURE, structure);
+            fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_EXTRAS, extras);
+            fillInIntent.putExtra(Intent.EXTRA_AUTO_FILL_CALLBACK, fillCallback);
+            return fillInIntent;
+        }
+
+        private void startAuthIntent(IntentSender intent, Intent fillInIntent) {
+            try {
+                mAppCallback.startIntentSender(intent, fillInIntent);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Error launching auth intent", e);
             }
         }
 
@@ -1036,11 +715,6 @@
             pw.print(prefix); pw.print("mId: "); pw.println(mId);
             pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken.get());
             pw.print(prefix); pw.print("mCurrentResponse: "); pw.println(mCurrentResponse);
-            pw.print(prefix);
-                pw.print("mResponseRequiringAuth: "); pw.println(mResponseRequiringAuth);
-            pw.print(prefix);
-                pw.print("mDatasetRequiringAuth: "); pw.println(mDatasetRequiringAuth);
-            pw.print(prefix); pw.print("mAutoFillDirectly: "); pw.println(mAutoFillDirectly);
             pw.print(prefix); pw.print("mCurrentViewStates: "); pw.println(mCurrentViewState);
             pw.print(prefix); pw.print("mViewStates: "); pw.println(mViewStates.size());
             final String prefix2 = prefix + "  ";
@@ -1057,42 +731,8 @@
             } else {
                 pw.println("null");
             }
-        }
 
-        /**
-         * Notifies the result of a {@link FillResponse} authentication request to the service.
-         *
-         * <p>Typically called by the UI after user taps the "Tap to autofill" affordance, or after user
-         * used the fingerprint sensors to authenticate.
-         */
-        void notifyResponseAuthenticationResult(Bundle extras, int flags) {
-            if (DEBUG) Slog.d(TAG, "notifyResponseAuthenticationResult(): flags=" + flags
-                    + ", extras=" + bundleToString(extras));
-            synchronized (mLock) {
-                try {
-                    mService.authenticateFillResponse(extras, flags);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Error sending authentication result back to service: " + e);
-                }
-            }
-        }
-
-        /**
-         * Notifies the result of a {@link Dataset} authentication request to the service.
-         *
-         * <p>Typically called by the UI after user taps the "Tap to autofill" affordance, or after
-         * it gets the results from a fingerprint authentication.
-         */
-        void notifyDatasetAuthenticationResult(Bundle extras, int flags) {
-            if (DEBUG) Slog.d(TAG, "notifyDatasetAuthenticationResult(): flags=" + flags
-                    + ", extras=" + bundleToString(extras));
-            synchronized (mLock) {
-                try {
-                    mService.authenticateDataset(extras, flags);
-                } catch (RemoteException e) {
-                    Slog.w(TAG, "Error sending authentication result back to service: " + e);
-                }
-            }
+            mRemoteFillService.dump(prefix, pw);
         }
 
         void autoFillApp(Dataset dataset) {
@@ -1106,32 +746,9 @@
             }
         }
 
-        /**
-         * Called by UI to trigger a save request to the service.
-         */
-        void requestSave() {
-            synchronized (mLock) {
-                onSaveLocked();
-            }
-        }
-
-        private void scanFingerprint(long opId) {
-            // TODO(b/33197203): add MetricsLogger call
-            if (DEBUG) Slog.d(TAG, "Starting fingerprint scan for op id: " + opId);
-
-            // TODO(b/33197203): since we're clearing the AutoFillService's identity, make sure
-            // this method is only called at the proper times, otherwise a malicious provider could
-            // keep the callback refence to bypass the check
-            final long token = Binder.clearCallingIdentity();
-            try {
-                // TODO(b/33197203): set a timeout?
-                mFingerprintService.authenticate(mAuthToken, opId, mUserId, mServiceReceiver, 0,
-                        null);
-            } catch (RemoteException e) {
-                // Local call, shouldn't happen.
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
+        private AutoFillUI getUiForShowing() {
+            mUi.setCallback(this, mId);
+            return mUi;
         }
 
         private ViewNode findViewNodeByIdLocked(AutoFillId id) {
@@ -1167,10 +784,89 @@
             return null;
         }
 
-        private void removeSelf() {
+        private void destroy() {
             synchronized (mLock) {
+                mRemoteFillService.destroy();
+                mUi.hideAll();
+                mUi.setCallback(null, 0);
                 removeSessionLocked(mId);
             }
         }
+
+        /**
+         * Creates a response from the {@code original} and an {@code update} by
+         * replacing all items that needed authentication (response or datasets)
+         * with their updated version if the latter does not need authentication.
+         * New datasets that don't require auth are appended.
+         *
+         * @param original The original response requiring auth at some level.
+         * @param update An updated response with auth not needed anymore at some level.
+         * @return A new response with updated items where auth is not needed anymore.
+         */
+        // TODO(b/33197203) Unit test
+        FillResponse createAuthenticatedResponse(FillResponse original, FillResponse update) {
+            // Can update only if ids match
+            if (!original.getId().equals(update.getId())) {
+                return original;
+            }
+
+            // If the original required auth and the update doesn't, the update wins
+            // but only if none of the update's datasets requires authentication.
+            if (original.getAuthentication() != null && update.getAuthentication() == null) {
+                ArraySet<Dataset> updateDatasets = update.getDatasets();
+                final int udpateDatasetCount = updateDatasets.size();
+                for (int i = 0; i < udpateDatasetCount; i++) {
+                    Dataset updateDataset = updateDatasets.valueAt(i);
+                    if (updateDataset.getAuthentication() != null) {
+                        return original;
+                    }
+                }
+                return update;
+            }
+
+            // If no auth on response level we create a response that has all
+            // datasets from the original with the ones that required auth but
+            // not anymore updated and new ones not requiring auth appended.
+
+            // The update shouldn't require auth
+            if (update.getAuthentication() != null) {
+                return original;
+            }
+
+            final FillResponse.Builder builder = new FillResponse.Builder(original.getId());
+
+            // Update existing datasets
+            final ArraySet<Dataset> origDatasets = original.getDatasets();
+            final int origDatasetCount = origDatasets.size();
+            for (int i = 0; i < origDatasetCount; i++) {
+                Dataset origDataset = origDatasets.valueAt(i);
+                ArraySet<Dataset> updateDatasets = update.getDatasets();
+                final int updateDatasetCount = updateDatasets.size();
+                for (int j = 0; j < updateDatasetCount; j++) {
+                    Dataset updateDataset = updateDatasets.valueAt(j);
+                    if (origDataset.getId().equals(updateDataset.getId())) {
+                        // The update shouldn't require auth
+                        if (updateDataset.getAuthentication() == null) {
+                            origDataset = updateDataset;
+                            updateDatasets.removeAt(j);
+                        }
+                        break;
+                    }
+                }
+                builder.addDataset(origDataset);
+            }
+
+            // Add new datasets
+            final ArraySet<Dataset> updateDatasets = update.getDatasets();
+            final int updateDatasetCount = updateDatasets.size();
+            for (int i = 0; i < updateDatasetCount; i++) {
+                final Dataset updateDataset = updateDatasets.valueAt(i);
+                builder.addDataset(updateDataset);
+            }
+
+            // For now no extras and savable id updates.
+
+            return builder.build();
+        }
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/AutoFillUI.java
index 76c2916..da54d85 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillUI.java
@@ -18,10 +18,7 @@
 
 import static com.android.server.autofill.Helper.DEBUG;
 
-import android.annotation.Nullable;
-import android.app.Activity;
 import android.app.Notification;
-import android.app.Notification.Action;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
@@ -29,12 +26,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.IntentSender;
 import android.graphics.Rect;
-import android.graphics.PixelFormat;
 import android.os.Binder;
-import android.os.Bundle;
+import android.util.ArraySet;
 import android.util.Slog;
-import android.view.autofill.AutoFillId;
 import android.view.autofill.Dataset;
 import android.view.autofill.FillResponse;
 import android.view.Gravity;
@@ -44,27 +40,28 @@
 import android.view.WindowManager.LayoutParams;
 import android.widget.Toast;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.server.UiThread;
-import com.android.server.autofill.AutoFillManagerServiceImpl.Session;
 import com.android.server.autofill.AutoFillManagerServiceImpl.ViewState;
 
 import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.List;
 
 /**
  * Handles all auto-fill related UI tasks.
  */
 // TODO(b/33197203): document exactly what once the auto-fill bar is implemented
 final class AutoFillUI {
-
     private static final String TAG = "AutoFillUI";
 
+    private static final String EXTRA_AUTH_INTENT_SENDER =
+            "com.android.server.autofill.extra.AUTH_INTENT_SENDER";
+    private static final String EXTRA_AUTH_FILL_IN_INTENT =
+            "com.android.server.autofill.extra.AUTH_FILL_IN_INTENT";
+
     private final Context mContext;
-    private final Session mSession;
     private final WindowManager mWm;
 
+    // TODO(b/33197203) Fix locking - some state requires lock and some not - requires refactoring
+
     // Fill UI variables
     private AnchoredWindow mFillWindow;
     private DatasetPicker mFillView;
@@ -72,21 +69,39 @@
     private Rect mBounds;
     private String mFilterText;
 
+    private AutoFillUiCallback mCallback;
+    private int mClientId;
+
+    public interface AutoFillUiCallback {
+        void authenticate(IntentSender intent, Intent fillInIntent);
+        void fill(Dataset dataset);
+        void save();
+    }
+
     /**
      * Custom snackbar UI used for saving autofill or other informational messages.
      */
     private View mSnackbar;
 
-    AutoFillUI(Context context, Session session) {
+    AutoFillUI(Context context) {
         mContext = context;
-        mSession = session;
         mWm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
     }
 
+    void setCallback(AutoFillUiCallback callback, int clientId) {
+        hideAll();
+        mCallback = callback;
+        mClientId = clientId;
+    }
+
     /**
      * Displays an error message to the user.
      */
     void showError(CharSequence message) {
+        if (!hasCallback()) {
+            return;
+        }
+        hideAll();
         // TODO(b/33197203): proper implementation
         UiThread.getHandler().runWithScissors(() -> {
             Toast.makeText(mContext, "AutoFill error: " + message, Toast.LENGTH_LONG).show();
@@ -95,21 +110,17 @@
 
     /**
      * Hides the fill UI.
-     * Shows the options from a {@link FillResponse} so the user can pick up the proper
-     * {@link Dataset} (when the response has one) for a given view (identified by
-     * {@code autoFillId}).
      */
     void hideFillUi() {
         UiThread.getHandler().runWithScissors(() -> {
-            hideFillUiLocked();
+            hideFillUiUiThread();
         }, 0);
     }
 
-    // Must be called in inside UI Thread
-    private void hideFillUiLocked() {
+    @android.annotation.UiThread
+    private void hideFillUiUiThread() {
         if (mFillWindow != null) {
-            if (DEBUG) Slog.d(TAG, "hideFillUiLocked(): hide" + mFillWindow);
-
+            if (DEBUG) Slog.d(TAG, "hideFillUiUiThread(): hide" + mFillWindow);
             mFillWindow.hide();
         }
 
@@ -120,7 +131,6 @@
         mFillWindow = null;
     }
 
-
     /**
      * Shows the fill UI, removing the previous fill UI if the has changed.
      *
@@ -129,26 +139,31 @@
      * @param bounds bounds of the view to be filled, used if changed
      * @param filterText text of the view to be filled, used if changed
      */
-    void showFillUi(ViewState viewState, List<Dataset> datasets, Rect bounds,
+    void showFillUi(ViewState viewState, ArraySet<Dataset> datasets, Rect bounds,
             String filterText) {
+        if (!hasCallback()) {
+            return;
+        }
+        hideAll();
         UiThread.getHandler().runWithScissors(() -> {
             if (mViewState != viewState) {
-                // new
-                hideFillUi();
-
                 mViewState = viewState;
 
                 mFillView = new DatasetPicker(mContext, datasets,
                         (dataset) -> {
-                            mSession.autoFillApp(dataset);
+                            final AutoFillUiCallback callback;
+                            synchronized (mLock) {
+                                callback = mCallback;
+                            }
+                            callback.fill(dataset);
                             hideFillUi();
                         });
+                // TODO: No magical numbers
                 mFillWindow = new AnchoredWindow(
                         mWm, mFillView, 800, ViewGroup.LayoutParams.WRAP_CONTENT);
 
                 if (DEBUG) Slog.d(TAG, "show FillUi");
             }
-
             if (!bounds.equals(mBounds)) {
                 if (DEBUG) Slog.d(TAG, "update FillUi bounds: " + mBounds);
                 mBounds = bounds;
@@ -170,27 +185,14 @@
      * <p>It typically replaces the auto-fill bar with a message saying "Press fingerprint or tap to
      * autofill" or "Tap to autofill", depending on the value of {@code usesFingerprint}.
      */
-    void showFillResponseAuthenticationRequest(boolean usesFingerprint,
-            Bundle extras, int flags) {
-        // TODO(b/33197203): proper implementation
-        showAuthNotification(usesFingerprint, extras, flags);
-    }
-
-    /**
-     * Shows an UI affordance asking indicating that user action is required before a
-     * {@link Dataset} can be used.
-     *
-     * <p>It typically replaces the auto-fill bar with a message saying "Press fingerprint to
-     * autofill".
-     */
-    void showDatasetFingerprintAuthenticationRequest(Dataset dataset) {
-        if (DEBUG) Slog.d(TAG, "showDatasetAuthenticationRequest(): dataset=" + dataset);
-
-        // TODO(b/33197203): proper implementation (either pop up a fingerprint dialog or replace
-        // the auto-fill bar with a new message.
+    void showFillResponseAuthRequest(IntentSender intent, Intent fillInIntent) {
+        if (!hasCallback()) {
+            return;
+        }
+        hideAll();
         UiThread.getHandler().runWithScissors(() -> {
-            Toast.makeText(mContext, "AutoFill: press fingerprint to unlock " + dataset.getName(),
-                    Toast.LENGTH_LONG).show();
+            // TODO(b/33197203): proper implementation
+            showFillResponseAuthUiUiThread(intent, fillInIntent);
         }, 0);
     }
 
@@ -198,46 +200,36 @@
      * Shows the UI asking the user to save for auto-fill.
      */
     void showSaveUi() {
-        showSnackbar(new SavePrompt(mContext, new SavePrompt.OnSaveListener() {
-            @Override
-            public void onSaveClick() {
-                hideSnackbar();
-
-                // TODO(b/33197203): add MetricsLogger call
-                mSession.requestSave();
-            }
-            @Override
-            public void onCancelClick() {
-                hideSnackbar();
-            }
-        }));
-    }
-
-    /**
-     * Called by service after the user user the fingerprint sensors to authenticate.
-     */
-    void dismissFingerprintRequest(boolean success) {
-        if (DEBUG) Slog.d(TAG, "dismissFingerprintRequest(): ok=" + success);
-
-        dismissAuthNotification();
-
-        if (!success) {
-            // TODO(b/33197203): proper implementation (snack bar / i18n string)
-            UiThread.getHandler().runWithScissors(() -> {
-                Toast.makeText(mContext, "AutoFill: fingerprint failed", Toast.LENGTH_LONG).show();
-            }, 0);
+        if (!hasCallback()) {
+            return;
         }
+        hideAll();
+        UiThread.getHandler().runWithScissors(() -> {
+            showSnackbarUiThread(new SavePrompt(mContext,
+                    new SavePrompt.OnSaveListener() {
+                @Override
+                public void onSaveClick() {
+                    hideSnackbarUiThread();
+                    // TODO(b/33197203): add MetricsLogger call
+                    mCallback.save();
+                }
+
+                @Override
+                public void onCancelClick() {
+                    hideSnackbarUiThread();
+                }
+            }));
+        }, 0);
     }
 
     /**
-     * Closes all UI affordances.
+     * Hides all UI affordances.
      */
-    void closeAll() {
-        if (DEBUG) Slog.d(TAG, "closeAll()");
-
+    void hideAll() {
         UiThread.getHandler().runWithScissors(() -> {
-            hideSnackbarLocked();
-            hideFillUiLocked();
+            hideSnackbarUiThread();
+            hideFillUiUiThread();
+            hideFillResponseAuthUiUiThread();
         }, 0);
     }
 
@@ -245,7 +237,7 @@
         pw.println("AufoFill UI");
         final String prefix = "  ";
         pw.print(prefix); pw.print("sResultCode: "); pw.println(sResultCode);
-        pw.print(prefix); pw.print("mSessionId: "); pw.println(mSession.mId);
+        pw.print(prefix); pw.print("mClientId: "); pw.println(mClientId);
         pw.print(prefix); pw.print("mSnackBar: "); pw.println(mSnackbar);
         pw.print(prefix); pw.print("mViewState: "); pw.println(mViewState);
         pw.print(prefix); pw.print("mBounds: "); pw.println(mBounds);
@@ -254,7 +246,7 @@
 
     //similar to a snackbar, but can be a bit custom since it is more than just text. This will
     //allow two buttons for saving or not saving the autofill for instance as well.
-    private void showSnackbar(View snackBar) {
+    private void showSnackbarUiThread(View snackBar) {
         final LayoutParams params = new LayoutParams();
         params.setTitle("AutoFill Save");
         params.type = LayoutParams.TYPE_PHONE; // TODO(b/33197203) use app window token
@@ -274,20 +266,19 @@
         }, 0);
     }
 
-    private void hideSnackbar() {
-        UiThread.getHandler().runWithScissors(() -> {
-            hideSnackbarLocked();
-        }, 0);
-    }
-
-    // Must be called in inside UI Thread
-    private void hideSnackbarLocked() {
+    private void hideSnackbarUiThread() {
         if (mSnackbar != null) {
             mWm.removeView(mSnackbar);
             mSnackbar = null;
         }
     }
 
+    private boolean hasCallback() {
+        synchronized (mLock) {
+            return mCallback != null;
+        }
+    }
+
     /////////////////////////////////////////////////////////////////////////////////
     // TODO(b/33197203): temporary code using a notification to request auto-fill. //
     // Will be removed once UX decide the right way to present it to the user.     //
@@ -297,25 +288,13 @@
     private static final String NOTIFICATION_AUTO_FILL_INTENT =
             "com.android.internal.autofill.action.REQUEST_AUTOFILL";
 
-    // Extras used in the notification intents
-    private static final String EXTRA_USER_ID = "user_id";
-    private static final String EXTRA_NOTIFICATION_TYPE = "notification_type";
-    private static final String EXTRA_SESSION_ID = "session_id";
-    private static final String EXTRA_FILL_RESPONSE = "fill_response";
-    private static final String EXTRA_DATASET = "dataset";
-    private static final String EXTRA_AUTH_REQUIRED_EXTRAS = "auth_required_extras";
-    private static final String EXTRA_FLAGS = "flags";
-
-    private static final String TYPE_OPTIONS = "options";
-    private static final String TYPE_AUTH_RESPONSE = "auth_response";
-
     private BroadcastReceiver mNotificationReceiver;
     private final Object mLock = new Object();
 
     // Hack used to generate unique pending intents
     static int sResultCode = 0;
 
-    private void setNotificationListener() {
+    private void ensureNotificationListener() {
         synchronized (mLock) {
             if (mNotificationReceiver == null) {
                 mNotificationReceiver = new NotificationReceiver();
@@ -328,83 +307,58 @@
     final class NotificationReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
-            final String type = intent.getStringExtra(EXTRA_NOTIFICATION_TYPE);
-            if (type == null) {
-                Slog.wtf(TAG, "No extra " + EXTRA_NOTIFICATION_TYPE + " on intent " + intent);
-                return;
-            }
-            final Dataset dataset = intent.getParcelableExtra(EXTRA_DATASET);
-            final int flags = intent.getIntExtra(EXTRA_FLAGS, 0);
-
-            if (DEBUG) Slog.d(TAG, "Notification received: type=" + type
-                    + ", sessionId=" + mSession.mId);
+            final AutoFillUiCallback callback;
             synchronized (mLock) {
-                switch (type) {
-                    case TYPE_AUTH_RESPONSE:
-                        mSession.notifyResponseAuthenticationResult(
-                                intent.getBundleExtra(EXTRA_AUTH_REQUIRED_EXTRAS), flags);
-                        break;
-                    default: {
-                        Slog.w(TAG, "Unknown notification type: " + type);
-                    }
-                }
+                callback = mCallback;
+            }
+            if (callback != null) {
+                IntentSender intentSender = intent.getParcelableExtra(EXTRA_AUTH_INTENT_SENDER);
+                Intent fillInIntent = intent.getParcelableExtra(EXTRA_AUTH_FILL_IN_INTENT);
+                callback.authenticate(intentSender, fillInIntent);
             }
             collapseStatusBar();
         }
     }
 
-    private static Intent newNotificationIntent(String type) {
-        final Intent intent = new Intent(NOTIFICATION_AUTO_FILL_INTENT);
-        intent.putExtra(EXTRA_NOTIFICATION_TYPE, type);
-        return intent;
-    }
-
-    private void showAuthNotification(boolean usesFingerprint,
-            Bundle extras, int flags) {
-        final long token = Binder.clearCallingIdentity();
-        try {
-            showAuthNotificationAsSystem(usesFingerprint, extras, flags);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    private void showAuthNotificationAsSystem(
-            boolean usesFingerprint, Bundle extras, int flags) {
+    @android.annotation.UiThread
+    private void showFillResponseAuthUiUiThread(IntentSender intent, Intent fillInIntent) {
         final String title = "AutoFill Authentication";
         final StringBuilder subTitle = new StringBuilder("Provider require user authentication.\n");
 
-        final Intent authIntent = newNotificationIntent(TYPE_AUTH_RESPONSE);
-        if (extras != null) {
-            authIntent.putExtra(EXTRA_AUTH_REQUIRED_EXTRAS, extras);
-        }
-        if (flags != 0) {
-            authIntent.putExtra(EXTRA_FLAGS, flags);
-        }
-        final PendingIntent authPendingIntent = PendingIntent.getBroadcast(mContext, ++sResultCode,
-                authIntent, PendingIntent.FLAG_ONE_SHOT);
+        final Intent authIntent = new Intent(NOTIFICATION_AUTO_FILL_INTENT);
+        authIntent.putExtra(EXTRA_AUTH_INTENT_SENDER, intent);
+        authIntent.putExtra(EXTRA_AUTH_FILL_IN_INTENT, fillInIntent);
 
-        if (usesFingerprint) {
-            subTitle.append("But kindly accepts your fingerprint instead"
-                    + "\n(tap fingerprint sensor to trigger it)");
+        final PendingIntent authPendingIntent = PendingIntent.getBroadcast(
+                mContext, ++sResultCode, authIntent, PendingIntent.FLAG_ONE_SHOT);
 
-        } else {
-            subTitle.append("Tap notification to launch its authentication UI.");
-        }
+        subTitle.append("Tap notification to launch its authentication UI.");
 
         final Notification.Builder notification = newNotificationBuilder()
                 .setAutoCancel(true)
                 .setOngoing(false)
                 .setContentTitle(title)
-                .setStyle(new Notification.BigTextStyle().bigText(subTitle.toString()));
-        if (authPendingIntent != null) {
-            notification.setContentIntent(authPendingIntent);
+                .setStyle(new Notification.BigTextStyle().bigText(subTitle.toString()))
+                .setContentIntent(authPendingIntent);
+
+        ensureNotificationListener();
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            NotificationManager.from(mContext).notify(mClientId, notification.build());
+        } finally {
+            Binder.restoreCallingIdentity(identity);
         }
-        NotificationManager.from(mContext).notify(mSession.mId, notification.build());
     }
 
-    private void dismissAuthNotification() {
-        NotificationManager.from(mContext).cancel(mSession.mId);
+    @android.annotation.UiThread
+    private void hideFillResponseAuthUiUiThread() {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            NotificationManager.from(mContext).cancel(mClientId);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
     }
 
     private Notification.Builder newNotificationBuilder() {
diff --git a/services/autofill/java/com/android/server/autofill/DatasetPicker.java b/services/autofill/java/com/android/server/autofill/DatasetPicker.java
index 7245aaa..8212cf1 100644
--- a/services/autofill/java/com/android/server/autofill/DatasetPicker.java
+++ b/services/autofill/java/com/android/server/autofill/DatasetPicker.java
@@ -17,6 +17,7 @@
 
 import android.content.Context;
 import android.graphics.Color;
+import android.util.ArraySet;
 import android.view.autofill.Dataset;
 import android.view.View;
 import android.view.ViewGroup;
@@ -38,15 +39,13 @@
  * 3) the View is detached.
  */
 final class DatasetPicker extends ListView implements OnItemClickListener {
-    private static final String TAG = "DatasetPicker";
-
     interface Listener {
         void onDatasetPicked(Dataset dataset);
     }
 
     private final Listener mListener;
 
-    DatasetPicker(Context context, List<Dataset> datasets, Listener listener) {
+    DatasetPicker(Context context, ArraySet<Dataset> datasets, Listener listener) {
         super(context);
         mListener = listener;
 
@@ -80,7 +79,7 @@
         adapter.getFilter().filter(prefix, new FilterListener() {
             @Override
             public void onFilterComplete(int count) {
-                DatasetPicker.this.requestLayout();
+                setVisibility(count > 0 ? View.VISIBLE : View.GONE);
             }
         });
     }
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 9171dac..7fff410 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -17,6 +17,9 @@
 package com.android.server.autofill;
 
 import android.os.Bundle;
+import android.util.ArraySet;
+import android.view.autofill.Dataset;
+import android.view.autofill.FillResponse;
 
 import java.util.Arrays;
 import java.util.Objects;
@@ -55,4 +58,26 @@
     private Helper() {
         throw new UnsupportedOperationException("contains static members only");
     }
+
+    /**
+     * Finds a data set by id in a response.
+     *
+     * @param id The dataset id.
+     * @param response The response to search.
+     * @return The dataset if found or null.
+     */
+    static Dataset findDatasetById(String id, FillResponse response) {
+        ArraySet<Dataset> datasets = response.getDatasets();
+        if (datasets == null || datasets.isEmpty()) {
+            return null;
+        }
+        final int datasetCount = datasets.size();
+        for (int i = 0; i < datasetCount; i++) {
+            Dataset dataset = datasets.valueAt(i);
+            if (dataset.getId().equals(id)) {
+                return dataset;
+            }
+        }
+        return null;
+    }
 }
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
new file mode 100644
index 0000000..c070f77
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.autofill;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.assist.AssistStructure;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.ICancellationSignal;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.autofill.AutoFillService;
+import android.service.autofill.IAutoFillService;
+import android.service.autofill.IFillCallback;
+import android.service.autofill.ISaveCallback;
+import android.text.format.DateUtils;
+import android.util.Slog;
+import android.view.autofill.FillResponse;
+import com.android.internal.os.HandlerCaller;
+import com.android.server.FgThread;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+
+/**
+ * This class represents a remote fill service. It abstracts away the binding
+ * and unbinding from the remote implementation.
+ *
+ * <p>Clients can call methods of this class without worrying about when and
+ * how to bind/unbind/timeout. All state of this class is modified on a handler
+ * thread.
+ */
+final class RemoteFillService implements DeathRecipient {
+    private static final String LOG_TAG = "RemoteFillService";
+
+    private static final boolean DEBUG = Helper.DEBUG;
+
+    // How long after the last interaction with the service we would unbind
+    private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.MINUTE_IN_MILLIS;
+
+    private final Context mContext;
+
+    private final ComponentName mComponentName;
+
+    private final Intent mIntent;
+
+    private final FillServiceCallbacks mCallbacks;
+
+    private final int mUserId;
+
+    private final ServiceConnection mServiceConnection = new RemoteServiceConnection();
+
+    private final HandlerCaller mHandler;
+
+    private IAutoFillService mAutoFillService;
+
+    private boolean mBinding;
+
+    private boolean mDestroyed;
+
+    private boolean mServiceDied;
+
+    private boolean mCompleted;
+
+    private PendingRequest mPendingRequest;
+
+    public interface FillServiceCallbacks {
+        void onFillRequestSuccess(FillResponse response);
+        void onFillRequestFailure(CharSequence message);
+        void onSaveRequestSuccess();
+        void onSaveRequestFailure(CharSequence message);
+        void onServiceDied(RemoteFillService service);
+    }
+
+    public RemoteFillService(Context context, ComponentName componentName,
+            int userId, FillServiceCallbacks callbacks) {
+        mContext = context;
+        mCallbacks = callbacks;
+        mComponentName = componentName;
+        mIntent = new Intent(AutoFillService.SERVICE_INTERFACE)
+                .setComponent(mComponentName);
+        mUserId = userId;
+        mHandler = new MyHandler(context);
+    }
+
+    public void destroy() {
+        mHandler.obtainMessage(MyHandler.MSG_DESTROY).sendToTarget();
+    }
+
+    private void handleDestroy() {
+        if (mPendingRequest != null) {
+            mPendingRequest.cancel();
+            mPendingRequest = null;
+        }
+        ensureUnbound();
+        mDestroyed = true;
+    }
+
+    @Override
+    public void binderDied() {
+        mHandler.obtainMessage(MyHandler.MSG_BINDER_DIED).sendToTarget();
+    }
+
+    private void handleBinderDied() {
+        if (mAutoFillService != null) {
+            mAutoFillService.asBinder().unlinkToDeath(this, 0);
+        }
+        mAutoFillService = null;
+        mServiceDied = true;
+        mCallbacks.onServiceDied(this);
+    }
+
+    public void onFillRequest(@NonNull AssistStructure structure, @Nullable Bundle extras) {
+        cancelScheduledUnbind();
+        PendingFillRequest request = new PendingFillRequest(structure, extras, this);
+        mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, request).sendToTarget();
+    }
+
+    public void onSaveRequest(@NonNull AssistStructure structure, @Nullable Bundle extras) {
+        cancelScheduledUnbind();
+        PendingSaveRequest request = new PendingSaveRequest(structure, extras, this);
+        mHandler.obtainMessageO(MyHandler.MSG_ON_PENDING_REQUEST, request).sendToTarget();
+    }
+
+    // Note: we are dumping without a lock held so this is a bit racy but
+    // adding a lock to a class that offloads to a handler thread would
+    // mean adding a lock adding overhead to normal runtime operation.
+    public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+        String tab = "  ";
+        pw.append(prefix).append("service:").println();
+        pw.append(prefix).append(tab).append("userId=")
+                .append(String.valueOf(mUserId)).println();
+        pw.append(prefix).append(tab).append("componentName=")
+                .append(mComponentName.flattenToString()).println();
+        pw.append(prefix).append(tab).append("destroyed=")
+                .append(String.valueOf(mDestroyed)).println();
+        pw.append(prefix).append(tab).append("bound=")
+                .append(String.valueOf(isBound())).println();
+        pw.append(prefix).append(tab).append("hasPendingRequest=")
+                .append(String.valueOf(mPendingRequest != null)).println();
+        pw.println();
+    }
+
+    private void cancelScheduledUnbind() {
+        mHandler.removeMessages(MyHandler.MSG_UNBIND);
+    }
+
+    private void scheduleUnbind() {
+        cancelScheduledUnbind();
+        Message message = mHandler.obtainMessage(MyHandler.MSG_UNBIND);
+        mHandler.sendMessageDelayed(message, TIMEOUT_IDLE_BIND_MILLIS);
+    }
+
+    private void handleUnbind() {
+        ensureUnbound();
+    }
+
+    private void handlePendingRequest(PendingRequest pendingRequest) {
+        if (mDestroyed || mCompleted) {
+            return;
+        }
+        if (pendingRequest.isFinal()) {
+            mCompleted = true;
+        }
+        if (!isBound()) {
+            if (mPendingRequest != null) {
+                mPendingRequest.cancel();
+            }
+            mPendingRequest = pendingRequest;
+            ensureBound();
+        } else {
+            if (DEBUG) {
+                Slog.d(LOG_TAG, "[user: " + mUserId + "] handleOnFillRequest()");
+            }
+            pendingRequest.run();
+        }
+    }
+
+    private boolean isBound() {
+        return mAutoFillService != null;
+    }
+
+    private void ensureBound() {
+        if (isBound() || mBinding) {
+            return;
+        }
+        if (DEBUG) {
+            Slog.d(LOG_TAG, "[user: " + mUserId + "] ensureBound()");
+        }
+        mBinding = true;
+
+        boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection,
+                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+                new UserHandle(mUserId));
+
+        if (!willBind) {
+            if (DEBUG) {
+                Slog.d(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent);
+            }
+            mBinding = false;
+
+            if (!mServiceDied) {
+                handleBinderDied();
+            }
+        }
+    }
+
+    private void ensureUnbound() {
+        if (!isBound() && !mBinding) {
+            return;
+        }
+        if (DEBUG) {
+            Slog.d(LOG_TAG, "[user: " + mUserId + "] ensureUnbound()");
+        }
+        mBinding = false;
+        if (isBound()) {
+            mAutoFillService.asBinder().unlinkToDeath(this, 0);
+            mAutoFillService = null;
+        }
+        mContext.unbindService(mServiceConnection);
+    }
+
+    private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest,
+            FillResponse response) {
+        mHandler.getHandler().post(() -> {
+            if (handleResponseCallbackCommon(pendingRequest)) {
+                mCallbacks.onFillRequestSuccess(response);
+            }
+        });
+    }
+
+    private void dispatchOnFillRequestFailure(PendingRequest pendingRequest,
+            CharSequence message) {
+        mHandler.getHandler().post(() -> {
+            if (handleResponseCallbackCommon(pendingRequest)) {
+                mCallbacks.onFillRequestFailure(message);
+            }
+        });
+    }
+
+    private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest) {
+        mHandler.getHandler().post(() -> {
+            if (handleResponseCallbackCommon(pendingRequest)) {
+                mCallbacks.onSaveRequestSuccess();
+            }
+        });
+    }
+
+    private void dispatchOnSaveRequestFailure(PendingRequest pendingRequest,
+            CharSequence message) {
+        mHandler.getHandler().post(() -> {
+            if (handleResponseCallbackCommon(pendingRequest)) {
+                mCallbacks.onSaveRequestFailure(message);
+            }
+        });
+    }
+
+    private boolean handleResponseCallbackCommon(PendingRequest pendingRequest) {
+        if (mDestroyed) {
+            return false;
+        }
+        if (mPendingRequest == pendingRequest) {
+            mPendingRequest = null;
+        }
+        if (mPendingRequest == null) {
+            scheduleUnbind();
+        }
+        return true;
+    }
+
+    private class RemoteServiceConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            if (mDestroyed || !mBinding) {
+                mContext.unbindService(mServiceConnection);
+                return;
+            }
+            mBinding = false;
+            mAutoFillService = IAutoFillService.Stub.asInterface(service);
+            try {
+                service.linkToDeath(RemoteFillService.this, 0);
+            } catch (RemoteException re) {
+                handleBinderDied();
+                return;
+            }
+
+            if (mPendingRequest != null) {
+                handlePendingRequest(mPendingRequest);
+            }
+
+            mServiceDied = false;
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            mBinding = true;
+            mAutoFillService = null;
+        }
+    }
+
+    private final class MyHandler extends HandlerCaller {
+        public static final int MSG_DESTROY = 1;
+        public static final int MSG_BINDER_DIED = 2;
+        public static final int MSG_UNBIND = 3;
+        public static final int MSG_ON_PENDING_REQUEST = 4;
+
+        public MyHandler(Context context) {
+            // Cannot use lambda - doesn't compile
+            super(context, FgThread.getHandler().getLooper(), new Callback() {
+                @Override
+                public void executeMessage(Message message) {
+                    if (mDestroyed) {
+                        Slog.w(LOG_TAG, "Not handling " + message + " as service for "
+                                + mComponentName + " is already destroyed");
+                        return;
+                    }
+                    switch (message.what) {
+                        case MSG_DESTROY: {
+                            handleDestroy();
+                        } break;
+
+                        case MSG_BINDER_DIED: {
+                            handleBinderDied();
+                        } break;
+
+                        case MSG_UNBIND: {
+                            handleUnbind();
+                        } break;
+
+                        case MSG_ON_PENDING_REQUEST: {
+                            handlePendingRequest((PendingRequest) message.obj);
+                        } break;
+                    }
+                }
+            }, false);
+        }
+    }
+
+    private static abstract class PendingRequest implements Runnable {
+        void cancel() {
+
+        }
+
+        /**
+         * @return whether this request leads to a final state where no
+         * other requests can be made.
+         */
+        boolean isFinal() {
+            return false;
+        }
+    }
+
+    private static final class PendingFillRequest extends PendingRequest {
+        private final Object mLock = new Object();
+        private final WeakReference<RemoteFillService> mWeakService;
+        private AssistStructure mStructure;
+        private Bundle mExtras;
+        private final IFillCallback mCallback;
+        private ICancellationSignal mCancellation;
+        private boolean mCancelled;
+
+        public PendingFillRequest(AssistStructure structure,
+                Bundle extras, RemoteFillService service) {
+            mStructure = structure;
+            mExtras = extras;
+            mWeakService = new WeakReference<>(service);
+            mCallback = new IFillCallback.Stub() {
+                @Override
+                public void onCancellable(ICancellationSignal cancellation) {
+                    synchronized (mLock) {
+                        final boolean cancelled;
+                        synchronized (mLock) {
+                            mCancellation = cancellation;
+                            cancelled = mCancelled;
+                        }
+                        if (cancelled) {
+                            try {
+                                cancellation.cancel();
+                            } catch (RemoteException e) {
+                                Slog.e(LOG_TAG, "Error requesting a cancellation", e);
+                            }
+                        }
+                    }
+                }
+
+                @Override
+                public void onSuccess(FillResponse response) {
+                    RemoteFillService remoteService = mWeakService.get();
+                    if (remoteService != null) {
+                        remoteService.dispatchOnFillRequestSuccess(
+                                PendingFillRequest.this, response);
+                    }
+                }
+
+                @Override
+                public void onFailure(CharSequence message) {
+                    RemoteFillService remoteService = mWeakService.get();
+                    if (remoteService != null) {
+                        remoteService.dispatchOnFillRequestFailure(
+                                PendingFillRequest.this, message);
+                    }
+                }
+            };
+        }
+
+        @Override
+        public void run() {
+            RemoteFillService remoteService = mWeakService.get();
+            if (remoteService != null) {
+                try {
+                    remoteService.mAutoFillService.onFillRequest(mStructure,
+                            mExtras, mCallback);
+                    synchronized (mLock) {
+                        mStructure = null;
+                        mExtras = null;
+                    }
+                } catch (RemoteException e) {
+                    Slog.e(LOG_TAG, "Error calling on fill request", e);
+                    cancel();
+                }
+            }
+        }
+
+        @Override
+        public void cancel() {
+            final ICancellationSignal cancellation;
+            synchronized (mLock) {
+                if (mCancelled) {
+                    return;
+                }
+                mCancelled = true;
+                cancellation = mCancellation;
+            }
+            if (cancellation == null) {
+                return;
+            }
+            try {
+                cancellation.cancel();
+            } catch (RemoteException e) {
+                Slog.e(LOG_TAG, "Error cancelling a fill request", e);
+            }
+        }
+    }
+
+    private static final class PendingSaveRequest extends PendingRequest {
+        private final Object mLock = new Object();
+        private final WeakReference<RemoteFillService> mWeakService;
+        private AssistStructure mStructure;
+        private Bundle mExtras;
+        private final ISaveCallback mCallback;
+
+        public PendingSaveRequest(@NonNull AssistStructure structure,
+                @Nullable Bundle extras, @NonNull RemoteFillService service) {
+            mStructure = structure;
+            mExtras = extras;
+            mWeakService = new WeakReference<>(service);
+            mCallback = new ISaveCallback.Stub() {
+                @Override
+                public void onSuccess() {
+                    RemoteFillService service = mWeakService.get();
+                    if (service != null) {
+                        service.dispatchOnSaveRequestSuccess(
+                                PendingSaveRequest.this);
+                    }
+                }
+
+                @Override
+                public void onFailure(CharSequence message) {
+                    RemoteFillService service = mWeakService.get();
+                    if (service != null) {
+                        service.dispatchOnSaveRequestFailure(
+                                PendingSaveRequest.this, message);
+                    }
+                }
+            };
+        }
+
+        @Override
+        public void run() {
+            RemoteFillService service = mWeakService.get();
+            if (service != null) {
+                try {
+                    service.mAutoFillService.onSaveRequest(mStructure,
+                            mExtras, mCallback);
+                    synchronized (mLock) {
+                        mStructure = null;
+                        mExtras = null;
+                    }
+                } catch (RemoteException e) {
+                    Slog.e(LOG_TAG, "Error calling on save request", e);
+                }
+            }
+        }
+
+        @Override
+        public boolean isFinal() {
+            return true;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index dd550f2..6248cab 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -49,8 +49,10 @@
 import android.os.UEventObserver;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.service.battery.BatteryServiceDumpProto;
 import android.util.EventLog;
 import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -801,6 +803,35 @@
         }
     }
 
+    private void dumpProto(FileDescriptor fd) {
+        final ProtoOutputStream proto = new ProtoOutputStream(fd);
+
+        synchronized (mLock) {
+            proto.write(BatteryServiceDumpProto.ARE_UPDATES_STOPPED, mUpdatesStopped);
+            int batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_NONE;
+            if (mBatteryProps.chargerAcOnline) {
+                batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_AC;
+            } else if (mBatteryProps.chargerUsbOnline) {
+                batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_USB;
+            } else if (mBatteryProps.chargerWirelessOnline) {
+                batteryPluggedValue = BatteryServiceDumpProto.BATTERY_PLUGGED_WIRELESS;
+            }
+            proto.write(BatteryServiceDumpProto.PLUGGED, batteryPluggedValue);
+            proto.write(BatteryServiceDumpProto.MAX_CHARGING_CURRENT, mBatteryProps.maxChargingCurrent);
+            proto.write(BatteryServiceDumpProto.MAX_CHARGING_VOLTAGE, mBatteryProps.maxChargingVoltage);
+            proto.write(BatteryServiceDumpProto.CHARGE_COUNTER, mBatteryProps.batteryChargeCounter);
+            proto.write(BatteryServiceDumpProto.STATUS, mBatteryProps.batteryStatus);
+            proto.write(BatteryServiceDumpProto.HEALTH, mBatteryProps.batteryHealth);
+            proto.write(BatteryServiceDumpProto.IS_PRESENT, mBatteryProps.batteryPresent);
+            proto.write(BatteryServiceDumpProto.LEVEL, mBatteryProps.batteryLevel);
+            proto.write(BatteryServiceDumpProto.SCALE, BATTERY_SCALE);
+            proto.write(BatteryServiceDumpProto.VOLTAGE, mBatteryProps.batteryVoltage);
+            proto.write(BatteryServiceDumpProto.TEMPERATURE, mBatteryProps.batteryTemperature);
+            proto.write(BatteryServiceDumpProto.TECHNOLOGY, mBatteryProps.batteryTechnology);
+        }
+        proto.flush();
+    }
+
     private final class Led {
         private final Light mBatteryLight;
 
@@ -878,7 +909,11 @@
                 return;
             }
 
-            dumpInternal(fd, pw, args);
+            if (args.length > 0 && "--proto".equals(args[0])) {
+                dumpProto(fd);
+            } else {
+                dumpInternal(fd, pw, args);
+            }
         }
 
         @Override public void onShellCommand(FileDescriptor in, FileDescriptor out,
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 3e711ec..22eca77 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -3028,22 +3028,22 @@
                 PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
                 mSettings.getCurrentUserId());
 
-        final HashMap<String, List<InputMethodSubtype>> additionalSubtypes =
+        final HashMap<String, List<InputMethodSubtype>> additionalSubtypeMap =
                 mFileManager.getAllAdditionalInputMethodSubtypes();
         for (int i = 0; i < services.size(); ++i) {
             ResolveInfo ri = services.get(i);
             ServiceInfo si = ri.serviceInfo;
-            ComponentName compName = new ComponentName(si.packageName, si.name);
-            if (!android.Manifest.permission.BIND_INPUT_METHOD.equals(
-                    si.permission)) {
-                Slog.w(TAG, "Skipping input method " + compName
+            final String imeId = InputMethodInfo.computeId(ri);
+            if (!android.Manifest.permission.BIND_INPUT_METHOD.equals(si.permission)) {
+                Slog.w(TAG, "Skipping input method " + imeId
                         + ": it does not require the permission "
                         + android.Manifest.permission.BIND_INPUT_METHOD);
                 continue;
             }
 
-            if (DEBUG) Slog.d(TAG, "Checking " + compName);
+            if (DEBUG) Slog.d(TAG, "Checking " + imeId);
 
+            final List<InputMethodSubtype> additionalSubtypes = additionalSubtypeMap.get(imeId);
             try {
                 InputMethodInfo p = new InputMethodInfo(mContext, ri, additionalSubtypes);
                 mMethodList.add(p);
@@ -3054,7 +3054,7 @@
                     Slog.d(TAG, "Found an input method " + p);
                 }
             } catch (Exception e) {
-                Slog.wtf(TAG, "Unable to load input method " + compName, e);
+                Slog.wtf(TAG, "Unable to load input method " + imeId, e);
             }
         }
 
diff --git a/services/core/java/com/android/server/LockSettingsStrongAuth.java b/services/core/java/com/android/server/LockSettingsStrongAuth.java
index 1314110..f5fe3db 100644
--- a/services/core/java/com/android/server/LockSettingsStrongAuth.java
+++ b/services/core/java/com/android/server/LockSettingsStrongAuth.java
@@ -51,6 +51,7 @@
     private static final int MSG_REGISTER_TRACKER = 2;
     private static final int MSG_UNREGISTER_TRACKER = 3;
     private static final int MSG_REMOVE_USER = 4;
+    private static final int MSG_SCHEDULE_STRONG_AUTH_TIMEOUT = 5;
 
     private static final String STRONG_AUTH_TIMEOUT_ALARM_TAG =
             "LockSettingsStrongAuth.timeoutForUser";
@@ -128,6 +129,23 @@
         }
     }
 
+    private void handleScheduleStrongAuthTimeout(int userId) {
+        final DevicePolicyManager dpm =
+                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
+        // cancel current alarm listener for the user (if there was one)
+        StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
+        if (alarm != null) {
+            mAlarmManager.cancel(alarm);
+        } else {
+            alarm = new StrongAuthTimeoutAlarmListener(userId);
+            mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
+        }
+        // schedule a new alarm listener for the user
+        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
+                alarm, mHandler);
+    }
+
     private void notifyStrongAuthTrackers(int strongAuthReason, int userId) {
         for (int i = 0; i < mStrongAuthTrackers.size(); i++) {
             try {
@@ -151,7 +169,8 @@
     }
 
     public void removeUser(int userId) {
-        mHandler.obtainMessage(MSG_REMOVE_USER, userId, 0).sendToTarget();
+        final int argNotUsed = 0;
+        mHandler.obtainMessage(MSG_REMOVE_USER, userId, argNotUsed).sendToTarget();
     }
 
     public void requireStrongAuth(int strongAuthReason, int userId) {
@@ -169,29 +188,8 @@
     }
 
     public void reportSuccessfulStrongAuthUnlock(int userId) {
-        scheduleStrongAuthTimeout(userId);
-    }
-
-    private void scheduleStrongAuthTimeout(int userId) {
-        final DevicePolicyManager dpm =
-                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null, userId);
-        // cancel current alarm listener for the user (if there was one)
-        StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId);
-        if (alarm != null) {
-            mAlarmManager.cancel(alarm);
-        } else {
-            alarm = new StrongAuthTimeoutAlarmListener(userId);
-            mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm);
-        }
-        // schedule a new alarm listener for the user
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, STRONG_AUTH_TIMEOUT_ALARM_TAG,
-                    alarm, mHandler);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
+        final int argNotUsed = 0;
+        mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget();
     }
 
     private class StrongAuthTimeoutAlarmListener implements OnAlarmListener {
@@ -224,6 +222,9 @@
                 case MSG_REMOVE_USER:
                     handleRemoveUser(msg.arg1);
                     break;
+                case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT:
+                    handleScheduleStrongAuthTimeout(msg.arg1);
+                    break;
             }
         }
     };
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 25016f6..5fe8b1a 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -183,11 +183,12 @@
                 // connection.
                 if (DBG) Log.d(TAG, "No active scorers available.");
                 unbindFromScoringServiceIfNeeded();
-            } else if (activeScorer.packageName.equals(scorerPackageName)) {
+            } else if (activeScorer.getRecommendationServicePackageName().equals(scorerPackageName))
+            {
                 // The active scoring service changed in some way.
                 if (DBG) {
                     Log.d(TAG, "Possible change to the active scorer: "
-                            + activeScorer.packageName);
+                            + activeScorer.getRecommendationServicePackageName());
                 }
                 if (forceUnbind) {
                     unbindFromScoringServiceIfNeeded();
@@ -198,7 +199,8 @@
                 // bound to the correct scoring app. The logic in bindToScoringServiceIfNeeded()
                 // will sort that out to leave us bound to the most recent active scorer.
                 if (DBG) {
-                    Log.d(TAG, "Binding to " + activeScorer.packageName + " if needed.");
+                    Log.d(TAG, "Binding to " + activeScorer.getRecommendationServiceComponent()
+                            + " if needed.");
                 }
                 bindToScoringServiceIfNeeded(activeScorer);
             }
@@ -334,22 +336,19 @@
         bindToScoringServiceIfNeeded(scorerData);
     }
 
-    private void bindToScoringServiceIfNeeded(NetworkScorerAppData scorerData) {
-        if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded(" + scorerData + ")");
-        if (scorerData != null && scorerData.recommendationServiceClassName != null) {
-            ComponentName componentName = new ComponentName(scorerData.packageName,
-                    scorerData.recommendationServiceClassName);
+    private void bindToScoringServiceIfNeeded(NetworkScorerAppData appData) {
+        if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded(" + appData + ")");
+        if (appData != null) {
             synchronized (mServiceConnectionLock) {
                 // If we're connected to a different component then drop it.
                 if (mServiceConnection != null
-                        && !mServiceConnection.mComponentName.equals(componentName)) {
+                        && !mServiceConnection.mAppData.equals(appData)) {
                     unbindFromScoringServiceIfNeeded();
                 }
 
                 // If we're not connected at all then create a new connection.
                 if (mServiceConnection == null) {
-                    mServiceConnection = new ScoringServiceConnection(componentName,
-                            scorerData.packageUid);
+                    mServiceConnection = new ScoringServiceConnection(appData);
                 }
 
                 // Make sure the connection is connected (idempotent)
@@ -625,7 +624,7 @@
         }
     }
 
-    private boolean isCallerSystemUid() {
+    private boolean callerCanRequestScores() {
         // REQUEST_NETWORK_SCORES is a signature only permission.
         return mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES) ==
                  PackageManager.PERMISSION_GRANTED;
@@ -634,7 +633,7 @@
     @Override
     public boolean clearScores() {
         // Only the active scorer or the system should be allowed to flush all scores.
-        if (isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) {
+        if (isCallerActiveScorer(getCallingUid()) || callerCanRequestScores()) {
             final long token = Binder.clearCallingIdentity();
             try {
                 clearInternal();
@@ -672,7 +671,8 @@
     @Override
     public boolean isCallerActiveScorer(int callingUid) {
         synchronized (mServiceConnectionLock) {
-            return mServiceConnection != null && mServiceConnection.mScoringAppUid == callingUid;
+            return mServiceConnection != null
+                    && mServiceConnection.mAppData.packageUid == callingUid;
         }
     }
 
@@ -686,7 +686,7 @@
     public String getActiveScorerPackage() {
         synchronized (mServiceConnectionLock) {
             if (mServiceConnection != null) {
-                return mServiceConnection.mComponentName.getPackageName();
+                return mServiceConnection.getPackageName();
             }
         }
         return null;
@@ -695,7 +695,7 @@
     @Override
     public void disableScoring() {
         // Only the active scorer or the system should be allowed to disable scoring.
-        if (isCallerActiveScorer(getCallingUid()) || isCallerSystemUid()) {
+        if (isCallerActiveScorer(getCallingUid()) || callerCanRequestScores()) {
             // no-op for now but we could write to the setting if needed.
         } else {
             throw new SecurityException(
@@ -881,7 +881,7 @@
                 writer.println("Scoring is disabled.");
                 return;
             }
-            writer.println("Current scorer: " + currentScorer.packageName);
+            writer.println("Current scorer: " + currentScorer);
 
             sendCacheUpdateCallback(new BiConsumer<INetworkScoreCache, Object>() {
                 @Override
@@ -927,7 +927,7 @@
                 try {
                     for (int i = 0; i < count; i++) {
                         consumer.accept(callbackList.getBroadcastItem(i),
-                                callbackList.getRegisteredCallbackCookie(i));
+                                callbackList.getBroadcastCookie(i));
                     }
                 } finally {
                     callbackList.finishBroadcast();
@@ -966,21 +966,19 @@
     }
 
     private static class ScoringServiceConnection implements ServiceConnection {
-        private final ComponentName mComponentName;
-        private final int mScoringAppUid;
+        private final NetworkScorerAppData mAppData;
         private volatile boolean mBound = false;
         private volatile boolean mConnected = false;
         private volatile INetworkRecommendationProvider mRecommendationProvider;
 
-        ScoringServiceConnection(ComponentName componentName, int scoringAppUid) {
-            mComponentName = componentName;
-            mScoringAppUid = scoringAppUid;
+        ScoringServiceConnection(NetworkScorerAppData appData) {
+            mAppData = appData;
         }
 
         void connect(Context context) {
             if (!mBound) {
                 Intent service = new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS);
-                service.setComponent(mComponentName);
+                service.setComponent(mAppData.getRecommendationServiceComponent());
                 mBound = context.bindServiceAsUser(service, this,
                         Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
                         UserHandle.SYSTEM);
@@ -1010,6 +1008,10 @@
             return mRecommendationProvider;
         }
 
+        String getPackageName() {
+            return mAppData.getRecommendationServiceComponent().getPackageName();
+        }
+
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             if (DBG) Log.d(TAG, "ScoringServiceConnection: " + name.flattenToString());
@@ -1027,7 +1029,9 @@
         }
 
         public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-            writer.println("ScoringServiceConnection: " + mComponentName + ", bound: " + mBound
+            writer.println("ScoringServiceConnection: "
+                    + mAppData.getRecommendationServiceComponent()
+                    + ", bound: " + mBound
                     + ", connected: " + mConnected);
         }
     }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index bfa3f04..fdd7cb1 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -287,16 +287,17 @@
                      * and then rebuild the cache. All under the cache lock. But that change is too
                      * large at this point.
                      */
+                    final String removedPackageName = intent.getData().toString();
                     Runnable purgingRunnable = new Runnable() {
                         @Override
                         public void run() {
                             purgeOldGrantsAll();
                             // Notify authenticator about removed app?
+                            removeVisibilityValuesForPackage(removedPackageName);
                         }
                     };
                     mHandler.post(purgingRunnable);
                 }
-
             }
         }, intentFilter);
 
@@ -429,7 +430,7 @@
 
     @Override
     public boolean addAccountExplicitlyWithVisibility(Account account, String password,
-            Bundle extras, Map uidToVisibility) {
+            Bundle extras, Map packageToVisibility) {
         Bundle.setDefusable(extras, true);
 
         final int callingUid = Binder.getCallingUid();
@@ -455,7 +456,7 @@
         try {
             UserAccounts accounts = getUserAccounts(userId);
             return addAccountInternal(accounts, account, password, extras, callingUid,
-                    (Map<Integer, Integer>) uidToVisibility);
+                    (Map<String, Integer>) packageToVisibility);
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -505,7 +506,7 @@
                 if (accountsOfType != null) {
                     for (Account account : accountsOfType) {
                         result.put(account,
-                                resolveAccountVisibility(account, uid, packageName, accounts));
+                                resolveAccountVisibility(account, packageName, accounts));
                     }
                 }
             }
@@ -514,7 +515,7 @@
     }
 
     @Override
-    public Map<Integer, Integer> getUidsAndVisibilityForAccount(Account account) {
+    public Map<String, Integer> getPackagesAndVisibilityForAccount(Account account) {
         if (account == null) throw new IllegalArgumentException("account is null");
         int callingUid = Binder.getCallingUid();
         int userId = UserHandle.getUserId(callingUid);
@@ -525,18 +526,18 @@
                     String.format("uid %s cannot get secrets for account %s", callingUid, account);
             throw new SecurityException(msg);
         }
-        return getUidsAndVisibilityForAccount(account, accounts);
+        return getPackagesAndVisibilityForAccount(account, accounts);
     }
 
     /**
-     * Returns all UIDs and visibility values, which were set for given account
+     * Returns all package names and visibility values, which were set for given account.
      *
-     * @param account account
+     * @param account Account to get visibility values.
      * @param accounts UserAccount that currently hosts the account and application
      *
-     * @return Map from uid to visibility.
+     * @return Map from package names to visibility.
      */
-    private Map<Integer, Integer> getUidsAndVisibilityForAccount(Account account,
+    private Map<String, Integer> getPackagesAndVisibilityForAccount(Account account,
             UserAccounts accounts) {
         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
         try {
@@ -548,7 +549,7 @@
     }
 
     @Override
-    public int getAccountVisibility(Account a, int uid) {
+    public int getAccountVisibility(Account a, String packageName) {
         if (a == null) throw new IllegalArgumentException("account is null");
         int callingUid = Binder.getCallingUid();
         if (!isAccountManagedByCaller(a.type, callingUid, UserHandle.getUserId(callingUid))
@@ -559,23 +560,24 @@
                     a.type);
             throw new SecurityException(msg);
         }
-        return getAccountVisibility(a, uid, getUserAccounts(UserHandle.getUserId(callingUid)));
+        return getAccountVisibility(a, packageName,
+                getUserAccounts(UserHandle.getUserId(callingUid)));
     }
 
     /**
-     * Method gets visibility for given account and UID from the database
+     * Method returns visibility for given account and package name.
      *
-     * @param account The account to check visibility of
-     * @param uid UID to check visibility of
+     * @param account The account to check visibility.
+     * @param packageName Package name to check visibility.
      * @param accounts UserAccount that currently hosts the account and application
      *
      * @return Visibility value, AccountManager.VISIBILITY_UNDEFINED if no value was stored.
      *
      */
-    private int getAccountVisibility(Account account, int uid, UserAccounts accounts) {
+    private int getAccountVisibility(Account account, String packageName, UserAccounts accounts) {
         final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
         try {
-            Integer visibility = accounts.accountsDb.findAccountVisibility(account, uid);
+            Integer visibility = accounts.accountsDb.findAccountVisibility(account, packageName);
             return visibility != null ? visibility : AccountManager.VISIBILITY_UNDEFINED;
         } finally {
             StrictMode.setThreadPolicy(oldPolicy);
@@ -586,19 +588,29 @@
      * Method which handles default values for Account visibility.
      *
      * @param account The account to check visibility.
-     * @param uid UID to check visibility.
-     * @param packageName Package name to check visibility - the method assumes that it has the same
-     *        uid as specified in the parameter.
+     * @param packageName Package name to check visibility
      * @param accounts UserAccount that currently hosts the account and application
      *
      * @return Visibility value, the method never returns AccountManager.VISIBILITY_UNDEFINED
      *
      */
-    private Integer resolveAccountVisibility(Account account, int uid, String packageName,
+    private Integer resolveAccountVisibility(Account account, @NonNull String packageName,
             UserAccounts accounts) {
-        if (packageName == null) {
-            packageName = getPackageNameForUid(uid);
+        Preconditions.checkNotNull(packageName, "packageName cannot be null");
+
+        int uid = -1;
+        try {
+            long identityToken = clearCallingIdentity();
+            try {
+                uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
+            } finally {
+                restoreCallingIdentity(identityToken);
+            }
+        } catch (NameNotFoundException e) {
+            Log.d(TAG, "Package not found " + e.getMessage());
+            return AccountManager.VISIBILITY_NOT_VISIBLE;
         }
+
         // System visibility can not be restricted.
         if (UserHandle.isSameApp(uid, Process.SYSTEM_UID)) {
             return AccountManager.VISIBILITY_VISIBLE;
@@ -612,8 +624,13 @@
             return AccountManager.VISIBILITY_VISIBLE; // Authenticator can always see the account
         }
 
+        if (isSpecialPackageKey(packageName)) {
+            Log.d(TAG, "Package name is forbidden: " + packageName);
+            return AccountManager.VISIBILITY_NOT_VISIBLE;
+        }
+
         // Return stored value if it was set.
-        int visibility = getAccountVisibility(account, uid, accounts);
+        int visibility = getAccountVisibility(account, packageName, accounts);
 
         if (AccountManager.VISIBILITY_UNDEFINED != visibility) {
             return visibility;
@@ -622,10 +639,9 @@
         if (isPermittedForPackage(packageName, accounts.userId,
                 Manifest.permission.GET_ACCOUNTS_PRIVILEGED)) {
             return AccountManager.VISIBILITY_VISIBLE;
-
         }
         // Profile owner gets visibility by default.
-        if(isProfileOwner(uid)) {
+        if (isProfileOwner(uid)) {
             return AccountManager.VISIBILITY_VISIBLE;
         }
         // Apps with READ_CONTACTS permission get visibility by default even post O.
@@ -638,13 +654,13 @@
             // Use legacy for preO apps with GET_ACCOUNTS permission or pre/postO with signature
             // match.
             visibility = getAccountVisibility(account,
-                    AccountManager.UID_KEY_DEFAULT_LEGACY_VISIBILITY, accounts);
+                    AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE, accounts);
             if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
                 visibility = AccountManager.VISIBILITY_USER_MANAGED_VISIBLE;
             }
         } else {
-            visibility = getAccountVisibility(account, AccountManager.UID_KEY_DEFAULT_VISIBILITY,
-                    accounts);
+            visibility = getAccountVisibility(account,
+                    AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE, accounts);
             if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
                 visibility = AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE;
             }
@@ -655,7 +671,7 @@
     /**
      * Checks targetSdk for a package;
      *
-     * @param packageName Package Name
+     * @param packageName Package name
      *
      * @return True if package's target SDK is below {@link android.os.Build.VERSION_CODES#O}, or
      *         undefined
@@ -682,7 +698,7 @@
     }
 
     @Override
-    public boolean setAccountVisibility(Account a, int uid, int newVisibility) {
+    public boolean setAccountVisibility(Account a, String packageName, int newVisibility) {
         if (a == null) throw new IllegalArgumentException("account is null");
         int callingUid = Binder.getCallingUid();
         if (!isAccountManagedByCaller(a.type, callingUid, UserHandle.getUserId(callingUid))
@@ -693,38 +709,42 @@
                     a.type);
             throw new SecurityException(msg);
         }
-        return setAccountVisibility(a, uid, newVisibility, true /* notify */,
+        return setAccountVisibility(a, packageName, newVisibility, true /* notify */,
                 getUserAccounts(UserHandle.getUserId(callingUid)));
     }
 
     /**
-     * Gives a certain UID, represented a application, access to an account. This method
-     * is called indirectly by the Authenticator.
+     * Updates visibility for given account name and package.
      *
-     * @param account Account to update visibility
-     * @param uid to add visibility of the Account
-     * @param newVisibility new visibility
+     * @param account Account to update visibility.
+     * @param packageName Package name for which visibility is updated.
+     * @param newVisibility New visibility calue
      * @param notify if the flag is set applications will get notification about visibility change
      * @param accounts UserAccount that currently hosts the account and application
      *
      * @return True if account visibility was changed.
      */
-    private boolean setAccountVisibility(Account account, int uid, int newVisibility,
+    private boolean setAccountVisibility(Account account, String packageName, int newVisibility,
             boolean notify, UserAccounts accounts) {
         synchronized (accounts.cacheLock) {
             LinkedHashSet<String> interestedPackages;
             if (notify) {
-                if (uid < 0) {
+                if (isSpecialPackageKey(packageName)) {
                     interestedPackages = getRequestingPackageNames(account.type, accounts);
                 } else {
-                    interestedPackages = new LinkedHashSet<>();
-                    String[] subPackages = mPackageManager.getPackagesForUid(uid);
-                    if (subPackages != null) {
-                        Collections.addAll(interestedPackages, subPackages);
+                    if (!packageExistsForUser(packageName, accounts.userId)) {
+                        return false; // package is not installed.
                     }
+                    interestedPackages = new LinkedHashSet<>();
+                    interestedPackages.add(packageName);
                 }
             } else {
                 // Notifications will not be send.
+                if (!isSpecialPackageKey(packageName) &&
+                        !packageExistsForUser(packageName, accounts.userId)) {
+                    // package is not installed and not meta value.
+                    return false;
+                }
                 interestedPackages = new LinkedHashSet<>();
             }
             Integer[] interestedPackagesVisibility = new Integer[interestedPackages.size()];
@@ -734,14 +754,15 @@
                 return false;
             }
             int index = 0;
-            for (String packageName : interestedPackages) {
+            for (String interestedPackage : interestedPackages) {
                 interestedPackagesVisibility[index++] =
-                        resolveAccountVisibility(account, uid, packageName, accounts);
+                        resolveAccountVisibility(account, interestedPackage, accounts);
             }
 
             final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
             try {
-                if (!accounts.accountsDb.setAccountVisibility(accountId, uid, newVisibility)) {
+                if (!accounts.accountsDb.setAccountVisibility(accountId, packageName,
+                        newVisibility)) {
                     return false;
                 }
             } finally {
@@ -749,10 +770,10 @@
             }
 
             index = 0;
-            for (String packageName : interestedPackages) {
-                int visibility = resolveAccountVisibility(account, uid, packageName, accounts);
+            for (String interestedPackage : interestedPackages) {
+                int visibility = resolveAccountVisibility(account, interestedPackage, accounts);
                 if (visibility != interestedPackagesVisibility[index++]) {
-                        sendNotification(packageName, account, accounts.userId);
+                        sendNotification(interestedPackage, account, accounts.userId);
                 }
             }
             if (notify) {
@@ -777,23 +798,40 @@
         LinkedHashSet<String> interestedPackages = getRequestingPackageNames(account.type,
                 accounts);
         for (String packageName : interestedPackages) {
-            try {
-                final int uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
-                int visibility = resolveAccountVisibility(account, uid, packageName, accounts);
-                if (visibility != AccountManager.VISIBILITY_NOT_VISIBLE) {
-                    sendNotification(packageName, account, accounts.userId);
-                }
-            } catch (NameNotFoundException e) {
-                // ignore
+            int visibility = resolveAccountVisibility(account, packageName, accounts);
+            if (visibility != AccountManager.VISIBILITY_NOT_VISIBLE) {
+                sendNotification(packageName, account, accounts.userId);
             }
         }
     }
 
-    LinkedHashSet<String> getRequestingPackageNames(String accountType, UserAccounts accouns) {
+    LinkedHashSet<String> getRequestingPackageNames(String accountType, UserAccounts accounts) {
         // TODO return packages registered to get notifications.
         return new LinkedHashSet<String>();
     }
 
+    private boolean packageExistsForUser(String packageName, int userId) {
+        try {
+            long identityToken = clearCallingIdentity();
+            try {
+                mPackageManager.getPackageUidAsUser(packageName, userId);
+                return true; // package exist
+            } finally {
+                restoreCallingIdentity(identityToken);
+            }
+        } catch (NameNotFoundException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Returns true if packageName is one of special values.
+     */
+    private boolean isSpecialPackageKey(String packageName) {
+        return (AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE.equals(packageName)
+                || AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE.equals(packageName));
+    }
+
     private void sendAccountsChangedBroadcast(int userId) {
         Log.i(TAG, "the accounts changed, sending broadcast of "
                 + ACCOUNTS_CHANGED_INTENT.getAction());
@@ -1075,6 +1113,20 @@
         }
     }
 
+    private void removeVisibilityValuesForPackage(String packageName) {
+        synchronized (mUsers) {
+          for (int i = 0; i < mUsers.size(); i++) {
+              UserAccounts accounts = mUsers.valueAt(i);
+              try {
+                  int uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
+              } catch (NameNotFoundException e) {
+                  // package does not exist - remove visibility values
+                  accounts.accountsDb.deleteAccountVisibilityForPackage(packageName);
+              }
+          }
+        }
+    }
+
     private void onUserRemoved(Intent intent) {
         int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
         if (userId < 1) return;
@@ -1472,7 +1524,7 @@
     }
 
     private boolean addAccountInternal(UserAccounts accounts, Account account, String password,
-            Bundle extras, int callingUid, Map<Integer, Integer> uidToVisibility) {
+            Bundle extras, int callingUid, Map<String, Integer> packageToVisibility) {
         Bundle.setDefusable(extras, true);
         if (account == null) {
             return false;
@@ -1513,9 +1565,9 @@
                     }
                 }
 
-                if (uidToVisibility != null) {
-                    for (Entry<Integer, Integer> entry : uidToVisibility.entrySet()) {
-                        setAccountVisibility(account, entry.getKey() /* uid */,
+                if (packageToVisibility != null) {
+                    for (Entry<String, Integer> entry : packageToVisibility.entrySet()) {
+                        setAccountVisibility(account, entry.getKey() /* package */,
                                 entry.getValue() /* visibility */, false /* notify */, accounts);
                     }
                 }
@@ -1569,6 +1621,7 @@
     public void hasFeatures(IAccountManagerResponse response,
             Account account, String[] features, String opPackageName) {
         int callingUid = Binder.getCallingUid();
+        mAppOpsManager.checkPackage(callingUid, opPackageName);
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "hasFeatures: " + account
                     + ", response " + response
@@ -1982,14 +2035,7 @@
             int[] visibilityForInterestedPackages = new int[interestedPackages.size()];
             int index = 0;
             for (String packageName : interestedPackages) {
-                int visibility = AccountManager.VISIBILITY_NOT_VISIBLE;
-                try {
-                    final int uid = mPackageManager.getPackageUidAsUser(packageName,
-                            UserHandle.getUserId(callingUid));
-                    visibility = resolveAccountVisibility(account, uid, packageName, accounts);
-                } catch (NameNotFoundException e) {
-                    // ignore
-                }
+                int visibility = resolveAccountVisibility(account, packageName, accounts);
                 visibilityForInterestedPackages[index++] = visibility;
             }
             accounts.accountsDb.beginTransaction();
@@ -3663,7 +3709,7 @@
         // In addition to the permissions required to get an auth token we also allow
         // the account to be accessed by apps for which user or authenticator granted visibility.
 
-        int visibility = resolveAccountVisibility(account, uid, packageName,
+        int visibility = resolveAccountVisibility(account, packageName,
                 getUserAccounts(UserHandle.getUserId(uid)));
         return (visibility == AccountManager.VISIBILITY_VISIBLE
                 || visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
@@ -3870,6 +3916,7 @@
     @NonNull
     public Account[] getAccounts(int userId, String opPackageName) {
         int callingUid = Binder.getCallingUid();
+        mAppOpsManager.checkPackage(callingUid, opPackageName);
         List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId,
                 opPackageName);
         if (visibleAccountTypes.isEmpty()) {
@@ -3890,7 +3937,7 @@
     }
 
     /**
-     * Returns accounts for all running users.
+     * Returns accounts for all running users, ignores visibility values.
      *
      * @hide
      */
@@ -3906,7 +3953,11 @@
         return getAccounts(runningUserIds);
     }
 
-    /** {@hide} */
+    /**
+     * Returns accounts for all users, ignores visibility values.
+     *
+     * @hide
+     */
     @NonNull
     public AccountAndUser[] getAllAccounts() {
         final List<UserInfo> users = getUserManager().getUsers(true);
@@ -3924,10 +3975,12 @@
             UserAccounts userAccounts = getUserAccounts(userId);
             if (userAccounts == null) continue;
             synchronized (userAccounts.cacheLock) {
-                Account[] accounts = getAccountsFromCacheLocked(userAccounts, null,
+                Account[] accounts = getAccountsFromCacheLocked(
+                        userAccounts,
+                        null /* type */,
                         Binder.getCallingUid(),
-                        null,
-                        false /* incl managed not visible*/);
+                        null /* packageName */,
+                        false /* include managed not visible*/);
                 for (int a = 0; a < accounts.length; a++) {
                     runningAccounts.add(new AccountAndUser(accounts[a], userId));
                 }
@@ -3941,9 +3994,10 @@
     @Override
     @NonNull
     public Account[] getAccountsAsUser(String type, int userId, String opPackageName) {
-        // Need calling package
-        return getAccountsAsUser(type, userId, null /* callingPackage */, -1, opPackageName,
-               false /* includeUserManagedNotVisible */);
+        int callingUid = Binder.getCallingUid();
+        mAppOpsManager.checkPackage(callingUid, opPackageName);
+        return getAccountsAsUser(type, userId, opPackageName /* callingPackage */, -1,
+                opPackageName, false /* includeUserManagedNotVisible */);
     }
 
     @NonNull
@@ -4112,6 +4166,7 @@
     public Account[] getAccountsForPackage(String packageName, int uid, String opPackageName) {
         int callingUid = Binder.getCallingUid();
         if (!UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)) {
+            // Don't do opPackageName check - caller is system.
             throw new SecurityException("getAccountsForPackage() called from unauthorized uid "
                     + callingUid + " with uid=" + uid);
         }
@@ -4125,6 +4180,7 @@
             String opPackageName) {
         int callingUid =  Binder.getCallingUid();
         int userId = UserHandle.getCallingUserId();
+        mAppOpsManager.checkPackage(callingUid, opPackageName);
         int packageUid = -1;
         try {
             packageUid = mPackageManager.getPackageUidAsUser(packageName, userId);
@@ -4148,6 +4204,7 @@
             String[] features,
             String opPackageName) {
         int callingUid = Binder.getCallingUid();
+        mAppOpsManager.checkPackage(callingUid, opPackageName);
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "getAccounts: accountType " + type
                     + ", response " + response
@@ -4738,7 +4795,7 @@
                 userAccounts.accountsDb.dumpDeAccountsTable(fout);
             } else {
                 Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */,
-                        Process.SYSTEM_UID, null, false);
+                        Process.SYSTEM_UID, null /* packageName */, false);
                 fout.println("Accounts: " + accounts.length);
                 for (Account account : accounts) {
                     fout.println("  " + account);
@@ -4954,7 +5011,7 @@
 
     // Method checks visibility for applications targeing API level below {@link
     // android.os.Build.VERSION_CODES#O},
-    // returns true if the the app has GET_ACCOUNTS or GET_ACCOUNTS_PRIVELEGED permission.
+    // returns true if the the app has GET_ACCOUNTS or GET_ACCOUNTS_PRIVILEGED permission.
     private boolean checkGetAccountsPermission(String packageName, int userId) {
         return isPermittedForPackage(packageName, userId, Manifest.permission.GET_ACCOUNTS,
                 Manifest.permission.GET_ACCOUNTS_PRIVILEGED);
@@ -5307,8 +5364,7 @@
         // filter based on visibility.
         Map<Account, Integer> firstPass = new HashMap<>();
         for (Account account : unfiltered) {
-            int visibility =
-                    resolveAccountVisibility(account, callingUid, callingPackage, accounts);
+            int visibility = resolveAccountVisibility(account, callingPackage, accounts);
             if ((visibility == AccountManager.VISIBILITY_VISIBLE
                     || visibility == AccountManager.VISIBILITY_USER_MANAGED_VISIBLE)
                     || (includeManagedNotVisible
@@ -5403,6 +5459,9 @@
      */
     protected Account[] getAccountsFromCacheLocked(UserAccounts userAccounts, String accountType,
             int callingUid, String callingPackage, boolean includeManagedNotVisible) {
+        if (callingPackage == null) {
+            callingPackage = getPackageNameForUid(callingUid);
+        }
         if (accountType != null) {
             final Account[] accounts = userAccounts.accountCache.get(accountType);
             if (accounts == null) {
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 85e4b5f..22543cb 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -54,7 +54,7 @@
     private static final String DATABASE_NAME = "accounts.db";
     private static final int PRE_N_DATABASE_VERSION = 9;
     private static final int CE_DATABASE_VERSION = 10;
-    private static final int DE_DATABASE_VERSION = 2; // Added visibility support in O.
+    private static final int DE_DATABASE_VERSION = 3; // Added visibility support in O
 
 
     static final String TABLE_ACCOUNTS = "accounts";
@@ -75,7 +75,7 @@
 
     private static final String TABLE_VISIBILITY = "visibility";
     private static final String VISIBILITY_ACCOUNTS_ID = "accounts_id";
-    private static final String VISIBILITY_UID = "_uid";
+    private static final String VISIBILITY_PACKAGE = "_package";
     private static final String VISIBILITY_VALUE = "value";
 
     private static final String TABLE_GRANTS = "grants";
@@ -252,7 +252,7 @@
                 createAccountsDeletionTrigger(db);
                 db.execSQL("DROP TABLE IF EXISTS " + TABLE_GRANTS);
                 db.execSQL("DROP TABLE IF EXISTS " + TABLE_DEBUG);
-                oldVersion ++;
+                oldVersion++;
             }
 
             if (oldVersion != newVersion) {
@@ -559,9 +559,9 @@
         private void createAccountsVisibilityTable(SQLiteDatabase db) {
             db.execSQL("CREATE TABLE " + TABLE_VISIBILITY + " ( "
                   + VISIBILITY_ACCOUNTS_ID + " INTEGER NOT NULL, "
-                  + VISIBILITY_UID + " TEXT NOT NULL, "
+                  + VISIBILITY_PACKAGE + " TEXT NOT NULL, "
                   + VISIBILITY_VALUE + " INTEGER, "
-                  + "PRIMARY KEY(" + VISIBILITY_ACCOUNTS_ID + "," + VISIBILITY_UID + "))");
+                  + "PRIMARY KEY(" + VISIBILITY_ACCOUNTS_ID + "," + VISIBILITY_PACKAGE + "))");
         }
 
         static void createDebugTable(SQLiteDatabase db) {
@@ -591,9 +591,18 @@
             Log.i(TAG, "upgrade from version " + oldVersion + " to version " + newVersion);
 
             if (oldVersion == 1) {
-              createAccountsVisibilityTable(db);
-              createAccountsDeletionVisibilityCleanupTrigger(db);
-              ++oldVersion;
+                createAccountsVisibilityTable(db);
+                createAccountsDeletionVisibilityCleanupTrigger(db);
+                oldVersion = 3; // skip version 2 which had uid based table
+            }
+
+            if (oldVersion == 2) {
+                // Remove uid based table and replace it with packageName based
+                db.execSQL("DROP TRIGGER IF EXISTS " + TABLE_ACCOUNTS + "DeleteVisibility");
+                db.execSQL("DROP TABLE IF EXISTS " + TABLE_VISIBILITY);
+                createAccountsVisibilityTable(db);
+                createAccountsDeletionVisibilityCleanupTrigger(db);
+                oldVersion++;
             }
 
             if (oldVersion != newVersion) {
@@ -890,20 +899,20 @@
                 new String[] {Integer.toString(uid)}) > 0;
     }
 
-    boolean setAccountVisibility(long accountId, int uid, int visibility) {
+    boolean setAccountVisibility(long accountId, String packageName, int visibility) {
         SQLiteDatabase db = mDeDatabase.getWritableDatabase();
         ContentValues values = new ContentValues();
         values.put(VISIBILITY_ACCOUNTS_ID, String.valueOf(accountId));
-        values.put(VISIBILITY_UID, String.valueOf(uid));
+        values.put(VISIBILITY_PACKAGE, packageName);
         values.put(VISIBILITY_VALUE, String.valueOf(visibility));
         return (db.replace(TABLE_VISIBILITY, VISIBILITY_VALUE, values) != -1);
     }
 
-    Integer findAccountVisibility(Account account, int uid) {
+    Integer findAccountVisibility(Account account, String packageName) {
         SQLiteDatabase db = mDeDatabase.getWritableDatabase();
         final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE},
-                SELECTION_ACCOUNTS_ID_BY_ACCOUNT + " AND " + VISIBILITY_UID + "=? ",
-                new String[] {account.name, account.type, String.valueOf(uid)}, null, null, null);
+                SELECTION_ACCOUNTS_ID_BY_ACCOUNT + " AND " + VISIBILITY_PACKAGE + "=? ",
+                new String[] {account.name, account.type, packageName}, null, null, null);
         try {
             while (cursor.moveToNext()) {
                 return cursor.getInt(0);
@@ -914,11 +923,11 @@
         return null;
     }
 
-    Integer findAccountVisibility(long accountId, int uid) {
+    Integer findAccountVisibility(long accountId, String packageName) {
         SQLiteDatabase db = mDeDatabase.getWritableDatabase();
         final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE},
-                VISIBILITY_ACCOUNTS_ID + "=? AND " + VISIBILITY_UID + "=? ",
-                new String[] {String.valueOf(accountId), String.valueOf(uid)}, null, null, null);
+                VISIBILITY_ACCOUNTS_ID + "=? AND " + VISIBILITY_PACKAGE + "=? ",
+                new String[] {String.valueOf(accountId), packageName}, null, null, null);
         try {
             while (cursor.moveToNext()) {
                 return cursor.getInt(0);
@@ -944,18 +953,18 @@
     }
 
     /**
-     * Returns a map from uid to visibility value.
+     * Returns a map from packageNames to visibility.
      */
-    Map<Integer, Integer> findAllVisibilityValuesForAccount(Account account) {
+    Map<String, Integer> findAllVisibilityValuesForAccount(Account account) {
         SQLiteDatabase db = mDeDatabase.getReadableDatabase();
-        Map<Integer, Integer> result = new HashMap<>();
+        Map<String, Integer> result = new HashMap<>();
         final Cursor cursor =
-                db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_UID, VISIBILITY_VALUE},
-                        SELECTION_ACCOUNTS_ID_BY_ACCOUNT,
-                        new String[] {account.name, account.type}, null, null, null);
+                db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_PACKAGE, VISIBILITY_VALUE},
+                        SELECTION_ACCOUNTS_ID_BY_ACCOUNT, new String[] {account.name, account.type},
+                        null, null, null);
         try {
             while (cursor.moveToNext()) {
-                result.put(cursor.getInt(0), cursor.getInt(1));
+                result.put(cursor.getString(0), cursor.getInt(1));
             }
         } finally {
             cursor.close();
@@ -963,10 +972,10 @@
         return result;
     }
 
-    boolean deleteAccountVisibilityForUid(int uid) {
+    boolean deleteAccountVisibilityForPackage(String packageName) {
         SQLiteDatabase db = mDeDatabase.getWritableDatabase();
-        return db.delete(TABLE_VISIBILITY, VISIBILITY_UID + "=? ",
-                new String[] {Integer.toString(uid)}) > 0;
+        return db.delete(TABLE_VISIBILITY, VISIBILITY_PACKAGE + "=? ",
+                new String[] {packageName}) > 0;
     }
 
     long insertOrReplaceMetaAuthTypeAndUid(String authenticatorType, int uid) {
diff --git a/services/core/java/com/android/server/am/ActiveInstrumentation.java b/services/core/java/com/android/server/am/ActiveInstrumentation.java
new file mode 100644
index 0000000..84e4ea9
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActiveInstrumentation.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.app.IInstrumentationWatcher;
+import android.app.IUiAutomationConnection;
+import android.content.ComponentName;
+import android.content.pm.ApplicationInfo;
+import android.os.Bundle;
+import android.util.PrintWriterPrinter;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class ActiveInstrumentation {
+    final ActivityManagerService mService;
+
+    // Class installed to instrument app
+    ComponentName mClass;
+
+    // All process names that should be instrumented
+    String[] mTargetProcesses;
+
+    // The application being instrumented
+    ApplicationInfo mTargetInfo;
+
+    // Where to save profiling
+    String mProfileFile;
+
+    // Who is waiting
+    IInstrumentationWatcher mWatcher;
+
+    // Connection to use the UI introspection APIs.
+    IUiAutomationConnection mUiAutomationConnection;
+
+    // As given to us
+    Bundle mArguments;
+
+    // Any intermediate results that have been collected.
+    Bundle mCurResults;
+
+    // Copy of instrumentationClass.
+    ComponentName mResultClass;
+
+    // Contains all running processes that have active instrumentation.
+    final ArrayList<ProcessRecord> mRunningProcesses = new ArrayList<>();
+
+    // Set to true when we have told the watcher the instrumentation is finished.
+    boolean mFinished;
+
+    ActiveInstrumentation(ActivityManagerService service) {
+        mService = service;
+    }
+
+    void removeProcess(ProcessRecord proc) {
+        mFinished = true;
+        mRunningProcesses.remove(proc);
+        if (mRunningProcesses.size() == 0) {
+            mService.mActiveInstrumentation.remove(this);
+        }
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder(128);
+        sb.append("ActiveInstrumentation{");
+        sb.append(Integer.toHexString(System.identityHashCode(this)));
+        sb.append(' ');
+        sb.append(mClass.toShortString());
+        if (mFinished) {
+            sb.append(" FINISHED");
+        }
+        sb.append(" ");
+        sb.append(mRunningProcesses.size());
+        sb.append(" procs");
+        sb.append('}');
+        return sb.toString();
+    }
+
+    void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.print("mClass="); pw.print(mClass);
+        pw.print(" mFinished="); pw.println(mFinished);
+        pw.print(prefix); pw.println("mRunningProcesses:");
+        for (int i=0; i<mRunningProcesses.size(); i++) {
+            pw.print(prefix); pw.print("  #"); pw.print(i); pw.print(": ");
+            pw.println(mRunningProcesses.get(i));
+        }
+        pw.print(prefix); pw.print("mTargetProcesses=");
+        pw.println(Arrays.toString(mTargetProcesses));
+        pw.print(prefix); pw.print("mTargetInfo=");
+        pw.println(mTargetInfo);
+        if (mTargetInfo != null) {
+            mTargetInfo.dump(new PrintWriterPrinter(pw), prefix + "  ", 0);
+        }
+        if (mProfileFile != null) {
+            pw.print(prefix); pw.print("mProfileFile="); pw.println(mProfileFile);
+        }
+        if (mWatcher != null) {
+            pw.print(prefix); pw.print("mWatcher="); pw.println(mWatcher);
+        }
+        if (mUiAutomationConnection != null) {
+            pw.print(prefix); pw.print("mUiAutomationConnection=");
+            pw.println(mUiAutomationConnection);
+        }
+        pw.print(prefix); pw.print("mArguments=");
+        pw.println(mArguments);
+    }
+}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 5655dc5..041fee2 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -16,6 +16,8 @@
 
 package com.android.server.am;
 
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
 import static com.android.server.am.ActivityManagerDebugConfig.*;
 
 import java.io.FileDescriptor;
@@ -1391,8 +1393,7 @@
         }
         if (r != null) {
             if (mAm.checkComponentPermission(r.permission,
-                    callingPid, callingUid, r.appInfo.uid, r.exported)
-                    != PackageManager.PERMISSION_GRANTED) {
+                    callingPid, callingUid, r.appInfo.uid, r.exported) != PERMISSION_GRANTED) {
                 if (!r.exported) {
                     Slog.w(TAG, "Permission Denial: Accessing service " + r.name
                             + " from pid=" + callingPid
@@ -2775,16 +2776,15 @@
         return info;
     }
 
-    List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum, int flags) {
+    List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum, int flags,
+        int callingUid, boolean allowed) {
         ArrayList<ActivityManager.RunningServiceInfo> res
                 = new ArrayList<ActivityManager.RunningServiceInfo>();
 
-        final int uid = Binder.getCallingUid();
         final long ident = Binder.clearCallingIdentity();
         try {
-            if (ActivityManager.checkUidPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    uid) == PackageManager.PERMISSION_GRANTED) {
+            if (ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, callingUid)
+                == PERMISSION_GRANTED) {
                 int[] users = mAm.mUserController.getUsers();
                 for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
                     ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(users[ui]);
@@ -2802,16 +2802,20 @@
                     res.add(info);
                 }
             } else {
-                int userId = UserHandle.getUserId(uid);
+                int userId = UserHandle.getUserId(callingUid);
                 ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(userId);
                 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
                     ServiceRecord sr = alls.valueAt(i);
-                    res.add(makeRunningServiceInfoLocked(sr));
+
+                    if (allowed || (sr.app != null && sr.app.uid == callingUid)) {
+                        res.add(makeRunningServiceInfoLocked(sr));
+                    }
                 }
 
                 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
                     ServiceRecord r = mRestartingServices.get(i);
-                    if (r.userId == userId) {
+                    if (r.userId == userId
+                        && (allowed || (r.app != null && r.app.uid == callingUid))) {
                         ActivityManager.RunningServiceInfo info =
                                 makeRunningServiceInfoLocked(r);
                         info.restarting = r.nextRestartTime;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ee1f28f..d75048d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -573,7 +573,9 @@
 
     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
 
-    public IntentFirewall mIntentFirewall;
+    final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
+
+    public final IntentFirewall mIntentFirewall;
 
     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
     // default action automatically.  Important for devices without direct input
@@ -3926,7 +3928,7 @@
             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                     aInfo.applicationInfo.uid, true);
-            if (app == null || app.instrumentationClass == null) {
+            if (app == null || app.instr == null) {
                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
             }
@@ -5092,9 +5094,9 @@
 
         app.activities.clear();
 
-        if (app.instrumentationClass != null) {
+        if (app.instr != null) {
             Slog.w(TAG, "Crash of app " + app.processName
-                  + " running instrumentation " + app.instrumentationClass);
+                  + " running instrumentation " + app.instr.mClass);
             Bundle info = new Bundle();
             info.putString("shortMsg", "Process crashed.");
             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
@@ -5227,7 +5229,7 @@
         // Clean up already done if the process has been re-started.
         if (app.pid == pid && app.thread != null &&
                 app.thread.asBinder() == thread.asBinder()) {
-            boolean doLowMem = app.instrumentationClass == null;
+            boolean doLowMem = app.instr == null;
             boolean doOomAdj = doLowMem;
             if (!app.killedByAm) {
                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
@@ -6383,7 +6385,7 @@
             handleAppDiedLocked(app, willRestart, allowRestart);
             if (willRestart) {
                 removeLruProcessLocked(app);
-                addAppLocked(app.info, false, null /* ABI override */);
+                addAppLocked(app.info, null, false, null /* ABI override */);
             }
         } else {
             mRemovedProcesses.add(app);
@@ -6559,7 +6561,7 @@
                     mWaitForDebugger = mOrigWaitForDebugger;
                 }
             }
-            String profileFile = app.instrumentationProfileFile;
+            String profileFile = app.instr != null ? app.instr.mProfileFile : null;
             ParcelFileDescriptor profileFd = null;
             int samplingInterval = 0;
             boolean profileAutoStop = false;
@@ -6587,14 +6589,13 @@
                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
             }
 
-            if (app.instrumentationClass != null) {
-                notifyPackageUse(app.instrumentationClass.getPackageName(),
+            if (app.instr != null) {
+                notifyPackageUse(app.instr.mClass.getPackageName(),
                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
             }
             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
                     + processName + " with config " + getGlobalConfiguration());
-            ApplicationInfo appInfo = app.instrumentationInfo != null
-                    ? app.instrumentationInfo : app.info;
+            ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
             app.compat = compatibilityInfoForPackageLocked(appInfo);
             if (profileFd != null) {
                 profileFd = profileFd.dup();
@@ -6614,16 +6615,57 @@
                         .getSerial();
 //            }
 
+            // Check if this is a secondary process that should be incorporated into some
+            // currently active instrumentation.  (Note we do this AFTER all of the profiling
+            // stuff above because profiling can currently happen only in the primary
+            // instrumentation process.)
+            if (mActiveInstrumentation.size() > 0 && app.instr == null) {
+                for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
+                    ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
+                    if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
+                        if (aInstr.mTargetProcesses.length == 0) {
+                            // This is the wildcard mode, where every process brought up for
+                            // the target instrumentation should be included.
+                            if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
+                                app.instr = aInstr;
+                                aInstr.mRunningProcesses.add(app);
+                            }
+                        } else {
+                            for (String proc : aInstr.mTargetProcesses) {
+                                if (proc.equals(app.processName)) {
+                                    app.instr = aInstr;
+                                    aInstr.mRunningProcesses.add(app);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
-            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
-                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
-                    app.instrumentationUiAutomationConnection, testMode,
-                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
-                    isRestrictedBackupMode || !normalMode, app.persistent,
-                    new Configuration(getGlobalConfiguration()), app.compat,
-                    getCommonServicesLocked(app.isolated),
-                    mCoreSettingsObserver.getCoreSettingsLocked(),
-                    buildSerial);
+            if (app.instr != null) {
+                thread.bindApplication(processName, appInfo, providers,
+                        app.instr.mClass,
+                        profilerInfo, app.instr.mArguments,
+                        app.instr.mWatcher,
+                        app.instr.mUiAutomationConnection, testMode,
+                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
+                        isRestrictedBackupMode || !normalMode, app.persistent,
+                        new Configuration(getGlobalConfiguration()), app.compat,
+                        getCommonServicesLocked(app.isolated),
+                        mCoreSettingsObserver.getCoreSettingsLocked(),
+                        buildSerial);
+            } else {
+                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
+                        null, null, null, testMode,
+                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
+                        isRestrictedBackupMode || !normalMode, app.persistent,
+                        new Configuration(getGlobalConfiguration()), app.compat,
+                        getCommonServicesLocked(app.isolated),
+                        mCoreSettingsObserver.getCoreSettingsLocked(),
+                        buildSerial);
+            }
 
             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
             updateLruProcessLocked(app, false, null);
@@ -11595,7 +11637,7 @@
                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
                 for (ApplicationInfo app : apps) {
                     if (!"android".equals(app.packageName)) {
-                        addAppLocked(app, false, null /* ABI override */);
+                        addAppLocked(app, null, false, null /* ABI override */);
                     }
                 }
             } catch (RemoteException ex) {
@@ -11783,17 +11825,18 @@
         return false;
     }
 
-    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
+    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
             String abiOverride) {
         ProcessRecord app;
         if (!isolated) {
-            app = getProcessRecordLocked(info.processName, info.uid, true);
+            app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
+                    info.uid, true);
         } else {
             app = null;
         }
 
         if (app == null) {
-            app = newProcessRecordLocked(info, null, isolated, 0);
+            app = newProcessRecordLocked(info, customProcess, isolated, 0);
             updateLruProcessLocked(app, false, null);
             updateOomAdjLocked();
         }
@@ -11814,7 +11857,8 @@
         }
         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
             mPersistentStartingProcesses.add(app);
-            startProcessLocked(app, "added application", app.processName, abiOverride,
+            startProcessLocked(app, "added application",
+                    customProcess != null ? customProcess : app.processName, abiOverride,
                     null /* entryPoint */, null /* entryPointArgs */);
         }
 
@@ -12269,11 +12313,11 @@
         synchronized (this) {
             synchronized (mPidsSelfLocked) {
                 final int callingPid = Binder.getCallingPid();
-                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
-                if (precessRecord == null) {
+                ProcessRecord proc = mPidsSelfLocked.get(callingPid);
+                if (proc == null) {
                     throw new SecurityException("Unknown process: " + callingPid);
                 }
-                if (precessRecord.instrumentationUiAutomationConnection  == null) {
+                if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
                     throw new SecurityException("Only an instrumentation process "
                             + "with a UiAutomation can call setUserIsMonkey");
                 }
@@ -12330,7 +12374,7 @@
     }
 
     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
-        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
+        if (r != null && (r.instr != null || r.usingWrapper)) {
             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
         }
         return KEY_DISPATCHING_TIMEOUT;
@@ -12391,7 +12435,7 @@
                     return false;
                 }
 
-                if (proc.instrumentationClass != null) {
+                if (proc.instr != null) {
                     Bundle info = new Bundle();
                     info.putString("shortMsg", "keyDispatchingTimedOut");
                     info.putString("longMsg", annotation);
@@ -14901,8 +14945,31 @@
                     printed = true;
                     needSep = true;
                 }
-                pw.println(String.format("%sIsolated #%2d: %s",
-                        "    ", i, r.toString()));
+                pw.print("    Isolated #"); pw.print(i); pw.print(": ");
+                pw.println(r);
+            }
+        }
+
+        if (mActiveInstrumentation.size() > 0) {
+            boolean printed = false;
+            for (int i=0; i<mActiveInstrumentation.size(); i++) {
+                ActiveInstrumentation ai = mActiveInstrumentation.get(i);
+                if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
+                        && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
+                    continue;
+                }
+                if (!printed) {
+                    if (needSep) {
+                        pw.println();
+                    }
+                    pw.println("  Active instrumentation:");
+                    printedAnything = true;
+                    printed = true;
+                    needSep = true;
+                }
+                pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
+                pw.println(ai);
+                ai.dump(pw, "      ");
             }
         }
 
@@ -17400,7 +17467,11 @@
             int flags) {
         enforceNotIsolatedCaller("getServices");
         synchronized (this) {
-            return mServices.getRunningServiceInfoLocked(maxNum, flags);
+            final int callingUid = Binder.getCallingUid();
+            final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
+                callingUid);
+
+            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, allowed);
         }
     }
 
@@ -19046,18 +19117,35 @@
                 throw new SecurityException(msg);
             }
 
+            ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
+            activeInstr.mClass = className;
+            String defProcess = ai.processName;;
+            if (ii.targetProcess == null) {
+                activeInstr.mTargetProcesses = new String[]{ai.processName};
+            } else if (ii.targetProcess.equals("*")) {
+                activeInstr.mTargetProcesses = new String[0];
+            } else {
+                activeInstr.mTargetProcesses = ii.targetProcess.split(",");
+                defProcess = activeInstr.mTargetProcesses[0];
+            }
+            activeInstr.mTargetInfo = ai;
+            activeInstr.mProfileFile = profileFile;
+            activeInstr.mArguments = arguments;
+            activeInstr.mWatcher = watcher;
+            activeInstr.mUiAutomationConnection = uiAutomationConnection;
+            activeInstr.mResultClass = className;
+
             final long origId = Binder.clearCallingIdentity();
             // Instrumentation can kill and relaunch even persistent processes
             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
                     "start instr");
-            ProcessRecord app = addAppLocked(ai, false, abiOverride);
-            app.instrumentationClass = className;
-            app.instrumentationInfo = ai;
-            app.instrumentationProfileFile = profileFile;
-            app.instrumentationArguments = arguments;
-            app.instrumentationWatcher = watcher;
-            app.instrumentationUiAutomationConnection = uiAutomationConnection;
-            app.instrumentationResultClass = className;
+            ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
+            app.instr = activeInstr;
+            activeInstr.mFinished = false;
+            activeInstr.mRunningProcesses.add(app);
+            if (!mActiveInstrumentation.contains(activeInstr)) {
+                mActiveInstrumentation.add(activeInstr);
+            }
             Binder.restoreCallingIdentity(origId);
         }
 
@@ -19084,24 +19172,70 @@
         }
     }
 
+    void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
+        if (app.instr == null) {
+            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
+            return;
+        }
+
+        if (!app.instr.mFinished && results != null) {
+            if (app.instr.mCurResults == null) {
+                app.instr.mCurResults = new Bundle(results);
+            } else {
+                app.instr.mCurResults.putAll(results);
+            }
+        }
+    }
+
+    public void addInstrumentationResults(IApplicationThread target, Bundle results) {
+        int userId = UserHandle.getCallingUserId();
+        // Refuse possible leaked file descriptors
+        if (results != null && results.hasFileDescriptors()) {
+            throw new IllegalArgumentException("File descriptors passed in Intent");
+        }
+
+        synchronized(this) {
+            ProcessRecord app = getRecordForAppLocked(target);
+            if (app == null) {
+                Slog.w(TAG, "addInstrumentationResults: no app for " + target);
+                return;
+            }
+            final long origId = Binder.clearCallingIdentity();
+            addInstrumentationResultsLocked(app, results);
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
-        if (app.instrumentationWatcher != null) {
-            mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
-                    app.instrumentationClass, resultCode, results);
+        if (app.instr == null) {
+            Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
+            return;
         }
 
-        // Can't call out of the system process with a lock held, so post a message.
-        if (app.instrumentationUiAutomationConnection != null) {
-            mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
-                    app.instrumentationUiAutomationConnection).sendToTarget();
+        if (!app.instr.mFinished) {
+            if (app.instr.mWatcher != null) {
+                Bundle finalResults = app.instr.mCurResults;
+                if (finalResults != null) {
+                    if (app.instr.mCurResults != null && results != null) {
+                        finalResults.putAll(results);
+                    }
+                } else {
+                    finalResults = results;
+                }
+                mInstrumentationReporter.reportFinished(app.instr.mWatcher,
+                        app.instr.mClass, resultCode, finalResults);
+            }
+
+            // Can't call out of the system process with a lock held, so post a message.
+            if (app.instr.mUiAutomationConnection != null) {
+                mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
+                        app.instr.mUiAutomationConnection).sendToTarget();
+            }
+            app.instr.mFinished = true;
         }
 
-        app.instrumentationWatcher = null;
-        app.instrumentationUiAutomationConnection = null;
-        app.instrumentationClass = null;
-        app.instrumentationInfo = null;
-        app.instrumentationProfileFile = null;
-        app.instrumentationArguments = null;
+        app.instr.removeProcess(app);
+        app.instr = null;
 
         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
                 "finished inst");
@@ -19884,7 +20018,7 @@
             app.adjType = "top-activity";
             foregroundActivities = true;
             procState = PROCESS_STATE_CUR_TOP;
-        } else if (app.instrumentationClass != null) {
+        } else if (app.instr != null) {
             // Don't want to kill running instrumentation.
             adj = ProcessList.FOREGROUND_APP_ADJ;
             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
@@ -21973,7 +22107,7 @@
                     mRemovedProcesses.remove(i);
 
                     if (app.persistent) {
-                        addAppLocked(app.info, false, null /* ABI override */);
+                        addAppLocked(app.info, null, false, null /* ABI override */);
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 962056f..58c17eb 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -30,6 +30,7 @@
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
 import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
+import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
 import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
 import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
 import static android.content.pm.ActivityInfo.FLAG_IMMERSIVE;
@@ -37,12 +38,17 @@
 import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
 import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
 import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
 import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
 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.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 com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
@@ -77,6 +83,7 @@
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.IBinder;
@@ -773,7 +780,10 @@
 
         // Remove the activity from the old task and add it to the new task
         prevTask.removeActivity(this);
-        setTask(newTask, null);
+        // TODO(b/34179495): This should really be set to null in removeActivity() call above,
+        // but really bad things that I can't track down right now happen when I do that.
+        // So, setting it here now and will change later when there is time for investigation.
+        task = null;
         newTask.addActivityAtIndex(position, this);
     }
 
@@ -821,19 +831,8 @@
         }
     }
 
-    void setTask(TaskRecord newTask, TaskRecord taskToAffiliateWith) {
-        if (task != null && task.removeActivity(this) && task != newTask
-                && task.getStack() != null) {
-            task.getStack().removeTask(task, "setTask");
-        }
-        task = newTask;
-        setTaskToAffiliateWith(taskToAffiliateWith);
-    }
-
     void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
-        if (taskToAffiliateWith != null &&
-                launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE &&
-                launchMode != ActivityInfo.LAUNCH_SINGLE_TASK) {
+        if (launchMode != LAUNCH_SINGLE_INSTANCE && launchMode != LAUNCH_SINGLE_TASK) {
             task.setTaskToAffiliateWith(taskToAffiliateWith);
         }
     }
@@ -2013,7 +2012,8 @@
                         + ", newGlobalConfig=" + newGlobalConfig
                         + ", newTaskMergedOverrideConfig=" + newTaskMergedOverrideConfig);
 
-        if ((changes&(~info.getRealConfigChanged())) != 0 || forceNewConfig) {
+        if (shouldRelaunchLocked(changes, newGlobalConfig, newTaskMergedOverrideConfig)
+                || forceNewConfig) {
             // Aha, the activity isn't handling the change, so DIE DIE DIE.
             configChangeFlags |= changes;
             startFreezingScreenLocked(app, globalChanges);
@@ -2064,6 +2064,27 @@
         return true;
     }
 
+    /**
+     * When assessing a configuration change, decide if the changes flags and the new configurations
+     * should cause the Activity to relaunch.
+     */
+    private boolean shouldRelaunchLocked(int changes, Configuration newGlobalConfig,
+            Configuration newTaskMergedOverrideConfig) {
+        int configChanged = info.getRealConfigChanged();
+
+        // Override for apps targeting pre-O sdks
+        // If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
+        // to the config change.
+        // For O and later, apps will be required to add configChanges="uimode" to their manifest.
+        if (appInfo.targetSdkVersion < O
+                && requestedVrComponent != null
+                && (isInVrUiMode(newGlobalConfig) || isInVrUiMode(newTaskMergedOverrideConfig))) {
+            configChanged |= CONFIG_UI_MODE;
+        }
+
+        return (changes&(~configChanged)) != 0;
+    }
+
     private static int getTaskConfigurationChanges(ActivityRecord record, Configuration taskConfig,
             Configuration oldTaskOverride) {
         // If we went from full-screen to non-full-screen, make sure to use the correct
@@ -2300,6 +2321,10 @@
         }
     }
 
+    private static boolean isInVrUiMode(Configuration config) {
+        return (config.uiMode & Configuration.UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
+    }
+
     @Override
     public String toString() {
         if (stringName != null) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 54082ea..ba25120 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1554,38 +1554,6 @@
         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
         final int focusedStackId = focusedStack.mStackId;
 
-        final TaskRecord topFocusedTask = focusedStack.topTask();
-        final boolean isOnTopLauncherFocused = topFocusedTask != null &&
-                topFocusedTask.isOnTopLauncher();
-        if (isOnTopLauncherFocused) {
-            // When an on-top launcher is focused, we should find out whether the freeform stack or
-            // the fullscreen stack appears first underneath and has activities to show, and then
-            // make it visible.
-            boolean behindFullscreenOrFreeForm = false;
-            for (int stackBehindFocusedIndex = mStacks.indexOf(focusedStack) - 1;
-                 stackBehindFocusedIndex >= 0; stackBehindFocusedIndex--) {
-                ActivityStack stack = mStacks.get(stackBehindFocusedIndex);
-                if ((stack.mStackId == FREEFORM_WORKSPACE_STACK_ID
-                        || stack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID)
-                        && stack.topRunningActivityLocked() != null) {
-                    if (stackIndex == stackBehindFocusedIndex) {
-                        return !behindFullscreenOrFreeForm ? STACK_VISIBLE : STACK_INVISIBLE;
-                    }
-                    behindFullscreenOrFreeForm = true;
-                }
-            }
-        }
-        // If an on-top launcher is on the top of the home stack but the home stack is not focused,
-        // then the whole stack should be invisible.
-        TaskRecord topTask = topTask();
-        if (mStackId != focusedStackId && topTask != null && topTask.isOnTopLauncher()) {
-            // We're here mostly because the on-top launcher didn't have a chance to move itself to
-            // back. We should move it to back as soon as possible to avoid other activities
-            // returning to it or other visibility issues.
-            moveTaskToBackLocked(topTask.taskId);
-            return STACK_INVISIBLE;
-        }
-
         if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID
                 && hasVisibleBehindActivity() && StackId.isHomeOrRecentsStack(focusedStackId)
                 && !focusedStack.topActivity().fullscreen) {
@@ -1790,28 +1758,7 @@
                     // status of an activity in a previous task affects other.
                     behindFullscreenActivity = stackVisibility == STACK_INVISIBLE;
                 } else if (mStackId == HOME_STACK_ID) {
-                    if (task.isOnTopLauncher()) {
-                        if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "On-top launcher: at " + task
-                                + " stackInvisible=" + stackInvisible
-                                + " behindFullscreenActivity=" + behindFullscreenActivity);
-                        // When an on-top launcher is visible, (e.g. it's on the top of the home stack),
-                        // other tasks in the home stack could be visible if and only if:
-                        // - some app is running in the docked stack;
-                        // - no app is running in either the fullscreen stack or the freefrom stack.
-                        final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
-                        final ActivityStack fullscreenStack = mStackSupervisor.getStack(
-                                FULLSCREEN_WORKSPACE_STACK_ID);
-                        final ActivityStack freeformStack = mStackSupervisor.getStack(
-                                FREEFORM_WORKSPACE_STACK_ID);
-                        final boolean dockedStackEmpty = dockedStack == null ||
-                                dockedStack.topRunningActivityLocked() == null;
-                        final boolean fullscreenStackEmpty = fullscreenStack == null ||
-                                fullscreenStack.topRunningActivityLocked() == null;
-                        final boolean freeformStackEmpty = freeformStack == null ||
-                                freeformStack.topRunningActivityLocked() == null;
-                        behindFullscreenActivity = dockedStackEmpty || !fullscreenStackEmpty ||
-                                !freeformStackEmpty;
-                    } else if (task.isHomeTask()) {
+                    if (task.isHomeTask()) {
                         if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Home task: at " + task
                                 + " stackInvisible=" + stackInvisible
                                 + " behindFullscreenActivity=" + behindFullscreenActivity);
@@ -2699,14 +2646,7 @@
             ActivityStack lastStack = mStackSupervisor.getLastStack();
             final boolean fromHomeOrRecents = lastStack.isHomeOrRecentsStack();
             final TaskRecord topTask = lastStack.topTask();
-            final boolean fromOnTopLauncher = topTask != null && topTask.isOnTopLauncher();
-            if (fromOnTopLauncher) {
-                // Since an on-top launcher will is moved to back when tasks are launched from it,
-                // those tasks should first try to return to a non-home activity.
-                // This also makes sure that non-home activities are visible under a transparent
-                // non-home activity.
-                task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
-            } else if (!isHomeOrRecentsStack() && (fromHomeOrRecents || topTask() != task)) {
+            if (!isHomeOrRecentsStack() && (fromHomeOrRecents || topTask() != task)) {
                 // If it's a last task over home - we default to keep its return to type not to
                 // make underlying task focused when this one will be finished.
                 int returnToType = isLastTaskOverHome
@@ -2775,7 +2715,12 @@
         // Slot the activity into the history stack and proceed
         if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
                 new RuntimeException("here").fillInStackTrace());
-        r.createWindowContainer();
+        // TODO: Need to investigate if it is okay for the controller to already be created by the
+        // time we get to this point. I think it is, but need to double check.
+        // Use test in b/34179495 to trace the call path.
+        if (r.getWindowContainerController() == null) {
+            r.createWindowContainer();
+        }
         task.setFrontOfTask();
 
         if (!isHomeOrRecentsStack() || numActivities() > 0) {
@@ -2952,8 +2897,7 @@
                             + targetTask + " Callers=" + Debug.getCallers(4));
                     if (DEBUG_TASKS) Slog.v(TAG_TASKS,
                             "Pushing next activity " + p + " out to target's task " + target.task);
-                    p.setTask(targetTask, null);
-                    targetTask.addActivityAtBottom(p);
+                    p.reparent(targetTask, 0 /* position - bottom */, "resetTargetTaskIfNeeded");
                 }
 
                 mWindowContainerController.positionChildAtBottom(
@@ -4400,23 +4344,6 @@
         if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
 
         if (mStackId == HOME_STACK_ID && topTask().isHomeTask()) {
-            if (topTask().isOnTopLauncher()) {
-                // An on-top launcher doesn't affect the visibility of activities on other stacks
-                // behind it. So if we're moving an on-top launcher to the back, we want to move the
-                // focus to the next focusable stack and resume an activity there.
-                // Besides, when the docked stack is visible, we should also move the home stack to
-                // the back to avoid the recents pops up on top of a fullscreen or freeform
-                // activity.
-
-                // Move the home stack to back.
-                moveToBack(topTask());
-
-                // Resume an activity in the next focusable stack.
-                adjustFocusToNextFocusableStackLocked("moveTaskToBack");
-                mStackSupervisor.resumeFocusedStackTopActivityLocked();
-                return true;
-            }
-
             // For the case where we are moving the home task back and there is an activity visible
             // behind it on the fullscreen stack, we want to move the focus to the visible behind
             // activity to maintain order with what the user is seeing.
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 73ef88b..d1606b4 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1498,15 +1498,7 @@
 
     private void updateTaskReturnToType(
             TaskRecord task, int launchFlags, ActivityStack focusedStack) {
-        if (focusedStack != null && focusedStack.isHomeOrRecentsStack()
-                && focusedStack.topTask() != null && focusedStack.topTask().isOnTopLauncher()) {
-            // Since an on-top launcher will is moved to back when tasks are launched from it,
-            // those tasks should first try to return to a non-home activity.
-            // This also makes sure that non-home activities are visible under a transparent
-            // non-home activity.
-            task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
-            return;
-        } else if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
+        if ((launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
                 == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
             // Caller wants to appear on home activity.
             task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
@@ -1615,7 +1607,7 @@
                     mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
                     mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
                     mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity.mActivityType);
-            mStartActivity.setTask(task, taskToAffiliate);
+            addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
             if (mLaunchBounds != null) {
                 final int stackId = mTargetStack.mStackId;
                 if (StackId.resizeStackWithLaunchBounds(stackId)) {
@@ -1625,11 +1617,14 @@
                     mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
                 }
             }
-            if (DEBUG_TASKS) Slog.v(TAG_TASKS,
-                    "Starting new activity " +
-                            mStartActivity + " in new task " + mStartActivity.task);
+            if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+                    + " in new task " + mStartActivity.task);
         } else {
-            mStartActivity.setTask(mReuseTask, taskToAffiliate);
+            addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
+        }
+
+        if (taskToAffiliate != null) {
+            mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
         }
 
         if (mSupervisor.isLockTaskModeViolation(mStartActivity.task)) {
@@ -1719,7 +1714,7 @@
 
         // An existing activity is starting this new activity, so we want to keep the new one in
         // the same task as the one that is starting it.
-        mStartActivity.setTask(sourceTask, null);
+        addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
         if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
                 + " in existing task " + mStartActivity.task + " from source " + mSourceRecord);
         return START_SUCCESS;
@@ -1752,7 +1747,8 @@
         // Check whether we should actually launch the new activity in to the task,
         // or just reuse the current activity on top.
         ActivityRecord top = mInTask.getTopActivity();
-        if (top != null && top.realActivity.equals(mStartActivity.realActivity) && top.userId == mStartActivity.userId) {
+        if (top != null && top.realActivity.equals(mStartActivity.realActivity)
+                && top.userId == mStartActivity.userId) {
             if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                     || mLaunchSingleTop || mLaunchSingleTask) {
                 ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
@@ -1761,7 +1757,8 @@
                     // anything if that is the case, so this is it!
                     return START_RETURN_INTENT_TO_CALLER;
                 }
-                top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
+                top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
+                        mStartActivity.launchedFromPackage);
                 return START_DELIVERED_TO_TOP;
             }
         }
@@ -1773,9 +1770,9 @@
             return START_TASK_TO_FRONT;
         }
 
-        mStartActivity.setTask(mInTask, null);
-        if (DEBUG_TASKS) Slog.v(TAG_TASKS,
-                "Starting new activity " + mStartActivity + " in explicit task " + mStartActivity.task);
+        addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
+        if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+                + " in explicit task " + mStartActivity.task);
 
         return START_SUCCESS;
     }
@@ -1790,10 +1787,18 @@
         final TaskRecord task = (prev != null) ? prev.task : mTargetStack.createTaskRecord(
                 mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
                 mIntent, null, null, true, mStartActivity.mActivityType);
-        mStartActivity.setTask(task, null);
-        mStartActivity.task.getStack().positionChildWindowContainerAtTop(mStartActivity.task);
-        if (DEBUG_TASKS) Slog.v(TAG_TASKS,
-                "Starting new activity " + mStartActivity + " in new guessed " + mStartActivity.task);
+        addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
+        mTargetStack.positionChildWindowContainerAtTop(task);
+        if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+                + " in new guessed " + mStartActivity.task);
+    }
+
+    private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
+        if (mStartActivity.task == null || mStartActivity.task == parent) {
+            parent.addActivityToTop(mStartActivity);
+        } else {
+            mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
+        }
     }
 
     private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 384f2f8..36a913f 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -357,7 +357,7 @@
              * If this process was running instrumentation, finish now - it will be handled in
              * {@link ActivityManagerService#handleAppDiedLocked}.
              */
-            if (r != null && r.instrumentationClass != null) {
+            if (r != null && r.instr != null) {
                 return;
             }
 
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index f1f8bb2..3571302 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -51,8 +51,8 @@
 import android.telephony.TelephonyManager;
 import android.util.IntArray;
 import android.util.Slog;
-
 import android.util.TimeUtils;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.BatteryStatsHelper;
@@ -1127,6 +1127,7 @@
         pw.println("      full-history: include additional detailed events in battery history:");
         pw.println("          wake_lock_in, alarms and proc events");
         pw.println("      no-auto-reset: don't automatically reset stats when unplugged");
+        pw.println("      pretend-screen-off: pretend the screen is off, even if screen state changes");
     }
 
     private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
@@ -1144,6 +1145,10 @@
             synchronized (mStats) {
                 mStats.setNoAutoReset(enable);
             }
+        } else if ("pretend-screen-off".equals(args[i])) {
+            synchronized (mStats) {
+                mStats.setPretendScreenOff(enable);
+            }
         } else {
             pw.println("Unknown enable/disable option: " + args[i]);
             dumpHelp(pw);
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 49fe79c..356781f 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -135,13 +135,7 @@
     int lruSeq;                 // Sequence id for identifying LRU update cycles
     CompatibilityInfo compat;   // last used compatibility mode
     IBinder.DeathRecipient deathRecipient; // Who is watching for the death.
-    ComponentName instrumentationClass;// class installed to instrument app
-    ApplicationInfo instrumentationInfo; // the application being instrumented
-    String instrumentationProfileFile; // where to save profiling
-    IInstrumentationWatcher instrumentationWatcher; // who is waiting
-    IUiAutomationConnection instrumentationUiAutomationConnection; // Connection to use the UI introspection APIs.
-    Bundle instrumentationArguments;// as given to us
-    ComponentName instrumentationResultClass;// copy of instrumentationClass
+    ActiveInstrumentation instr;// Set to currently active instrumentation running in process
     boolean usingWrapper;       // Set to true when process was launched with a wrapper attached
     final ArraySet<BroadcastRecord> curReceivers = new ArraySet<BroadcastRecord>();// receivers currently running in the app
     long lastWakeTime;          // How long proc held wake lock at last check
@@ -248,19 +242,8 @@
             pw.println("}");
         }
         pw.print(prefix); pw.print("compat="); pw.println(compat);
-        if (instrumentationClass != null || instrumentationProfileFile != null
-                || instrumentationArguments != null) {
-            pw.print(prefix); pw.print("instrumentationClass=");
-                    pw.print(instrumentationClass);
-                    pw.print(" instrumentationProfileFile=");
-                    pw.println(instrumentationProfileFile);
-            pw.print(prefix); pw.print("instrumentationArguments=");
-                    pw.println(instrumentationArguments);
-            pw.print(prefix); pw.print("instrumentationInfo=");
-                    pw.println(instrumentationInfo);
-            if (instrumentationInfo != null) {
-                instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + "  ");
-            }
+        if (instr != null) {
+            pw.print(prefix); pw.print("instr="); pw.println(instr);
         }
         pw.print(prefix); pw.print("thread="); pw.println(thread);
         pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index fef4073..e237e41 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -51,6 +51,7 @@
 import com.android.internal.app.IVoiceInteractor;
 import com.android.internal.util.XmlUtils;
 
+import com.android.server.wm.AppWindowContainerController;
 import com.android.server.wm.TaskWindowContainerController;
 import com.android.server.wm.TaskWindowContainerListener;
 
@@ -74,7 +75,6 @@
 import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
-import static android.content.pm.ActivityInfo.FLAG_ON_TOP_LAUNCHER;
 import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_ALWAYS;
 import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
@@ -190,17 +190,15 @@
 
     int mResizeMode;        // The resize mode of this task and its activities.
                             // Based on the {@link ActivityInfo#resizeMode} of the root activity.
-    boolean mSupportsPictureInPicture;  // Whether or not this task and its activities support PiP.
-            // Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag of the root
-            // activity.
+    private boolean mSupportsPictureInPicture;  // Whether or not this task and its activities
+            // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
+            // of the root activity.
     boolean mTemporarilyUnresizable; // Separate flag from mResizeMode used to suppress resize
                                      // changes on a temporary basis.
     private int mLockTaskMode;  // Which tasklock mode to launch this task in. One of
                                 // ActivityManager.LOCK_TASK_LAUNCH_MODE_*
     private boolean mPrivileged;    // The root activity application of this task holds
                                     // privileged permissions.
-    private boolean mIsOnTopLauncher; // Whether this task is an on-top launcher. See
-                                      // android.R.attr#onTopLauncher.
 
     /** Can't be put in lockTask mode. */
     final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
@@ -423,8 +421,8 @@
         final Configuration overrideConfig = getOverrideConfiguration();
         mWindowContainerController = new TaskWindowContainerController(taskId, this,
                 getStack().getWindowContainerController(), userId, bounds, overrideConfig,
-                mResizeMode, mSupportsPictureInPicture, isHomeTask(), isOnTopLauncher(),
-                onTop, showForAllUsers, lastTaskDescription);
+                mResizeMode, mSupportsPictureInPicture, isHomeTask(), onTop, showForAllUsers,
+                lastTaskDescription);
     }
 
     void removeWindowContainer() {
@@ -687,7 +685,6 @@
         }
         mResizeMode = info.resizeMode;
         mSupportsPictureInPicture = info.supportsPictureInPicture();
-        mIsOnTopLauncher = (info.flags & FLAG_ON_TOP_LAUNCHER) != 0;
         mLockTaskMode = info.lockTaskLaunchMode;
         mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
         setLockTaskAuth();
@@ -1033,6 +1030,12 @@
      * be in the current task or unparented to any task.
      */
     void addActivityAtIndex(int index, ActivityRecord r) {
+        if (r.task != null && r.task != this) {
+            throw new IllegalArgumentException("Can not add r=" + " to task=" + this
+                    + " current parent=" + r.task);
+        }
+        r.task = this;
+
         // Remove r first, and if it wasn't already in the list and it's fullscreen, count it.
         if (!mActivities.remove(r) && r.fullscreen) {
             // Was not previously in list.
@@ -1063,6 +1066,7 @@
             }
         }
 
+        index = Math.min(size, index);
         mActivities.add(index, r);
         updateEffectiveIntent();
         if (r.isPersistable()) {
@@ -1071,7 +1075,12 @@
 
         // Sync. with window manager
         updateOverrideConfigurationFromLaunchBounds();
-        mWindowContainerController.positionChildAt(r.getWindowContainerController(), index);
+        final AppWindowContainerController appController = r.getWindowContainerController();
+        if (appController != null) {
+            // Only attempt to move in WM if the child has a controller. It is possible we haven't
+            // created controller for the activity we are starting yet.
+            mWindowContainerController.positionChildAt(appController, index);
+        }
         r.onOverrideConfigurationSent();
     }
 
@@ -1322,7 +1331,7 @@
      * @param bounds The bounds to be tested.
      * @return True if the requested bounds are okay for a resizing request.
      */
-    boolean canResizeToBounds(Rect bounds) {
+    private boolean canResizeToBounds(Rect bounds) {
         if (bounds == null || getStackId() != FREEFORM_WORKSPACE_STACK_ID) {
             // Note: If not on the freeform workspace, we ignore the bounds.
             return true;
@@ -1335,10 +1344,6 @@
                 && (mResizeMode != RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY || landscape);
     }
 
-    boolean isOnTopLauncher() {
-        return isHomeTask() && mIsOnTopLauncher;
-    }
-
     /**
      * Find the activity in the history stack within the given task.  Returns
      * the index within the history at which it's found, or < 0 if not found.
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index ef792b0..1d60946 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5933,7 +5933,7 @@
         final AccessibilityManager accessibilityManager =
                 (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
         updateDefaultStreamOverrideDelay(accessibilityManager.isTouchExplorationEnabled());
-        updateA11yVolumeAlias(accessibilityManager.isEnabled());
+        updateA11yVolumeAlias(accessibilityManager.isAccessibilityVolumeStreamActive());
         accessibilityManager.addTouchExplorationStateChangeListener(this);
         accessibilityManager.addAccessibilityServicesStateChangeListener(this);
     }
@@ -6066,6 +6066,7 @@
         pw.print("  mSafeMediaVolumeState=");
         pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState));
         pw.print("  mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex);
+        pw.print("  sIndependentA11yVolume="); pw.println(sIndependentA11yVolume);
         pw.print("  mPendingVolumeCommand="); pw.println(mPendingVolumeCommand);
         pw.print("  mMusicActiveMs="); pw.println(mMusicActiveMs);
         pw.print("  mMcc="); pw.println(mMcc);
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 816d5fe..4930c53 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -46,7 +46,7 @@
         implements AudioPlaybackConfiguration.PlayerDeathMonitor, PlayerFocusEnforcer {
 
     public final static String TAG = "AudioService.PlaybackActivityMonitor";
-    private final static boolean DEBUG = true;
+    private final static boolean DEBUG = false;
 
     private ArrayList<PlayMonitorClient> mClients = new ArrayList<PlayMonitorClient>();
     // a public client is one that needs an anonymized version of the playback configurations, we
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 08a3332..017c5fb 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -66,9 +66,9 @@
     public static final int EVENT_ON_LINKPROPERTIES = 3;
     public static final int EVENT_ON_LOST           = 4;
 
-    private static final int LISTEN_ALL = 1;
-    private static final int TRACK_DEFAULT = 2;
-    private static final int MOBILE_REQUEST = 3;
+    private static final int CALLBACK_LISTEN_ALL = 1;
+    private static final int CALLBACK_TRACK_DEFAULT = 2;
+    private static final int CALLBACK_MOBILE_REQUEST = 3;
 
     private final Context mContext;
     private final StateMachine mTarget;
@@ -98,10 +98,10 @@
 
         final NetworkRequest listenAllRequest = new NetworkRequest.Builder()
                 .clearCapabilities().build();
-        mListenAllCallback = new UpstreamNetworkCallback(LISTEN_ALL);
+        mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL);
         cm().registerNetworkCallback(listenAllRequest, mListenAllCallback);
 
-        mDefaultNetworkCallback = new UpstreamNetworkCallback(TRACK_DEFAULT);
+        mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_TRACK_DEFAULT);
         cm().registerDefaultNetworkCallback(mDefaultNetworkCallback);
     }
 
@@ -136,30 +136,25 @@
             return;
         }
 
-        final NetworkRequest.Builder builder = new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-        if (mDunRequired) {
-            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                   .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
-        } else {
-            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        }
-        final NetworkRequest mobileUpstreamRequest = builder.build();
+        // The following use of the legacy type system cannot be removed until
+        // after upstream selection no longer finds networks by legacy type.
+        // See also http://b/34364553 .
+        final int legacyType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI;
+
+        final NetworkRequest mobileUpstreamRequest = new NetworkRequest.Builder()
+                .setCapabilities(ConnectivityManager.networkCapabilitiesForType(legacyType))
+                .build();
 
         // The existing default network and DUN callbacks will be notified.
         // Therefore, to avoid duplicate notifications, we only register a no-op.
-        mMobileNetworkCallback = new UpstreamNetworkCallback(MOBILE_REQUEST);
+        mMobileNetworkCallback = new UpstreamNetworkCallback(CALLBACK_MOBILE_REQUEST);
 
         // TODO: Change the timeout from 0 (no onUnavailable callback) to some
         // moderate callback timeout. This might be useful for updating some UI.
         // Additionally, we log a message to aid in any subsequent debugging.
         Log.d(TAG, "requesting mobile upstream network: " + mobileUpstreamRequest);
 
-        // The following use of the legacy type system cannot be removed until
-        // after upstream selection no longer finds networks by legacy type.
-        // See also b/34364553.
-        final int apnType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI;
-        cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, apnType);
+        cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType);
     }
 
     public void releaseMobileNetworkRequest() {
@@ -184,17 +179,18 @@
         // Always request whatever extra information we can, in case this
         // was already up when start() was called, in which case we would
         // not have been notified of any information that had not changed.
-        final NetworkCallback cb =
-                (callbackType == TRACK_DEFAULT) ? mDefaultNetworkCallback :
-                (callbackType == MOBILE_REQUEST) ? mMobileNetworkCallback : null;
-        if (cb != null) {
-            final ConnectivityManager cm = cm();
-            cm.requestNetworkCapabilities(mDefaultNetworkCallback);
-            cm.requestLinkProperties(mDefaultNetworkCallback);
-        }
-
-        if (callbackType == TRACK_DEFAULT) {
-            mCurrentDefault = network;
+        switch (callbackType) {
+            case CALLBACK_LISTEN_ALL:
+                break;
+            case CALLBACK_TRACK_DEFAULT:
+                cm().requestNetworkCapabilities(mDefaultNetworkCallback);
+                cm().requestLinkProperties(mDefaultNetworkCallback);
+                mCurrentDefault = network;
+                break;
+            case CALLBACK_MOBILE_REQUEST:
+                cm().requestNetworkCapabilities(mMobileNetworkCallback);
+                cm().requestLinkProperties(mMobileNetworkCallback);
+                break;
         }
 
         // Requesting updates for mListenAllCallback is not currently possible
@@ -262,7 +258,7 @@
     }
 
     private void handleLost(int callbackType, Network network) {
-        if (callbackType == TRACK_DEFAULT) {
+        if (callbackType == CALLBACK_TRACK_DEFAULT) {
             mCurrentDefault = null;
             // Receiving onLost() for a default network does not necessarily
             // mean the network is gone.  We wait for a separate notification
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 3da49d8..168744b 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -18,9 +18,6 @@
 
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
-import com.android.server.twilight.TwilightListener;
-import com.android.server.twilight.TwilightManager;
-import com.android.server.twilight.TwilightState;
 
 import android.annotation.Nullable;
 import android.hardware.Sensor;
@@ -55,9 +52,6 @@
     // non-zero, which in turn ensures that the total weight is non-zero.
     private static final long AMBIENT_LIGHT_PREDICTION_TIME_MILLIS = 100;
 
-    // Specifies the maximum magnitude of the time of day adjustment.
-    private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1f;
-
     // Debounce for sampling user-initiated changes in display brightness to ensure
     // the user is satisfied with the result before storing the sample.
     private static final int BRIGHTNESS_ADJUSTMENT_SAMPLE_DEBOUNCE_MILLIS = 10000;
@@ -74,9 +68,6 @@
     // The light sensor, or null if not available or needed.
     private final Sensor mLightSensor;
 
-    // The twilight service.
-    private final TwilightManager mTwilight;
-
     // The auto-brightness spline adjustment.
     // The brightness values have been scaled to a range of 0..1.
     private final Spline mScreenAutoBrightnessSpline;
@@ -186,8 +177,6 @@
     private int mBrightnessAdjustmentSampleOldBrightness;
     private float mBrightnessAdjustmentSampleOldGamma;
 
-    private boolean mUseTwilight;
-
     public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
             SensorManager sensorManager, Spline autoBrightnessSpline, int lightSensorWarmUpTime,
             int brightnessMin, int brightnessMax, float dozeScaleFactor,
@@ -196,7 +185,6 @@
             int ambientLightHorizon, float autoBrightnessAdjustmentMaxGamma,
             HysteresisLevels dynamicHysteresis) {
         mCallbacks = callbacks;
-        mTwilight = LocalServices.getService(TwilightManager.class);
         mSensorManager = sensorManager;
         mScreenAutoBrightnessSpline = autoBrightnessSpline;
         mScreenBrightnessRangeMinimum = brightnessMin;
@@ -233,7 +221,7 @@
     }
 
     public void configure(boolean enable, float adjustment, boolean dozing,
-            boolean userInitiatedChange, boolean useTwilight) {
+            boolean userInitiatedChange) {
         // While dozing, the application processor may be suspended which will prevent us from
         // receiving new information from the light sensor. On some devices, we may be able to
         // switch to a wake-up light sensor instead but for now we will simply disable the sensor
@@ -242,7 +230,6 @@
         mDozing = dozing;
         boolean changed = setLightSensorEnabled(enable && !dozing);
         changed |= setScreenAutoBrightnessAdjustment(adjustment);
-        changed |= setUseTwilight(useTwilight);
         if (changed) {
             updateAutoBrightness(false /*sendUpdate*/);
         }
@@ -251,17 +238,6 @@
         }
     }
 
-    private boolean setUseTwilight(boolean useTwilight) {
-        if (mUseTwilight == useTwilight) return false;
-        if (useTwilight) {
-            mTwilight.registerListener(mTwilightListener, mHandler);
-        } else {
-            mTwilight.unregisterListener(mTwilightListener);
-        }
-        mUseTwilight = useTwilight;
-        return true;
-    }
-
     public void dump(PrintWriter pw) {
         pw.println();
         pw.println("Automatic Brightness Controller Configuration:");
@@ -276,7 +252,6 @@
         pw.println();
         pw.println("Automatic Brightness Controller State:");
         pw.println("  mLightSensor=" + mLightSensor);
-        pw.println("  mTwilight.getLastTwilightState()=" + mTwilight.getLastTwilightState());
         pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
         pw.println("  mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime));
         pw.println("  mAmbientLux=" + mAmbientLux);
@@ -522,19 +497,6 @@
             }
         }
 
-        if (mUseTwilight) {
-            TwilightState state = mTwilight.getLastTwilightState();
-            if (state != null && state.isNight()) {
-                final long duration = state.sunriseTimeMillis() - state.sunsetTimeMillis();
-                final long progress = System.currentTimeMillis() - state.sunsetTimeMillis();
-                final float amount = (float) Math.pow(2.0 * progress / duration - 1.0, 2.0);
-                gamma *= 1 + amount * TWILIGHT_ADJUSTMENT_MAX_GAMMA;
-                if (DEBUG) {
-                    Slog.d(TAG, "updateAutoBrightness: twilight amount=" + amount);
-                }
-            }
-        }
-
         if (gamma != 1.0f) {
             final float in = value;
             value = MathUtils.pow(value, gamma);
@@ -649,13 +611,6 @@
         }
     };
 
-    private final TwilightListener mTwilightListener = new TwilightListener() {
-        @Override
-        public void onTwilightStateChanged(@Nullable TwilightState state) {
-            updateAutoBrightness(true /*sendUpdate*/);
-        }
-    };
-
     /** Callbacks to request updates to the display's power state. */
     interface Callbacks {
         void updateBrightness();
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 015345c..bed269c 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -642,7 +642,7 @@
                     && mPowerRequest.brightnessSetByUser;
             mAutomaticBrightnessController.configure(autoBrightnessEnabled,
                     mPowerRequest.screenAutoBrightnessAdjustment, state != Display.STATE_ON,
-                    userInitiatedChange, mPowerRequest.useTwilight);
+                    userInitiatedChange);
         }
 
         // Apply brightness boost.
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index b089ba7..7cb223d 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -70,6 +70,8 @@
             ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
     /** Amount of time a job is allowed to execute for before being considered timed-out. */
     private static final long EXECUTING_TIMESLICE_MILLIS = 10 * 60 * 1000;  // 10mins.
+    /** Amount of time the JobScheduler waits for the initial service launch+bind. */
+    private static final long OP_BIND_TIMEOUT_MILLIS = 18 * 1000;
     /** Amount of time the JobScheduler will wait for a response from an app for a message. */
     private static final long OP_TIMEOUT_MILLIS = 8 * 1000;
 
@@ -645,8 +647,20 @@
     private void scheduleOpTimeOut() {
         removeOpTimeOut();
 
-        final long timeoutMillis = (mVerb == VERB_EXECUTING) ?
-                EXECUTING_TIMESLICE_MILLIS : OP_TIMEOUT_MILLIS;
+        final long timeoutMillis;
+        switch (mVerb) {
+            case VERB_EXECUTING:
+                timeoutMillis = EXECUTING_TIMESLICE_MILLIS;
+                break;
+
+            case VERB_BINDING:
+                timeoutMillis = OP_BIND_TIMEOUT_MILLIS;
+                break;
+
+            default:
+                timeoutMillis = OP_TIMEOUT_MILLIS;
+                break;
+        }
         if (DEBUG) {
             Slog.d(TAG, "Scheduling time out for '" +
                     mRunningJob.getServiceComponent().getShortClassName() + "' jId: " +
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index ede6e30..10ecb86 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -1123,6 +1123,38 @@
             }
         }
 
+        public void addQueueItem(MediaDescription description) {
+            try {
+                mCb.onAddQueueItem(description);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in addQueueItem.", e);
+            }
+        }
+
+        public void addQueueItemAt(MediaDescription description, int index) {
+            try {
+                mCb.onAddQueueItemAt(description, index);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in addQueueItemAt.", e);
+            }
+        }
+
+        public void removeQueueItem(MediaDescription description) {
+            try {
+                mCb.onRemoveQueueItem(description);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in removeQueueItem.", e);
+            }
+        }
+
+        public void removeQueueItemAt(int index) {
+            try {
+                mCb.onRemoveQueueItemAt(index);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in removeQueueItem.", e);
+            }
+        }
+
         public void adjustVolume(int direction) {
             try {
                 mCb.onAdjustVolume(direction);
@@ -1397,6 +1429,30 @@
         }
 
         @Override
+        public void addQueueItem(MediaDescription description) {
+            updateCallingPackage();
+            mSessionCb.addQueueItem(description);
+        }
+
+        @Override
+        public void addQueueItemAt(MediaDescription description, int index) {
+            updateCallingPackage();
+            mSessionCb.addQueueItemAt(description, index);
+        }
+
+        @Override
+        public void removeQueueItem(MediaDescription description) {
+            updateCallingPackage();
+            mSessionCb.removeQueueItem(description);
+        }
+
+        @Override
+        public void removeQueueItemAt(int index) {
+            updateCallingPackage();
+            mSessionCb.removeQueueItemAt(index);
+        }
+
+        @Override
         public CharSequence getQueueTitle() {
             return mQueueTitle;
         }
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 3bf95ef..98177fe 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -155,10 +155,10 @@
     }
 
     /**
-     * Tells the system UI that volume has changed on a remote session.
+     * Tells the system UI that volume has changed on an active remote session.
      */
     public void notifyRemoteVolumeChanged(int flags, MediaSessionRecord session) {
-        if (mRvc == null) {
+        if (mRvc == null || !session.isActive()) {
             return;
         }
         try {
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index 6f49df4..d6c89a4 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -31,6 +31,8 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 
+import com.android.internal.util.NotificationMessagingUtil;
+
 import java.util.Comparator;
 import java.util.Objects;
 
@@ -40,18 +42,15 @@
 public class NotificationComparator
         implements Comparator<NotificationRecord> {
 
-    private final String DEFAULT_SMS_APP_SETTING = Settings.Secure.SMS_DEFAULT_APPLICATION;
-
     private final Context mContext;
+    private final NotificationMessagingUtil mMessagingUtil;
     private String mDefaultPhoneApp;
-    private ArrayMap<Integer, String> mDefaultSmsApp = new ArrayMap<>();
 
     public NotificationComparator(Context context) {
         mContext = context;
         mContext.registerReceiver(mPhoneAppBroadcastReceiver,
                 new IntentFilter(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED));
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING), false, mSmsContentObserver);
+        mMessagingUtil = new NotificationMessagingUtil(mContext);
     }
 
     @Override
@@ -73,9 +72,15 @@
             return -1 * Boolean.compare(leftImportantOngoing, rightImportantOngoing);
         }
 
+        boolean leftMessaging = isImportantMessaging(left);
+        boolean rightMessaging = isImportantMessaging(right);
+        if (leftMessaging != rightMessaging) {
+            return -1 * Boolean.compare(leftMessaging, rightMessaging);
+        }
+
         // Next: sufficiently import person to person communication
-        boolean leftPeople = isImportantMessaging(left);
-        boolean rightPeople = isImportantMessaging(right);
+        boolean leftPeople = isImportantPeople(left);
+        boolean rightPeople = isImportantPeople(right);
 
         if (leftPeople && rightPeople){
             // by contact proximity, close to far. if same proximity, check further fields.
@@ -128,53 +133,33 @@
         if (record.getImportance() < NotificationManager.IMPORTANCE_LOW) {
             return false;
         }
-
         // TODO: add whitelist
 
         return isCall(record) || isMediaNotification(record);
     }
 
-    protected boolean isImportantMessaging(NotificationRecord record) {
+    protected boolean isImportantPeople(NotificationRecord record) {
         if (record.getImportance() < NotificationManager.IMPORTANCE_LOW) {
             return false;
         }
-
-        Class<? extends Notification.Style> style = getNotificationStyle(record);
-        if (Notification.MessagingStyle.class.equals(style)) {
-            return true;
-        }
-
         if (record.getContactAffinity() > ValidateNotificationPeople.NONE) {
             return true;
         }
-
-        if (record.getNotification().category == Notification.CATEGORY_MESSAGE
-                && isDefaultMessagingApp(record)) {
-            return true;
-        }
-
         return false;
     }
 
+    protected boolean isImportantMessaging(NotificationRecord record) {
+        return mMessagingUtil.isImportantMessaging(record.sbn, record.getImportance());
+    }
+
     private boolean isOngoing(NotificationRecord record) {
         final int ongoingFlags =
                 Notification.FLAG_FOREGROUND_SERVICE | Notification.FLAG_ONGOING_EVENT;
         return (record.getNotification().flags & ongoingFlags) != 0;
     }
 
-    private Class<? extends Notification.Style> getNotificationStyle(NotificationRecord record) {
-        String templateClass =
-                record.getNotification().extras.getString(Notification.EXTRA_TEMPLATE);
-
-        if (!TextUtils.isEmpty(templateClass)) {
-            return Notification.getNotificationStyleClass(templateClass);
-        }
-        return null;
-    }
-
     private boolean isMediaNotification(NotificationRecord record) {
-        return record.getNotification().extras.getParcelable(
-                Notification.EXTRA_MEDIA_SESSION) != null;
+        return record.getNotification().hasMediaSession();
     }
 
     private boolean isCall(NotificationRecord record) {
@@ -191,18 +176,6 @@
         return Objects.equals(pkg, mDefaultPhoneApp);
     }
 
-    @SuppressWarnings("deprecation")
-    private boolean isDefaultMessagingApp(NotificationRecord record) {
-        final int userId = record.getUserId();
-        if (userId == UserHandle.USER_NULL || userId == UserHandle.USER_ALL) return false;
-        if (mDefaultSmsApp.get(userId) == null) {
-            mDefaultSmsApp.put(userId, Settings.Secure.getStringForUser(
-                    mContext.getContentResolver(),
-                    Settings.Secure.SMS_DEFAULT_APPLICATION, userId));
-        }
-        return Objects.equals(mDefaultSmsApp.get(userId), record.sbn.getPackageName());
-    }
-
     private final BroadcastReceiver mPhoneAppBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -210,17 +183,4 @@
                     intent.getStringExtra(TelecomManager.EXTRA_CHANGE_DEFAULT_DIALER_PACKAGE_NAME);
         }
     };
-
-    private final ContentObserver mSmsContentObserver = new ContentObserver(
-            new Handler(Looper.getMainLooper())) {
-        @Override
-        public void onChange(boolean selfChange, Uri uri, int userId) {
-            if (Settings.Secure.getUriFor(DEFAULT_SMS_APP_SETTING).equals(uri)) {
-                mDefaultSmsApp.put(userId, Settings.Secure.getStringForUser(
-                        mContext.getContentResolver(),
-                        Settings.Secure.SMS_DEFAULT_APPLICATION, userId));
-
-            }
-        }
-    };
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 6f20f10..4207998 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -712,6 +712,7 @@
     // System configuration read by SystemConfig.
     final int[] mGlobalGids;
     final SparseArray<ArraySet<String>> mSystemPermissions;
+    @GuardedBy("mAvailableFeatures")
     final ArrayMap<String, FeatureInfo> mAvailableFeatures;
 
     // If mac_permissions.xml was found for seinfo labeling.
@@ -832,7 +833,6 @@
     private List<String> mKeepUninstalledPackages;
 
     private UserManagerInternal mUserManagerInternal;
-    private final UserDataPreparer mUserDataPreparer;
 
     private File mCacheDir;
 
@@ -1936,7 +1936,7 @@
 
                     // Clean up any users or apps that were removed or recreated
                     // while this volume was missing
-                    reconcileUsers(volumeUuid);
+                    sUserManager.reconcileUsers(volumeUuid);
                     reconcileApps(volumeUuid);
 
                     // Clean up any install sessions that expired or were
@@ -2160,19 +2160,24 @@
         if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
             SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
             // We will wait for up to 100 seconds.
-            final long timeEnd = SystemClock.uptimeMillis() + 100 * 1000;
+            final long timeStart = SystemClock.uptimeMillis();
+            final long timeEnd = timeStart + 100 * 1000;
+            long timeNow = timeStart;
             while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
                 try {
                     Thread.sleep(WAIT_TIME_MS);
                 } catch (InterruptedException e) {
                     // Do nothing
                 }
-                if (SystemClock.uptimeMillis() > timeEnd) {
+                timeNow = SystemClock.uptimeMillis();
+                if (timeNow > timeEnd) {
                     SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
                     Slog.wtf(TAG, "cppreopt did not finish!");
                     break;
                 }
             }
+
+            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
         }
     }
 
@@ -2264,8 +2269,8 @@
             mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
             mAsecInternalPath = new File(dataDir, "app-asec").getPath();
             mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
-            mUserDataPreparer = new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore);
-            sUserManager = new UserManagerService(context, this, mUserDataPreparer, mPackages);
+            sUserManager = new UserManagerService(context, this,
+                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
 
             // Propagate permission configuration in to package manager.
             ArrayMap<String, SystemConfig.PermissionEntry> permConfig
@@ -4215,21 +4220,22 @@
 
     @Override
     public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
-        synchronized (mPackages) {
-            final ArrayList<FeatureInfo> res = new ArrayList<>(mAvailableFeatures.values());
-
-            final FeatureInfo fi = new FeatureInfo();
-            fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
-                    FeatureInfo.GL_ES_VERSION_UNDEFINED);
-            res.add(fi);
-
-            return new ParceledListSlice<>(res);
+        ArrayList<FeatureInfo> res;
+        synchronized (mAvailableFeatures) {
+            res = new ArrayList<>(mAvailableFeatures.size() + 1);
+            res.addAll(mAvailableFeatures.values());
         }
+        final FeatureInfo fi = new FeatureInfo();
+        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
+                FeatureInfo.GL_ES_VERSION_UNDEFINED);
+        res.add(fi);
+
+        return new ParceledListSlice<>(res);
     }
 
     @Override
     public boolean hasSystemFeature(String name, int version) {
-        synchronized (mPackages) {
+        synchronized (mAvailableFeatures) {
             final FeatureInfo feat = mAvailableFeatures.get(name);
             if (feat == null) {
                 return false;
@@ -19964,7 +19970,7 @@
         });
 
         // Now that we're mostly running, clean up stale users and apps
-        reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
+        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
         reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
     }
 
@@ -20379,20 +20385,22 @@
                     pw.println("Features:");
                 }
 
-                for (FeatureInfo feat : mAvailableFeatures.values()) {
-                    if (checkin) {
-                        pw.print("feat,");
-                        pw.print(feat.name);
-                        pw.print(",");
-                        pw.println(feat.version);
-                    } else {
-                        pw.print("  ");
-                        pw.print(feat.name);
-                        if (feat.version > 0) {
-                            pw.print(" version=");
-                            pw.print(feat.version);
+                synchronized (mAvailableFeatures) {
+                    for (FeatureInfo feat : mAvailableFeatures.values()) {
+                        if (checkin) {
+                            pw.print("feat,");
+                            pw.print(feat.name);
+                            pw.print(",");
+                            pw.println(feat.version);
+                        } else {
+                            pw.print("  ");
+                            pw.print(feat.name);
+                            if (feat.version > 0) {
+                                pw.print(" version=");
+                                pw.print(feat.version);
+                            }
+                            pw.println();
                         }
-                        pw.println();
                     }
                 }
             }
@@ -21300,60 +21308,6 @@
         }
     }
 
-    /**
-     * Examine all users present on given mounted volume, and destroy data
-     * belonging to users that are no longer valid, or whose user ID has been
-     * recycled.
-     */
-    private void reconcileUsers(String volumeUuid) {
-        final List<File> files = new ArrayList<>();
-        Collections.addAll(files, FileUtils
-                .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
-        Collections.addAll(files, FileUtils
-                .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
-        Collections.addAll(files, FileUtils
-                .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
-        Collections.addAll(files, FileUtils
-                .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
-        Collections.addAll(files, FileUtils
-                .listFilesOrEmpty(Environment.getDataMiscCeDirectory()));
-        for (File file : files) {
-            if (!file.isDirectory()) continue;
-
-            final int userId;
-            final UserInfo info;
-            try {
-                userId = Integer.parseInt(file.getName());
-                info = sUserManager.getUserInfo(userId);
-            } catch (NumberFormatException e) {
-                Slog.w(TAG, "Invalid user directory " + file);
-                continue;
-            }
-
-            boolean destroyUser = false;
-            if (info == null) {
-                logCriticalInfo(Log.WARN, "Destroying user directory " + file
-                        + " because no matching user was found");
-                destroyUser = true;
-            } else if (!mOnlyCore) {
-                try {
-                    UserManagerService.enforceSerialNumber(file, info.serialNumber);
-                } catch (IOException e) {
-                    logCriticalInfo(Log.WARN, "Destroying user directory " + file
-                            + " because we failed to enforce serial number: " + e);
-                    destroyUser = true;
-                }
-            }
-
-            if (destroyUser) {
-                synchronized (mInstallLock) {
-                    mUserDataPreparer.destroyUserDataLI(volumeUuid, userId,
-                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
-                }
-            }
-        }
-    }
-
     private void assertPackageKnown(String volumeUuid, String packageName)
             throws PackageManagerException {
         synchronized (mPackages) {
diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java
index 52599fd..fc00acc 100644
--- a/services/core/java/com/android/server/pm/UserDataPreparer.java
+++ b/services/core/java/com/android/server/pm/UserDataPreparer.java
@@ -17,13 +17,28 @@
 package com.android.server.pm;
 
 import android.content.Context;
+import android.content.pm.UserInfo;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
 import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
 
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Objects;
+import java.util.Set;
 
 import static com.android.server.pm.PackageManagerService.logCriticalInfo;
 
@@ -31,6 +46,9 @@
  * Helper class for preparing and destroying user storage
  */
 class UserDataPreparer {
+    private static final String TAG = "UserDataPreparer";
+    private static final String XATTR_SERIAL = "user.serial";
+
     private final Object mInstallLock;
     private final Context mContext;
     private final boolean mOnlyCore;
@@ -65,19 +83,15 @@
             storage.prepareUserStorage(volumeUuid, userId, userSerial, flags);
 
             if ((flags & StorageManager.FLAG_STORAGE_DE) != 0 && !mOnlyCore) {
-                UserManagerService.enforceSerialNumber(
-                        Environment.getDataUserDeDirectory(volumeUuid, userId), userSerial);
+                enforceSerialNumber(getDataUserDeDirectory(volumeUuid, userId), userSerial);
                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
-                    UserManagerService.enforceSerialNumber(
-                            Environment.getDataSystemDeDirectory(userId), userSerial);
+                    enforceSerialNumber(getDataSystemDeDirectory(userId), userSerial);
                 }
             }
             if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && !mOnlyCore) {
-                UserManagerService.enforceSerialNumber(
-                        Environment.getDataUserCeDirectory(volumeUuid, userId), userSerial);
+                enforceSerialNumber(getDataUserCeDirectory(volumeUuid, userId), userSerial);
                 if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
-                    UserManagerService.enforceSerialNumber(
-                            Environment.getDataSystemCeDirectory(userId), userSerial);
+                    enforceSerialNumber(getDataSystemCeDirectory(userId), userSerial);
                 }
             }
 
@@ -117,13 +131,13 @@
             // Clean up system data
             if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
                 if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
-                    FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId));
-                    FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId));
-                    FileUtils.deleteContentsAndDir(Environment.getDataMiscDeDirectory(userId));
+                    FileUtils.deleteContentsAndDir(getUserSystemDirectory(userId));
+                    FileUtils.deleteContentsAndDir(getDataSystemDeDirectory(userId));
+                    FileUtils.deleteContentsAndDir(getDataMiscDeDirectory(userId));
                 }
                 if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
-                    FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId));
-                    FileUtils.deleteContentsAndDir(Environment.getDataMiscCeDirectory(userId));
+                    FileUtils.deleteContentsAndDir(getDataSystemCeDirectory(userId));
+                    FileUtils.deleteContentsAndDir(getDataMiscCeDirectory(userId));
                 }
             }
 
@@ -136,4 +150,183 @@
         }
     }
 
+    /**
+     * Examine all users present on given mounted volume, and destroy data
+     * belonging to users that are no longer valid, or whose user ID has been
+     * recycled.
+     */
+    void reconcileUsers(String volumeUuid, List<UserInfo> validUsersList) {
+        final List<File> files = new ArrayList<>();
+        Collections.addAll(files, FileUtils
+                .listFilesOrEmpty(Environment.getDataUserDeDirectory(volumeUuid)));
+        Collections.addAll(files, FileUtils
+                .listFilesOrEmpty(Environment.getDataUserCeDirectory(volumeUuid)));
+        Collections.addAll(files, FileUtils
+                .listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
+        Collections.addAll(files, FileUtils
+                .listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
+        Collections.addAll(files, FileUtils
+                .listFilesOrEmpty(Environment.getDataMiscCeDirectory()));
+        reconcileUsers(volumeUuid, validUsersList, files);
+    }
+
+    @VisibleForTesting
+    void reconcileUsers(String volumeUuid, List<UserInfo> validUsersList, List<File> files) {
+        final int userCount = validUsersList.size();
+        SparseArray<UserInfo> users = new SparseArray<>(userCount);
+        for (int i = 0; i < userCount; i++) {
+            UserInfo user = validUsersList.get(i);
+            users.put(user.id, user);
+        }
+        for (File file : files) {
+            if (!file.isDirectory()) {
+                continue;
+            }
+
+            final int userId;
+            final UserInfo info;
+            try {
+                userId = Integer.parseInt(file.getName());
+                info = users.get(userId);
+            } catch (NumberFormatException e) {
+                Slog.w(TAG, "Invalid user directory " + file);
+                continue;
+            }
+
+            boolean destroyUser = false;
+            if (info == null) {
+                logCriticalInfo(Log.WARN, "Destroying user directory " + file
+                        + " because no matching user was found");
+                destroyUser = true;
+            } else if (!mOnlyCore) {
+                try {
+                    enforceSerialNumber(file, info.serialNumber);
+                } catch (IOException e) {
+                    logCriticalInfo(Log.WARN, "Destroying user directory " + file
+                            + " because we failed to enforce serial number: " + e);
+                    destroyUser = true;
+                }
+            }
+
+            if (destroyUser) {
+                synchronized (mInstallLock) {
+                    destroyUserDataLI(volumeUuid, userId,
+                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+                }
+            }
+        }
+    }
+
+    @VisibleForTesting
+    protected File getDataMiscCeDirectory(int userId) {
+        return Environment.getDataMiscCeDirectory(userId);
+    }
+
+    @VisibleForTesting
+    protected File getDataSystemCeDirectory(int userId) {
+        return Environment.getDataSystemCeDirectory(userId);
+    }
+
+    @VisibleForTesting
+    protected File getDataMiscDeDirectory(int userId) {
+        return Environment.getDataMiscDeDirectory(userId);
+    }
+
+    @VisibleForTesting
+    protected File getUserSystemDirectory(int userId) {
+        return Environment.getUserSystemDirectory(userId);
+    }
+
+    @VisibleForTesting
+    protected File getDataUserCeDirectory(String volumeUuid, int userId) {
+        return Environment.getDataUserCeDirectory(volumeUuid, userId);
+    }
+
+    @VisibleForTesting
+    protected File getDataSystemDeDirectory(int userId) {
+        return Environment.getDataSystemDeDirectory(userId);
+    }
+
+    @VisibleForTesting
+    protected File getDataUserDeDirectory(String volumeUuid, int userId) {
+        return Environment.getDataUserDeDirectory(volumeUuid, userId);
+    }
+
+    @VisibleForTesting
+    protected boolean isFileEncryptedEmulatedOnly() {
+        return StorageManager.isFileEncryptedEmulatedOnly();
+    }
+
+    /**
+     * Enforce that serial number stored in user directory inode matches the
+     * given expected value. Gracefully sets the serial number if currently
+     * undefined.
+     *
+     * @throws IOException when problem extracting serial number, or serial
+     *             number is mismatched.
+     */
+    void enforceSerialNumber(File file, int serialNumber) throws IOException {
+        if (isFileEncryptedEmulatedOnly()) {
+            // When we're emulating FBE, the directory may have been chmod
+            // 000'ed, meaning we can't read the serial number to enforce it;
+            // instead of destroying the user, just log a warning.
+            Slog.w(TAG, "Device is emulating FBE; assuming current serial number is valid");
+            return;
+        }
+
+        final int foundSerial = getSerialNumber(file);
+        Slog.v(TAG, "Found " + file + " with serial number " + foundSerial);
+
+        if (foundSerial == -1) {
+            Slog.d(TAG, "Serial number missing on " + file + "; assuming current is valid");
+            try {
+                setSerialNumber(file, serialNumber);
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to set serial number on " + file, e);
+            }
+
+        } else if (foundSerial != serialNumber) {
+            throw new IOException("Found serial number " + foundSerial
+                    + " doesn't match expected " + serialNumber);
+        }
+    }
+
+    /**
+     * Set serial number stored in user directory inode.
+     *
+     * @throws IOException if serial number was already set
+     */
+    private static void setSerialNumber(File file, int serialNumber) throws IOException {
+        try {
+            final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8);
+            Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
+
+    /**
+     * Return serial number stored in user directory inode.
+     *
+     * @return parsed serial number, or -1 if not set
+     */
+    @VisibleForTesting
+    static int getSerialNumber(File file) throws IOException {
+        try {
+            final byte[] buf = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL);
+            final String serial = new String(buf);
+            try {
+                return Integer.parseInt(serial);
+            } catch (NumberFormatException e) {
+                throw new IOException("Bad serial number: " + serial);
+            }
+        } catch (ErrnoException e) {
+            if (e.errno == OsConstants.ENODATA) {
+                return -1;
+            } else {
+                throw e.rethrowAsIOException();
+            }
+        }
+    }
+
 }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 455d3e4..627fa54 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -218,8 +218,6 @@
     static final int WRITE_USER_MSG = 1;
     static final int WRITE_USER_DELAY = 2*1000;  // 2 seconds
 
-    private static final String XATTR_SERIAL = "user.serial";
-
     // Tron counters
     private static final String TRON_GUEST_CREATED = "users_guest_created";
     private static final String TRON_USER_CREATED = "users_user_created";
@@ -3159,6 +3157,15 @@
     }
 
     /**
+     * Examine all users present on given mounted volume, and destroy data
+     * belonging to users that are no longer valid, or whose user ID has been
+     * recycled.
+     */
+    void reconcileUsers(String volumeUuid) {
+        mUserDataPreparer.reconcileUsers(volumeUuid, getUsers(true /* excludeDying */));
+    }
+
+    /**
      * Make a note of the last started time of a user and do some cleanup.
      * This is called with ActivityManagerService lock held.
      * @param userId the user that was just foregrounded
@@ -3219,78 +3226,6 @@
         return RESTRICTIONS_FILE_PREFIX + packageName + XML_SUFFIX;
     }
 
-    /**
-     * Enforce that serial number stored in user directory inode matches the
-     * given expected value. Gracefully sets the serial number if currently
-     * undefined.
-     *
-     * @throws IOException when problem extracting serial number, or serial
-     *             number is mismatched.
-     */
-    public static void enforceSerialNumber(File file, int serialNumber) throws IOException {
-        if (StorageManager.isFileEncryptedEmulatedOnly()) {
-            // When we're emulating FBE, the directory may have been chmod
-            // 000'ed, meaning we can't read the serial number to enforce it;
-            // instead of destroying the user, just log a warning.
-            Slog.w(LOG_TAG, "Device is emulating FBE; assuming current serial number is valid");
-            return;
-        }
-
-        final int foundSerial = getSerialNumber(file);
-        Slog.v(LOG_TAG, "Found " + file + " with serial number " + foundSerial);
-
-        if (foundSerial == -1) {
-            Slog.d(LOG_TAG, "Serial number missing on " + file + "; assuming current is valid");
-            try {
-                setSerialNumber(file, serialNumber);
-            } catch (IOException e) {
-                Slog.w(LOG_TAG, "Failed to set serial number on " + file, e);
-            }
-
-        } else if (foundSerial != serialNumber) {
-            throw new IOException("Found serial number " + foundSerial
-                    + " doesn't match expected " + serialNumber);
-        }
-    }
-
-    /**
-     * Set serial number stored in user directory inode.
-     *
-     * @throws IOException if serial number was already set
-     */
-    private static void setSerialNumber(File file, int serialNumber)
-            throws IOException {
-        try {
-            final byte[] buf = Integer.toString(serialNumber).getBytes(StandardCharsets.UTF_8);
-            Os.setxattr(file.getAbsolutePath(), XATTR_SERIAL, buf, OsConstants.XATTR_CREATE);
-        } catch (ErrnoException e) {
-            throw e.rethrowAsIOException();
-        }
-    }
-
-    /**
-     * Return serial number stored in user directory inode.
-     *
-     * @return parsed serial number, or -1 if not set
-     */
-    private static int getSerialNumber(File file) throws IOException {
-        try {
-            final byte[] buf = Os.getxattr(file.getAbsolutePath(), XATTR_SERIAL);
-            final String serial = new String(buf);
-            try {
-                return Integer.parseInt(serial);
-            } catch (NumberFormatException e) {
-                throw new IOException("Bad serial number: " + serial);
-            }
-        } catch (ErrnoException e) {
-            if (e.errno == OsConstants.ENODATA) {
-                return -1;
-            } else {
-                throw e.rethrowAsIOException();
-            }
-        }
-    }
-
     @Override
     public void setSeedAccountData(int userId, String accountName, String accountType,
             PersistableBundle accountOptions, boolean persist) {
diff --git a/services/core/java/com/android/server/policy/BarController.java b/services/core/java/com/android/server/policy/BarController.java
index 6edb4d2..7a28081 100644
--- a/services/core/java/com/android/server/policy/BarController.java
+++ b/services/core/java/com/android/server/policy/BarController.java
@@ -18,6 +18,7 @@
 
 import android.app.StatusBarManager;
 import android.os.Handler;
+import android.os.Message;
 import android.os.SystemClock;
 import android.util.Slog;
 import android.view.View;
@@ -43,6 +44,8 @@
 
     private static final int TRANSLUCENT_ANIMATION_DELAY_MS = 1000;
 
+    private static final int MSG_NAV_BAR_VISIBILITY_CHANGED = 1;
+
     protected final String mTag;
     private final int mTransientFlag;
     private final int mUnhideFlag;
@@ -63,6 +66,8 @@
     private boolean mSetUnHideFlagWhenNextTransparent;
     private boolean mNoAnimationOnNextShow;
 
+    private OnBarVisibilityChangedListener mVisibilityChangeListener;
+
     public BarController(String tag, int transientFlag, int unhideFlag, int translucentFlag,
             int statusBarManagerId, int translucentWmFlag, int transparentFlag) {
         mTag = "BarController." + tag;
@@ -72,7 +77,7 @@
         mStatusBarManagerId = statusBarManagerId;
         mTranslucentWmFlag = translucentWmFlag;
         mTransparentFlag = transparentFlag;
-        mHandler = new Handler();
+        mHandler = new BarHandler();
     }
 
     public void setWindow(WindowState win) {
@@ -153,9 +158,18 @@
         mNoAnimationOnNextShow = false;
         final int state = computeStateLw(wasVis, wasAnim, mWin, change);
         final boolean stateChanged = updateStateLw(state);
+
+        if (change && (mVisibilityChangeListener != null)) {
+            mHandler.obtainMessage(MSG_NAV_BAR_VISIBILITY_CHANGED, show ? 1 : 0, 0).sendToTarget();
+        }
+
         return change || stateChanged;
     }
 
+    void setOnBarVisibilityChangedListener(OnBarVisibilityChangedListener listener) {
+        mVisibilityChangeListener = listener;
+    }
+
     protected boolean skipAnimation() {
         return false;
     }
@@ -300,4 +314,22 @@
             pw.println(transientBarStateToString(mTransientBarState));
         }
     }
+
+    private class BarHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_NAV_BAR_VISIBILITY_CHANGED:
+                    final boolean visible = msg.arg1 != 0;
+                    if (mVisibilityChangeListener != null) {
+                        mVisibilityChangeListener.onBarVisibilityChanged(visible);
+                    }
+                    break;
+            }
+        }
+    }
+
+    interface OnBarVisibilityChangedListener {
+        void onBarVisibilityChanged(boolean visible);
+    }
 }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 37fff68..c795676 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -16,17 +16,24 @@
 
 package com.android.server.policy;
 
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.app.AppOpsManager.OP_TOAST_WINDOW;
 import static android.content.Context.DISPLAY_SERVICE;
 import static android.content.Context.WINDOW_SERVICE;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
 import static android.content.pm.PackageManager.FEATURE_TELEVISION;
 import static android.content.pm.PackageManager.FEATURE_WATCH;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.res.Configuration.EMPTY;
 import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
 import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
+import static android.os.Build.VERSION_CODES.M;
+import static android.os.Build.VERSION_CODES.O;
 import static android.view.WindowManager.DOCKED_LEFT;
 import static android.view.WindowManager.DOCKED_RIGHT;
 import static android.view.WindowManager.DOCKED_TOP;
@@ -63,21 +70,14 @@
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
 import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
@@ -103,8 +103,11 @@
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
 import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
 import static android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION;
+import static android.view.WindowManagerGlobal.ADD_OKAY;
+import static android.view.WindowManagerGlobal.ADD_PERMISSION_DENIED;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVERED;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_COVER_ABSENT;
 import static android.view.WindowManagerPolicy.WindowManagerFuncs.CAMERA_LENS_UNCOVERED;
@@ -156,7 +159,6 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
-import android.os.Debug;
 import android.os.FactoryTest;
 import android.os.Handler;
 import android.os.IBinder;
@@ -314,12 +316,6 @@
     // Nav bar is always translucent when the freeform stack is visible, otherwise always opaque.
     static final int NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE = 1;
 
-    static final int APPLICATION_MEDIA_SUBLAYER = -2;
-    static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
-    static final int APPLICATION_PANEL_SUBLAYER = 1;
-    static final int APPLICATION_SUB_PANEL_SUBLAYER = 2;
-    static final int APPLICATION_ABOVE_SUB_PANEL_SUBLAYER = 3;
-
     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
     static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
@@ -994,6 +990,14 @@
             WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
             View.NAVIGATION_BAR_TRANSPARENT);
 
+    private final BarController.OnBarVisibilityChangedListener mNavBarVisibilityListener =
+            new BarController.OnBarVisibilityChangedListener() {
+        @Override
+        public void onBarVisibilityChanged(boolean visible) {
+            mAccessibilityManager.notifyAccessibilityButtonAvailabilityChanged(visible);
+        }
+    };
+
     private ImmersiveModeConfirmation mImmersiveModeConfirmation;
 
     private SystemGesturesPointerEventListener mSystemGestures;
@@ -2315,86 +2319,82 @@
 
         if (type < FIRST_SYSTEM_WINDOW || type > LAST_SYSTEM_WINDOW) {
             // Window manager will make sure these are okay.
-            return WindowManagerGlobal.ADD_OKAY;
+            return ADD_OKAY;
         }
-        String permission = null;
-        switch (type) {
-            case TYPE_TOAST:
-                // XXX right now the app process has complete control over
-                // this...  should introduce a token to let the system
-                // monitor/control what they are doing.
-                outAppOp[0] = AppOpsManager.OP_TOAST_WINDOW;
-                break;
-            case TYPE_DREAM:
-            case TYPE_INPUT_METHOD:
-            case TYPE_WALLPAPER:
-            case TYPE_PRESENTATION:
-            case TYPE_PRIVATE_PRESENTATION:
-            case TYPE_VOICE_INTERACTION:
-            case TYPE_ACCESSIBILITY_OVERLAY:
-            case TYPE_QS_DIALOG:
-                // The window manager will check these.
-                break;
-            case TYPE_PHONE:
-            case TYPE_PRIORITY_PHONE:
-            case TYPE_SYSTEM_ALERT:
-            case TYPE_SYSTEM_ERROR:
-            case TYPE_SYSTEM_OVERLAY:
-                permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW;
-                outAppOp[0] = AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
-                break;
+
+        if (!isSystemAlertWindowType(type)) {
+            switch (type) {
+                case TYPE_TOAST:
+                    // Only apps that target older than O SDK can add window without a token, after
+                    // that we require a token so apps cannot add toasts directly as the token is
+                    // added by the notification system.
+                    // Window manager does the checking for this.
+                    outAppOp[0] = OP_TOAST_WINDOW;
+                    return ADD_OKAY;
+                case TYPE_DREAM:
+                case TYPE_INPUT_METHOD:
+                case TYPE_WALLPAPER:
+                case TYPE_PRESENTATION:
+                case TYPE_PRIVATE_PRESENTATION:
+                case TYPE_VOICE_INTERACTION:
+                case TYPE_ACCESSIBILITY_OVERLAY:
+                case TYPE_QS_DIALOG:
+                    // The window manager will check these.
+                    return ADD_OKAY;
+            }
+            return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
+                    == PERMISSION_GRANTED ? ADD_OKAY : ADD_PERMISSION_DENIED;
+        }
+
+        // Things get a little more interesting for alert windows...
+        outAppOp[0] = OP_SYSTEM_ALERT_WINDOW;
+
+        final int callingUid = Binder.getCallingUid();
+        // system processes will be automatically granted privilege to draw
+        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
+            return ADD_OKAY;
+        }
+
+        ApplicationInfo appInfo;
+        try {
+            appInfo = mContext.getPackageManager().getApplicationInfo(attrs.packageName,
+                            UserHandle.getUserId(callingUid));
+        } catch (PackageManager.NameNotFoundException e) {
+            appInfo = null;
+        }
+
+        if (appInfo == null || (type != TYPE_APPLICATION_OVERLAY && appInfo.targetSdkVersion >= O)) {
+            /**
+             * Apps targeting >= {@link Build.VERSION_CODES#O} are required to hold
+             * {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} (system signature apps)
+             * permission to add alert windows that aren't
+             * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}.
+             */
+            return (mContext.checkCallingPermission(INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED)
+                    ? ADD_OKAY : ADD_PERMISSION_DENIED;
+        }
+
+        // check if user has enabled this operation. SecurityException will be thrown if this app
+        // has not been allowed by the user
+        final int mode = mAppOpsManager.checkOpNoThrow(outAppOp[0], callingUid, attrs.packageName);
+        switch (mode) {
+            case AppOpsManager.MODE_ALLOWED:
+            case AppOpsManager.MODE_IGNORED:
+                // although we return ADD_OKAY for MODE_IGNORED, the added window will
+                // actually be hidden in WindowManagerService
+                return ADD_OKAY;
+            case AppOpsManager.MODE_ERRORED:
+                // Don't crash legacy apps
+                if (appInfo.targetSdkVersion < M) {
+                    return ADD_OKAY;
+                }
+                return ADD_PERMISSION_DENIED;
             default:
-                permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+                // in the default mode, we will make a decision here based on
+                // checkCallingPermission()
+                return (mContext.checkCallingPermission(SYSTEM_ALERT_WINDOW) == PERMISSION_GRANTED)
+                        ? ADD_OKAY : ADD_PERMISSION_DENIED;
         }
-        if (permission != null) {
-            if (android.Manifest.permission.SYSTEM_ALERT_WINDOW.equals(permission)) {
-                final int callingUid = Binder.getCallingUid();
-                // system processes will be automatically allowed privilege to draw
-                if (callingUid == Process.SYSTEM_UID) {
-                    return WindowManagerGlobal.ADD_OKAY;
-                }
-
-                // check if user has enabled this operation. SecurityException will be thrown if
-                // this app has not been allowed by the user
-                final int mode = mAppOpsManager.checkOpNoThrow(outAppOp[0], callingUid,
-                        attrs.packageName);
-                switch (mode) {
-                    case AppOpsManager.MODE_ALLOWED:
-                    case AppOpsManager.MODE_IGNORED:
-                        // although we return ADD_OKAY for MODE_IGNORED, the added window will
-                        // actually be hidden in WindowManagerService
-                        return WindowManagerGlobal.ADD_OKAY;
-                    case AppOpsManager.MODE_ERRORED:
-                        try {
-                            ApplicationInfo appInfo = mContext.getPackageManager()
-                                    .getApplicationInfo(attrs.packageName,
-                                            UserHandle.getUserId(callingUid));
-                            // Don't crash legacy apps
-                            if (appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
-                                return WindowManagerGlobal.ADD_OKAY;
-                            }
-                        } catch (PackageManager.NameNotFoundException e) {
-                            /* ignore */
-                        }
-                        return WindowManagerGlobal.ADD_PERMISSION_DENIED;
-                    default:
-                        // in the default mode, we will make a decision here based on
-                        // checkCallingPermission()
-                        if (mContext.checkCallingPermission(permission) !=
-                                PackageManager.PERMISSION_GRANTED) {
-                            return WindowManagerGlobal.ADD_PERMISSION_DENIED;
-                        } else {
-                            return WindowManagerGlobal.ADD_OKAY;
-                        }
-                }
-            }
-
-            if (mContext.checkCallingOrSelfPermission(permission)
-                    != PackageManager.PERMISSION_GRANTED) {
-                return WindowManagerGlobal.ADD_PERMISSION_DENIED;
-            }
-        }
-        return WindowManagerGlobal.ADD_OKAY;
     }
 
     @Override
@@ -2440,9 +2440,7 @@
         }
 
         // Check if third party app has set window to system window type.
-        return mContext.checkCallingOrSelfPermission(
-                android.Manifest.permission.INTERNAL_SYSTEM_WINDOW)
-                        != PackageManager.PERMISSION_GRANTED;
+        return mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED;
     }
 
     @Override
@@ -2591,130 +2589,9 @@
         }
     }
 
-    /** {@inheritDoc} */
-    @Override
-    public int windowTypeToLayerLw(int type) {
-        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
-            return 2;
-        }
-        switch (type) {
-        case TYPE_WALLPAPER:
-            // wallpaper is at the bottom, though the window manager may move it.
-            return 1;
-        case TYPE_PRESENTATION:
-        case TYPE_PRIVATE_PRESENTATION:
-            return 2;
-        case TYPE_DOCK_DIVIDER:
-            return 2;
-        case TYPE_QS_DIALOG:
-            return 2;
-        case TYPE_PHONE:
-            return 3;
-        case TYPE_SEARCH_BAR:
-        case TYPE_VOICE_INTERACTION_STARTING:
-            return 4;
-        case TYPE_VOICE_INTERACTION:
-            // voice interaction layer is almost immediately above apps.
-            return 5;
-        case TYPE_INPUT_CONSUMER:
-            return 6;
-        case TYPE_SYSTEM_DIALOG:
-            return 7;
-        case TYPE_TOAST:
-            // toasts and the plugged-in battery thing
-            return 8;
-        case TYPE_PRIORITY_PHONE:
-            // SIM errors and unlock.  Not sure if this really should be in a high layer.
-            return 9;
-        case TYPE_DREAM:
-            // used for Dreams (screensavers with TYPE_DREAM windows)
-            return 10;
-        case TYPE_SYSTEM_ALERT:
-            // like the ANR / app crashed dialogs
-            return 11;
-        case TYPE_INPUT_METHOD:
-            // on-screen keyboards and other such input method user interfaces go here.
-            return 12;
-        case TYPE_INPUT_METHOD_DIALOG:
-            // on-screen keyboards and other such input method user interfaces go here.
-            return 13;
-        case TYPE_STATUS_BAR_SUB_PANEL:
-            return 15;
-        case TYPE_STATUS_BAR:
-            return 16;
-        case TYPE_STATUS_BAR_PANEL:
-            return 17;
-        case TYPE_KEYGUARD_DIALOG:
-            return 18;
-        case TYPE_VOLUME_OVERLAY:
-            // the on-screen volume indicator and controller shown when the user
-            // changes the device volume
-            return 19;
-        case TYPE_SYSTEM_OVERLAY:
-            // the on-screen volume indicator and controller shown when the user
-            // changes the device volume
-            return 20;
-        case TYPE_NAVIGATION_BAR:
-            // the navigation bar, if available, shows atop most things
-            return 21;
-        case TYPE_NAVIGATION_BAR_PANEL:
-            // some panels (e.g. search) need to show on top of the navigation bar
-            return 22;
-        case TYPE_SCREENSHOT:
-            // screenshot selection layer shouldn't go above system error, but it should cover
-            // navigation bars at the very least.
-            return 23;
-        case TYPE_SYSTEM_ERROR:
-            // system-level error dialogs
-            return 24;
-        case TYPE_MAGNIFICATION_OVERLAY:
-            // used to highlight the magnified portion of a display
-            return 25;
-        case TYPE_DISPLAY_OVERLAY:
-            // used to simulate secondary display devices
-            return 26;
-        case TYPE_DRAG:
-            // the drag layer: input for drag-and-drop is associated with this window,
-            // which sits above all other focusable windows
-            return 27;
-        case TYPE_ACCESSIBILITY_OVERLAY:
-            // overlay put by accessibility services to intercept user interaction
-            return 28;
-        case TYPE_SECURE_SYSTEM_OVERLAY:
-            return 29;
-        case TYPE_BOOT_PROGRESS:
-            return 30;
-        case TYPE_POINTER:
-            // the (mouse) pointer layer
-            return 31;
-        }
-        Log.e(TAG, "Unknown window type: " + type);
-        return 2;
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public int subWindowTypeToLayerLw(int type) {
-        switch (type) {
-        case TYPE_APPLICATION_PANEL:
-        case TYPE_APPLICATION_ATTACHED_DIALOG:
-            return APPLICATION_PANEL_SUBLAYER;
-        case TYPE_APPLICATION_MEDIA:
-            return APPLICATION_MEDIA_SUBLAYER;
-        case TYPE_APPLICATION_MEDIA_OVERLAY:
-            return APPLICATION_MEDIA_OVERLAY_SUBLAYER;
-        case TYPE_APPLICATION_SUB_PANEL:
-            return APPLICATION_SUB_PANEL_SUBLAYER;
-        case TYPE_APPLICATION_ABOVE_SUB_PANEL:
-            return APPLICATION_ABOVE_SUB_PANEL_SUBLAYER;
-        }
-        Log.e(TAG, "Unknown sub-window type: " + type);
-        return 0;
-    }
-
     @Override
     public int getMaxWallpaperLayer() {
-        return windowTypeToLayerLw(TYPE_STATUS_BAR);
+        return getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
     }
 
     private int getNavigationBarWidth(int rotation, int uiMode) {
@@ -2797,8 +2674,7 @@
                 return false;
             default:
                 // Hide only windows below the keyguard host window.
-                return windowTypeToLayerLw(win.getBaseType())
-                        < windowTypeToLayerLw(TYPE_STATUS_BAR);
+                return getWindowLayerLw(win) < getWindowLayerFromTypeLw(TYPE_STATUS_BAR);
         }
     }
 
@@ -3032,6 +2908,8 @@
                 }
                 mNavigationBar = win;
                 mNavigationBarController.setWindow(win);
+                mNavigationBarController.setOnBarVisibilityChangedListener(
+                        mNavBarVisibilityListener);
                 if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar);
                 break;
             case TYPE_NAVIGATION_BAR_PANEL:
@@ -3043,7 +2921,7 @@
                         "PhoneWindowManager");
                 break;
         }
-        return WindowManagerGlobal.ADD_OKAY;
+        return ADD_OKAY;
     }
 
     /** {@inheritDoc} */
@@ -7837,8 +7715,8 @@
         immersiveSticky = (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
         final boolean navAllowedHidden = immersive || immersiveSticky;
 
-        if (hideNavBarSysui && !navAllowedHidden && windowTypeToLayerLw(win.getBaseType())
-                > windowTypeToLayerLw(TYPE_INPUT_CONSUMER)) {
+        if (hideNavBarSysui && !navAllowedHidden
+                && getWindowLayerLw(win) > getWindowLayerFromTypeLw(TYPE_INPUT_CONSUMER)) {
             // We can't hide the navbar from this window otherwise the input consumer would not get
             // the input events.
             vis = (vis & ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 238866a..91a5f4f 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -517,9 +517,6 @@
     private final ArrayList<PowerManagerInternal.LowPowerModeListener> mLowPowerModeListeners
             = new ArrayList<PowerManagerInternal.LowPowerModeListener>();
 
-    // True if brightness should be affected by twilight.
-    private boolean mBrightnessUseTwilight;
-
     // True if we are currently in VR Mode.
     private boolean mIsVrModeEnabled;
 
@@ -735,9 +732,6 @@
             resolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.DOUBLE_TAP_TO_WAKE),
                     false, mSettingsObserver, UserHandle.USER_ALL);
-            resolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Secure.BRIGHTNESS_USE_TWILIGHT),
-                    false, mSettingsObserver, UserHandle.USER_ALL);
             IVrManager vrManager =
                     (IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE);
             if (vrManager != null) {
@@ -878,9 +872,6 @@
                 Settings.System.SCREEN_BRIGHTNESS_MODE,
                 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT);
 
-        mBrightnessUseTwilight = Settings.Secure.getIntForUser(resolver,
-                Secure.BRIGHTNESS_USE_TWILIGHT, 0, UserHandle.USER_CURRENT) != 0;
-
         final boolean lowPowerModeEnabled = Settings.Global.getInt(resolver,
                 Settings.Global.LOW_POWER_MODE, 0) != 0;
         final boolean autoLowPowerModeConfigured = Settings.Global.getInt(resolver,
@@ -2254,7 +2245,6 @@
             mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();
             mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;
             mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness();
-            mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight;
 
             if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
                 mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
index fb0dd2a..b4467af 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java
@@ -23,9 +23,6 @@
 
 public interface StatusBarManagerInternal {
     void setNotificationDelegate(NotificationDelegate delegate);
-    void buzzBeepBlinked();
-    void notificationLightPulse(int argb, int onMillis, int offMillis);
-    void notificationLightOff();
     void showScreenPinningRequest(int taskId);
     void showAssistDisclosure();
 
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 7b7db0e..2dfe20a8 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -120,40 +120,6 @@
         }
 
         @Override
-        public void buzzBeepBlinked() {
-            if (mBar != null) {
-                try {
-                    mBar.buzzBeepBlinked();
-                } catch (RemoteException ex) {
-                }
-            }
-        }
-
-        @Override
-        public void notificationLightPulse(int argb, int onMillis, int offMillis) {
-            mNotificationLightOn = true;
-            if (mBar != null) {
-                try {
-                    mBar.notificationLightPulse(argb, onMillis, offMillis);
-                } catch (RemoteException ex) {
-                }
-            }
-        }
-
-        @Override
-        public void notificationLightOff() {
-            if (mNotificationLightOn) {
-                mNotificationLightOn = false;
-                if (mBar != null) {
-                    try {
-                        mBar.notificationLightOff();
-                    } catch (RemoteException ex) {
-                    }
-                }
-            }
-        }
-
-        @Override
         public void showScreenPinningRequest(int taskId) {
             if (mBar != null) {
                 try {
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 8cc53f0..e026130 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -23,15 +23,12 @@
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.OperationApplicationException;
 import android.content.ServiceConnection;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
@@ -84,12 +81,9 @@
 import com.android.server.IoThread;
 import com.android.server.SystemService;
 
-import org.xmlpull.v1.XmlPullParserException;
-
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -241,44 +235,6 @@
                 // the update can be handled in {@link #onSomePackagesChanged}.
                 return true;
             }
-
-            @Override
-            public void onPackageRemoved(String packageName, int uid) {
-                synchronized (mLock) {
-                    UserState userState = getOrCreateUserStateLocked(getChangingUserId());
-                    if (!userState.packageSet.contains(packageName)) {
-                        // Not a TV input package.
-                        return;
-                    }
-                }
-
-                ArrayList<ContentProviderOperation> operations = new ArrayList<>();
-
-                String selection = TvContract.BaseTvColumns.COLUMN_PACKAGE_NAME + "=?";
-                String[] selectionArgs = { packageName };
-
-                operations.add(ContentProviderOperation.newDelete(TvContract.Channels.CONTENT_URI)
-                        .withSelection(selection, selectionArgs).build());
-                operations.add(ContentProviderOperation.newDelete(TvContract.Programs.CONTENT_URI)
-                        .withSelection(selection, selectionArgs).build());
-                operations.add(ContentProviderOperation
-                        .newDelete(TvContract.WatchedPrograms.CONTENT_URI)
-                        .withSelection(selection, selectionArgs).build());
-
-                ContentProviderResult[] results = null;
-                try {
-                    ContentResolver cr = getContentResolverForUser(getChangingUserId());
-                    results = cr.applyBatch(TvContract.AUTHORITY, operations);
-                } catch (RemoteException | OperationApplicationException e) {
-                    Slog.e(TAG, "error in applyBatch", e);
-                }
-
-                if (DEBUG) {
-                    Slog.d(TAG, "onPackageRemoved(packageName=" + packageName + ", uid=" + uid
-                            + ")");
-                    Slog.d(TAG, "results=" + results);
-                }
-            }
         };
         monitor.register(mContext, null, UserHandle.ALL, true);
 
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 0fc1900..45b7baf 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -79,4 +79,13 @@
      *       given in {@link android.service.vr.VrModeException} on failure.
      */
     public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId);
+
+    /**
+     * 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.
+     *
+     * @param enabled true if the device should be placed in persistent VR mode.
+     */
+    public abstract void setPersistentVrModeEnabled(boolean enabled);
 }
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index e8385fc..51c4ce31 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -20,18 +20,12 @@
 import android.app.AppOpsManager;
 import android.app.NotificationManager;
 import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.FeatureInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.hardware.display.DisplayManager;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -54,7 +48,6 @@
 import android.util.SparseArray;
 
 import com.android.internal.R;
-import com.android.server.LocalServices;
 import com.android.server.SystemConfig;
 import com.android.server.SystemService;
 import com.android.server.utils.ManagedApplicationService.PendingEvent;
@@ -70,8 +63,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Date;
-import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -122,8 +113,10 @@
     // State protected by mLock
     private boolean mVrModeAllowed;
     private boolean mVrModeEnabled;
+    private boolean mPersistentVrModeEnabled;
     private EnabledComponentsObserver mComponentObserver;
     private ManagedApplicationService mCurrentVrService;
+    private ComponentName mDefaultVrService;
     private Context mContext;
     private ComponentName mCurrentVrModeComponent;
     private int mCurrentVrModeUser;
@@ -138,7 +131,6 @@
     private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
     /** Tracks the state of the screen and keyguard UI.*/
     private int mSystemSleepFlags = FLAG_NONE;
-    private CompatibilityDisplay mCompatibilityDisplay;
 
     private static final int MSG_VR_STATE_CHANGE = 0;
     private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
@@ -159,6 +151,10 @@
             if (mVrModeAllowed) {
                 consumeAndApplyPendingStateLocked();
             } else {
+                // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
+                // exit persistent VR mode when screen is turned off.
+                mPersistentVrModeEnabled = false;
+
                 // Set pending state to current state.
                 mPendingState = (mVrModeEnabled && mCurrentVrService != null)
                     ? new VrState(mVrModeEnabled, mCurrentVrService.getComponent(),
@@ -380,6 +376,12 @@
         }
 
         @Override
+        public void setPersistentVrModeEnabled(boolean enabled) {
+            enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER);
+            VrManagerService.this.setPersistentVrModeEnabled(enabled);
+        }
+
+        @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                     != PackageManager.PERMISSION_GRANTED) {
@@ -389,6 +391,8 @@
             }
             pw.println("********* Dump of VrManagerService *********");
             pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
+            pw.println("Persistent VR mode is currently: " +
+                    ((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
             pw.println("Previous state transitions:\n");
             String tab = "  ";
             dumpStateTransitions(pw);
@@ -464,6 +468,11 @@
         public int hasVrPackage(ComponentName packageName, int userId) {
             return VrManagerService.this.hasVrPackage(packageName, userId);
         }
+
+        @Override
+        public void setPersistentVrModeEnabled(boolean enabled) {
+            VrManagerService.this.setPersistentVrModeEnabled(enabled);
+        }
     }
 
     public VrManagerService(Context context) {
@@ -497,10 +506,14 @@
                 mComponentObserver.rebuildAll();
             }
 
-            DisplayManager dm =
-                    (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
-            mCompatibilityDisplay = new CompatibilityDisplay(dm, mVrManager);
-            mCompatibilityDisplay.init();
+            //TODO: something more robust than picking the first one
+            ArraySet<ComponentName> defaultVrComponents =
+                    SystemConfig.getInstance().getDefaultVrComponents();
+            if (defaultVrComponents.size() > 0) {
+                mDefaultVrService = defaultVrComponents.valueAt(0);
+            } else {
+                Slog.i(TAG, "No default vr listener service found.");
+            }
         } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
             synchronized (mLock) {
                 mVrModeAllowed = true;
@@ -644,8 +657,8 @@
                 }
             }
 
+            mCurrentVrModeComponent = calling;
             if (calling != null && !Objects.equals(calling, mCurrentVrModeComponent)) {
-                mCurrentVrModeComponent = calling;
                 sendUpdatedCaller = true;
             }
 
@@ -954,7 +967,25 @@
             int userId, @NonNull ComponentName callingPackage) {
 
         synchronized (mLock) {
-            VrState pending = new VrState(enabled, targetPackageName, userId, callingPackage);
+            VrState pending;
+            ComponentName targetListener;
+            ComponentName foregroundVrComponent;
+
+            // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
+            // and the system default VR listener is used.
+            boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
+            if (!enabled && mPersistentVrModeEnabled) {
+                targetListener = mDefaultVrService;
+
+                // Current foreground component isn't a VR one (in 2D app case)
+                foregroundVrComponent = null;
+            } else {
+                targetListener = targetPackageName;
+                foregroundVrComponent = callingPackage;
+            }
+            pending = new VrState(
+                    targetEnabledState, targetListener, userId, foregroundVrComponent);
+
             if (!mVrModeAllowed) {
                 // We're not allowed to be in VR mode.  Make this state pending.  This will be
                 // applied the next time we are allowed to enter VR mode unless it is superseded by
@@ -963,7 +994,7 @@
                 return;
             }
 
-            if (!enabled && mCurrentVrService != null) {
+            if (!targetEnabledState && mCurrentVrService != null) {
                 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
                 // and service bind/unbind in case we are immediately switching to another VR app.
                 if (mPendingState == null) {
@@ -978,7 +1009,19 @@
                 mPendingState = null;
             }
 
-            updateCurrentVrServiceLocked(enabled, targetPackageName, userId, callingPackage);
+            updateCurrentVrServiceLocked(
+                    targetEnabledState, targetListener, userId, foregroundVrComponent);
+        }
+    }
+
+    private void setPersistentVrModeEnabled(boolean enabled) {
+        synchronized (mLock) {
+            mPersistentVrModeEnabled = enabled;
+
+            // Disabling persistent mode when not showing a VR should disable the overall vr mode.
+            if (!enabled && mCurrentVrModeComponent == null) {
+                setVrMode(false, null, 0, null);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 49ffa22..f7a9e41 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -369,6 +369,7 @@
                         case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
                         case WindowManager.LayoutParams.TYPE_TOAST:
                         case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
+                        case WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:
                         case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
                         case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
                         case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
@@ -687,7 +688,7 @@
                     mSurfaceControl = surfaceControl;
                     mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay()
                             .getLayerStack());
-                    mSurfaceControl.setLayer(mWindowManagerService.mPolicy.windowTypeToLayerLw(
+                    mSurfaceControl.setLayer(mWindowManagerService.mPolicy.getWindowLayerFromTypeLw(
                             WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY)
                             * WindowManagerService.TYPE_LAYER_MULTIPLIER);
                     mSurfaceControl.setPosition(0, 0);
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 3eb529b..4eb8e02 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -951,9 +951,9 @@
         float scaleW = appWidth / thumbWidth;
         getNextAppTransitionStartRect(taskId, mTmpRect);
         final float fromX;
-        final float fromY;
+        float fromY;
         final float toX;
-        final float toY;
+        float toY;
         final float pivotX;
         final float pivotY;
         if (shouldScaleDownThumbnailTransition(uiMode, orientation)) {
@@ -966,6 +966,12 @@
             toY = appRect.height() / 2 * (1 - 1 / scaleW) + appRect.top;
             pivotX = mTmpRect.width() / 2;
             pivotY = appRect.height() / 2 / scaleW;
+            if (mGridLayoutRecentsEnabled) {
+                // In the grid layout, the header is displayed above the thumbnail instead of
+                // overlapping it.
+                fromY -= thumbHeightI;
+                toY -= thumbHeightI * scaleW;
+            }
         } else {
             pivotX = 0;
             pivotY = 0;
@@ -1014,7 +1020,10 @@
             // This AnimationSet uses the Interpolators assigned above.
             AnimationSet set = new AnimationSet(false);
             set.addAnimation(scale);
-            set.addAnimation(alpha);
+            if (!mGridLayoutRecentsEnabled) {
+                // In the grid layout, the header should be shown for the whole animation.
+                set.addAnimation(alpha);
+            }
             set.addAnimation(translate);
             set.addAnimation(clipAnim);
             a = set;
@@ -1033,7 +1042,10 @@
             // This AnimationSet uses the Interpolators assigned above.
             AnimationSet set = new AnimationSet(false);
             set.addAnimation(scale);
-            set.addAnimation(alpha);
+            if (!mGridLayoutRecentsEnabled) {
+                // In the grid layout, the header should be shown for the whole animation.
+                set.addAnimation(alpha);
+            }
             set.addAnimation(translate);
             a = set;
 
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index d643769..061aa83 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -192,7 +192,8 @@
 
     AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
             DisplayContent dc) {
-        super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc);
+        super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
+                false /* ownerCanManageAppTokens */);
         appToken = token;
         mVoiceInteraction = voiceInteraction;
         mInputApplicationHandle = new InputApplicationHandle(this);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 679f178..c45136c 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2185,7 +2185,7 @@
                     && !mService.mInputMethodTarget.isInMultiWindowMode();
         }
 
-        final int aboveAppLayer = (mService.mPolicy.windowTypeToLayerLw(TYPE_APPLICATION) + 1)
+        final int aboveAppLayer = (mService.mPolicy.getWindowLayerFromTypeLw(TYPE_APPLICATION) + 1)
                 * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
         final MutableBoolean mutableIncludeFullDisplay = new MutableBoolean(includeFullDisplay);
         synchronized(mService.mWindowMap) {
@@ -2728,8 +2728,10 @@
          */
         private final Comparator<WindowToken> mWindowComparator = (token1, token2) ->
                 // Tokens with higher base layer are z-ordered on-top.
-                mService.mPolicy.windowTypeToLayerLw(token1.windowType)
-                < mService.mPolicy.windowTypeToLayerLw(token2.windowType) ? -1 : 1;
+                mService.mPolicy.getWindowLayerFromTypeLw(token1.windowType,
+                        token1.mOwnerCanManageAppTokens)
+                < mService.mPolicy.getWindowLayerFromTypeLw(token2.windowType,
+                        token2.mOwnerCanManageAppTokens) ? -1 : 1;
 
         private final Predicate<WindowState> mGetOrientingWindow = w -> {
             if (!w.isVisibleLw() || !w.mPolicyVisibilityAfterAnim) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 5a2ee9a..0a92a81 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -621,11 +621,7 @@
         final boolean homeVisible = homeTask.getTopVisibleAppToken() != null;
         final boolean homeBehind = (fullscreenStack != null && fullscreenStack.isVisible())
                 || (homeStack.hasMultipleTaskWithHomeTaskNotTop());
-        // If the home task is an on-top launcher, we don't want to minimize the docked stack.
-        // Instead we want everything underneath that was visible to remain visible.
-        // See android.R.attr#onTopLauncher.
-        final boolean isOnTopLauncher = homeStack.topTaskIsOnTopLauncher();
-        setMinimizedDockedStack(homeVisible && !homeBehind && !isOnTopLauncher, animate);
+        setMinimizedDockedStack(homeVisible && !homeBehind, animate);
     }
 
     private boolean isWithinDisplay(Task task) {
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 1ae987f..3fdafc7 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -239,7 +239,7 @@
     }
 
     int getDragLayerLw() {
-        return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_DRAG)
+        return mService.mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_DRAG)
                 * WindowManagerService.TYPE_LAYER_MULTIPLIER
                 + WindowManagerService.TYPE_LAYER_OFFSET;
     }
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index b92bfb9..36753b7 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -77,7 +77,7 @@
     }
 
     private int getLayerLw(int windowType) {
-        return mService.mPolicy.windowTypeToLayerLw(windowType)
+        return mService.mPolicy.getWindowLayerFromTypeLw(windowType)
                 * WindowManagerService.TYPE_LAYER_MULTIPLIER
                 + WindowManagerService.TYPE_LAYER_OFFSET;
     }
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 5f53d84..37b8deb 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
@@ -237,8 +238,8 @@
                 // Figure out whether this window is layered above system windows.
                 // We need to do this here to help the activity manager know how to
                 // layer its ANR dialog.
-                int systemAlertLayer = mService.mPolicy.windowTypeToLayerLw(
-                        WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+                int systemAlertLayer = mService.mPolicy.getWindowLayerFromTypeLw(
+                        TYPE_APPLICATION_OVERLAY, windowState.mOwnerCanAddInternalSystemWindow);
                 aboveSystem = windowState.mBaseLayer > systemAlertLayer;
             } else if (appWindowToken != null) {
                 Slog.i(TAG_WM, "Input event dispatching timed out "
@@ -471,7 +472,7 @@
     /* Callback to get pointer layer. */
     @Override
     public int getPointerLayer() {
-        return mService.mPolicy.windowTypeToLayerLw(WindowManager.LayoutParams.TYPE_POINTER)
+        return mService.mPolicy.getWindowLayerFromTypeLw(WindowManager.LayoutParams.TYPE_POINTER)
                 * WindowManagerService.TYPE_LAYER_MULTIPLIER
                 + WindowManagerService.TYPE_LAYER_OFFSET;
     }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index d96e1ef..ab9a378 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -91,20 +91,16 @@
 
     private boolean mHomeTask;
 
-    // Whether this task is an on-top launcher task, which is determined by the root activity.
-    private boolean mIsOnTopLauncher;
-
     private TaskDescription mTaskDescription;
 
     Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
-            Configuration overrideConfig, boolean isOnTopLauncher, int resizeMode,
-            boolean supportsPictureInPicture, boolean homeTask, TaskDescription taskDescription,
+            Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
+            boolean homeTask, TaskDescription taskDescription,
             TaskWindowContainerController controller) {
         mTaskId = taskId;
         mStack = stack;
         mUserId = userId;
         mService = service;
-        mIsOnTopLauncher = isOnTopLauncher;
         mResizeMode = resizeMode;
         mSupportsPictureInPicture = supportsPictureInPicture;
         mHomeTask = homeTask;
@@ -117,7 +113,7 @@
         return mStack != null ? mStack.getDisplayContent() : null;
     }
 
-    int getAdjustedAddPosition(int suggestedPosition) {
+    private int getAdjustedAddPosition(int suggestedPosition) {
         final int size = mChildren.size();
         if (suggestedPosition >= size) {
             return Math.min(size, suggestedPosition);
@@ -347,10 +343,6 @@
                 || mResizeMode == RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
     }
 
-    boolean isOnTopLauncher() {
-        return mIsOnTopLauncher;
-    }
-
     boolean cropWindowsToStackBounds() {
         return isResizeable();
     }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 538f0d9..a1c9c29 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -160,10 +160,6 @@
         return mChildren.size() > 1 && !mChildren.get(mChildren.size() - 1).isHomeTask();
     }
 
-    boolean topTaskIsOnTopLauncher() {
-        return mChildren.get(mChildren.size() - 1).isOnTopLauncher();
-    }
-
     /**
      * Set the bounds of the stack and its containing tasks.
      * @param stackBounds New stack bounds. Passing in null sets the bounds to fullscreen.
diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
index 11667c0..efc2e11 100644
--- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
@@ -51,17 +51,17 @@
     public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
             StackWindowController stackController, int userId, Rect bounds,
             Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            boolean homeTask, boolean isOnTopLauncher, boolean toTop, boolean showForAllUsers,
+            boolean homeTask, boolean toTop, boolean showForAllUsers,
             TaskDescription taskDescription) {
         this(taskId, listener, stackController, userId, bounds, overrideConfig, resizeMode,
-                supportsPictureInPicture, homeTask, isOnTopLauncher, toTop, showForAllUsers,
-                taskDescription, WindowManagerService.getInstance());
+                supportsPictureInPicture, homeTask, toTop, showForAllUsers, taskDescription,
+                WindowManagerService.getInstance());
     }
 
     public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
             StackWindowController stackController, int userId, Rect bounds,
             Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            boolean homeTask, boolean isOnTopLauncher, boolean toTop, boolean showForAllUsers,
+            boolean homeTask, boolean toTop, boolean showForAllUsers,
             TaskDescription taskDescription, WindowManagerService service) {
         super(listener, service);
         mTaskId = taskId;
@@ -78,7 +78,7 @@
             }
             EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
             final Task task = createTask(taskId, stack, userId, bounds, overrideConfig, resizeMode,
-                    supportsPictureInPicture, homeTask, isOnTopLauncher, taskDescription);
+                    supportsPictureInPicture, homeTask, taskDescription);
             final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
             stack.addTask(task, position, showForAllUsers, true /* moveParents */);
         }
@@ -87,9 +87,9 @@
     @VisibleForTesting
     Task createTask(int taskId, TaskStack stack, int userId, Rect bounds,
             Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            boolean homeTask, boolean isOnTopLauncher, TaskDescription taskDescription) {
-        return new Task(taskId, stack, userId, mService, bounds, overrideConfig, isOnTopLauncher,
-                resizeMode, supportsPictureInPicture, homeTask, taskDescription, this);
+            boolean homeTask, TaskDescription taskDescription) {
+        return new Task(taskId, stack, userId, mService, bounds, overrideConfig, resizeMode,
+                supportsPictureInPicture, homeTask, taskDescription, this);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 8ea1b3b..28aebbb 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -40,8 +40,8 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperWindowToken" : TAG_WM;
 
     WallpaperWindowToken(WindowManagerService service, IBinder token, boolean explicit,
-            DisplayContent dc) {
-        super(service, token, TYPE_WALLPAPER, explicit, dc);
+            DisplayContent dc, boolean ownerCanManageAppTokens) {
+        super(service, token, TYPE_WALLPAPER, explicit, dc, ownerCanManageAppTokens);
         dc.mWallpaperController.addWallpaperToken(this);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index e0c3d60..d56110c 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -59,7 +59,6 @@
     private ArrayDeque<WindowState> mPinnedWindows = new ArrayDeque<>();
     private ArrayDeque<WindowState> mDockedWindows = new ArrayDeque<>();
     private ArrayDeque<WindowState> mInputMethodWindows = new ArrayDeque<>();
-    private ArrayDeque<WindowState> mOnTopLauncherWindows = new ArrayDeque<>();
     private WindowState mDockDivider = null;
     private ArrayDeque<WindowState> mReplacingWindows = new ArrayDeque<>();
     private int mCurBaseLayer;
@@ -138,7 +137,6 @@
         mPinnedWindows.clear();
         mInputMethodWindows.clear();
         mDockedWindows.clear();
-        mOnTopLauncherWindows.clear();
         mReplacingWindows.clear();
         mDockDivider = null;
 
@@ -182,9 +180,6 @@
         if (task == null) {
             return;
         }
-        if (task.isOnTopLauncher()) {
-            mOnTopLauncherWindows.add(w);
-        }
         final TaskStack stack = task.mStack;
         if (stack == null) {
             return;
@@ -206,10 +201,6 @@
 
         layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer);
 
-        while (!mOnTopLauncherWindows.isEmpty()) {
-            layer = assignAndIncreaseLayerIfNeeded(mOnTopLauncherWindows.remove(), layer);
-        }
-
         // We know that we will be animating a relaunching window in the near future, which will
         // receive a z-order increase. We want the replaced window to immediately receive the same
         // treatment, e.g. to be above the dock divider.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9b96523..971794b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -16,13 +16,14 @@
 
 package com.android.server.wm;
 
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_APP_TOKENS;
 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
 import static android.app.StatusBarManager.DISABLE_MASK;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.DOCKED_INVALID;
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
@@ -101,7 +102,6 @@
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
-import android.app.RemoteAction;
 import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -236,7 +236,6 @@
 import java.util.HashMap;
 import java.util.List;
 
-import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
@@ -523,7 +522,7 @@
     boolean mSupportsPictureInPicture = false;
 
     int getDragLayerLocked() {
-        return mPolicy.windowTypeToLayerLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
+        return mPolicy.getWindowLayerFromTypeLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
     }
 
     class RotationWatcher {
@@ -1099,6 +1098,8 @@
         long origId;
         final int callingUid = Binder.getCallingUid();
         final int type = attrs.type;
+        final boolean ownerCanAddInternalSystemWindow =
+                mContext.checkCallingPermission(INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
 
         synchronized(mWindowMap) {
             if (!mDisplayReady) {
@@ -1200,7 +1201,8 @@
                         return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
                     }
                 }
-                token = new WindowToken(this, attrs.token, type, false, displayContent);
+                token = new WindowToken(this, attrs.token, type, false, displayContent,
+                        ownerCanAddInternalSystemWindow);
             } else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
                 atoken = token.asAppWindowToken();
                 if (atoken == null) {
@@ -1270,11 +1272,13 @@
                 // It is not valid to use an app token with other system types; we will
                 // instead make a new token for it (as if null had been passed in for the token).
                 attrs.token = null;
-                token = new WindowToken(this, null, type, false, displayContent);
+                token = new WindowToken(this, null, type, false, displayContent,
+                        ownerCanAddInternalSystemWindow);
             }
 
-            WindowState win = new WindowState(this, session, client, token, parentWindow,
-                    appOp[0], seq, attrs, viewVisibility, session.mUid);
+            final WindowState win = new WindowState(this, session, client, token, parentWindow,
+                    appOp[0], seq, attrs, viewVisibility, session.mUid,
+                    ownerCanAddInternalSystemWindow);
             if (win.mDeathRecipient == null) {
                 // Client has apparently died, so there is no reason to
                 // continue.
@@ -2405,9 +2409,10 @@
                 return;
             }
             if (type == TYPE_WALLPAPER) {
-                new WallpaperWindowToken(this, binder, true, dc);
+                new WallpaperWindowToken(this, binder, true, dc,
+                        true /* ownerCanManageAppTokens */);
             } else {
-                new WindowToken(this, binder, type, true, dc);
+                new WindowToken(this, binder, type, true, dc, true /* ownerCanManageAppTokens */);
             }
         }
     }
@@ -3606,7 +3611,7 @@
                         mCircularDisplayMask = new CircularDisplayMask(
                                 getDefaultDisplayContentLocked().getDisplay(),
                                 mFxSession,
-                                mPolicy.windowTypeToLayerLw(
+                                mPolicy.getWindowLayerFromTypeLw(
                                         WindowManager.LayoutParams.TYPE_POINTER)
                                         * TYPE_LAYER_MULTIPLIER + 10, screenOffset, maskThickness);
                     }
@@ -3635,7 +3640,7 @@
                             mContext,
                             getDefaultDisplayContentLocked().getDisplay(),
                             mFxSession,
-                            mPolicy.windowTypeToLayerLw(
+                            mPolicy.getWindowLayerFromTypeLw(
                                     WindowManager.LayoutParams.TYPE_POINTER)
                                     * TYPE_LAYER_MULTIPLIER + 10);
                 }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 050adfe..867080e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -18,7 +18,6 @@
 
 import static android.app.ActivityManager.ENABLE_TASK_SNAPSHOTS;
 import static android.app.ActivityManager.StackId;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.isLowRamDeviceStatic;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
@@ -164,6 +163,8 @@
     final int mAppOp;
     // UserId and appId of the owner. Don't display windows of non-current user.
     final int mOwnerUid;
+    /** The owner has {@link android.Manifest.permission#INTERNAL_SYSTEM_WINDOW} */
+    final boolean mOwnerCanAddInternalSystemWindow;
     final IWindowId mWindowId;
     WindowToken mToken;
     // The same object as mToken if this is an app window and null for non-app windows.
@@ -561,7 +562,7 @@
 
     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
            WindowState parentWindow, int appOp, int seq, WindowManager.LayoutParams a,
-           int viewVisibility, int ownerId) {
+           int viewVisibility, int ownerId, boolean ownerCanAddInternalSystemWindow) {
         mService = service;
         mSession = s;
         mClient = c;
@@ -569,6 +570,7 @@
         mToken = token;
         mAppToken = mToken.asAppWindowToken();
         mOwnerUid = ownerId;
+        mOwnerCanAddInternalSystemWindow = ownerCanAddInternalSystemWindow;
         mWindowId = new IWindowId.Stub() {
             @Override
             public void registerFocusObserver(IWindowFocusObserver observer) {
@@ -613,9 +615,9 @@
         if (mAttrs.type >= FIRST_SUB_WINDOW && mAttrs.type <= LAST_SUB_WINDOW) {
             // The multiplier here is to reserve space for multiple
             // windows in the same type layer.
-            mBaseLayer = mPolicy.windowTypeToLayerLw(parentWindow.mAttrs.type)
+            mBaseLayer = mPolicy.getWindowLayerLw(parentWindow)
                     * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
-            mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
+            mSubLayer = mPolicy.getSubWindowLayerFromTypeLw(a.type);
             mIsChildWindow = true;
 
             if (DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + parentWindow);
@@ -629,7 +631,7 @@
         } else {
             // The multiplier here is to reserve space for multiple
             // windows in the same type layer.
-            mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
+            mBaseLayer = mPolicy.getWindowLayerLw(this)
                     * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
             mSubLayer = 0;
             mIsChildWindow = false;
@@ -676,6 +678,11 @@
         return mAttrs.packageName;
     }
 
+    @Override
+    public boolean canAddInternalSystemWindow() {
+        return mOwnerCanAddInternalSystemWindow;
+    }
+
     /**
      * Subtracts the insets calculated by intersecting {@param layoutFrame} with {@param insetFrame}
      * from {@param frame}. In other words, it applies the insets that would result if
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index b163abf..d2ea64c8 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -915,10 +915,15 @@
             if (attachedTransformation != null) {
                 tmpMatrix.postConcat(attachedTransformation.getMatrix());
             }
-            tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
             if (appTransformation != null) {
                 tmpMatrix.postConcat(appTransformation.getMatrix());
             }
+
+            // The translation that applies the position of the window needs to be applied at the
+            // end in case that other translations include scaling. Otherwise the scaling will
+            // affect this translation. But it needs to be set before the screen rotation animation
+            // so the pivot point is at the center of the screen for all windows.
+            tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
             if (screenAnimation) {
                 tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
             }
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 4b94d15..8beb87d 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -77,6 +77,9 @@
     // The display this token is on.
     protected DisplayContent mDisplayContent;
 
+    /** The owner has {@link android.Manifest.permission#MANAGE_APP_TOKENS} */
+    final boolean mOwnerCanManageAppTokens;
+
     /**
      * Compares two child window of this token and returns -1 if the first is lesser than the
      * second in terms of z-order and 1 otherwise.
@@ -98,11 +101,12 @@
     };
 
     WindowToken(WindowManagerService service, IBinder _token, int type, boolean persistOnEmpty,
-            DisplayContent dc) {
+            DisplayContent dc, boolean ownerCanManageAppTokens) {
         mService = service;
         token = _token;
         windowType = type;
         mPersistOnEmpty = persistOnEmpty;
+        mOwnerCanManageAppTokens = ownerCanManageAppTokens;
         onDisplayChanged(dc);
     }
 
diff --git a/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp b/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp
index 545b3d7..703518d 100644
--- a/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp
+++ b/services/core/jni/com_android_server_HardwarePropertiesManagerService.cpp
@@ -70,7 +70,7 @@
 static void nativeInit(JNIEnv* env, jobject obj) {
     // TODO(b/31632518)
     if (gThermalModule == nullptr) {
-        gThermalModule = IThermal::getService("thermal");
+        gThermalModule = IThermal::getService();
     }
 
     if (gThermalModule == nullptr) {
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index e46490b..3120af56 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -26,18 +26,11 @@
 
 namespace android {
 
-static int start_sensor_service(void* /*unused*/) {
-    SensorService::instantiate();
-    return 0;
-}
-
 static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
     char propBuf[PROPERTY_VALUE_MAX];
     property_get("system_init.startsensorservice", propBuf, "1");
     if (strcmp(propBuf, "1") == 0) {
-        // Start the sensor service in a new thread
-        createThreadEtc(start_sensor_service, nullptr,
-                        "StartSensorThread", PRIORITY_FOREGROUND);
+        SensorService::instantiate();
     }
 }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 578e0b3..deb9ee0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -6706,6 +6706,8 @@
         policy.mDelegationMap.clear();
         policy.mStatusBarDisabled = false;
         policy.mUserProvisioningState = DevicePolicyManager.STATE_USER_UNMANAGED;
+        policy.mAffiliationIds.clear();
+        policy.mLockTaskPackages.clear();
         saveSettingsLocked(userId);
 
         try {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b911d2d..83e209d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -125,8 +125,13 @@
 public final class SystemServer {
     private static final String TAG = "SystemServer";
 
+    // Tag for timing measurement of main thread.
+    private static final String SYSTEM_SERVER_TIMING_TAG = "SystemServerTiming";
+    // Tag for timing measurement of non-main asynchronous operations.
+    private static final String SYSTEM_SERVER_TIMING_ASYNC_TAG = SYSTEM_SERVER_TIMING_TAG + "Async";
+
     private static final BootTimingsTraceLog BOOT_TIMINGS_TRACE_LOG
-            = new BootTimingsTraceLog("SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER);
+            = new BootTimingsTraceLog(SYSTEM_SERVER_TIMING_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
 
     private static final String ENCRYPTING_STATE = "trigger_restart_min_framework";
     private static final String ENCRYPTED_STATE = "1";
@@ -149,6 +154,8 @@
             "com.android.server.voiceinteraction.VoiceInteractionManagerService";
     private static final String PRINT_MANAGER_SERVICE_CLASS =
             "com.android.server.print.PrintManagerService";
+    private static final String COMPANION_DEVICE_MANAGER_SERVICE_CLASS =
+            "com.android.server.print.CompanionDeviceManagerService";
     private static final String USB_SERVICE_CLASS =
             "com.android.server.usb.UsbService$Lifecycle";
     private static final String MIDI_SERVICE_CLASS =
@@ -227,8 +234,11 @@
     private boolean mFirstBoot;
     private final boolean mRuntimeRestart;
 
+    private static final String START_SENSOR_SERVICE = "StartSensorService";
+    private Future<?> mSensorServiceStart;
+
     /**
-     * Start the sensor service.
+     * Start the sensor service. This is a blocking call and can take time.
      */
     private static native void startSensorService();
 
@@ -382,7 +392,7 @@
             MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
             final int MAX_UPTIME_MILLIS = 60 * 1000;
             if (uptimeMillis > MAX_UPTIME_MILLIS) {
-                Slog.wtf("SystemServerTiming",
+                Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                         "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
             }
         }
@@ -584,9 +594,15 @@
 
         // The sensor service needs access to package manager service, app ops
         // service, and permissions service, therefore we start it after them.
-        traceBeginAndSlog("StartSensorService");
-        startSensorService();
-        traceEnd();
+        // Start sensor service in a separate thread. Completion should be checked
+        // before using it.
+        mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
+            BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
+                    SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+            traceLog.traceBegin(START_SENSOR_SERVICE);
+            startSensorService();
+            traceLog.traceEnd();
+        }, START_SENSOR_SERVICE);
     }
 
     /**
@@ -742,6 +758,9 @@
             traceEnd();
 
             traceBeginAndSlog("StartWindowManagerService");
+            // WMS needs sensor service ready
+            ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
+            mSensorServiceStart = null;
             wm = WindowManagerService.main(context, inputManager,
                     mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                     !mFirstBoot, mOnlyCore, new PhoneWindowManager());
@@ -1333,6 +1352,10 @@
                 traceEnd();
             }
 
+            traceBeginAndSlog("StartCompanionDeviceManager");
+            mSystemServiceManager.startService(COMPANION_DEVICE_MANAGER_SERVICE_CLASS);
+            traceEnd();
+
             traceBeginAndSlog("StartRestrictionManager");
             mSystemServiceManager.startService(RestrictionsManagerService.class);
             traceEnd();
@@ -1590,7 +1613,7 @@
                 webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
                     Slog.i(TAG, WEBVIEW_PREPARATION);
                     BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
-                            "SystemServerTiming", Trace.TRACE_TAG_SYSTEM_SERVER);
+                            SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
                     traceLog.traceBegin(WEBVIEW_PREPARATION);
                     mWebViewUpdateService.prepareWebViewInSystemServer();
                     traceLog.traceEnd();
@@ -1651,13 +1674,13 @@
             Watchdog.getInstance().start();
             traceEnd();
 
-            if (webviewPrep != null) {
-                ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
-            }
-
             // It is now okay to let the various system services start their
             // third party code...
             traceBeginAndSlog("PhaseThirdPartyAppsCanStart");
+            // confirm webview completion before starting 3rd party
+            if (webviewPrep != null) {
+                ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);
+            }
             mSystemServiceManager.startBootPhase(
                     SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
             traceEnd();
diff --git a/services/print/java/com/android/server/print/CompanionDeviceManagerService.java b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
new file mode 100644
index 0000000..9824c1d
--- /dev/null
+++ b/services/print/java/com/android/server/print/CompanionDeviceManagerService.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.server.print;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.app.PendingIntent;
+import android.companion.AssociationRequest;
+import android.companion.ICompanionDeviceManager;
+import android.companion.ICompanionDeviceManagerService;
+import android.companion.IOnAssociateCallback;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.server.SystemService;
+
+//TODO move to own package!
+/** @hide */
+public class CompanionDeviceManagerService extends SystemService {
+
+    private static final ComponentName SERVICE_TO_BIND_TO = ComponentName.createRelative(
+            "com.android.companiondevicemanager", ".DeviceDiscoveryService");
+
+    private static final boolean DEBUG = false;
+    private static final String LOG_TAG = "CompanionDeviceManagerService";
+
+    private final CompanionDeviceManagerImpl mImpl;
+
+    public CompanionDeviceManagerService(Context context) {
+        super(context);
+        mImpl = new CompanionDeviceManagerImpl();
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.COMPANION_DEVICE_SERVICE, mImpl);
+    }
+
+    class CompanionDeviceManagerImpl extends ICompanionDeviceManager.Stub {
+
+        @Override
+        public void associate(
+                AssociationRequest request,
+                IOnAssociateCallback callback,
+                String callingPackage) throws RemoteException {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "associate(request = " + request + ", callback = " + callback
+                        + ", callingPackage = " + callingPackage + ")");
+            }
+            checkNotNull(request);
+            checkNotNull(callback);
+            final long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                //TODO bindServiceAsUser
+                getContext().bindService(
+                        new Intent().setComponent(SERVICE_TO_BIND_TO),
+                        getServiceConnection(request, callback, callingPackage),
+                        Context.BIND_AUTO_CREATE);
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
+            }
+        }
+    }
+
+    private ServiceConnection getServiceConnection(
+            final AssociationRequest<?> request,
+            final IOnAssociateCallback callback,
+            final String callingPackage) {
+        return new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                if (DEBUG) {
+                    Log.i(LOG_TAG,
+                            "onServiceConnected(name = " + name + ", service = "
+                                    + service + ")");
+                }
+                try {
+                    ICompanionDeviceManagerService.Stub
+                            .asInterface(service)
+                            .startDiscovery(
+                                    request,
+                                    getCallback(callingPackage, callback),
+                                    callingPackage);
+                } catch (RemoteException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+                if (DEBUG) Log.i(LOG_TAG, "onServiceDisconnected(name = " + name + ")");
+            }
+        };
+    }
+
+    private IOnAssociateCallback.Stub getCallback(
+            String callingPackage,
+            IOnAssociateCallback propagateTo) {
+        return new IOnAssociateCallback.Stub() {
+
+            @Override
+            public void onSuccess(PendingIntent launcher)
+                    throws RemoteException {
+                if (DEBUG) Log.i(LOG_TAG, "onSuccess(launcher = " + launcher + ")");
+                recordSpecialPriviledgesForPackage(callingPackage);
+                propagateTo.onSuccess(launcher);
+            }
+
+            @Override
+            public void onFailure(CharSequence reason) throws RemoteException {
+                if (DEBUG) Log.i(LOG_TAG, "onFailure()");
+                propagateTo.onFailure(reason);
+            }
+        };
+    }
+
+    void recordSpecialPriviledgesForPackage(String priviledgedPackage) {
+        //TODO Show dialog before recording notification access
+//        final SettingStringHelper setting =
+//                new SettingStringHelper(
+//                        getContext().getContentResolver(),
+//                        Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
+//                        Binder.getCallingUid());
+//        setting.write(ColonDelimitedSet.OfStrings.add(setting.read(), priviledgedPackage));
+    }
+}
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
index f30c466..f943ee2c 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
@@ -541,6 +541,8 @@
     }
 
     private void stopDemoMode() {
+        mDeviceInDemoMode = false;
+        mIsCarrierDemoMode = false;
         mPreloadAppsInstaller = null;
         mCameraIdsWithFlash = null;
         mInjector.destroyWakeLock();
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
index aa08b41..064ab0a 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
@@ -112,6 +112,7 @@
         Notification n2 = new Notification.Builder(mContext)
                 .setCategory(Notification.CATEGORY_CALL)
                 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
+                .setColorized(true /* colorized */)
                 .build();
         mRecordHighCall = new NotificationRecord(mContext, new StatusBarNotification(callPkg,
                 callPkg, 1, "highcall", callUid, callUid, n2,
@@ -186,10 +187,10 @@
         final List<NotificationRecord> expected = new ArrayList<>();
         expected.add(mRecordHighCall);
         expected.add(mRecordDefaultMedia);
-        expected.add(mRecordStarredContact);
-        expected.add(mRecordContact);
         expected.add(mRecordInlineReply);
         expected.add(mRecordSms);
+        expected.add(mRecordStarredContact);
+        expected.add(mRecordContact);
         expected.add(mRecordEmail);
         expected.add(mRecordUrgent);
         expected.add(mRecordCheater);
@@ -207,14 +208,19 @@
     @Test
     public void testMessaging() throws Exception {
         NotificationComparator comp = new NotificationComparator(mContext);
-        assertTrue(comp.isImportantMessaging(mRecordStarredContact));
-        assertTrue(comp.isImportantMessaging(mRecordContact));
         assertTrue(comp.isImportantMessaging(mRecordInlineReply));
         assertTrue(comp.isImportantMessaging(mRecordSms));
         assertFalse(comp.isImportantMessaging(mRecordEmail));
         assertFalse(comp.isImportantMessaging(mRecordCheater));
     }
 
+    @Test
+    public void testPeople() throws Exception {
+        NotificationComparator comp = new NotificationComparator(mContext);
+        assertTrue(comp.isImportantPeople(mRecordStarredContact));
+        assertTrue(comp.isImportantPeople(mRecordContact));
+    }
+
     private NotificationChannel getDefaultChannel() {
         return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
                 NotificationManager.IMPORTANCE_LOW);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 152b9c9..fa9e9a8 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -117,6 +117,8 @@
     private static final String SSID = "ssid";
     private static final String SSID_2 = "ssid_2";
     private static final String SSID_3 = "ssid_3";
+    private static final ComponentName RECOMMENDATION_SERVICE_COMP =
+            new ComponentName("newPackageName", "newScoringServiceClass");
     private static final ScoredNetwork SCORED_NETWORK =
             new ScoredNetwork(new NetworkKey(new WifiKey(quote(SSID), "00:00:00:00:00:00")),
                     null /* rssiCurve*/);
@@ -124,7 +126,7 @@
             new ScoredNetwork(new NetworkKey(new WifiKey(quote(SSID_2), "00:00:00:00:00:00")),
                     null /* rssiCurve*/);
     private static final NetworkScorerAppData NEW_SCORER =
-        new NetworkScorerAppData("newPackageName", 1, "newScoringServiceClass");
+        new NetworkScorerAppData(1, RECOMMENDATION_SERVICE_COMP);
 
     @Mock private NetworkScorerAppManager mNetworkScorerAppManager;
     @Mock private Context mContext;
@@ -203,8 +205,7 @@
 
         verify(mContext).bindServiceAsUser(MockUtils.checkIntent(
                 new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS)
-                        .setComponent(new ComponentName(NEW_SCORER.packageName,
-                                NEW_SCORER.recommendationServiceClassName))),
+                        .setComponent(RECOMMENDATION_SERVICE_COMP)),
                 any(ServiceConnection.class),
                 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
                 eq(UserHandle.SYSTEM));
@@ -657,7 +658,8 @@
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
         mNetworkScoreService.systemRunning();
 
-        assertEquals(NEW_SCORER.packageName, mNetworkScoreService.getActiveScorerPackage());
+        assertEquals(NEW_SCORER.getRecommendationServicePackageName(),
+                mNetworkScoreService.getActiveScorerPackage());
     }
 
     @Test
@@ -829,8 +831,6 @@
 
     // "injects" the mock INetworkRecommendationProvider into the NetworkScoreService.
     private void injectProvider() {
-        final ComponentName componentName = new ComponentName(NEW_SCORER.packageName,
-                NEW_SCORER.recommendationServiceClassName);
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
         when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
                 isA(UserHandle.class))).thenAnswer(new Answer<Boolean>() {
@@ -840,7 +840,8 @@
                 when(mockBinder.queryLocalInterface(anyString()))
                         .thenReturn(mRecommendationProvider);
                 invocation.getArgumentAt(1, ServiceConnection.class)
-                        .onServiceConnected(componentName, mockBinder);
+                        .onServiceConnected(NEW_SCORER.getRecommendationServiceComponent(),
+                                mockBinder);
                 return true;
             }
         });
@@ -849,8 +850,8 @@
 
     private void bindToScorer(boolean callerIsScorer) {
         final int callingUid = callerIsScorer ? Binder.getCallingUid() : 0;
-        NetworkScorerAppData appData = new NetworkScorerAppData(NEW_SCORER.packageName,
-                callingUid, NEW_SCORER.recommendationServiceClassName);
+        NetworkScorerAppData appData =
+                new NetworkScorerAppData(callingUid, RECOMMENDATION_SERVICE_COMP);
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(appData);
         when(mContext.bindServiceAsUser(isA(Intent.class), isA(ServiceConnection.class), anyInt(),
                 isA(UserHandle.class))).thenReturn(true);
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 213fb27..e433b60 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -190,6 +190,8 @@
         mAms.addAccountExplicitly(a31, "p31", null);
         mAms.addAccountExplicitly(a32, "p32", null);
 
+        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
+        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
         Account[] accounts = mAms.getAccounts(null, mContext.getOpPackageName());
         Arrays.sort(accounts, new AccountSorter());
         assertEquals(6, accounts.length);
@@ -306,6 +308,8 @@
 
     @SmallTest
     public void testRemovedAccountSync() throws Exception {
+        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
+        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
         unlockSystemUser();
         Account a1 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
         Account a2 = new Account("account2", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_2);
@@ -347,6 +351,8 @@
 
         // Start testing
         unlockSystemUser();
+        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
+        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
         Account[] accounts = mAms.getAccounts(null, mContext.getOpPackageName());
         assertEquals("1 account should be migrated", 1, accounts.length);
         assertEquals(PreNTestDatabaseHelper.ACCOUNT_NAME, accounts[0].name);
@@ -1048,7 +1054,6 @@
         // Assert finishSessionAsUser added calling uid and pid into the sessionBundle
         assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_UID));
         assertTrue(sessionBundle.containsKey(AccountManager.KEY_CALLER_PID));
-        // Assert App bundle data overrides sessionBundle data
         assertEquals(sessionBundle.getString(
                 AccountManager.KEY_ANDROID_PACKAGE_NAME), "APCT.package");
 
@@ -1387,6 +1392,9 @@
 
     @SmallTest
     public void testRemoveAccountAsUserRemovalAllowed() throws Exception {
+        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
+        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
+
         unlockSystemUser();
         mAms.addAccountExplicitly(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS, "p1", null);
         Account[] addedAccounts =
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
index 2e045ff..2cb8af4 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
@@ -355,49 +355,49 @@
     @Test
     public void testVisibilityFindSetDelete() {
         long accId = 10;
-        int uid1 = 100500;
-        int uid2 = 100501;
+        String packageName1 = "com.example.one";
+        String packageName2 = "com.example.two";
         Account account = new Account("name", "example.com");
-        assertNull(mAccountsDb.findAccountVisibility(account, uid1));
+        assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
 
         mAccountsDb.insertDeAccount(account, accId);
-        assertNull(mAccountsDb.findAccountVisibility(account, uid1));
-        assertNull(mAccountsDb.findAccountVisibility(accId, uid1));
+        assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
+        assertNull(mAccountsDb.findAccountVisibility(accId, packageName1));
 
-        mAccountsDb.setAccountVisibility(accId, uid1, 1);
-        assertEquals(mAccountsDb.findAccountVisibility(account, uid1), Integer.valueOf(1));
-        assertEquals(mAccountsDb.findAccountVisibility(accId, uid1), Integer.valueOf(1));
+        mAccountsDb.setAccountVisibility(accId, packageName1, 1);
+        assertEquals(mAccountsDb.findAccountVisibility(account, packageName1), Integer.valueOf(1));
+        assertEquals(mAccountsDb.findAccountVisibility(accId, packageName1), Integer.valueOf(1));
 
-        mAccountsDb.setAccountVisibility(accId, uid2, 2);
-        assertEquals(mAccountsDb.findAccountVisibility(accId, uid2), Integer.valueOf(2));
+        mAccountsDb.setAccountVisibility(accId, packageName2, 2);
+        assertEquals(mAccountsDb.findAccountVisibility(accId, packageName2), Integer.valueOf(2));
 
-        mAccountsDb.setAccountVisibility(accId, uid2, 3);
-        assertEquals(mAccountsDb.findAccountVisibility(accId, uid2), Integer.valueOf(3));
+        mAccountsDb.setAccountVisibility(accId, packageName2, 3);
+        assertEquals(mAccountsDb.findAccountVisibility(accId, packageName2), Integer.valueOf(3));
 
-        Map<Integer, Integer> vis = mAccountsDb.findAllVisibilityValuesForAccount(account);
+        Map<String, Integer> vis = mAccountsDb.findAllVisibilityValuesForAccount(account);
         assertEquals(vis.size(), 2);
-        assertEquals(vis.get(uid1), Integer.valueOf(1));
-        assertEquals(vis.get(uid2), Integer.valueOf(3));
+        assertEquals(vis.get(packageName1), Integer.valueOf(1));
+        assertEquals(vis.get(packageName2), Integer.valueOf(3));
 
-        assertTrue(mAccountsDb.deleteAccountVisibilityForUid(uid1));
-        assertNull(mAccountsDb.findAccountVisibility(accId, uid1));
-        assertFalse(mAccountsDb.deleteAccountVisibilityForUid(uid1)); // Already deleted.
+        assertTrue(mAccountsDb.deleteAccountVisibilityForPackage(packageName1));
+        assertNull(mAccountsDb.findAccountVisibility(accId, packageName1));
+        assertFalse(mAccountsDb.deleteAccountVisibilityForPackage(packageName1)); // 2nd attempt.
     }
 
     @Test
     public void testVisibilityCleanupTrigger() {
         long accId = 10;
-        int uid1 = 100500;
+        String packageName1 = "com.example.one";
         Account account = new Account("name", "example.com");
 
-        assertNull(mAccountsDb.findAccountVisibility(account, uid1));
+        assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
         mAccountsDb.insertDeAccount(account, accId);
-        assertNull(mAccountsDb.findAccountVisibility(account, uid1));
+        assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
 
-        mAccountsDb.setAccountVisibility(accId, uid1, 1);
-        assertEquals(mAccountsDb.findAccountVisibility(accId, uid1), Integer.valueOf(1));
+        mAccountsDb.setAccountVisibility(accId, packageName1, 1);
+        assertEquals(mAccountsDb.findAccountVisibility(accId, packageName1), Integer.valueOf(1));
 
         assertTrue(mAccountsDb.deleteDeAccount(accId)); // Trigger should remove visibility.
-        assertNull(mAccountsDb.findAccountVisibility(account, uid1));
+        assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 7df638c..6fb65d5 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -2089,9 +2089,19 @@
         assertTrue(dpm.getAffiliationIds(admin2).isEmpty());
         assertFalse(dpm.isAffiliatedUser());
 
+        // Set affiliation ids again, then clear PO to check that the user becomes unaffiliated
+        dpm.setAffiliationIds(admin2, userAffiliationIds);
+        assertTrue(dpm.isAffiliatedUser());
+        dpm.clearProfileOwner(admin2);
+        assertFalse(dpm.isAffiliatedUser());
+
         // Check that the system user remains affiliated.
         mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
         assertTrue(dpm.isAffiliatedUser());
+
+        // Clear the device owner - the user becomes unaffiliated.
+        clearDeviceOwner();
+        assertFalse(dpm.isAffiliatedUser());
     }
 
     public void testGetUserProvisioningState_defaultResult() {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index e30bd5d..e5640c7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -309,6 +309,7 @@
 
         // Sanity check for InstrumentationInfo.
         assertEquals(a.info.targetPackage, b.info.targetPackage);
+        assertEquals(a.info.targetProcess, b.info.targetProcess);
         assertEquals(a.info.sourceDir, b.info.sourceDir);
         assertEquals(a.info.publicSourceDir, b.info.publicSourceDir);
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java
new file mode 100644
index 0000000..7a676e25
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/UserDataPreparerTest.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.pm;
+
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.os.FileUtils;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * <p>Run with:<pre>
+ * m FrameworksServicesTests &&
+ * adb install \
+ * -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
+ * adb shell am instrument -e class com.android.server.pm.UserDataPreparerTest \
+ * -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ * </pre>
+ */
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+@SmallTest
+public class UserDataPreparerTest {
+
+    private static final int TEST_USER_SERIAL = 1000;
+    private static final int TEST_USER_ID = 10;
+
+    private TestUserDataPreparer mUserDataPreparer;
+
+    @Mock
+    private StorageManager mStorageManagerMock;
+
+    @Mock
+    private Context mContextMock;
+
+    @Mock
+    private Installer mInstaller;
+
+    private Object mInstallLock;
+
+    @Before
+    public void setup() {
+        Context ctx = InstrumentationRegistry.getContext();
+        FileUtils.deleteContents(ctx.getCacheDir());
+        mInstallLock = new Object();
+        MockitoAnnotations.initMocks(this);
+        mUserDataPreparer = new TestUserDataPreparer(mInstaller, mInstallLock, mContextMock, false,
+                ctx.getCacheDir());
+        when(mContextMock.getSystemServiceName(StorageManager.class))
+                .thenReturn(Context.STORAGE_SERVICE);
+        when(mContextMock.getSystemService(eq(Context.STORAGE_SERVICE)))
+                .thenReturn(mStorageManagerMock);
+        VolumeInfo testVolume = new VolumeInfo("testuuid", VolumeInfo.TYPE_PRIVATE, null, null);
+        when(mStorageManagerMock.getWritablePrivateVolumes()).thenReturn(Arrays.asList(testVolume));
+    }
+
+    @Test
+    public void testPrepareUserData_De() throws Exception {
+        File userDeDir = mUserDataPreparer.getDataUserDeDirectory(null, TEST_USER_ID);
+        userDeDir.mkdirs();
+        File systemDeDir = mUserDataPreparer.getDataSystemDeDirectory(TEST_USER_ID);
+        systemDeDir.mkdirs();
+        mUserDataPreparer
+                .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_DE);
+        verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID),
+                eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_DE));
+        verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID),
+                eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_DE));
+        int serialNumber = UserDataPreparer.getSerialNumber(userDeDir);
+        assertEquals(TEST_USER_SERIAL, serialNumber);
+        serialNumber = UserDataPreparer.getSerialNumber(systemDeDir);
+        assertEquals(TEST_USER_SERIAL, serialNumber);
+    }
+
+    @Test
+    public void testPrepareUserData_Ce() throws Exception {
+        File userCeDir = mUserDataPreparer.getDataUserCeDirectory(null, TEST_USER_ID);
+        userCeDir.mkdirs();
+        File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID);
+        systemCeDir.mkdirs();
+        mUserDataPreparer
+                .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_CE);
+        verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID),
+                eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_CE));
+        verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID),
+                eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_CE));
+        int serialNumber = UserDataPreparer.getSerialNumber(userCeDir);
+        assertEquals(TEST_USER_SERIAL, serialNumber);
+        serialNumber = UserDataPreparer.getSerialNumber(systemCeDir);
+        assertEquals(TEST_USER_SERIAL, serialNumber);
+    }
+
+    @Test
+    public void testDestroyUserData() throws Exception {
+        // Add file in CE
+        File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID);
+        systemCeDir.mkdirs();
+        File ceFile = new File(systemCeDir, "file");
+        writeFile(ceFile, "-----" );
+        testDestroyUserData_De();
+        // CE directory should be preserved
+        assertEquals(Collections.singletonList(ceFile), Arrays.asList(FileUtils.listFilesOrEmpty(
+                systemCeDir)));
+
+        testDestroyUserData_Ce();
+
+        // Verify that testDir is empty
+        assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+                mUserDataPreparer.testDir)));
+    }
+
+    @Test
+    public void testDestroyUserData_De() throws Exception {
+        File systemDir = mUserDataPreparer.getUserSystemDirectory(TEST_USER_ID);
+        systemDir.mkdirs();
+        writeFile(new File(systemDir, "file"), "-----" );
+        File systemDeDir = mUserDataPreparer.getDataSystemDeDirectory(TEST_USER_ID);
+        systemDeDir.mkdirs();
+        writeFile(new File(systemDeDir, "file"), "-----" );
+        File miscDeDir = mUserDataPreparer.getDataMiscDeDirectory(TEST_USER_ID);
+        miscDeDir.mkdirs();
+        writeFile(new File(miscDeDir, "file"), "-----" );
+
+        mUserDataPreparer.destroyUserData(TEST_USER_ID, StorageManager.FLAG_STORAGE_DE);
+
+        verify(mInstaller).destroyUserData(isNull(String.class), eq(TEST_USER_ID),
+                        eq(StorageManager.FLAG_STORAGE_DE));
+        verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID),
+                        eq(StorageManager.FLAG_STORAGE_DE));
+
+        assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(systemDir)));
+        assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+                systemDeDir)));
+        assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+                miscDeDir)));
+    }
+
+    @Test
+    public void testDestroyUserData_Ce() throws Exception {
+        File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID);
+        systemCeDir.mkdirs();
+        writeFile(new File(systemCeDir, "file"), "-----" );
+        File miscCeDir = mUserDataPreparer.getDataMiscCeDirectory(TEST_USER_ID);
+        miscCeDir.mkdirs();
+        writeFile(new File(miscCeDir, "file"), "-----" );
+
+        mUserDataPreparer.destroyUserData(TEST_USER_ID, StorageManager.FLAG_STORAGE_CE);
+
+        verify(mInstaller).destroyUserData(isNull(String.class), eq(TEST_USER_ID),
+                eq(StorageManager.FLAG_STORAGE_CE));
+        verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID),
+                eq(StorageManager.FLAG_STORAGE_CE));
+
+        assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+                systemCeDir)));
+        assertEquals(Collections.emptyList(), Arrays.asList(FileUtils.listFilesOrEmpty(
+                miscCeDir)));
+    }
+
+    @Test
+    public void testReconcileUsers() throws Exception {
+        UserInfo u1 = new UserInfo(1, "u1", 0);
+        UserInfo u2 = new UserInfo(2, "u2", 0);
+        File testDir = mUserDataPreparer.testDir;
+        File dir1 = new File(testDir, "1");
+        dir1.mkdirs();
+        File dir2 = new File(testDir, "2");
+        dir2.mkdirs();
+        File dir3 = new File(testDir, "3");
+        dir3.mkdirs();
+
+        mUserDataPreparer
+                .reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL, Arrays.asList(u1, u2),
+                        Arrays.asList(dir1, dir2, dir3));
+        // Verify that user 3 data is removed
+        verify(mInstaller).destroyUserData(isNull(String.class), eq(3),
+                eq(StorageManager.FLAG_STORAGE_DE|StorageManager.FLAG_STORAGE_CE));
+    }
+
+    private static void writeFile(File file, String content) throws IOException {
+        try (FileOutputStream os = new FileOutputStream(file)) {
+            os.write(content.getBytes(Charset.defaultCharset()));
+        }
+    }
+
+    private static class TestUserDataPreparer extends UserDataPreparer {
+        File testDir;
+
+        TestUserDataPreparer(Installer installer, Object installLock, Context context,
+                boolean onlyCore, File testDir) {
+            super(installer, installLock, context, onlyCore);
+            this.testDir = testDir;
+        }
+
+        @Override
+        protected File getDataMiscCeDirectory(int userId) {
+            return new File(testDir, "misc_ce_" + userId);
+        }
+
+        @Override
+        protected File getDataSystemCeDirectory(int userId) {
+            return new File(testDir, "system_ce_" + userId);
+        }
+
+        @Override
+        protected File getDataMiscDeDirectory(int userId) {
+            return new File(testDir, "misc_de_" + userId);
+        }
+
+        @Override
+        protected File getUserSystemDirectory(int userId) {
+            return new File(testDir, "user_system_" + userId);
+        }
+
+        @Override
+        protected File getDataUserCeDirectory(String volumeUuid, int userId) {
+            return new File(testDir, "user_ce_" + userId);
+        }
+
+        @Override
+        protected File getDataSystemDeDirectory(int userId) {
+            return new File(testDir, "system_de_" + userId);
+        }
+
+        @Override
+        protected File getDataUserDeDirectory(String volumeUuid, int userId) {
+            return new File(testDir, "user_de_" + userId);
+        }
+
+        @Override
+        protected boolean isFileEncryptedEmulatedOnly() {
+            return false;
+        }
+    }
+
+}
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 ec429a0..1e471e3 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -16,49 +16,7 @@
 
 package com.android.server.wm;
 
-import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
-import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
-import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
-import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
-import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
-import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
-import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
-import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
-import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
-import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
-import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
 import static org.mockito.Mockito.mock;
 
 import android.annotation.Nullable;
@@ -70,12 +28,10 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.Log;
 import android.view.Display;
 import android.view.IWindowManager;
 import android.view.KeyEvent;
 import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
 import android.view.WindowManagerPolicy;
 import android.view.animation.Animation;
 import android.os.PowerManagerInternal;
@@ -163,127 +119,6 @@
     }
 
     @Override
-    public int windowTypeToLayerLw(int type) {
-        // TODO: figure-out a good way to keep this in-sync with PhoneWindowManager...sigh!
-        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
-            return 2;
-        }
-        switch (type) {
-            case TYPE_PRESENTATION:
-            case TYPE_PRIVATE_PRESENTATION:
-                return 2;
-            case TYPE_WALLPAPER:
-                // wallpaper is at the bottom, though the window manager may move it.
-                return 2;
-            case TYPE_DOCK_DIVIDER:
-                return 2;
-            case TYPE_QS_DIALOG:
-                return 2;
-            case TYPE_PHONE:
-                return 3;
-            case TYPE_SEARCH_BAR:
-            case TYPE_VOICE_INTERACTION_STARTING:
-                return 4;
-            case TYPE_VOICE_INTERACTION:
-                // voice interaction layer is almost immediately above apps.
-                return 5;
-            case TYPE_INPUT_CONSUMER:
-                return 6;
-            case TYPE_SYSTEM_DIALOG:
-                return 7;
-            case TYPE_TOAST:
-                // toasts and the plugged-in battery thing
-                return 8;
-            case TYPE_PRIORITY_PHONE:
-                // SIM errors and unlock.  Not sure if this really should be in a high layer.
-                return 9;
-            case TYPE_DREAM:
-                // used for Dreams (screensavers with TYPE_DREAM windows)
-                return 10;
-            case TYPE_SYSTEM_ALERT:
-                // like the ANR / app crashed dialogs
-                return 11;
-            case TYPE_INPUT_METHOD:
-                // on-screen keyboards and other such input method user interfaces go here.
-                return 12;
-            case TYPE_INPUT_METHOD_DIALOG:
-                // on-screen keyboards and other such input method user interfaces go here.
-                return 13;
-            case TYPE_STATUS_BAR_SUB_PANEL:
-                return 15;
-            case TYPE_STATUS_BAR:
-                return 16;
-            case TYPE_STATUS_BAR_PANEL:
-                return 17;
-            case TYPE_KEYGUARD_DIALOG:
-                return 18;
-            case TYPE_VOLUME_OVERLAY:
-                // the on-screen volume indicator and controller shown when the user
-                // changes the device volume
-                return 19;
-            case TYPE_SYSTEM_OVERLAY:
-                // the on-screen volume indicator and controller shown when the user
-                // changes the device volume
-                return 20;
-            case TYPE_NAVIGATION_BAR:
-                // the navigation bar, if available, shows atop most things
-                return 21;
-            case TYPE_NAVIGATION_BAR_PANEL:
-                // some panels (e.g. search) need to show on top of the navigation bar
-                return 22;
-            case TYPE_SCREENSHOT:
-                // screenshot selection layer shouldn't go above system error, but it should cover
-                // navigation bars at the very least.
-                return 23;
-            case TYPE_SYSTEM_ERROR:
-                // system-level error dialogs
-                return 24;
-            case TYPE_MAGNIFICATION_OVERLAY:
-                // used to highlight the magnified portion of a display
-                return 25;
-            case TYPE_DISPLAY_OVERLAY:
-                // used to simulate secondary display devices
-                return 26;
-            case TYPE_DRAG:
-                // the drag layer: input for drag-and-drop is associated with this window,
-                // which sits above all other focusable windows
-                return 27;
-            case TYPE_ACCESSIBILITY_OVERLAY:
-                // overlay put by accessibility services to intercept user interaction
-                return 28;
-            case TYPE_SECURE_SYSTEM_OVERLAY:
-                return 29;
-            case TYPE_BOOT_PROGRESS:
-                return 30;
-            case TYPE_POINTER:
-                // the (mouse) pointer layer
-                return 31;
-        }
-        Log.e(TAG, "Unknown window type: " + type);
-        return 2;
-    }
-
-    @Override
-    public int subWindowTypeToLayerLw(int type) {
-        // TODO: figure-out a good way to keep this in-sync with PhoneWindowManager...
-        switch (type) {
-            case TYPE_APPLICATION_PANEL:
-            case TYPE_APPLICATION_ATTACHED_DIALOG:
-                return 1;
-            case TYPE_APPLICATION_MEDIA:
-                return -2;
-            case TYPE_APPLICATION_MEDIA_OVERLAY:
-                return -1;
-            case TYPE_APPLICATION_SUB_PANEL:
-                return 2;
-            case TYPE_APPLICATION_ABOVE_SUB_PANEL:
-                return 3;
-        }
-        Log.e(TAG, "Unknown sub-window type: " + type);
-        return 0;
-    }
-
-    @Override
     public int getMaxWallpaperLayer() {
         return 0;
     }
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 186884b..98ff0e2 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -57,7 +57,8 @@
         final Task mTask;
         boolean mDockedResizingForTest = false;
         WindowStateWithTask(WindowManager.LayoutParams attrs, Task t) {
-            super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0);
+            super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0,
+                    false /* ownerCanAddInternalSystemWindow */);
             mTask = t;
         }
 
@@ -77,8 +78,7 @@
         final Rect mInsetBounds = new Rect();
         boolean mFullscreenForTest = true;
         TaskWithBounds(Rect bounds) {
-            super(0, mStubStack, 0, sWm, null, null, false, 0, false, false, new TaskDescription(),
-                    null);
+            super(0, mStubStack, 0, sWm, null, null, 0, false, false, new TaskDescription(), null);
             mBounds = bounds;
         }
         @Override
@@ -106,7 +106,7 @@
         sWm.mSystemDecorLayer = 10000;
 
         mWindowToken = new WindowToken(sWm, new Binder(), 0, false,
-                sWm.getDefaultDisplayContentLocked());
+                sWm.getDefaultDisplayContentLocked(), false /* ownerCanManageAppTokens */);
         mStubStack = new TaskStack(sWm, 0);
     }
 
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 c6f88ed..bc85017 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -181,7 +181,7 @@
         attrs.setTitle(name);
 
         final WindowState w = new WindowState(sWm, sMockSession, sIWindow, token, parent, OP_NONE,
-                0, attrs, 0, 0);
+                0, attrs, 0, 0, false /* ownerCanAddInternalSystemWindow */);
         // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
         // adding it to the token...
         token.addWindow(w);
@@ -201,8 +201,8 @@
 
     /** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
     static Task createTaskInStack(TaskStack stack, int userId) {
-        final Task newTask = new Task(sNextTaskId++, stack, userId, sWm, null, EMPTY, false, 0,
-                false, false, new TaskDescription(), null);
+        final Task newTask = new Task(sNextTaskId++, stack, userId, sWm, null, EMPTY, 0, false,
+                false, new TaskDescription(), null);
         stack.addTask(newTask, POSITION_TOP);
         return newTask;
     }
@@ -223,7 +223,8 @@
         }
 
         TestWindowToken(int type, DisplayContent dc, boolean persistOnEmpty) {
-            super(sWm, mock(IBinder.class), type, persistOnEmpty, dc);
+            super(sWm, mock(IBinder.class), type, persistOnEmpty, dc,
+                    false /* ownerCanManageAppTokens */);
         }
 
         int getWindowsCount() {
@@ -282,12 +283,10 @@
         private boolean mIsAnimating = false;
 
         TestTask(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
-                Configuration overrideConfig, boolean isOnTopLauncher, int resizeMode,
-                boolean supportsPictureInPicture, boolean homeTask,
-                TaskWindowContainerController controller) {
-            super(taskId, stack, userId, service, bounds, overrideConfig, isOnTopLauncher,
-                    resizeMode, supportsPictureInPicture, homeTask, new TaskDescription(),
-                            controller);
+                Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
+                boolean homeTask, TaskWindowContainerController controller) {
+            super(taskId, stack, userId, service, bounds, overrideConfig, resizeMode,
+                    supportsPictureInPicture, homeTask, new TaskDescription(), controller);
         }
 
         boolean shouldDeferRemoval() {
@@ -338,17 +337,16 @@
                         }
                     }, stackController, 0 /* userId */, null /* bounds */,
                     EMPTY /* overrideConfig*/, RESIZE_MODE_UNRESIZEABLE,
-                    false /* supportsPictureInPicture */, false /* homeTask*/,
-                    false /* isOnTopLauncher */, true /* toTop*/, true /* showForAllUsers */,
-                    new TaskDescription(), sWm);
+                    false /* supportsPictureInPicture */, false /* homeTask*/, true /* toTop*/,
+                    true /* showForAllUsers */, new TaskDescription(), sWm);
         }
 
         @Override
         TestTask createTask(int taskId, TaskStack stack, int userId, Rect bounds,
                 Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-                boolean homeTask, boolean isOnTopLauncher, TaskDescription taskDescription) {
-            return new TestTask(taskId, stack, userId, mService, bounds, overrideConfig,
-                    isOnTopLauncher, resizeMode, supportsPictureInPicture, homeTask, this);
+                boolean homeTask, TaskDescription taskDescription) {
+            return new TestTask(taskId, stack, userId, mService, bounds, overrideConfig, resizeMode,
+                    supportsPictureInPicture, homeTask, this);
         }
     }
 
@@ -403,7 +401,8 @@
         boolean resizeReported;
 
         TestWindowState(WindowManager.LayoutParams attrs, WindowToken token) {
-            super(sWm, sMockSession, sIWindow, token, null, OP_NONE, 0, attrs, 0, 0);
+            super(sWm, sMockSession, sIWindow, token, null, OP_NONE, 0, attrs, 0, 0,
+                    false /* ownerCanAddInternalSystemWindow */);
         }
 
         @Override
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 4d2c3b9..07b4ca1 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -17,6 +17,7 @@
 package com.android.server.usb;
 
 import android.app.Notification;
+import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
@@ -134,6 +135,8 @@
 
     private static final String BOOT_MODE_PROPERTY = "ro.bootmode";
 
+    private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv";
+
     private UsbHandler mHandler;
     private boolean mBootCompleted;
 
@@ -239,6 +242,16 @@
         mNotificationManager = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
 
+        // Ensure that the notification channels are set up
+        if (isTv()) {
+            // TV-specific notification channel
+            mNotificationManager.createNotificationChannel(
+                    new NotificationChannel(ADB_NOTIFICATION_CHANNEL_ID_TV,
+                        mContext.getString(
+                            com.android.internal.R.string.adb_debugging_notification_channel_tv),
+                        NotificationManager.IMPORTANCE_HIGH));
+        }
+
         // We do not show the USB notification if the primary volume supports mass storage.
         // The legacy mass storage UI will be used instead.
         boolean massStorageSupported = false;
@@ -325,6 +338,10 @@
         }
     }
 
+    private boolean isTv() {
+        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+    }
+
     private final class UsbHandler extends Handler {
 
         // current USB state
@@ -928,9 +945,9 @@
                     CharSequence message = r.getText(
                             com.android.internal.R.string.adb_active_notification_message);
 
-                    Intent intent = Intent.makeRestartActivityTask(
-                            new ComponentName("com.android.settings",
-                                    "com.android.settings.DevelopmentSettings"));
+                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
+                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                            | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                     PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
                             intent, 0, null, UserHandle.CURRENT);
 
@@ -947,6 +964,8 @@
                             .setContentText(message)
                             .setContentIntent(pi)
                             .setVisibility(Notification.VISIBILITY_PUBLIC)
+                            .extend(new Notification.TvExtender()
+                                    .setChannel(ADB_NOTIFICATION_CHANNEL_ID_TV))
                             .build();
                     mAdbNotificationShown = true;
                     mNotificationManager.notifyAsUser(null, id, notification,
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index d0ccd55..6e10029 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -98,6 +98,7 @@
     private static final String SESSION_ADD_CS_ADAPTER = "CS.aCSA";
     private static final String SESSION_REMOVE_CS_ADAPTER = "CS.rCSA";
     private static final String SESSION_CREATE_CONN = "CS.crCo";
+    private static final String SESSION_CREATE_CONN_FAILED = "CS.crCoF";
     private static final String SESSION_ABORT = "CS.ab";
     private static final String SESSION_ANSWER = "CS.an";
     private static final String SESSION_ANSWER_VIDEO = "CS.anV";
@@ -142,6 +143,7 @@
     private static final int MSG_PULL_EXTERNAL_CALL = 22;
     private static final int MSG_SEND_CALL_EVENT = 23;
     private static final int MSG_ON_EXTRAS_CHANGED = 24;
+    private static final int MSG_CREATE_CONNECTION_FAILED = 25;
 
     private static Connection sNullConnection;
 
@@ -211,6 +213,25 @@
         }
 
         @Override
+        public void createConnectionFailed(
+                String callId,
+                ConnectionRequest request,
+                boolean isIncoming,
+                Session.Info sessionInfo) {
+            Log.startSession(sessionInfo, SESSION_CREATE_CONN_FAILED);
+            try {
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = callId;
+                args.arg2 = request;
+                args.arg3 = Log.createSubsession();
+                args.argi1 = isIncoming ? 1 : 0;
+                mHandler.obtainMessage(MSG_CREATE_CONNECTION_FAILED, args).sendToTarget();
+            } finally {
+                Log.endSession();
+            }
+        }
+
+        @Override
         public void abort(String callId, Session.Info sessionInfo) {
             Log.startSession(sessionInfo, SESSION_ABORT);
             try {
@@ -552,6 +573,35 @@
                     }
                     break;
                 }
+                case MSG_CREATE_CONNECTION_FAILED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Log.continueSession((Session) args.arg3, SESSION_HANDLER +
+                            SESSION_CREATE_CONN_FAILED);
+                    try {
+                        final String id = (String) args.arg1;
+                        final ConnectionRequest request = (ConnectionRequest) args.arg2;
+                        final boolean isIncoming = args.argi1 == 1;
+                        if (!mAreAccountsInitialized) {
+                            Log.d(this, "Enqueueing pre-init request %s", id);
+                            mPreInitializationConnectionRequests.add(
+                                    new android.telecom.Logging.Runnable(
+                                            SESSION_HANDLER + SESSION_CREATE_CONN_FAILED + ".pICR",
+                                            null /*lock*/) {
+                                        @Override
+                                        public void loggedRun() {
+                                            createConnectionFailed(id, request, isIncoming);
+                                        }
+                                    }.prepare());
+                        } else {
+                            Log.i(this, "createConnectionFailed %s", id);
+                            createConnectionFailed(id, request, isIncoming);
+                        }
+                    } finally {
+                        args.recycle();
+                        Log.endSession();
+                    }
+                    break;
+                }
                 case MSG_ABORT: {
                     SomeArgs args = (SomeArgs) msg.obj;
                     Log.continueSession((Session) args.arg2, SESSION_HANDLER + SESSION_ABORT);
@@ -1175,6 +1225,17 @@
         }
     }
 
+    private void createConnectionFailed(final String callId, final ConnectionRequest request,
+            boolean isIncoming) {
+
+        Log.i(this, "createConnectionFailed %s", callId);
+        if (isIncoming) {
+            onCreateIncomingConnectionFailed(request);
+        } else {
+            onCreateOutgoingConnectionFailed(request);
+        }
+    }
+
     private void abort(String callId) {
         Log.d(this, "abort %s", callId);
         findConnectionForAction(callId, "abort").onAbort();
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index ba7b6a1..96070b8 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1517,6 +1517,10 @@
      *      otherwise.
      */
     public boolean isIncomingCallPermitted(PhoneAccountHandle phoneAccountHandle) {
+        if (phoneAccountHandle == null) {
+            return false;
+        }
+
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
index 8a27675..20feba7 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
@@ -46,6 +46,9 @@
             boolean isUnknown,
             in Session.Info sessionInfo);
 
+    void createConnectionFailed(String callId, in ConnectionRequest request, boolean isIncoming,
+            in Session.Info sessionInfo);
+
     void abort(String callId, in Session.Info sessionInfo);
 
     void answerVideo(String callId, int videoState, in Session.Info sessionInfo);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 6c45233..3b15f1c 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1173,6 +1173,9 @@
      * and {@code NEW_CODE} is the new {@code ImsReasonInfo#CODE_*} which this combination of
      * original code and message shall be remapped to.
      *
+     * Note: If {@code *} is specified for the original code, any ImsReasonInfo with the matching
+     * {@code MESSAGE} will be remapped to {@code NEW_CODE}.
+     *
      * Example: "501|call completion elsewhere|1014"
      * When the {@link ImsReasonInfo#getCode()} is {@link ImsReasonInfo#CODE_USER_TERMINATED} and
      * the {@link ImsReasonInfo#getExtraMessage()} is {@code "call completion elsewhere"},
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index 10cb7c9..e53e246 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -246,23 +246,18 @@
      */
     public static final int IMEI_NOT_ACCEPTED = 58;
 
+    /**
+     * A call over WIFI was disconnected because the WIFI signal was lost or became too degraded to
+     * continue the call.
+     */
+    public static final int WIFI_LOST = 59;
+
     //*********************************************************************************************
     // When adding a disconnect type:
-    // 1) Please assign the new type the next id value below.
-    // 2) Increment the next id value below to a new value.
-    // 3) Update MAXIMUM_VALID_VALUE to the new disconnect type.
-    // 4) Update toString() with the newly added disconnect type.
-    // 5) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause.
-    //
-    // NextId: 59
+    // 1) Update toString() with the newly added disconnect type.
+    // 2) Update android.telecom.DisconnectCauseUtil with any mappings to a telecom.DisconnectCause.
     //*********************************************************************************************
 
-    /** Smallest valid value for call disconnect codes. */
-    public static final int MINIMUM_VALID_VALUE = NOT_DISCONNECTED;
-
-    /** Largest valid value for call disconnect codes. */
-    public static final int MAXIMUM_VALID_VALUE = IMEI_NOT_ACCEPTED;
-
     /** Private constructor to avoid class instantiation. */
     private DisconnectCause() {
         // Do nothing.
@@ -387,6 +382,8 @@
             return "DIALED_CALL_FORWARDING_WHILE_ROAMING";
         case IMEI_NOT_ACCEPTED:
             return "IMEI_NOT_ACCEPTED";
+        case WIFI_LOST:
+            return "WIFI_LOST";
         default:
             return "INVALID: " + cause;
         }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 913da82..1b3aa8a 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -819,37 +819,6 @@
     public static final String EVENT_DOWNGRADE_DATA_DISABLED =
             "android.telephony.event.EVENT_DOWNGRADE_DATA_DISABLED";
 
-    /**
-     * Response codes for sim activation. Activation completed successfully.
-     * @hide
-     */
-    @SystemApi
-    public static final int SIM_ACTIVATION_RESULT_COMPLETE = 0;
-    /**
-     * Response codes for sim activation. Activation not supported (device has no SIM).
-     * @hide
-     */
-    @SystemApi
-    public static final int SIM_ACTIVATION_RESULT_NOT_SUPPORTED = 1;
-    /**
-     * Response codes for sim activation. Activation is in progress.
-     * @hide
-     */
-    @SystemApi
-    public static final int SIM_ACTIVATION_RESULT_IN_PROGRESS = 2;
-    /**
-     * Response codes for sim activation. Activation failed to complete.
-     * @hide
-     */
-    @SystemApi
-    public static final int SIM_ACTIVATION_RESULT_FAILED = 3;
-    /**
-     * Response codes for sim activation. Activation canceled by user.
-     * @hide
-     */
-    @SystemApi
-    public static final int SIM_ACTIVATION_RESULT_CANCELED = 4;
-
     /* Visual voicemail protocols */
 
     /**
diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java
index 56b8822..c71808c 100644
--- a/telephony/java/com/android/ims/ImsReasonInfo.java
+++ b/telephony/java/com/android/ims/ImsReasonInfo.java
@@ -308,6 +308,11 @@
     public static final int CODE_DATA_DISABLED = 1406;
 
     /**
+     * Indicates a call was disconnected due to loss of wifi signal.
+     */
+    public static final int CODE_WIFI_LOST = 1407;
+
+    /**
      * Network string error messages.
      * mExtraMessage may have these values.
      */
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 891b8a1a..5ee7e23 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -417,7 +417,7 @@
     int RIL_UNSOL_RESPONSE_BASE = 1000;
     int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
     int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
-    int RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED = 1002;
+    int RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED = 1002;
     int RIL_UNSOL_RESPONSE_NEW_SMS = 1003;
     int RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT = 1004;
     int RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM = 1005;
diff --git a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
index 6629770..251bf24 100644
--- a/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
+++ b/tests/TransitionTests/src/com/android/transitiontests/ListViewAddRemove.java
@@ -30,8 +30,9 @@
 import android.transition.AutoTransition;
 import android.transition.ChangeBounds;
 import android.transition.Transition;
-import android.transition.TransitionSet;
+import android.transition.TransitionListenerAdapter;
 import android.transition.TransitionManager;
+import android.transition.TransitionSet;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -84,7 +85,7 @@
         fadeIn.setDuration(50);
         noFadeIn.addTransition(new Fade(Fade.OUT)).addTransition(new ChangeBounds()).addTransition(fadeIn);
 
-        myTransition.addListener(new Transition.TransitionListenerAdapter() {
+        myTransition.addListener(new TransitionListenerAdapter() {
             @Override
             public void onTransitionStart(Transition transition) {
                 System.out.println("---------ListView Tops: Before--------");
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
new file mode 100644
index 0000000..b984bbf
--- /dev/null
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -0,0 +1,176 @@
+/*
+ * 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.net;
+
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
+import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class ConnectivityManagerTest {
+    static NetworkCapabilities verifyNetworkCapabilities(
+            int legacyType, int transportType, int... capabilities) {
+        final NetworkCapabilities nc = ConnectivityManager.networkCapabilitiesForType(legacyType);
+        assertNotNull(nc);
+        assertTrue(nc.hasTransport(transportType));
+        for (int capability : capabilities) {
+            assertTrue(nc.hasCapability(capability));
+        }
+
+        return nc;
+    }
+
+    static void verifyUnrestrictedNetworkCapabilities(int legacyType, int transportType) {
+        verifyNetworkCapabilities(
+                legacyType,
+                transportType,
+                NET_CAPABILITY_INTERNET,
+                NET_CAPABILITY_NOT_RESTRICTED,
+                NET_CAPABILITY_NOT_VPN,
+                NET_CAPABILITY_TRUSTED);
+    }
+
+    static void verifyRestrictedMobileNetworkCapabilities(int legacyType, int capability) {
+        final NetworkCapabilities nc = verifyNetworkCapabilities(
+                legacyType,
+                TRANSPORT_CELLULAR,
+                capability,
+                NET_CAPABILITY_NOT_VPN,
+                NET_CAPABILITY_TRUSTED);
+
+        assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
+        assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeMobile() {
+        verifyUnrestrictedNetworkCapabilities(
+                ConnectivityManager.TYPE_MOBILE, TRANSPORT_CELLULAR);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeMobileCbs() {
+        verifyRestrictedMobileNetworkCapabilities(
+                ConnectivityManager.TYPE_MOBILE_CBS, NET_CAPABILITY_CBS);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeMobileDun() {
+        verifyRestrictedMobileNetworkCapabilities(
+                ConnectivityManager.TYPE_MOBILE_DUN, NET_CAPABILITY_DUN);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeMobileFota() {
+        verifyRestrictedMobileNetworkCapabilities(
+                ConnectivityManager.TYPE_MOBILE_FOTA, NET_CAPABILITY_FOTA);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeMobileHipri() {
+        verifyUnrestrictedNetworkCapabilities(
+                ConnectivityManager.TYPE_MOBILE_HIPRI, TRANSPORT_CELLULAR);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeMobileIms() {
+        verifyRestrictedMobileNetworkCapabilities(
+                ConnectivityManager.TYPE_MOBILE_IMS, NET_CAPABILITY_IMS);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeMobileMms() {
+        final NetworkCapabilities nc = verifyNetworkCapabilities(
+                ConnectivityManager.TYPE_MOBILE_MMS,
+                TRANSPORT_CELLULAR,
+                NET_CAPABILITY_MMS,
+                NET_CAPABILITY_NOT_VPN,
+                NET_CAPABILITY_TRUSTED);
+
+        assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeMobileSupl() {
+        final NetworkCapabilities nc = verifyNetworkCapabilities(
+                ConnectivityManager.TYPE_MOBILE_SUPL,
+                TRANSPORT_CELLULAR,
+                NET_CAPABILITY_SUPL,
+                NET_CAPABILITY_NOT_VPN,
+                NET_CAPABILITY_TRUSTED);
+
+        assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeWifi() {
+        verifyUnrestrictedNetworkCapabilities(
+                ConnectivityManager.TYPE_WIFI, TRANSPORT_WIFI);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeWifiP2p() {
+        final NetworkCapabilities nc = verifyNetworkCapabilities(
+                ConnectivityManager.TYPE_WIFI_P2P,
+                TRANSPORT_WIFI,
+                NET_CAPABILITY_NOT_RESTRICTED, NET_CAPABILITY_NOT_VPN,
+                NET_CAPABILITY_TRUSTED, NET_CAPABILITY_WIFI_P2P);
+
+        assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeBluetooth() {
+        verifyUnrestrictedNetworkCapabilities(
+                ConnectivityManager.TYPE_BLUETOOTH, TRANSPORT_BLUETOOTH);
+    }
+
+    @Test
+    public void testNetworkCapabilitiesForTypeEthernet() {
+        verifyUnrestrictedNetworkCapabilities(
+                ConnectivityManager.TYPE_ETHERNET, TRANSPORT_ETHERNET);
+    }
+}
diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
index b8c739b..3ed56df 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
@@ -23,7 +23,13 @@
 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.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.content.Context;
 import android.net.ConnectivityManager;
@@ -40,6 +46,7 @@
 import org.junit.runner.RunWith;
 import org.junit.Test;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.util.HashMap;
@@ -64,7 +71,7 @@
         reset(mContext);
         reset(mCS);
 
-        mCM = new TestConnectivityManager(mContext, mCS);
+        mCM = spy(new TestConnectivityManager(mContext, mCS));
         mUNM = new UpstreamNetworkMonitor(null, EVENT_UNM_UPDATE, (ConnectivityManager) mCM);
     }
 
@@ -126,6 +133,42 @@
     }
 
     @Test
+    public void testDuplicateMobileRequestsIgnored() throws Exception {
+        assertFalse(mUNM.mobileNetworkRequested());
+        assertEquals(0, mCM.requested.size());
+
+        mUNM.start();
+        verify(mCM, Mockito.times(1)).registerNetworkCallback(
+                any(NetworkRequest.class), any(NetworkCallback.class));
+        verify(mCM, Mockito.times(1)).registerDefaultNetworkCallback(any(NetworkCallback.class));
+        assertFalse(mUNM.mobileNetworkRequested());
+        assertEquals(0, mCM.requested.size());
+
+        mUNM.updateMobileRequiresDun(true);
+        mUNM.registerMobileNetworkRequest();
+        verify(mCM, Mockito.times(1)).requestNetwork(
+                any(NetworkRequest.class), any(NetworkCallback.class), anyInt(), anyInt());
+
+        assertTrue(mUNM.mobileNetworkRequested());
+        assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
+        assertTrue(mCM.isDunRequested());
+
+        // Try a few things that must not result in any state change.
+        mUNM.registerMobileNetworkRequest();
+        mUNM.updateMobileRequiresDun(true);
+        mUNM.registerMobileNetworkRequest();
+
+        assertTrue(mUNM.mobileNetworkRequested());
+        assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
+        assertTrue(mCM.isDunRequested());
+
+        mUNM.stop();
+        verify(mCM, times(3)).unregisterNetworkCallback(any(NetworkCallback.class));
+
+        verifyNoMoreInteractions(mCM);
+    }
+
+    @Test
     public void testRequestsDunNetwork() throws Exception {
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
@@ -149,7 +192,7 @@
     }
 
     @Test
-    public void testUpdateMobileRequiredDun() throws Exception {
+    public void testUpdateMobileRequiresDun() throws Exception {
         mUNM.start();
 
         // Test going from no-DUN to DUN correctly re-registers callbacks.
@@ -180,7 +223,7 @@
                 mCM.legacyTypeMap.values().iterator().next());
     }
 
-    private static class TestConnectivityManager extends ConnectivityManager {
+    public static class TestConnectivityManager extends ConnectivityManager {
         public Set<NetworkCallback> trackingDefault = new HashSet<>();
         public Map<NetworkCallback, NetworkRequest> listening = new HashMap<>();
         public Map<NetworkCallback, NetworkRequest> requested = new HashMap<>();
diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp
index 3d466ef..3d7bd94 100644
--- a/tools/aapt2/LoadedApk.cpp
+++ b/tools/aapt2/LoadedApk.cpp
@@ -16,10 +16,15 @@
 
 #include "LoadedApk.h"
 
+#include "ResourceValues.h"
+#include "ValueVisitor.h"
+#include "flatten/Archive.h"
+#include "flatten/TableFlattener.h"
+
 namespace aapt {
 
-std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(
-    IAaptContext* context, const StringPiece& path) {
+std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(IAaptContext* context,
+                                                      const android::StringPiece& path) {
   Source source(path);
   std::string error;
   std::unique_ptr<io::ZipFileCollection> apk =
@@ -53,4 +58,67 @@
   return util::make_unique<LoadedApk>(source, std::move(apk), std::move(table));
 }
 
+bool LoadedApk::WriteToArchive(IAaptContext* context, IArchiveWriter* writer) {
+  std::set<std::string> referenced_resources;
+  // List the files being referenced in the resource table.
+  for (auto& pkg : table_->packages) {
+    for (auto& type : pkg->types) {
+      for (auto& entry : type->entries) {
+        for (auto& config_value : entry->values) {
+          FileReference* file_ref = ValueCast<FileReference>(config_value->value.get());
+          if (file_ref) {
+            referenced_resources.insert(*file_ref->path);
+          }
+        }
+      }
+    }
+  }
+
+  std::unique_ptr<io::IFileCollectionIterator> iterator = apk_->Iterator();
+  while (iterator->HasNext()) {
+    io::IFile* file = iterator->Next();
+
+    std::string path = file->GetSource().path;
+    // The name of the path has the format "<zip-file-name>@<path-to-file>".
+    path = path.substr(path.find("@") + 1);
+
+    // Skip resources that are not referenced if requested.
+    if (path.find("res/") == 0 && referenced_resources.find(path) == referenced_resources.end()) {
+      if (context->IsVerbose()) {
+        context->GetDiagnostics()->Note(DiagMessage()
+                                        << "Removing resource '" << path << "' from APK.");
+      }
+      continue;
+    }
+
+    // The resource table needs to be reserialized since it might have changed.
+    if (path == "resources.arsc") {
+      BigBuffer buffer = BigBuffer(1024);
+      TableFlattener flattener(&buffer);
+      if (!flattener.Consume(context, table_.get())) {
+        return false;
+      }
+
+      if (!writer->StartEntry(path, ArchiveEntry::kAlign) || !writer->WriteEntry(buffer) ||
+          !writer->FinishEntry()) {
+        context->GetDiagnostics()->Error(DiagMessage()
+                                         << "Error when writing file '" << path << "' in APK.");
+        return false;
+      }
+      continue;
+    }
+
+    std::unique_ptr<io::IData> data = file->OpenAsData();
+    uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
+    if (!writer->StartEntry(path, compression_flags) ||
+        !writer->WriteEntry(data->data(), data->size()) || !writer->FinishEntry()) {
+      context->GetDiagnostics()->Error(DiagMessage()
+                                       << "Error when writing file '" << path << "' in APK.");
+      return false;
+    }
+  }
+
+  return true;
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/LoadedApk.h b/tools/aapt2/LoadedApk.h
index 0cc2d22..f8878d1 100644
--- a/tools/aapt2/LoadedApk.h
+++ b/tools/aapt2/LoadedApk.h
@@ -19,12 +19,11 @@
 
 #include "androidfw/StringPiece.h"
 
-#include "io/ZipArchive.h"
 #include "ResourceTable.h"
+#include "flatten/Archive.h"
+#include "io/ZipArchive.h"
 #include "unflatten/BinaryResourceParser.h"
 
-using android::StringPiece;
-
 namespace aapt {
 
 /** Info about an APK loaded in memory. */
@@ -42,8 +41,14 @@
 
   const Source& GetSource() { return source_; }
 
-  static std::unique_ptr<LoadedApk> LoadApkFromPath(
-      IAaptContext* context, const StringPiece& path);
+  /**
+   * Writes the APK on disk at the given path, while also removing the resource
+   * files that are not referenced in the resource table.
+   */
+  bool WriteToArchive(IAaptContext* context, IArchiveWriter* writer);
+
+  static std::unique_ptr<LoadedApk> LoadApkFromPath(IAaptContext* context,
+                                                    const android::StringPiece& path);
 
  private:
   Source source_;
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 3ed698b..227ffa3 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -25,7 +25,7 @@
 static const char* sMajorVersion = "2";
 
 // Update minor version whenever a feature or flag is added.
-static const char* sMinorVersion = "5";
+static const char* sMinorVersion = "6";
 
 int PrintVersion() {
   std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "."
diff --git a/tools/aapt2/Resource.cpp b/tools/aapt2/Resource.cpp
index fdabce1..35971e7 100644
--- a/tools/aapt2/Resource.cpp
+++ b/tools/aapt2/Resource.cpp
@@ -39,6 +39,8 @@
       return "bool";
     case ResourceType::kColor:
       return "color";
+    case ResourceType::kConfigVarying:
+      return "configVarying";
     case ResourceType::kDimen:
       return "dimen";
     case ResourceType::kDrawable:
@@ -85,6 +87,7 @@
     {"^attr-private", ResourceType::kAttrPrivate},
     {"bool", ResourceType::kBool},
     {"color", ResourceType::kColor},
+    {"configVarying", ResourceType::kConfigVarying},
     {"dimen", ResourceType::kDimen},
     {"drawable", ResourceType::kDrawable},
     {"font", ResourceType::kFont},
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index 1950ea3..4d915d9 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -44,6 +44,11 @@
   kAttrPrivate,
   kBool,
   kColor,
+
+  // Not really a type, but it shows up in some CTS tests and
+  // we need to continue respecting it.
+  kConfigVarying,
+
   kDimen,
   kDrawable,
   kFont,
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 79379fe..1c750c6 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -338,50 +338,52 @@
   using BagParseFunc = std::function<bool(ResourceParser*, xml::XmlPullParser*,
                                           ParsedResource*)>;
 
-  static const auto elToItemMap =
-      ImmutableMap<std::string, ItemTypeFormat>::CreatePreSorted({
-          {"bool", {ResourceType::kBool, android::ResTable_map::TYPE_BOOLEAN}},
-          {"color", {ResourceType::kColor, android::ResTable_map::TYPE_COLOR}},
-          {"dimen",
-           {ResourceType::kDimen, android::ResTable_map::TYPE_FLOAT |
-                                      android::ResTable_map::TYPE_FRACTION |
-                                      android::ResTable_map::TYPE_DIMENSION}},
-          {"drawable",
-           {ResourceType::kDrawable, android::ResTable_map::TYPE_COLOR}},
-          {"fraction",
-           {ResourceType::kFraction,
-            android::ResTable_map::TYPE_FLOAT |
-                android::ResTable_map::TYPE_FRACTION |
-                android::ResTable_map::TYPE_DIMENSION}},
-          {"integer",
-           {ResourceType::kInteger, android::ResTable_map::TYPE_INTEGER}},
-          {"string",
-           {ResourceType::kString, android::ResTable_map::TYPE_STRING}},
-      });
+  static const auto elToItemMap = ImmutableMap<std::string, ItemTypeFormat>::CreatePreSorted({
+      {"bool", {ResourceType::kBool, android::ResTable_map::TYPE_BOOLEAN}},
+      {"color", {ResourceType::kColor, android::ResTable_map::TYPE_COLOR}},
+      {"configVarying", {ResourceType::kConfigVarying, android::ResTable_map::TYPE_ANY}},
+      {"dimen",
+       {ResourceType::kDimen,
+        android::ResTable_map::TYPE_FLOAT | android::ResTable_map::TYPE_FRACTION |
+            android::ResTable_map::TYPE_DIMENSION}},
+      {"drawable", {ResourceType::kDrawable, android::ResTable_map::TYPE_COLOR}},
+      {"fraction",
+       {ResourceType::kFraction,
+        android::ResTable_map::TYPE_FLOAT | android::ResTable_map::TYPE_FRACTION |
+            android::ResTable_map::TYPE_DIMENSION}},
+      {"integer", {ResourceType::kInteger, android::ResTable_map::TYPE_INTEGER}},
+      {"string", {ResourceType::kString, android::ResTable_map::TYPE_STRING}},
+  });
 
-  static const auto elToBagMap =
-      ImmutableMap<std::string, BagParseFunc>::CreatePreSorted({
-          {"add-resource", std::mem_fn(&ResourceParser::ParseAddResource)},
-          {"array", std::mem_fn(&ResourceParser::ParseArray)},
-          {"attr", std::mem_fn(&ResourceParser::ParseAttr)},
-          {"declare-styleable",
-           std::mem_fn(&ResourceParser::ParseDeclareStyleable)},
-          {"integer-array", std::mem_fn(&ResourceParser::ParseIntegerArray)},
-          {"java-symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
-          {"plurals", std::mem_fn(&ResourceParser::ParsePlural)},
-          {"public", std::mem_fn(&ResourceParser::ParsePublic)},
-          {"public-group", std::mem_fn(&ResourceParser::ParsePublicGroup)},
-          {"string-array", std::mem_fn(&ResourceParser::ParseStringArray)},
-          {"style", std::mem_fn(&ResourceParser::ParseStyle)},
-          {"symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
-      });
+  static const auto elToBagMap = ImmutableMap<std::string, BagParseFunc>::CreatePreSorted({
+      {"add-resource", std::mem_fn(&ResourceParser::ParseAddResource)},
+      {"array", std::mem_fn(&ResourceParser::ParseArray)},
+      {"attr", std::mem_fn(&ResourceParser::ParseAttr)},
+      {"configVarying",
+       std::bind(&ResourceParser::ParseStyle, std::placeholders::_1, ResourceType::kConfigVarying,
+                 std::placeholders::_2, std::placeholders::_3)},
+      {"declare-styleable", std::mem_fn(&ResourceParser::ParseDeclareStyleable)},
+      {"integer-array", std::mem_fn(&ResourceParser::ParseIntegerArray)},
+      {"java-symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
+      {"plurals", std::mem_fn(&ResourceParser::ParsePlural)},
+      {"public", std::mem_fn(&ResourceParser::ParsePublic)},
+      {"public-group", std::mem_fn(&ResourceParser::ParsePublicGroup)},
+      {"string-array", std::mem_fn(&ResourceParser::ParseStringArray)},
+      {"style", std::bind(&ResourceParser::ParseStyle, std::placeholders::_1, ResourceType::kStyle,
+                          std::placeholders::_2, std::placeholders::_3)},
+      {"symbol", std::mem_fn(&ResourceParser::ParseSymbol)},
+  });
 
   std::string resource_type = parser->element_name();
 
   // The value format accepted for this resource.
   uint32_t resource_format = 0u;
 
+  bool can_be_item = true;
+  bool can_be_bag = true;
   if (resource_type == "item") {
+    can_be_bag = false;
+
     // Items have their type encoded in the type attribute.
     if (Maybe<StringPiece> maybe_type =
             xml::FindNonEmptyAttribute(parser, "type")) {
@@ -406,6 +408,17 @@
         return false;
       }
     }
+  } else if (resource_type == "bag") {
+    can_be_item = false;
+
+    // Bags have their type encoded in the type attribute.
+    if (Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
+      resource_type = maybe_type.value().to_string();
+    } else {
+      diag_->Error(DiagMessage(source_.WithLine(parser->line_number()))
+                   << "<bag> must have a 'type' attribute");
+      return false;
+    }
   }
 
   // Get the name of the resource. This will be checked later, because not all
@@ -426,36 +439,61 @@
     return true;
   }
 
-  const auto item_iter = elToItemMap.find(resource_type);
-  if (item_iter != elToItemMap.end()) {
-    // This is an item, record its type and format and start parsing.
+  if (can_be_item) {
+    const auto item_iter = elToItemMap.find(resource_type);
+    if (item_iter != elToItemMap.end()) {
+      // This is an item, record its type and format and start parsing.
 
-    if (!maybe_name) {
-      diag_->Error(DiagMessage(out_resource->source)
-                   << "<" << parser->element_name()
-                   << "> missing 'name' attribute");
-      return false;
+      if (!maybe_name) {
+        diag_->Error(DiagMessage(out_resource->source)
+                     << "<" << parser->element_name() << "> missing 'name' attribute");
+        return false;
+      }
+
+      out_resource->name.type = item_iter->second.type;
+      out_resource->name.entry = maybe_name.value().to_string();
+
+      // Only use the implicit format for this type if it wasn't overridden.
+      if (!resource_format) {
+        resource_format = item_iter->second.format;
+      }
+
+      if (!ParseItem(parser, out_resource, resource_format)) {
+        return false;
+      }
+      return true;
     }
-
-    out_resource->name.type = item_iter->second.type;
-    out_resource->name.entry = maybe_name.value().to_string();
-
-    // Only use the implicit format for this type if it wasn't overridden.
-    if (!resource_format) {
-      resource_format = item_iter->second.format;
-    }
-
-    if (!ParseItem(parser, out_resource, resource_format)) {
-      return false;
-    }
-    return true;
   }
 
   // This might be a bag or something.
-  const auto bag_iter = elToBagMap.find(resource_type);
-  if (bag_iter != elToBagMap.end()) {
-    // Ensure we have a name (unless this is a <public-group>).
-    if (resource_type != "public-group") {
+  if (can_be_bag) {
+    const auto bag_iter = elToBagMap.find(resource_type);
+    if (bag_iter != elToBagMap.end()) {
+      // Ensure we have a name (unless this is a <public-group>).
+      if (resource_type != "public-group") {
+        if (!maybe_name) {
+          diag_->Error(DiagMessage(out_resource->source)
+                       << "<" << parser->element_name() << "> missing 'name' attribute");
+          return false;
+        }
+
+        out_resource->name.entry = maybe_name.value().to_string();
+      }
+
+      // Call the associated parse method. The type will be filled in by the
+      // parse func.
+      if (!bag_iter->second(this, parser, out_resource)) {
+        return false;
+      }
+      return true;
+    }
+  }
+
+  if (can_be_item) {
+    // Try parsing the elementName (or type) as a resource. These shall only be
+    // resources like 'layout' or 'xml' and they can only be references.
+    const ResourceType* parsed_type = ParseResourceType(resource_type);
+    if (parsed_type) {
       if (!maybe_name) {
         diag_->Error(DiagMessage(out_resource->source)
                      << "<" << parser->element_name()
@@ -463,39 +501,16 @@
         return false;
       }
 
+      out_resource->name.type = *parsed_type;
       out_resource->name.entry = maybe_name.value().to_string();
+      out_resource->value = ParseXml(parser, android::ResTable_map::TYPE_REFERENCE, kNoRawString);
+      if (!out_resource->value) {
+        diag_->Error(DiagMessage(out_resource->source)
+                     << "invalid value for type '" << *parsed_type << "'. Expected a reference");
+        return false;
+      }
+      return true;
     }
-
-    // Call the associated parse method. The type will be filled in by the
-    // parse func.
-    if (!bag_iter->second(this, parser, out_resource)) {
-      return false;
-    }
-    return true;
-  }
-
-  // Try parsing the elementName (or type) as a resource. These shall only be
-  // resources like 'layout' or 'xml' and they can only be references.
-  const ResourceType* parsed_type = ParseResourceType(resource_type);
-  if (parsed_type) {
-    if (!maybe_name) {
-      diag_->Error(DiagMessage(out_resource->source)
-                   << "<" << parser->element_name()
-                   << "> missing 'name' attribute");
-      return false;
-    }
-
-    out_resource->name.type = *parsed_type;
-    out_resource->name.entry = maybe_name.value().to_string();
-    out_resource->value =
-        ParseXml(parser, android::ResTable_map::TYPE_REFERENCE, kNoRawString);
-    if (!out_resource->value) {
-      diag_->Error(DiagMessage(out_resource->source)
-                   << "invalid value for type '" << *parsed_type
-                   << "'. Expected a reference");
-      return false;
-    }
-    return true;
   }
 
   diag_->Warn(DiagMessage(out_resource->source)
@@ -1048,9 +1063,9 @@
   return true;
 }
 
-bool ResourceParser::ParseStyle(xml::XmlPullParser* parser,
+bool ResourceParser::ParseStyle(const ResourceType type, xml::XmlPullParser* parser,
                                 ParsedResource* out_resource) {
-  out_resource->name.type = ResourceType::kStyle;
+  out_resource->name.type = type;
 
   std::unique_ptr<Style> style = util::make_unique<Style>();
 
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index c12dacf..cc0fa26 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -102,7 +102,8 @@
                      bool weak);
   Maybe<Attribute::Symbol> ParseEnumOrFlagItem(xml::XmlPullParser* parser,
                                                const android::StringPiece& tag);
-  bool ParseStyle(xml::XmlPullParser* parser, ParsedResource* out_resource);
+  bool ParseStyle(const ResourceType type, xml::XmlPullParser* parser,
+                  ParsedResource* out_resource);
   bool ParseStyleItem(xml::XmlPullParser* parser, Style* style);
   bool ParseDeclareStyleable(xml::XmlPullParser* parser,
                              ParsedResource* out_resource);
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 5762fb0..cf901da 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -719,4 +719,23 @@
   EXPECT_EQ(uint32_t(android::Res_value::TYPE_FLOAT), val->value.dataType);
 }
 
+TEST_F(ResourceParserTest, ParseConfigVaryingItem) {
+  std::string input = R"EOF(<item name="foo" type="configVarying">Hey</item>)EOF";
+  ASSERT_TRUE(TestParse(input));
+  ASSERT_NE(nullptr, test::GetValue<String>(&table_, "configVarying/foo"));
+}
+
+TEST_F(ResourceParserTest, ParseBagElement) {
+  std::string input =
+      R"EOF(<bag name="bag" type="configVarying"><item name="test">Hello!</item></bag>)EOF";
+  ASSERT_TRUE(TestParse(input));
+
+  Style* val = test::GetValue<Style>(&table_, "configVarying/bag");
+  ASSERT_NE(nullptr, val);
+
+  ASSERT_EQ(1u, val->entries.size());
+  EXPECT_EQ(Reference(test::ParseNameOrDie("attr/test")), val->entries[0].key);
+  EXPECT_NE(nullptr, ValueCast<RawString>(val->entries[0].value.get()));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/Resource_test.cpp b/tools/aapt2/Resource_test.cpp
index 6acb4d3..ad4e3ce 100644
--- a/tools/aapt2/Resource_test.cpp
+++ b/tools/aapt2/Resource_test.cpp
@@ -49,6 +49,10 @@
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kColor);
 
+  type = ParseResourceType("configVarying");
+  ASSERT_NE(type, nullptr);
+  EXPECT_EQ(*type, ResourceType::kConfigVarying);
+
   type = ParseResourceType("dimen");
   ASSERT_NE(type, nullptr);
   EXPECT_EQ(*type, ResourceType::kDimen);
diff --git a/tools/aapt2/io/File.h b/tools/aapt2/io/File.h
index 3d5b5b1..1ef9743 100644
--- a/tools/aapt2/io/File.h
+++ b/tools/aapt2/io/File.h
@@ -63,6 +63,11 @@
 
   IFile* CreateFileSegment(size_t offset, size_t len);
 
+  /** Returns whether the file was compressed before it was stored in memory. */
+  virtual bool WasCompressed() {
+    return false;
+  }
+
  private:
   // Any segments created from this IFile need to be owned by this IFile, so
   // keep them
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index 62b436f..6494d2d 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -59,6 +59,10 @@
 
 const Source& ZipFile::GetSource() const { return source_; }
 
+bool ZipFile::WasCompressed() {
+  return zip_entry_.method != kCompressStored;
+}
+
 ZipFileCollectionIterator::ZipFileCollectionIterator(
     ZipFileCollection* collection)
     : current_(collection->files_.begin()), end_(collection->files_.end()) {}
@@ -66,7 +70,7 @@
 bool ZipFileCollectionIterator::HasNext() { return current_ != end_; }
 
 IFile* ZipFileCollectionIterator::Next() {
-  IFile* result = current_->second.get();
+  IFile* result = current_->get();
   ++current_;
   return result;
 }
@@ -110,8 +114,10 @@
         std::string(reinterpret_cast<const char*>(zip_entry_name.name),
                     zip_entry_name.name_length);
     std::string nested_path = path.to_string() + "@" + zip_entry_path;
-    collection->files_[zip_entry_path] = util::make_unique<ZipFile>(
-        collection->handle_, zip_data, Source(nested_path));
+    std::unique_ptr<IFile> file =
+        util::make_unique<ZipFile>(collection->handle_, zip_data, Source(nested_path));
+    collection->files_by_name_[zip_entry_path] = file.get();
+    collection->files_.push_back(std::move(file));
   }
 
   if (result != -1) {
@@ -122,9 +128,9 @@
 }
 
 IFile* ZipFileCollection::FindFile(const StringPiece& path) {
-  auto iter = files_.find(path.to_string());
-  if (iter != files_.end()) {
-    return iter->second.get();
+  auto iter = files_by_name_.find(path.to_string());
+  if (iter != files_by_name_.end()) {
+    return iter->second;
   }
   return nullptr;
 }
diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h
index 634adad..56c74e3 100644
--- a/tools/aapt2/io/ZipArchive.h
+++ b/tools/aapt2/io/ZipArchive.h
@@ -40,6 +40,7 @@
 
   std::unique_ptr<IData> OpenAsData() override;
   const Source& GetSource() const override;
+  bool WasCompressed() override;
 
  private:
   ZipArchiveHandle zip_handle_;
@@ -57,7 +58,7 @@
   io::IFile* Next() override;
 
  private:
-  std::map<std::string, std::unique_ptr<IFile>>::const_iterator current_, end_;
+  std::vector<std::unique_ptr<IFile>>::const_iterator current_, end_;
 };
 
 /**
@@ -78,7 +79,8 @@
   ZipFileCollection();
 
   ZipArchiveHandle handle_;
-  std::map<std::string, std::unique_ptr<IFile>> files_;
+  std::vector<std::unique_ptr<IFile>> files_;
+  std::map<std::string, IFile*> files_by_name_;
 };
 
 }  // namespace io
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index e5eaf2f..b4cf4f8 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -111,6 +111,36 @@
   return true;
 }
 
+// Checks that <uses-feature> has android:glEsVersion or android:name, not both (or neither).
+static bool VerifyUsesFeature(xml::Element* el, SourcePathDiagnostics* diag) {
+  bool has_name = false;
+  if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "name")) {
+    if (attr->value.empty()) {
+      diag->Error(DiagMessage(el->line_number)
+                  << "android:name in <uses-feature> must not be empty");
+      return false;
+    }
+    has_name = true;
+  }
+
+  bool has_gl_es_version = false;
+  if (xml::Attribute* attr = el->FindAttribute(xml::kSchemaAndroid, "glEsVersion")) {
+    if (has_name) {
+      diag->Error(DiagMessage(el->line_number)
+                  << "cannot define both android:name and android:glEsVersion in <uses-feature>");
+      return false;
+    }
+    has_gl_es_version = true;
+  }
+
+  if (!has_name && !has_gl_es_version) {
+    diag->Error(DiagMessage(el->line_number)
+                << "<uses-feature> must have either android:name or android:glEsVersion attribute");
+    return false;
+  }
+  return true;
+}
+
 bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
                                IDiagnostics* diag) {
   // First verify some options.
@@ -134,15 +164,25 @@
     }
   }
 
-  // Common intent-filter actions.
+  // Common <intent-filter> actions.
   xml::XmlNodeAction intent_filter_action;
   intent_filter_action["action"];
   intent_filter_action["category"];
   intent_filter_action["data"];
 
-  // Common meta-data actions.
+  // Common <meta-data> actions.
   xml::XmlNodeAction meta_data_action;
 
+  // Common <uses-feature> actions.
+  xml::XmlNodeAction uses_feature_action;
+  uses_feature_action.Action(VerifyUsesFeature);
+
+  // Common component actions.
+  xml::XmlNodeAction component_action;
+  component_action.Action(RequiredNameIsJavaClassName);
+  component_action["intent-filter"] = intent_filter_action;
+  component_action["meta-data"] = meta_data_action;
+
   // Manifest actions.
   xml::XmlNodeAction& manifest_action = (*executor)["manifest"];
   manifest_action.Action(VerifyManifest);
@@ -190,6 +230,7 @@
   });
 
   // Instrumentation actions.
+  manifest_action["instrumentation"].Action(RequiredNameIsJavaClassName);
   manifest_action["instrumentation"].Action([&](xml::Element* el) -> bool {
     if (!options_.rename_instrumentation_target_package) {
       return true;
@@ -201,6 +242,7 @@
     }
     return true;
   });
+  manifest_action["instrumentation"]["meta-data"] = meta_data_action;
 
   manifest_action["original-package"];
   manifest_action["protected-broadcast"];
@@ -208,51 +250,28 @@
   manifest_action["permission"];
   manifest_action["permission-tree"];
   manifest_action["permission-group"];
-
   manifest_action["uses-configuration"];
-  manifest_action["uses-feature"];
   manifest_action["supports-screens"];
-
+  manifest_action["uses-feature"] = uses_feature_action;
+  manifest_action["feature-group"]["uses-feature"] = uses_feature_action;
   manifest_action["compatible-screens"];
   manifest_action["compatible-screens"]["screen"];
-
   manifest_action["supports-gl-texture"];
-
   manifest_action["meta-data"] = meta_data_action;
 
   // Application actions.
   xml::XmlNodeAction& application_action = manifest_action["application"];
   application_action.Action(OptionalNameIsJavaClassName);
 
-  // Uses library actions.
   application_action["uses-library"];
-
-  // Meta-data.
   application_action["meta-data"] = meta_data_action;
-
-  // Activity actions.
-  application_action["activity"].Action(RequiredNameIsJavaClassName);
-  application_action["activity"]["intent-filter"] = intent_filter_action;
-  application_action["activity"]["meta-data"] = meta_data_action;
-
-  // Activity alias actions.
-  application_action["activity-alias"]["intent-filter"] = intent_filter_action;
-  application_action["activity-alias"]["meta-data"] = meta_data_action;
-
-  // Service actions.
-  application_action["service"].Action(RequiredNameIsJavaClassName);
-  application_action["service"]["intent-filter"] = intent_filter_action;
-  application_action["service"]["meta-data"] = meta_data_action;
-
-  // Receiver actions.
-  application_action["receiver"].Action(RequiredNameIsJavaClassName);
-  application_action["receiver"]["intent-filter"] = intent_filter_action;
-  application_action["receiver"]["meta-data"] = meta_data_action;
+  application_action["activity"] = component_action;
+  application_action["activity-alias"] = component_action;
+  application_action["service"] = component_action;
+  application_action["receiver"] = component_action;
 
   // Provider actions.
-  application_action["provider"].Action(RequiredNameIsJavaClassName);
-  application_action["provider"]["intent-filter"] = intent_filter_action;
-  application_action["provider"]["meta-data"] = meta_data_action;
+  application_action["provider"] = component_action;
   application_action["provider"]["grant-uri-permissions"];
   application_action["provider"]["path-permissions"];
 
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 12a304a..ce84993 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -90,7 +90,7 @@
 }
 
 TEST_F(ManifestFixerTest, AllowMetaData) {
-    auto doc = Verify(R"EOF(
+  auto doc = Verify(R"EOF(
         <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                   package="android">
           <meta-data />
@@ -98,12 +98,13 @@
             <meta-data />
             <activity android:name=".Hi"><meta-data /></activity>
             <activity-alias android:name=".Ho"><meta-data /></activity-alias>
-            <receiver android:name=".OffToWork"><meta-data /></receiver>
-            <provider android:name=".We"><meta-data /></provider>
-            <service android:name=".Go"><meta-data /></service>
+            <receiver android:name=".OffTo"><meta-data /></receiver>
+            <provider android:name=".Work"><meta-data /></provider>
+            <service android:name=".We"><meta-data /></service>
           </application>
+          <instrumentation android:name=".Go"><meta-data /></instrumentation>
         </manifest>)EOF");
-    ASSERT_NE(nullptr, doc);
+  ASSERT_NE(nullptr, doc);
 }
 
 TEST_F(ManifestFixerTest, UseDefaultSdkVersionsIfNonePresent) {
@@ -290,7 +291,7 @@
   std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"
                 package="android">
-        <instrumentation android:targetPackage="android" />
+        <instrumentation android:name=".TestRunner" android:targetPackage="android" />
       </manifest>)EOF",
                                                             options);
   ASSERT_NE(nullptr, doc);
@@ -354,4 +355,51 @@
   EXPECT_NE(nullptr, ValueCast<BinaryPrimitive>(attr->compiled_value.get()));
 }
 
+TEST_F(ManifestFixerTest, UsesFeatureMustHaveNameOrGlEsVersion) {
+  std::string input = R"EOF(
+        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                  package="android">
+          <uses-feature android:name="feature" />
+          <uses-feature android:glEsVersion="1" />
+          <feature-group />
+          <feature-group>
+            <uses-feature android:name="feature_in_group" />
+            <uses-feature android:glEsVersion="2" />
+          </feature-group>
+        </manifest>)EOF";
+  EXPECT_NE(nullptr, Verify(input));
+
+  input = R"EOF(
+        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                  package="android">
+          <uses-feature android:name="feature" android:glEsVersion="1" />
+        </manifest>)EOF";
+  EXPECT_EQ(nullptr, Verify(input));
+
+  input = R"EOF(
+        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                  package="android">
+          <uses-feature />
+        </manifest>)EOF";
+  EXPECT_EQ(nullptr, Verify(input));
+
+  input = R"EOF(
+        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                  package="android">
+          <feature-group>
+            <uses-feature android:name="feature" android:glEsVersion="1" />
+          </feature-group>
+        </manifest>)EOF";
+  EXPECT_EQ(nullptr, Verify(input));
+
+  input = R"EOF(
+        <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+                  package="android">
+          <feature-group>
+            <uses-feature />
+          </feature-group>
+        </manifest>)EOF";
+  EXPECT_EQ(nullptr, Verify(input));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md
index e2a752e..44d22c4 100644
--- a/tools/aapt2/readme.md
+++ b/tools/aapt2/readme.md
@@ -1,5 +1,12 @@
 # Android Asset Packaging Tool 2.0 (AAPT2) release notes
 
+## Version 2.6
+### `aapt2`
+- Support legacy `configVarying` resource type.
+- Support `<bag>` tag and treat as `<style>` regardless of type.
+- Add `<feature-group>` manifest tag verification.
+- Add `<meta-data>` tag support to `<instrumentation>`.
+
 ## Version 2.5
 ### `aapt2 link ...`
 - Transition XML versioning: Adds a new flag `--no-version-transitions` to disable automatic
diff --git a/tools/aapt2/strip/Strip.cpp b/tools/aapt2/strip/Strip.cpp
index b3787ec..c34cfbf3 100644
--- a/tools/aapt2/strip/Strip.cpp
+++ b/tools/aapt2/strip/Strip.cpp
@@ -22,6 +22,7 @@
 #include "Diagnostics.h"
 #include "Flags.h"
 #include "LoadedApk.h"
+#include "split/TableSplitter.h"
 
 using android::StringPiece;
 
@@ -78,7 +79,27 @@
       context_->GetDiagnostics()->Note(DiagMessage() << "Stripping APK...");
     }
 
-    // TODO(lecesne): Implement stripping here.
+    // TODO(lecesne): Add support for more than one density.
+    if (options_.target_configs.size() > 1) {
+      context_->GetDiagnostics()->Error(DiagMessage()
+                                        << "Multiple densities not supported at the moment");
+      return 1;
+    }
+
+    // Stripping the APK using the TableSplitter with no splits and the target
+    // density as the preferred density. The resource table is modified in
+    // place in the LoadedApk.
+    TableSplitterOptions splitter_options;
+    splitter_options.preferred_density = options_.target_configs[0].density;
+    std::vector<SplitConstraints> splits;
+    TableSplitter splitter(splits, splitter_options);
+    splitter.SplitTable(apk->GetResourceTable());
+
+    std::unique_ptr<IArchiveWriter> writer =
+        CreateZipFileArchiveWriter(context_->GetDiagnostics(), options_.output_path);
+    if (!apk->WriteToArchive(context_, writer.get())) {
+      return 1;
+    }
 
     return 0;
   }
diff --git a/tools/aapt2/unflatten/BinaryResourceParser.cpp b/tools/aapt2/unflatten/BinaryResourceParser.cpp
index aeabcff..7098fe9 100644
--- a/tools/aapt2/unflatten/BinaryResourceParser.cpp
+++ b/tools/aapt2/unflatten/BinaryResourceParser.cpp
@@ -370,8 +370,7 @@
       return false;
     }
 
-    if (!table_->AddResourceAllowMangled(name, config, {},
-                                         std::move(resource_value),
+    if (!table_->AddResourceAllowMangled(name, res_id, config, {}, std::move(resource_value),
                                          context_->GetDiagnostics())) {
       return false;
     }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index 9d9d71f..8c6740c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -636,6 +636,20 @@
                 Bitmap.getDefaultDensity());
     }
 
+    @LayoutlibDelegate
+    /*package*/ static Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer) {
+        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+                "Bitmap.nativeCreateHardwareBitmap() is not supported", null /*data*/);
+        return null;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap) {
+        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED,
+                "Bitmap.nativeCreateGraphicBufferHandle() is not supported", null /*data*/);
+        return null;
+    }
+
     // ---- Private delegate/helper methods ----
 
     private Bitmap_Delegate(BufferedImage image, Config config) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index c599e9d..47216ee 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -209,20 +209,20 @@
     }
 
     @LayoutlibDelegate
-    public static void nRestore(long nativeCanvas, boolean throwOnUnderflow) {
+    public static boolean nRestore(long nativeCanvas) {
         // FIXME: implement throwOnUnderflow.
         // get the delegate from the native int.
         Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
         if (canvasDelegate == null) {
-            return;
+            return false;
         }
 
         canvasDelegate.restore();
+        return true;
     }
 
     @LayoutlibDelegate
-    public static void nRestoreToCount(long nativeCanvas, int saveCount,
-            boolean throwOnUnderflow) {
+    public static void nRestoreToCount(long nativeCanvas, int saveCount) {
         // FIXME: implement throwOnUnderflow.
         // get the delegate from the native int.
         Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(nativeCanvas);
@@ -427,7 +427,7 @@
     }
 
     @LayoutlibDelegate
-    public static void nGetCTM(long canvas, long matrix) {
+    public static void nGetMatrix(long canvas, long matrix) {
         // get the delegate from the native int.
         Canvas_Delegate canvasDelegate = Canvas_Delegate.getDelegate(canvas);
         if (canvasDelegate == null) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index 147ed99..a43e545 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -313,7 +313,8 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static boolean nAddFontFromAsset(long builderPtr, AssetManager mgr, String path) {
+    /*package*/ static boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, String path,
+            int cookie, boolean isAsset) {
         FontFamily_Delegate ffd = sManager.getDelegate(builderPtr);
         if (ffd == null) {
             return false;
@@ -388,6 +389,10 @@
         return false;
     }
 
+    @LayoutlibDelegate
+    /*package*/ static void nAbort(long builderPtr) {
+        sManager.removeJavaReferenceFor(builderPtr);
+    }
 
     // ---- private helper methods ----
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 9b8fa99..aa1f00d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -1062,8 +1062,6 @@
 
     @LayoutlibDelegate
     /*package*/ static void nSetWordSpacing(long nativePaint, float wordSpacing) {
-        Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
-                "Paint.setWordSpacing() not supported.", null, null);
         Paint_Delegate delegate = sManager.getDelegate(nativePaint);
         if (delegate == null) {
             return;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index f6c463f..11328dc 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -16,12 +16,14 @@
 
 package android.graphics;
 
-import android.text.FontConfig;
+import com.android.ide.common.rendering.api.LayoutLog;
+import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
 import android.annotation.NonNull;
 import android.graphics.FontFamily_Delegate.FontVariant;
+import android.text.FontConfig;
 
 import java.awt.Font;
 import java.io.File;
@@ -160,6 +162,18 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static synchronized long nativeCreateFromTypefaceWithVariation(long native_instance,
+            List<FontConfig.Axis> axes) {
+        long newInstance = nativeCreateFromTypeface(native_instance, 0);
+
+        if (newInstance != 0) {
+            Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                    "nativeCreateFromTypefaceWithVariation is not supported", null, null);
+        }
+        return newInstance;
+    }
+
+    @LayoutlibDelegate
     /*package*/ static long nativeCreateWeightAlias(long native_instance, int weight) {
         Typeface_Delegate delegate = sManager.getDelegate(native_instance);
         if (delegate == null) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
index 430607a..eee7473 100644
--- a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
@@ -156,7 +156,7 @@
         bounds.offsetTo(0, 0);
         nativePathRenderer.draw(canvasWrapperPtr, colorFilterPtr, bounds.width(), bounds.height());
 
-        Canvas_Delegate.nRestore(canvasWrapperPtr, true);
+        Canvas_Delegate.nRestore(canvasWrapperPtr);
 
         return bounds.width() * bounds.height();
     }
@@ -1122,7 +1122,7 @@
                     drawPath(currentGroup, childPath, canvasPtr, w, h, filterPtr);
                 }
             }
-            Canvas_Delegate.nRestore(canvasPtr, true);
+            Canvas_Delegate.nRestore(canvasPtr);
         }
 
         public void draw(long canvasPtr, long filterPtr, int w, int h) {
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
index 65c0a07..970c7d5 100644
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -75,7 +75,8 @@
     /*package*/ static void nSetupParagraph(long nativeBuilder, char[] text, int length,
             float firstWidth, int firstWidthLineCount, float restWidth,
             int[] variableTabStops, int defaultTabStop, int breakStrategy,
-            int hyphenationFrequency) {
+            int hyphenationFrequency, boolean isJustified) {
+        // TODO: implement justified alignment
         Builder builder = sBuilderManager.getDelegate(nativeBuilder);
         if (builder == null) {
             return;
diff --git a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
index a801cb0..152878b 100644
--- a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java
@@ -57,7 +57,7 @@
     private String mName;
 
     @LayoutlibDelegate
-    /*package*/ static long nCreate(RenderNode thisRenderNode, String name) {
+    /*package*/ static long nCreate(String name) {
         RenderNode_Delegate renderNodeDelegate = new RenderNode_Delegate();
         renderNodeDelegate.mName = name;
         return sManager.addNewDelegate(renderNodeDelegate);
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ab725e2..3fb8ef3 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -973,7 +973,6 @@
      *
      * @param config The Passpoint configuration to be added
      * @return true on success
-     * @hide
      */
     public boolean addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
         try {
@@ -988,7 +987,6 @@
      *
      * @param fqdn The FQDN of the passpoint configuration to be removed
      * @return true on success
-     * @hide
      */
     public boolean removePasspointConfiguration(String fqdn) {
         try {
@@ -1004,7 +1002,6 @@
      * An empty list will be returned when no configurations are installed.
      *
      * @return A list of {@link PasspointConfiguration}
-     * @hide
      */
     public List<PasspointConfiguration> getPasspointConfigurations() {
         try {
diff --git a/wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
similarity index 97%
rename from wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java
rename to wifi/java/android/net/wifi/hotspot2/ConfigParser.java
index 78b335d..027b049a 100644
--- a/wifi/java/android/net/wifi/hotspot2/ConfigBuilder.java
+++ b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
@@ -16,7 +16,7 @@
 
 package android.net.wifi.hotspot2;
 
-import android.net.wifi.hotspot2.omadm.PPSMOParser;
+import android.net.wifi.hotspot2.omadm.PpsMoParser;
 import android.text.TextUtils;
 import android.util.Base64;
 import android.util.Log;
@@ -41,11 +41,9 @@
 
 /**
  * Utility class for building PasspointConfiguration from an installation file.
- *
- * @hide
  */
-public final class ConfigBuilder {
-    private static final String TAG = "ConfigBuilder";
+public final class ConfigParser {
+    private static final String TAG = "ConfigParser";
 
     // Header names.
     private static final String CONTENT_TYPE = "Content-Type";
@@ -101,6 +99,10 @@
         public String encodingType = null;
     }
 
+    /**
+     * @hide
+     */
+    public ConfigParser() {}
 
     /**
      * Parse the Hotspot 2.0 Release 1 configuration data into a {@link PasspointConfiguration}
@@ -133,7 +135,7 @@
      *             certificate chain (optional).
      * @return {@link PasspointConfiguration}
      */
-    public static PasspointConfiguration buildPasspointConfig(String mimeType, byte[] data) {
+    public static PasspointConfiguration parsePasspointConfig(String mimeType, byte[] data) {
         // Verify MIME type.
         if (!TextUtils.equals(mimeType, TYPE_WIFI_CONFIG)) {
             Log.e(TAG, "Unexpected MIME type: " + mimeType);
@@ -169,7 +171,7 @@
             throw new IOException("Missing Passpoint Profile");
         }
 
-        PasspointConfiguration config = PPSMOParser.parseMOText(new String(profileData));
+        PasspointConfiguration config = PpsMoParser.parseMoText(new String(profileData));
         if (config == null) {
             throw new IOException("Failed to parse Passpoint profile");
         }
@@ -470,4 +472,4 @@
         }
         return new Pair<PrivateKey, List<X509Certificate>>(clientKey, clientCertificateChain);
     }
-}
\ No newline at end of file
+}
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index c2b307d..7b73b4b 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -17,7 +17,7 @@
 package android.net.wifi.hotspot2;
 
 import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
 import android.net.wifi.hotspot2.pps.Policy;
 import android.net.wifi.hotspot2.pps.UpdateParameter;
 import android.os.Parcelable;
@@ -38,8 +38,6 @@
  *
  * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
  * Release 2 Technical Specification.
- *
- * @hide
  */
 public final class PasspointConfiguration implements Parcelable {
     private static final String TAG = "PasspointConfiguration";
@@ -60,11 +58,11 @@
     private static final int NULL_VALUE = -1;
 
     /**
-     * Configurations under HomeSP subtree.
+     * Configurations under HomeSp subtree.
      */
-    private HomeSP mHomeSp = null;
-    public void setHomeSp(HomeSP homeSp) { mHomeSp = homeSp; }
-    public HomeSP getHomeSp() { return mHomeSp; }
+    private HomeSp mHomeSp = null;
+    public void setHomeSp(HomeSp homeSp) { mHomeSp = homeSp; }
+    public HomeSp getHomeSp() { return mHomeSp; }
 
     /**
      * Configurations under Credential subtree.
@@ -248,7 +246,7 @@
         }
 
         if (source.mHomeSp != null) {
-            mHomeSp = new HomeSP(source.mHomeSp);
+            mHomeSp = new HomeSp(source.mHomeSp);
         }
         if (source.mCredential != null) {
             mCredential = new Credential(source.mCredential);
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
similarity index 98%
rename from wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java
rename to wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
index 24672d4..2ffe428 100644
--- a/wifi/java/android/net/wifi/hotspot2/omadm/PPSMOParser.java
+++ b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
@@ -18,7 +18,7 @@
 
 import android.net.wifi.hotspot2.PasspointConfiguration;
 import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
 import android.net.wifi.hotspot2.pps.Policy;
 import android.net.wifi.hotspot2.pps.UpdateParameter;
 import android.text.TextUtils;
@@ -109,11 +109,9 @@
  *     </Node>
  *   </Node>
  * </MgmtTree>
- *
- * @hide
  */
-public final class PPSMOParser {
-    private static final String TAG = "PPSMOParser";
+public final class PpsMoParser {
+    private static final String TAG = "PpsMoParser";
 
     /**
      * XML tags expected in the PPS MO (PerProviderSubscription Management Object) XML tree.
@@ -326,13 +324,18 @@
     }
 
     /**
+     * @hide
+     */
+    public PpsMoParser() {}
+
+    /**
      * Convert a XML string representation of a PPS MO (PerProviderSubscription
      * Management Object) tree to a {@link PasspointConfiguration} object.
      *
      * @param xmlString XML string representation of a PPS MO tree
      * @return {@link PasspointConfiguration} or null
      */
-    public static PasspointConfiguration parseMOText(String xmlString) {
+    public static PasspointConfiguration parseMoText(String xmlString) {
         // Convert the XML string to a XML tree.
         XMLParser xmlParser = new XMLParser();
         XMLNode root = null;
@@ -640,12 +643,12 @@
      * @return HomeSP
      * @throws ParsingException
      */
-    private static HomeSP parseHomeSP(PPSNode node) throws ParsingException {
+    private static HomeSp parseHomeSP(PPSNode node) throws ParsingException {
         if (node.isLeaf()) {
             throw new ParsingException("Leaf node not expected for HomeSP");
         }
 
-        HomeSP homeSp = new HomeSP();
+        HomeSp homeSp = new HomeSp();
         for (PPSNode child : node.getChildren()) {
             switch (child.getName()) {
                 case NODE_FQDN:
@@ -655,7 +658,7 @@
                     homeSp.setFriendlyName(getPpsNodeValue(child));
                     break;
                 case NODE_ROAMING_CONSORTIUM_OI:
-                    homeSp.setRoamingConsortiumOIs(
+                    homeSp.setRoamingConsortiumOis(
                             parseRoamingConsortiumOI(getPpsNodeValue(child)));
                     break;
                 case NODE_ICON_URL:
@@ -666,8 +669,8 @@
                     break;
                 case NODE_HOME_OI_LIST:
                     Pair<List<Long>, List<Long>> homeOIs = parseHomeOIList(child);
-                    homeSp.setMatchAllOIs(convertFromLongList(homeOIs.first));
-                    homeSp.setMatchAnyOIs(convertFromLongList(homeOIs.second));
+                    homeSp.setMatchAllOis(convertFromLongList(homeOIs.first));
+                    homeSp.setMatchAnyOis(convertFromLongList(homeOIs.second));
                     break;
                 case NODE_OTHER_HOME_PARTNERS:
                     homeSp.setOtherHomePartners(parseOtherHomePartners(child));
@@ -909,7 +912,7 @@
                     credential.setRealm(getPpsNodeValue(child));
                     break;
                 case NODE_CHECK_AAA_SERVER_CERT_STATUS:
-                    credential.setCheckAAAServerCertStatus(
+                    credential.setCheckAaaServerCertStatus(
                             Boolean.parseBoolean(getPpsNodeValue(child)));
                     break;
                 case NODE_SIM:
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index ff93486..025d4d3 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -42,8 +42,6 @@
  *
  * In addition to the fields in the Credential subtree, this will also maintain necessary
  * information for the private key and certificates associated with this credential.
- *
- * @hide
  */
 public final class Credential implements Parcelable {
     private static final String TAG = "Credential";
@@ -98,12 +96,12 @@
      * and Accounting) server's certificate during EAP (Extensible Authentication
      * Protocol) authentication.
      */
-    private boolean mCheckAAAServerCertStatus = false;
-    public void setCheckAAAServerCertStatus(boolean checkAAAServerCertStatus) {
-        mCheckAAAServerCertStatus = checkAAAServerCertStatus;
+    private boolean mCheckAaaServerCertStatus = false;
+    public void setCheckAaaServerCertStatus(boolean checkAaaServerCertStatus) {
+        mCheckAaaServerCertStatus = checkAaaServerCertStatus;
     }
-    public boolean getCheckAAAServerStatus() {
-        return mCheckAAAServerCertStatus;
+    public boolean getCheckAaaServerStatus() {
+        return mCheckAaaServerCertStatus;
     }
 
     /**
@@ -685,7 +683,7 @@
             mCreationTimeInMs = source.mCreationTimeInMs;
             mExpirationTimeInMs = source.mExpirationTimeInMs;
             mRealm = source.mRealm;
-            mCheckAAAServerCertStatus = source.mCheckAAAServerCertStatus;
+            mCheckAaaServerCertStatus = source.mCheckAaaServerCertStatus;
             if (source.mUserCredential != null) {
                 mUserCredential = new UserCredential(source.mUserCredential);
             }
@@ -714,7 +712,7 @@
         dest.writeLong(mCreationTimeInMs);
         dest.writeLong(mExpirationTimeInMs);
         dest.writeString(mRealm);
-        dest.writeInt(mCheckAAAServerCertStatus ? 1 : 0);
+        dest.writeInt(mCheckAaaServerCertStatus ? 1 : 0);
         dest.writeParcelable(mUserCredential, flags);
         dest.writeParcelable(mCertCredential, flags);
         dest.writeParcelable(mSimCredential, flags);
@@ -736,7 +734,7 @@
         return TextUtils.equals(mRealm, that.mRealm)
                 && mCreationTimeInMs == that.mCreationTimeInMs
                 && mExpirationTimeInMs == that.mExpirationTimeInMs
-                && mCheckAAAServerCertStatus == that.mCheckAAAServerCertStatus
+                && mCheckAaaServerCertStatus == that.mCheckAaaServerCertStatus
                 && (mUserCredential == null ? that.mUserCredential == null
                     : mUserCredential.equals(that.mUserCredential))
                 && (mCertCredential == null ? that.mCertCredential == null
@@ -751,7 +749,7 @@
     @Override
     public int hashCode() {
         return Objects.hash(mRealm, mCreationTimeInMs, mExpirationTimeInMs,
-                mCheckAAAServerCertStatus, mUserCredential, mCertCredential, mSimCredential,
+                mCheckAaaServerCertStatus, mUserCredential, mCertCredential, mSimCredential,
                 mCaCertificate, mClientCertificateChain, mClientPrivateKey);
     }
 
@@ -800,7 +798,7 @@
                 credential.setCreationTimeInMs(in.readLong());
                 credential.setExpirationTimeInMs(in.readLong());
                 credential.setRealm(in.readString());
-                credential.setCheckAAAServerCertStatus(in.readInt() != 0);
+                credential.setCheckAaaServerCertStatus(in.readInt() != 0);
                 credential.setUserCredential(in.readParcelable(null));
                 credential.setCertCredential(in.readParcelable(null));
                 credential.setSimCredential(in.readParcelable(null));
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl
similarity index 96%
rename from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
rename to wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl
index 62d5603..6d343bd 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.aidl
@@ -16,4 +16,4 @@
 
 package android.net.wifi.hotspot2.pps;
 
-parcelable HomeSP;
+parcelable HomeSp;
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
similarity index 79%
rename from wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
rename to wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
index 8b3b79c..7a46129 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
@@ -34,11 +34,9 @@
  *
  * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
  * Release 2 Technical Specification.
- *
- * @hide
  */
-public final class HomeSP implements Parcelable {
-    private static final String TAG = "HomeSP";
+public final class HomeSp implements Parcelable {
+    private static final String TAG = "HomeSp";
 
     /**
      * Maximum number of bytes allowed for a SSID.
@@ -108,12 +106,12 @@
      * Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
      * (MO) tree for more detail.
      */
-    private long[] mMatchAllOIs = null;
-    public void setMatchAllOIs(long[] matchAllOIs) {
-        mMatchAllOIs = matchAllOIs;
+    private long[] mMatchAllOis = null;
+    public void setMatchAllOis(long[] matchAllOis) {
+        mMatchAllOis = matchAllOis;
     }
-    public long[] getMatchAllOIs() {
-        return mMatchAllOIs;
+    public long[] getMatchAllOis() {
+        return mMatchAllOis;
     }
 
     /**
@@ -129,12 +127,12 @@
      * Refer to HomeSP/HomeOIList subtree in PerProviderSubscription (PPS) Management Object
      * (MO) tree for more detail.
      */
-    private long[] mMatchAnyOIs = null;
-    public void setMatchAnyOIs(long[] matchAnyOIs) {
-        mMatchAnyOIs = matchAnyOIs;
+    private long[] mMatchAnyOis = null;
+    public void setMatchAnyOis(long[] matchAnyOis) {
+        mMatchAnyOis = matchAnyOis;
     }
-    public long[] getMatchAnysOIs() {
-        return mMatchAnyOIs;
+    public long[] getMatchAnysOis() {
+        return mMatchAnyOis;
     }
 
     /**
@@ -155,25 +153,25 @@
      * List of Organization Identifiers (OIs) identifying a roaming consortium of
      * which this provider is a member.
      */
-    private long[] mRoamingConsortiumOIs = null;
-    public void setRoamingConsortiumOIs(long[] roamingConsortiumOIs) {
-        mRoamingConsortiumOIs = roamingConsortiumOIs;
+    private long[] mRoamingConsortiumOis = null;
+    public void setRoamingConsortiumOis(long[] roamingConsortiumOis) {
+        mRoamingConsortiumOis = roamingConsortiumOis;
     }
-    public long[] getRoamingConsortiumOIs() {
-        return mRoamingConsortiumOIs;
+    public long[] getRoamingConsortiumOis() {
+        return mRoamingConsortiumOis;
     }
 
     /**
-     * Constructor for creating HomeSP with default values.
+     * Constructor for creating HomeSp with default values.
      */
-    public HomeSP() {}
+    public HomeSp() {}
 
     /**
      * Copy constructor.
      *
      * @param source The source to copy from
      */
-    public HomeSP(HomeSP source) {
+    public HomeSp(HomeSp source) {
         if (source == null) {
             return;
         }
@@ -183,19 +181,19 @@
         if (source.mHomeNetworkIds != null) {
             mHomeNetworkIds = Collections.unmodifiableMap(source.mHomeNetworkIds);
         }
-        if (source.mMatchAllOIs != null) {
-            mMatchAllOIs = Arrays.copyOf(source.mMatchAllOIs, source.mMatchAllOIs.length);
+        if (source.mMatchAllOis != null) {
+            mMatchAllOis = Arrays.copyOf(source.mMatchAllOis, source.mMatchAllOis.length);
         }
-        if (source.mMatchAnyOIs != null) {
-            mMatchAnyOIs = Arrays.copyOf(source.mMatchAnyOIs, source.mMatchAnyOIs.length);
+        if (source.mMatchAnyOis != null) {
+            mMatchAnyOis = Arrays.copyOf(source.mMatchAnyOis, source.mMatchAnyOis.length);
         }
         if (source.mOtherHomePartners != null) {
             mOtherHomePartners = Arrays.copyOf(source.mOtherHomePartners,
                     source.mOtherHomePartners.length);
         }
-        if (source.mRoamingConsortiumOIs != null) {
-            mRoamingConsortiumOIs = Arrays.copyOf(source.mRoamingConsortiumOIs,
-                    source.mRoamingConsortiumOIs.length);
+        if (source.mRoamingConsortiumOis != null) {
+            mRoamingConsortiumOis = Arrays.copyOf(source.mRoamingConsortiumOis,
+                    source.mRoamingConsortiumOis.length);
         }
     }
 
@@ -210,10 +208,10 @@
         dest.writeString(mFriendlyName);
         dest.writeString(mIconUrl);
         writeHomeNetworkIds(dest, mHomeNetworkIds);
-        dest.writeLongArray(mMatchAllOIs);
-        dest.writeLongArray(mMatchAnyOIs);
+        dest.writeLongArray(mMatchAllOis);
+        dest.writeLongArray(mMatchAnyOis);
         dest.writeStringArray(mOtherHomePartners);
-        dest.writeLongArray(mRoamingConsortiumOIs);
+        dest.writeLongArray(mRoamingConsortiumOis);
     }
 
     @Override
@@ -221,30 +219,30 @@
         if (this == thatObject) {
             return true;
         }
-        if (!(thatObject instanceof HomeSP)) {
+        if (!(thatObject instanceof HomeSp)) {
             return false;
         }
-        HomeSP that = (HomeSP) thatObject;
+        HomeSp that = (HomeSp) thatObject;
 
         return TextUtils.equals(mFqdn, that.mFqdn)
                 && TextUtils.equals(mFriendlyName, that.mFriendlyName)
                 && TextUtils.equals(mIconUrl, that.mIconUrl)
                 && (mHomeNetworkIds == null ? that.mHomeNetworkIds == null
                         : mHomeNetworkIds.equals(that.mHomeNetworkIds))
-                && Arrays.equals(mMatchAllOIs, that.mMatchAllOIs)
-                && Arrays.equals(mMatchAnyOIs, that.mMatchAnyOIs)
+                && Arrays.equals(mMatchAllOis, that.mMatchAllOis)
+                && Arrays.equals(mMatchAnyOis, that.mMatchAnyOis)
                 && Arrays.equals(mOtherHomePartners, that.mOtherHomePartners)
-                && Arrays.equals(mRoamingConsortiumOIs, that.mRoamingConsortiumOIs);
+                && Arrays.equals(mRoamingConsortiumOis, that.mRoamingConsortiumOis);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mFqdn, mFriendlyName, mIconUrl, mHomeNetworkIds, mMatchAllOIs,
-                mMatchAnyOIs, mOtherHomePartners, mRoamingConsortiumOIs);
+        return Objects.hash(mFqdn, mFriendlyName, mIconUrl, mHomeNetworkIds, mMatchAllOis,
+                mMatchAnyOis, mOtherHomePartners, mRoamingConsortiumOis);
     }
 
     /**
-     * Validate HomeSP data.
+     * Validate HomeSp data.
      *
      * @return true on success or false on failure
      */
@@ -270,25 +268,25 @@
         return true;
     }
 
-    public static final Creator<HomeSP> CREATOR =
-        new Creator<HomeSP>() {
+    public static final Creator<HomeSp> CREATOR =
+        new Creator<HomeSp>() {
             @Override
-            public HomeSP createFromParcel(Parcel in) {
-                HomeSP homeSp = new HomeSP();
+            public HomeSp createFromParcel(Parcel in) {
+                HomeSp homeSp = new HomeSp();
                 homeSp.setFqdn(in.readString());
                 homeSp.setFriendlyName(in.readString());
                 homeSp.setIconUrl(in.readString());
                 homeSp.setHomeNetworkIds(readHomeNetworkIds(in));
-                homeSp.setMatchAllOIs(in.createLongArray());
-                homeSp.setMatchAnyOIs(in.createLongArray());
+                homeSp.setMatchAllOis(in.createLongArray());
+                homeSp.setMatchAnyOis(in.createLongArray());
                 homeSp.setOtherHomePartners(in.createStringArray());
-                homeSp.setRoamingConsortiumOIs(in.createLongArray());
+                homeSp.setRoamingConsortiumOis(in.createLongArray());
                 return homeSp;
             }
 
             @Override
-            public HomeSP[] newArray(int size) {
-                return new HomeSP[size];
+            public HomeSp[] newArray(int size) {
+                return new HomeSp[size];
             }
 
             /**
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
index ceaada4..caca0e4 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
@@ -40,18 +40,11 @@
  *
  * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
  * Release 2 Technical Specification.
- *
- * @hide
  */
 public final class Policy implements Parcelable {
     private static final String TAG = "Policy";
 
     /**
-     * Default priority for preferred roaming partner.
-     */
-    public static final int PREFERRED_ROAMING_PARTNER_DEFAULT_PRIORITY = 128;
-
-    /**
      * Maximum number of SSIDs in the exclusion list.
      */
     private static final int MAX_EXCLUSION_SSIDS = 128;
@@ -189,8 +182,9 @@
 
         /**
          * Priority associated with this roaming partner policy.
+         * Using Integer.MIN_VALUE to indicate unset value.
          */
-        private int mPriority = PREFERRED_ROAMING_PARTNER_DEFAULT_PRIORITY;
+        private int mPriority = Integer.MIN_VALUE;
         public void setPriority(int priority) {
             mPriority = priority;
         }
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
index 17fbf9f..70264b0e 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
@@ -34,8 +34,6 @@
  *
  * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
  * Release 2 Technical Specification.
- *
- * @hide
  */
 public final class UpdateParameter implements Parcelable {
     private static final String TAG = "UpdateParameter";
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
similarity index 91%
rename from wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java
rename to wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
index f7dbf7e..56bb437 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/ConfigBuilderTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/ConfigParserTest.java
@@ -21,7 +21,7 @@
 
 import android.net.wifi.FakeKeys;
 import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import java.io.BufferedReader;
@@ -33,10 +33,10 @@
 import org.junit.Test;
 
 /**
- * Unit tests for {@link android.net.wifi.hotspot2.ConfigBuilder}.
+ * Unit tests for {@link android.net.wifi.hotspot2.ConfigParser}.
  */
 @SmallTest
-public class ConfigBuilderTest {
+public class ConfigParserTest {
     /**
      * Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a
      * CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}.
@@ -83,10 +83,10 @@
         PasspointConfiguration config = new PasspointConfiguration();
 
         // HomeSP configuration.
-        HomeSP homeSp = new HomeSP();
+        HomeSp homeSp = new HomeSp();
         homeSp.setFriendlyName("Century House");
         homeSp.setFqdn("mi6.co.uk");
-        homeSp.setRoamingConsortiumOIs(new long[] {0x112233L, 0x445566L});
+        homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
         config.setHomeSp(homeSp);
 
         // Credential configuration.
@@ -123,7 +123,7 @@
         String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
         PasspointConfiguration expectedConfig = generateConfigurationFromProfile();
         PasspointConfiguration actualConfig =
-                ConfigBuilder.buildPasspointConfig(
+                ConfigParser.parsePasspointConfig(
                         "application/x-wifi-config", configStr.getBytes());
         assertTrue(actualConfig.equals(expectedConfig));
     }
@@ -136,7 +136,7 @@
     @Test
     public void parseConfigFileWithInvalidMimeType() throws Exception {
         String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
-        assertNull(ConfigBuilder.buildPasspointConfig(
+        assertNull(ConfigParser.parsePasspointConfig(
                 "application/wifi-config", configStr.getBytes()));
     }
 
@@ -148,7 +148,7 @@
     @Test
     public void parseConfigFileWithUnencodedData() throws Exception {
         String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_UNENCODED_DATA);
-        assertNull(ConfigBuilder.buildPasspointConfig(
+        assertNull(ConfigParser.parsePasspointConfig(
                 "application/x-wifi-config", configStr.getBytes()));
     }
 
@@ -160,7 +160,7 @@
     @Test
     public void parseConfigFileWithInvalidPart() throws Exception {
         String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_INVALID_PART);
-        assertNull(ConfigBuilder.buildPasspointConfig(
+        assertNull(ConfigParser.parsePasspointConfig(
                 "application/x-wifi-config", configStr.getBytes()));
     }
 
@@ -172,7 +172,7 @@
     @Test
     public void parseConfigFileWithMissingBoundary() throws Exception {
         String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_MISSING_BOUNDARY);
-        assertNull(ConfigBuilder.buildPasspointConfig(
+        assertNull(ConfigParser.parsePasspointConfig(
                 "application/x-wifi-config", configStr.getBytes()));
     }
 
@@ -185,7 +185,7 @@
     @Test
     public void parseConfigFileWithInvalidContentType() throws Exception {
         String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_INVALID_CONTENT_TYPE);
-        assertNull(ConfigBuilder.buildPasspointConfig(
+        assertNull(ConfigParser.parsePasspointConfig(
                 "application/x-wifi-config", configStr.getBytes()));
     }
 
@@ -197,7 +197,7 @@
     @Test
     public void parseConfigFileWithoutPasspointProfile() throws Exception {
         String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITHOUT_PROFILE);
-        assertNull(ConfigBuilder.buildPasspointConfig(
+        assertNull(ConfigParser.parsePasspointConfig(
                 "application/x-wifi-config", configStr.getBytes()));
     }
 }
\ No newline at end of file
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
index 3aed918..7df4fcf 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java
@@ -21,7 +21,7 @@
 
 import android.net.wifi.EAPConstants;
 import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
 import android.net.wifi.hotspot2.pps.Policy;
 import android.net.wifi.hotspot2.pps.UpdateParameter;
 import android.os.Parcel;
@@ -50,11 +50,11 @@
      *
      * @return {@link android.net.wifi.hotspot2.pps.HomeSP}
      */
-    private static HomeSP createHomeSp() {
-        HomeSP homeSp = new HomeSP();
+    private static HomeSp createHomeSp() {
+        HomeSp homeSp = new HomeSp();
         homeSp.setFqdn("fqdn");
         homeSp.setFriendlyName("friendly name");
-        homeSp.setRoamingConsortiumOIs(new long[] {0x55, 0x66});
+        homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
         return homeSp;
     }
 
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
similarity index 91%
rename from wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java
rename to wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
index 15de5c7..7cd72f0 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/omadm/PPSMOParserTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/omadm/PpsMoParserTest.java
@@ -19,10 +19,10 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import android.net.wifi.hotspot2.omadm.PPSMOParser;
+import android.net.wifi.hotspot2.omadm.PpsMoParser;
 import android.net.wifi.hotspot2.PasspointConfiguration;
 import android.net.wifi.hotspot2.pps.Credential;
-import android.net.wifi.hotspot2.pps.HomeSP;
+import android.net.wifi.hotspot2.pps.HomeSp;
 import android.net.wifi.hotspot2.pps.Policy;
 import android.net.wifi.hotspot2.pps.UpdateParameter;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -43,10 +43,10 @@
 import java.util.Map;
 
 /**
- * Unit tests for {@link android.net.wifi.hotspot2.omadm.PPSMOParser}.
+ * Unit tests for {@link android.net.wifi.hotspot2.omadm.PpsMoParser}.
  */
 @SmallTest
-public class PPSMOParserTest {
+public class PpsMoParserTest {
     private static final String VALID_PPS_MO_XML_FILE = "assets/pps/PerProviderSubscription.xml";
     private static final String PPS_MO_XML_FILE_DUPLICATE_HOMESP =
             "assets/pps/PerProviderSubscription_DuplicateHomeSP.xml";
@@ -122,17 +122,17 @@
         config.setUsageLimitUsageTimePeriodInMinutes(99910);
 
         // HomeSP configuration.
-        HomeSP homeSp = new HomeSP();
+        HomeSp homeSp = new HomeSp();
         homeSp.setFriendlyName("Century House");
         homeSp.setFqdn("mi6.co.uk");
-        homeSp.setRoamingConsortiumOIs(new long[] {0x112233L, 0x445566L});
+        homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
         homeSp.setIconUrl("icon.test.com");
         Map<String, Long> homeNetworkIds = new HashMap<>();
         homeNetworkIds.put("TestSSID", 0x12345678L);
         homeNetworkIds.put("NullHESSID", null);
         homeSp.setHomeNetworkIds(homeNetworkIds);
-        homeSp.setMatchAllOIs(new long[] {0x11223344});
-        homeSp.setMatchAnyOIs(new long[] {0x55667788});
+        homeSp.setMatchAllOis(new long[] {0x11223344});
+        homeSp.setMatchAnyOis(new long[] {0x55667788});
         homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"});
         config.setHomeSp(homeSp);
 
@@ -141,7 +141,7 @@
         credential.setCreationTimeInMs(format.parse("2016-01-01T10:00:00Z").getTime());
         credential.setExpirationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime());
         credential.setRealm("shaken.stirred.com");
-        credential.setCheckAAAServerCertStatus(true);
+        credential.setCheckAaaServerCertStatus(true);
         Credential.UserCredential userCredential = new Credential.UserCredential();
         userCredential.setUsername("james");
         userCredential.setPassword("Ym9uZDAwNw==");
@@ -209,53 +209,53 @@
     public void parseValidPPSMOTree() throws Exception {
         String ppsMoTree = loadResourceFile(VALID_PPS_MO_XML_FILE);
         PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree();
-        PasspointConfiguration actualConfig = PPSMOParser.parseMOText(ppsMoTree);
+        PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree);
         assertTrue(actualConfig.equals(expectedConfig));
     }
 
     @Test
     public void parseNullPPSMOTree() throws Exception {
-        assertEquals(null, PPSMOParser.parseMOText(null));
+        assertEquals(null, PpsMoParser.parseMoText(null));
     }
 
     @Test
     public void parseEmptyPPSMOTree() throws Exception {
-        assertEquals(null, PPSMOParser.parseMOText(new String()));
+        assertEquals(null, PpsMoParser.parseMoText(new String()));
     }
 
     @Test
     public void parsePPSMOTreeWithDuplicateHomeSP() throws Exception {
-        assertEquals(null, PPSMOParser.parseMOText(
+        assertEquals(null, PpsMoParser.parseMoText(
                 loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_HOMESP)));
     }
 
     @Test
     public void parsePPSMOTreeWithDuplicateValue() throws Exception {
-        assertEquals(null, PPSMOParser.parseMOText(
+        assertEquals(null, PpsMoParser.parseMoText(
                 loadResourceFile(PPS_MO_XML_FILE_DUPLICATE_VALUE)));
     }
 
     @Test
     public void parsePPSMOTreeWithMissingValue() throws Exception {
-        assertEquals(null, PPSMOParser.parseMOText(
+        assertEquals(null, PpsMoParser.parseMoText(
                 loadResourceFile(PPS_MO_XML_FILE_MISSING_VALUE)));
     }
 
     @Test
     public void parsePPSMOTreeWithMissingName() throws Exception {
-        assertEquals(null, PPSMOParser.parseMOText(
+        assertEquals(null, PpsMoParser.parseMoText(
                 loadResourceFile(PPS_MO_XML_FILE_MISSING_NAME)));
     }
 
     @Test
     public void parsePPSMOTreeWithInvalidNode() throws Exception {
-        assertEquals(null, PPSMOParser.parseMOText(
+        assertEquals(null, PpsMoParser.parseMoText(
                 loadResourceFile(PPS_MO_XML_FILE_INVALID_NODE)));
     }
 
     @Test
     public void parsePPSMOTreeWithInvalidName() throws Exception {
-        assertEquals(null, PPSMOParser.parseMOText(
+        assertEquals(null, PpsMoParser.parseMoText(
                 loadResourceFile(PPS_MO_XML_FILE_INVALID_NAME)));
     }
 }
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
index 6f68e1c..c7ade00 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java
@@ -59,7 +59,7 @@
         cred.setCreationTimeInMs(123455L);
         cred.setExpirationTimeInMs(2310093L);
         cred.setRealm("realm");
-        cred.setCheckAAAServerCertStatus(true);
+        cred.setCheckAaaServerCertStatus(true);
         cred.setUserCredential(userCred);
         cred.setCertCredential(certCred);
         cred.setSimCredential(simCred);
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
similarity index 68%
rename from wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
rename to wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
index 92e94ee..c41c11f 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
@@ -30,10 +30,10 @@
 import java.util.Map;
 
 /**
- * Unit tests for {@link android.net.wifi.hotspot2.pps.HomeSP}.
+ * Unit tests for {@link android.net.wifi.hotspot2.pps.HomeSp}.
  */
 @SmallTest
-public class HomeSPTest {
+public class HomeSpTest {
 
     /**
      * Helper function for creating a map of home network IDs for testing.
@@ -48,68 +48,68 @@
     }
 
     /**
-     * Helper function for creating a HomeSP for testing.
+     * Helper function for creating a HomeSp for testing.
      *
-     * @param homeNetworkIds The map of home network IDs associated with HomeSP
-     * @return {@link HomeSP}
+     * @param homeNetworkIds The map of home network IDs associated with HomeSp
+     * @return {@link HomeSp}
      */
-    private static HomeSP createHomeSp(Map<String, Long> homeNetworkIds) {
-        HomeSP homeSp = new HomeSP();
+    private static HomeSp createHomeSp(Map<String, Long> homeNetworkIds) {
+        HomeSp homeSp = new HomeSp();
         homeSp.setFqdn("fqdn");
         homeSp.setFriendlyName("friendly name");
         homeSp.setIconUrl("icon.url");
         homeSp.setHomeNetworkIds(homeNetworkIds);
-        homeSp.setMatchAllOIs(new long[] {0x11L, 0x22L});
-        homeSp.setMatchAnyOIs(new long[] {0x33L, 0x44L});
+        homeSp.setMatchAllOis(new long[] {0x11L, 0x22L});
+        homeSp.setMatchAnyOis(new long[] {0x33L, 0x44L});
         homeSp.setOtherHomePartners(new String[] {"partner1", "partner2"});
-        homeSp.setRoamingConsortiumOIs(new long[] {0x55, 0x66});
+        homeSp.setRoamingConsortiumOis(new long[] {0x55, 0x66});
         return homeSp;
     }
 
     /**
-     * Helper function for creating a HomeSP with home network IDs for testing.
+     * Helper function for creating a HomeSp with home network IDs for testing.
      *
-     * @return {@link HomeSP}
+     * @return {@link HomeSp}
      */
-    private static HomeSP createHomeSpWithHomeNetworkIds() {
+    private static HomeSp createHomeSpWithHomeNetworkIds() {
         return createHomeSp(createHomeNetworkIds());
     }
 
     /**
-     * Helper function for creating a HomeSP without home network IDs for testing.
+     * Helper function for creating a HomeSp without home network IDs for testing.
      *
-     * @return {@link HomeSP}
+     * @return {@link HomeSp}
      */
-    private static HomeSP createHomeSpWithoutHomeNetworkIds() {
+    private static HomeSp createHomeSpWithoutHomeNetworkIds() {
         return createHomeSp(null);
     }
 
     /**
-     * Helper function for verifying HomeSP after parcel write then read.
+     * Helper function for verifying HomeSp after parcel write then read.
      * @param writeHomeSp
      * @throws Exception
      */
-    private static void verifyParcel(HomeSP writeHomeSp) throws Exception {
+    private static void verifyParcel(HomeSp writeHomeSp) throws Exception {
         Parcel parcel = Parcel.obtain();
         writeHomeSp.writeToParcel(parcel, 0);
 
         parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
-        HomeSP readHomeSp = HomeSP.CREATOR.createFromParcel(parcel);
+        HomeSp readHomeSp = HomeSp.CREATOR.createFromParcel(parcel);
         assertTrue(readHomeSp.equals(writeHomeSp));
     }
 
     /**
-     * Verify parcel read/write for an empty HomeSP.
+     * Verify parcel read/write for an empty HomeSp.
      *
      * @throws Exception
      */
     @Test
-    public void verifyParcelWithEmptyHomeSP() throws Exception {
-        verifyParcel(new HomeSP());
+    public void verifyParcelWithEmptyHomeSp() throws Exception {
+        verifyParcel(new HomeSp());
     }
 
     /**
-     * Verify parcel read/write for a HomeSP containing Home Network IDs.
+     * Verify parcel read/write for a HomeSp containing Home Network IDs.
      *
      * @throws Exception
      */
@@ -119,7 +119,7 @@
     }
 
     /**
-     * Verify parcel read/write for a HomeSP without Home Network IDs.
+     * Verify parcel read/write for a HomeSp without Home Network IDs.
      *
      * @throws Exception
      */
@@ -129,62 +129,62 @@
     }
 
     /**
-     * Verify that a HomeSP is valid when both FQDN and Friendly Name
+     * Verify that a HomeSp is valid when both FQDN and Friendly Name
      * are provided.
      *
      * @throws Exception
      */
     @Test
-    public void validateValidHomeSP() throws Exception {
-        HomeSP homeSp = createHomeSpWithHomeNetworkIds();
+    public void validateValidHomeSp() throws Exception {
+        HomeSp homeSp = createHomeSpWithHomeNetworkIds();
         assertTrue(homeSp.validate());
     }
 
     /**
-     * Verify that a HomeSP is not valid when FQDN is not provided
+     * Verify that a HomeSp is not valid when FQDN is not provided
      *
      * @throws Exception
      */
     @Test
     public void validateHomeSpWithoutFqdn() throws Exception {
-        HomeSP homeSp = createHomeSpWithHomeNetworkIds();
+        HomeSp homeSp = createHomeSpWithHomeNetworkIds();
         homeSp.setFqdn(null);
         assertFalse(homeSp.validate());
     }
 
     /**
-     * Verify that a HomeSP is not valid when Friendly Name is not provided
+     * Verify that a HomeSp is not valid when Friendly Name is not provided
      *
      * @throws Exception
      */
     @Test
     public void validateHomeSpWithoutFriendlyName() throws Exception {
-        HomeSP homeSp = createHomeSpWithHomeNetworkIds();
+        HomeSp homeSp = createHomeSpWithHomeNetworkIds();
         homeSp.setFriendlyName(null);
         assertFalse(homeSp.validate());
     }
 
     /**
-     * Verify that a HomeSP is valid when the optional Home Network IDs are
+     * Verify that a HomeSp is valid when the optional Home Network IDs are
      * not provided.
      *
      * @throws Exception
      */
     @Test
     public void validateHomeSpWithoutHomeNetworkIds() throws Exception {
-        HomeSP homeSp = createHomeSpWithoutHomeNetworkIds();
+        HomeSp homeSp = createHomeSpWithoutHomeNetworkIds();
         assertTrue(homeSp.validate());
     }
 
     /**
-     * Verify that a HomeSP is invalid when the optional Home Network IDs
+     * Verify that a HomeSp is invalid when the optional Home Network IDs
      * contained an invalid SSID (exceeding maximum number of bytes).
      *
      * @throws Exception
      */
     @Test
     public void validateHomeSpWithInvalidHomeNetworkIds() throws Exception {
-        HomeSP homeSp = createHomeSpWithoutHomeNetworkIds();
+        HomeSp homeSp = createHomeSpWithoutHomeNetworkIds();
         // HomeNetworkID with SSID exceeding the maximum length.
         Map<String, Long> homeNetworkIds = new HashMap<>();
         byte[] rawSsidBytes = new byte[33];
@@ -202,8 +202,8 @@
      */
     @Test
     public void validateCopyConstructorFromNullSource() throws Exception {
-        HomeSP copySp = new HomeSP(null);
-        HomeSP defaultSp = new HomeSP();
+        HomeSp copySp = new HomeSp(null);
+        HomeSp defaultSp = new HomeSp();
         assertTrue(copySp.equals(defaultSp));
     }
 
@@ -214,8 +214,8 @@
      */
     @Test
     public void validateCopyConstructorFromValidSource() throws Exception {
-        HomeSP sourceSp = createHomeSpWithHomeNetworkIds();
-        HomeSP copySp = new HomeSP(sourceSp);
+        HomeSp sourceSp = createHomeSpWithHomeNetworkIds();
+        HomeSp copySp = new HomeSp(sourceSp);
         assertTrue(copySp.equals(sourceSp));
     }
 }