Merge "Only use surface based touchable region for updating input window"
diff --git a/Android.bp b/Android.bp
index cbc67d0..c568d36 100644
--- a/Android.bp
+++ b/Android.bp
@@ -162,6 +162,7 @@
         "core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl",
         "core/java/android/hardware/biometrics/IBiometricServiceReceiverInternal.aidl",
         "core/java/android/hardware/biometrics/IBiometricServiceLockoutResetCallback.aidl",
+        "core/java/android/hardware/display/IColorDisplayManager.aidl",
         "core/java/android/hardware/display/IDisplayManager.aidl",
         "core/java/android/hardware/display/IDisplayManagerCallback.aidl",
         "core/java/android/hardware/display/IVirtualDisplayCallback.aidl",
@@ -572,6 +573,7 @@
         "telephony/java/com/android/internal/telephony/IApnSourceService.aidl",
         "telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl",
         "telephony/java/com/android/internal/telephony/IMms.aidl",
+        "telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl",
         "telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl",
         "telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl",
         "telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl",
@@ -652,6 +654,8 @@
         "core/java/com/android/server/DropboxLogTags.logtags",
         "core/java/org/chromium/arc/EventLogTags.logtags",
 
+        ":platform-properties",
+
         ":framework-statslog-gen",
     ],
 
@@ -781,9 +785,11 @@
 java_library_host {
     name: "inspector-annotation",
     srcs: [
-        "core/java/android/view/inspector/InspectableChildren.java",
         "core/java/android/view/inspector/InspectableNodeName.java",
         "core/java/android/view/inspector/InspectableProperty.java",
+        // Needed for the ResourceId.ID_NULL constant
+        "core/java/android/content/res/ResourceId.java",
+        "core/java/android/annotation/AnyRes.java",
     ],
 }
 
diff --git a/Android.mk b/Android.mk
index b7dda9a..92e33e9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -76,10 +76,9 @@
 .KATI_RESTAT: $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS)
 $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): \
     frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py \
-    frameworks/base/config/hiddenapi-light-greylist.txt \
-    frameworks/base/config/hiddenapi-vendor-list.txt \
+    frameworks/base/config/hiddenapi-greylist.txt \
+    frameworks/base/config/hiddenapi-greylist-max-p.txt \
     frameworks/base/config/hiddenapi-greylist-max-o.txt \
-    frameworks/base/config/hiddenapi-max-sdk-p-blacklist.txt \
     frameworks/base/config/hiddenapi-force-blacklist.txt \
     $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
     $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST) \
@@ -88,10 +87,9 @@
 	    --public $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
 	    --private $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST) \
 	    --csv $(PRIVATE_FLAGS_INPUTS) \
-	    --greylist \
-	        frameworks/base/config/hiddenapi-light-greylist.txt \
-	        frameworks/base/config/hiddenapi-vendor-list.txt \
+	    --greylist frameworks/base/config/hiddenapi-greylist.txt \
 	    --greylist-ignore-conflicts $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE) \
+	    --greylist-max-p frameworks/base/config/hiddenapi-greylist-max-p.txt \
 	    --greylist-max-o-ignore-conflicts \
 	        frameworks/base/config/hiddenapi-greylist-max-o.txt \
 	    --blacklist frameworks/base/config/hiddenapi-force-blacklist.txt \
diff --git a/api/current.txt b/api/current.txt
index 3967896..2eb90d5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7692,6 +7692,7 @@
     method protected void prepareView(android.view.View);
     method public void setAppWidget(int, android.appwidget.AppWidgetProviderInfo);
     method public void setExecutor(java.util.concurrent.Executor);
+    method public void setOnLightBackground(boolean);
     method public void updateAppWidget(android.widget.RemoteViews);
     method public void updateAppWidgetOptions(android.os.Bundle);
     method public void updateAppWidgetSize(android.os.Bundle, int, int, int, int);
@@ -13728,6 +13729,7 @@
   public abstract class ColorSpace {
     method public static android.graphics.ColorSpace adapt(android.graphics.ColorSpace, float[]);
     method public static android.graphics.ColorSpace adapt(android.graphics.ColorSpace, float[], android.graphics.ColorSpace.Adaptation);
+    method public static float[] cctToIlluminantdXyz(int);
     method public static float[] chromaticAdaptation(android.graphics.ColorSpace.Adaptation, float[], float[]);
     method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace);
     method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace, android.graphics.ColorSpace.RenderIntent);
@@ -24550,16 +24552,30 @@
 
   public final class MediaFormat {
     ctor public MediaFormat();
+    ctor public MediaFormat(android.media.MediaFormat);
+    method public boolean containsFeature(java.lang.String);
     method public boolean containsKey(java.lang.String);
     method public static android.media.MediaFormat createAudioFormat(java.lang.String, int, int);
     method public static android.media.MediaFormat createSubtitleFormat(java.lang.String, java.lang.String);
     method public static android.media.MediaFormat createVideoFormat(java.lang.String, int, int);
     method public java.nio.ByteBuffer getByteBuffer(java.lang.String);
+    method public java.nio.ByteBuffer getByteBuffer(java.lang.String, java.nio.ByteBuffer);
     method public boolean getFeatureEnabled(java.lang.String);
+    method public java.util.Set<java.lang.String> getFeatures();
     method public float getFloat(java.lang.String);
+    method public float getFloat(java.lang.String, float);
     method public int getInteger(java.lang.String);
+    method public int getInteger(java.lang.String, int);
+    method public java.util.Set<java.lang.String> getKeys();
     method public long getLong(java.lang.String);
+    method public long getLong(java.lang.String, long);
+    method public java.lang.Number getNumber(java.lang.String);
+    method public java.lang.Number getNumber(java.lang.String, java.lang.Number);
     method public java.lang.String getString(java.lang.String);
+    method public java.lang.String getString(java.lang.String, java.lang.String);
+    method public int getValueTypeForKey(java.lang.String);
+    method public void removeFeature(java.lang.String);
+    method public void removeKey(java.lang.String);
     method public void setByteBuffer(java.lang.String, java.nio.ByteBuffer);
     method public void setFeatureEnabled(java.lang.String, boolean);
     method public void setFloat(java.lang.String, float);
@@ -24664,6 +24680,12 @@
     field public static final java.lang.String MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled";
     field public static final java.lang.String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
     field public static final java.lang.String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
+    field public static final int TYPE_BYTE_BUFFER = 5; // 0x5
+    field public static final int TYPE_FLOAT = 3; // 0x3
+    field public static final int TYPE_INTEGER = 1; // 0x1
+    field public static final int TYPE_LONG = 2; // 0x2
+    field public static final int TYPE_NULL = 0; // 0x0
+    field public static final int TYPE_STRING = 4; // 0x4
   }
 
   public final class MediaMetadata implements android.os.Parcelable {
@@ -33538,6 +33560,7 @@
     method public static boolean isExternalStorageRemovable();
     method public static boolean isExternalStorageRemovable(java.io.File);
     field public static java.lang.String DIRECTORY_ALARMS;
+    field public static java.lang.String DIRECTORY_AUDIOBOOKS;
     field public static java.lang.String DIRECTORY_DCIM;
     field public static java.lang.String DIRECTORY_DOCUMENTS;
     field public static java.lang.String DIRECTORY_DOWNLOADS;
@@ -37395,6 +37418,7 @@
     field public static final java.lang.String COMPOSER = "composer";
     field public static final java.lang.String DURATION = "duration";
     field public static final java.lang.String IS_ALARM = "is_alarm";
+    field public static final java.lang.String IS_AUDIOBOOK = "is_audiobook";
     field public static final java.lang.String IS_MUSIC = "is_music";
     field public static final java.lang.String IS_NOTIFICATION = "is_notification";
     field public static final java.lang.String IS_PODCAST = "is_podcast";
@@ -37513,8 +37537,8 @@
     field public static final java.lang.String DATE_TAKEN = "datetaken";
     field public static final java.lang.String DESCRIPTION = "description";
     field public static final java.lang.String IS_PRIVATE = "isprivate";
-    field public static final java.lang.String LATITUDE = "latitude";
-    field public static final java.lang.String LONGITUDE = "longitude";
+    field public static final deprecated java.lang.String LATITUDE = "latitude";
+    field public static final deprecated java.lang.String LONGITUDE = "longitude";
     field public static final deprecated java.lang.String MINI_THUMB_MAGIC = "mini_thumb_magic";
     field public static final java.lang.String ORIENTATION = "orientation";
     field public static final deprecated java.lang.String PICASA_ID = "picasa_id";
@@ -37638,8 +37662,8 @@
     field public static final java.lang.String DURATION = "duration";
     field public static final java.lang.String IS_PRIVATE = "isprivate";
     field public static final java.lang.String LANGUAGE = "language";
-    field public static final java.lang.String LATITUDE = "latitude";
-    field public static final java.lang.String LONGITUDE = "longitude";
+    field public static final deprecated java.lang.String LATITUDE = "latitude";
+    field public static final deprecated java.lang.String LONGITUDE = "longitude";
     field public static final deprecated java.lang.String MINI_THUMB_MAGIC = "mini_thumb_magic";
     field public static final java.lang.String RESOLUTION = "resolution";
     field public static final java.lang.String TAGS = "tags";
@@ -42900,6 +42924,19 @@
     field public static final int BAND_9 = 9; // 0x9
   }
 
+  public final class AvailableNetworkInfo implements android.os.Parcelable {
+    ctor public AvailableNetworkInfo(int, int, java.util.ArrayList<java.lang.String>);
+    method public int describeContents();
+    method public java.util.List<java.lang.String> getMccMncs();
+    method public int getPriority();
+    method public int getSubId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.AvailableNetworkInfo> CREATOR;
+    field public static final int PRIORITY_HIGH = 1; // 0x1
+    field public static final int PRIORITY_LOW = 3; // 0x3
+    field public static final int PRIORITY_MED = 2; // 0x2
+  }
+
   public class CarrierConfigManager {
     method public android.os.PersistableBundle getConfig();
     method public android.os.PersistableBundle getConfigForSubId(int);
@@ -43878,6 +43915,7 @@
     method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
     method public deprecated void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
     method public deprecated void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
+    method public boolean updateAvailableNetworks(java.util.List<android.telephony.AvailableNetworkInfo>);
     field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
     field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
     field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -45850,6 +45888,7 @@
     method public java.util.Locale getLocaleObject();
     method public int getSpanTypeId();
     method public java.lang.String[] getSuggestions();
+    method public int getUnderlineColor();
     method public void setFlags(int);
     method public void updateDrawState(android.text.TextPaint);
     method public void writeToParcel(android.os.Parcel, int);
@@ -47850,6 +47889,7 @@
     method public final boolean isFunctionPressed();
     method public static final boolean isGamepadButton(int);
     method public final boolean isLongPress();
+    method public static final boolean isMediaSessionKey(int);
     method public final boolean isMetaPressed();
     method public static boolean isModifierKey(int);
     method public final boolean isNumLockOn();
@@ -51965,6 +52005,86 @@
 
 }
 
+package android.view.inspector {
+
+  public abstract interface InspectionCompanion<T> {
+    method public default java.lang.String getNodeName();
+    method public abstract void mapProperties(android.view.inspector.PropertyMapper);
+    method public abstract void readProperties(T, android.view.inspector.PropertyReader);
+  }
+
+  public static class InspectionCompanion.UninitializedPropertyMapException extends java.lang.RuntimeException {
+    ctor public InspectionCompanion.UninitializedPropertyMapException();
+  }
+
+  public final class IntEnumMapping {
+    method public java.lang.String nameOf(int);
+  }
+
+  public static final class IntEnumMapping.Builder {
+    ctor public IntEnumMapping.Builder();
+    method public android.view.inspector.IntEnumMapping.Builder addValue(java.lang.String, int);
+    method public android.view.inspector.IntEnumMapping build();
+    method public void clear();
+  }
+
+  public final class IntFlagMapping {
+    method public java.lang.String[] namesOf(int);
+  }
+
+  public static final class IntFlagMapping.Builder {
+    ctor public IntFlagMapping.Builder();
+    method public android.view.inspector.IntFlagMapping.Builder addFlag(java.lang.String, int);
+    method public android.view.inspector.IntFlagMapping.Builder addFlag(java.lang.String, int, int);
+    method public android.view.inspector.IntFlagMapping build();
+    method public void clear();
+  }
+
+  public abstract interface PropertyMapper {
+    method public abstract int mapBoolean(java.lang.String, int);
+    method public abstract int mapByte(java.lang.String, int);
+    method public abstract int mapChar(java.lang.String, int);
+    method public abstract int mapColor(java.lang.String, int);
+    method public abstract int mapDouble(java.lang.String, int);
+    method public abstract int mapFloat(java.lang.String, int);
+    method public abstract int mapGravity(java.lang.String, int);
+    method public abstract int mapInt(java.lang.String, int);
+    method public abstract int mapIntEnum(java.lang.String, int, android.view.inspector.IntEnumMapping);
+    method public abstract int mapIntFlag(java.lang.String, int, android.view.inspector.IntFlagMapping);
+    method public abstract int mapLong(java.lang.String, int);
+    method public abstract int mapObject(java.lang.String, int);
+    method public abstract int mapShort(java.lang.String, int);
+  }
+
+  public static class PropertyMapper.PropertyConflictException extends java.lang.RuntimeException {
+    ctor public PropertyMapper.PropertyConflictException(java.lang.String, java.lang.String, java.lang.String);
+  }
+
+  public abstract interface PropertyReader {
+    method public abstract void readBoolean(int, boolean);
+    method public abstract void readByte(int, byte);
+    method public abstract void readChar(int, char);
+    method public abstract void readColor(int, int);
+    method public abstract void readColor(int, long);
+    method public abstract void readColor(int, android.graphics.Color);
+    method public abstract void readDouble(int, double);
+    method public abstract void readFloat(int, float);
+    method public abstract void readGravity(int, int);
+    method public abstract void readInt(int, int);
+    method public abstract void readIntEnum(int, int);
+    method public abstract void readIntFlag(int, int);
+    method public abstract void readLong(int, long);
+    method public abstract void readObject(int, java.lang.Object);
+    method public abstract void readShort(int, short);
+  }
+
+  public static class PropertyReader.PropertyTypeMismatchException extends java.lang.RuntimeException {
+    ctor public PropertyReader.PropertyTypeMismatchException(int, java.lang.String, java.lang.String, java.lang.String);
+    ctor public PropertyReader.PropertyTypeMismatchException(int, java.lang.String, java.lang.String);
+  }
+
+}
+
 package android.view.intelligence {
 
   public final class ContentCaptureManager {
@@ -54962,6 +55082,7 @@
     method public void setInt(int, java.lang.String, int);
     method public void setIntent(int, java.lang.String, android.content.Intent);
     method public void setLabelFor(int, int);
+    method public void setLightBackgroundLayoutId(int);
     method public void setLong(int, java.lang.String, long);
     method public void setOnClickFillInIntent(int, android.content.Intent);
     method public void setOnClickPendingIntent(int, android.app.PendingIntent);
diff --git a/api/system-current.txt b/api/system-current.txt
index 7a2c233..6a71c04 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -57,6 +57,7 @@
     field public static final java.lang.String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
     field public static final java.lang.String CONNECTIVITY_INTERNAL = "android.permission.CONNECTIVITY_INTERNAL";
     field public static final java.lang.String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
+    field public static final java.lang.String CONTROL_DISPLAY_COLOR_TRANSFORMS = "android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS";
     field public static final java.lang.String CONTROL_DISPLAY_SATURATION = "android.permission.CONTROL_DISPLAY_SATURATION";
     field public static final java.lang.String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE";
     field public static final java.lang.String CONTROL_KEYGUARD_SECURE_NOTIFICATIONS = "android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS";
@@ -108,6 +109,7 @@
     field public static final java.lang.String MANAGE_DEVICE_ADMINS = "android.permission.MANAGE_DEVICE_ADMINS";
     field public static final java.lang.String MANAGE_IPSEC_TUNNELS = "android.permission.MANAGE_IPSEC_TUNNELS";
     field public static final java.lang.String MANAGE_ROLE_HOLDERS = "android.permission.MANAGE_ROLE_HOLDERS";
+    field public static final java.lang.String MANAGE_SMART_SUGGESTIONS = "android.permission.MANAGE_SMART_SUGGESTIONS";
     field public static final java.lang.String MANAGE_SOUND_TRIGGER = "android.permission.MANAGE_SOUND_TRIGGER";
     field public static final java.lang.String MANAGE_SUBSCRIPTION_PLANS = "android.permission.MANAGE_SUBSCRIPTION_PLANS";
     field public static final java.lang.String MANAGE_USB = "android.permission.MANAGE_USB";
@@ -3013,6 +3015,7 @@
 package android.media.session {
 
   public final class MediaSessionManager {
+    method public android.media.session.ISession createSession(android.media.session.MediaSession.CallbackStub, java.lang.String, int);
     method public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, android.os.Handler);
     method public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, android.os.Handler);
   }
@@ -3889,14 +3892,6 @@
 
 }
 
-package android.net.wifi.p2p {
-
-  public class WifiP2pManager {
-    method public void factoryReset(android.net.wifi.p2p.WifiP2pManager.Channel, android.net.wifi.p2p.WifiP2pManager.ActionListener);
-  }
-
-}
-
 package android.net.wifi.rtt {
 
   public static final class RangingRequest.Builder {
@@ -4629,6 +4624,7 @@
   public static final class Settings.Secure extends android.provider.Settings.NameValueTable {
     method public static boolean putString(android.content.ContentResolver, java.lang.String, java.lang.String, java.lang.String, boolean);
     method public static void resetToDefaults(android.content.ContentResolver, java.lang.String);
+    field public static final java.lang.String ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED = "accessibility_display_magnification_navbar_enabled";
     field public static final java.lang.String ASSIST_GESTURE_SETUP_COMPLETE = "assist_gesture_setup_complete";
     field public static final java.lang.String AUTOFILL_FEATURE_FIELD_CLASSIFICATION = "autofill_field_classification";
     field public static final java.lang.String AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT = "autofill_user_data_max_category_count";
@@ -4996,6 +4992,7 @@
   }
 
   public final class FillRequest {
+    method public android.view.autofill.AutofillValue getFocusedAutofillValue();
     method public android.view.autofill.AutofillId getFocusedId();
     method public android.service.intelligence.PresentationParams getPresentationParams();
     method public android.service.intelligence.InteractionSessionId getSessionId();
@@ -5711,6 +5708,26 @@
     field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
+  public abstract interface NumberVerificationCallback {
+    method public default void onCallReceived(java.lang.String);
+    method public default void onVerificationFailed(int);
+    field public static final int REASON_CONCURRENT_REQUESTS = 4; // 0x4
+    field public static final int REASON_IN_ECBM = 5; // 0x5
+    field public static final int REASON_IN_EMERGENCY_CALL = 6; // 0x6
+    field public static final int REASON_NETWORK_NOT_AVAILABLE = 2; // 0x2
+    field public static final int REASON_TIMED_OUT = 1; // 0x1
+    field public static final int REASON_TOO_MANY_CALLS = 3; // 0x3
+    field public static final int REASON_UNSPECIFIED = 0; // 0x0
+  }
+
+  public final class PhoneNumberRange implements android.os.Parcelable {
+    ctor public PhoneNumberRange(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+    method public int describeContents();
+    method public boolean matches(java.lang.String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR;
+  }
+
   public class PhoneStateListener {
     method public void onRadioPowerStateChanged(int);
     method public void onSrvccStateChanged(int);
@@ -5764,6 +5781,8 @@
     method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
     method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
     method public void requestEmbeddedSubscriptionInfoListRefresh();
+    method public void setDefaultDataSubId(int);
+    method public void setDefaultSmsSubId(int);
     method public void setSubscriptionOverrideCongested(int, boolean, long);
     method public void setSubscriptionOverrideUnmetered(int, boolean, long);
     method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
@@ -5875,6 +5894,7 @@
     method public boolean needsOtaServiceProvisioning();
     method public boolean rebootRadio();
     method public void requestCellInfoUpdate(android.os.WorkSource, java.util.concurrent.Executor, android.telephony.TelephonyManager.CellInfoCallback);
+    method public void requestNumberVerification(android.telephony.PhoneNumberRange, long, java.util.concurrent.Executor, android.telephony.NumberVerificationCallback);
     method public boolean resetRadioConfig();
     method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
     method public void setCarrierDataEnabled(boolean);
@@ -5904,6 +5924,7 @@
     field public static final java.lang.String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
     field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+    field public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000L; // 0xea60L
     field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4
     field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5
     field public static final int NETWORK_MODE_EVDO_NO_CDMA = 6; // 0x6
diff --git a/config/hiddenapi-max-sdk-p-blacklist.txt b/config/hiddenapi-greylist-max-p.txt
similarity index 100%
rename from config/hiddenapi-max-sdk-p-blacklist.txt
rename to config/hiddenapi-greylist-max-p.txt
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-greylist.txt
similarity index 94%
rename from config/hiddenapi-light-greylist.txt
rename to config/hiddenapi-greylist.txt
index e10f729..579ef93 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -51,6 +51,7 @@
 Landroid/app/backup/IFullBackupRestoreObserver$Stub;-><init>()V
 Landroid/app/backup/IRestoreObserver$Stub;-><init>()V
 Landroid/app/DownloadManager;->restartDownload([J)V
+Landroid/app/IActivityController$Stub;-><init>()V
 Landroid/app/IActivityManager$Stub$Proxy;->getConfiguration()Landroid/content/res/Configuration;
 Landroid/app/IActivityManager$Stub$Proxy;->getLaunchedFromUid(Landroid/os/IBinder;)I
 Landroid/app/IActivityManager$Stub$Proxy;->getProcessLimit()I
@@ -62,25 +63,35 @@
 Landroid/app/IActivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
 Landroid/app/IActivityManager;->bindService(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;ILjava/lang/String;I)I
 Landroid/app/IActivityManager;->broadcastIntent(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
+Landroid/app/IActivityManager;->cancelRecentsAnimation(Z)V
+Landroid/app/IActivityManager;->cancelTaskWindowTransition(I)V
 Landroid/app/IActivityManager;->checkPermission(Ljava/lang/String;II)I
+Landroid/app/IActivityManager;->closeSystemDialogs(Ljava/lang/String;)V
 Landroid/app/IActivityManager;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
 Landroid/app/IActivityManager;->finishHeavyWeightApp()V
 Landroid/app/IActivityManager;->finishReceiver(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/Bundle;ZI)V
 Landroid/app/IActivityManager;->forceStopPackage(Ljava/lang/String;I)V
 Landroid/app/IActivityManager;->getAllStackInfos()Ljava/util/List;
 Landroid/app/IActivityManager;->getConfiguration()Landroid/content/res/Configuration;
+Landroid/app/IActivityManager;->getCurrentUser()Landroid/content/pm/UserInfo;
+Landroid/app/IActivityManager;->getFilteredTasks(III)Ljava/util/List;
 Landroid/app/IActivityManager;->getIntentForIntentSender(Landroid/content/IIntentSender;)Landroid/content/Intent;
 Landroid/app/IActivityManager;->getIntentSender(ILjava/lang/String;Landroid/os/IBinder;Ljava/lang/String;I[Landroid/content/Intent;[Ljava/lang/String;ILandroid/os/Bundle;I)Landroid/content/IIntentSender;
 Landroid/app/IActivityManager;->getLaunchedFromPackage(Landroid/os/IBinder;)Ljava/lang/String;
 Landroid/app/IActivityManager;->getLaunchedFromUid(Landroid/os/IBinder;)I
+Landroid/app/IActivityManager;->getLockTaskModeState()I
 Landroid/app/IActivityManager;->getMemoryInfo(Landroid/app/ActivityManager$MemoryInfo;)V
 Landroid/app/IActivityManager;->getPackageProcessState(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/app/IActivityManager;->getProcessLimit()I
+Landroid/app/IActivityManager;->getProcessMemoryInfo([I)[Landroid/os/Debug$MemoryInfo;
 Landroid/app/IActivityManager;->getProcessPss([I)[J
 Landroid/app/IActivityManager;->getProviderMimeType(Landroid/net/Uri;I)Ljava/lang/String;
+Landroid/app/IActivityManager;->getRecentTasks(III)Landroid/content/pm/ParceledListSlice;
+Landroid/app/IActivityManager;->getRunningAppProcesses()Ljava/util/List;
 Landroid/app/IActivityManager;->getServices(II)Ljava/util/List;
 Landroid/app/IActivityManager;->getTaskBounds(I)Landroid/graphics/Rect;
 Landroid/app/IActivityManager;->getTaskForActivity(Landroid/os/IBinder;Z)I
+Landroid/app/IActivityManager;->getTaskSnapshot(IZ)Landroid/app/ActivityManager$TaskSnapshot;
 Landroid/app/IActivityManager;->handleApplicationStrictModeViolation(Landroid/os/IBinder;ILandroid/os/StrictMode$ViolationInfo;)V
 Landroid/app/IActivityManager;->hang(Landroid/os/IBinder;Z)V
 Landroid/app/IActivityManager;->isInLockTaskMode()Z
@@ -98,9 +109,11 @@
 Landroid/app/IActivityManager;->publishContentProviders(Landroid/app/IApplicationThread;Ljava/util/List;)V
 Landroid/app/IActivityManager;->registerProcessObserver(Landroid/app/IProcessObserver;)V
 Landroid/app/IActivityManager;->registerReceiver(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/IIntentReceiver;Landroid/content/IntentFilter;Ljava/lang/String;II)Landroid/content/Intent;
+Landroid/app/IActivityManager;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
 Landroid/app/IActivityManager;->registerUserSwitchObserver(Landroid/app/IUserSwitchObserver;Ljava/lang/String;)V
 Landroid/app/IActivityManager;->removeContentProviderExternal(Ljava/lang/String;Landroid/os/IBinder;)V
 Landroid/app/IActivityManager;->removeStack(I)V
+Landroid/app/IActivityManager;->removeTask(I)Z
 Landroid/app/IActivityManager;->requestBugReport(I)V
 Landroid/app/IActivityManager;->resizeDockedStack(Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
 Landroid/app/IActivityManager;->resizeStack(ILandroid/graphics/Rect;ZZZI)V
@@ -120,8 +133,12 @@
 Landroid/app/IActivityManager;->setRequestedOrientation(Landroid/os/IBinder;I)V
 Landroid/app/IActivityManager;->setTaskResizeable(II)V
 Landroid/app/IActivityManager;->shutdown(I)Z
+Landroid/app/IActivityManager;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
+Landroid/app/IActivityManager;->startActivityAsUser(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;I)I
+Landroid/app/IActivityManager;->startActivityFromRecents(ILandroid/os/Bundle;)I
 Landroid/app/IActivityManager;->startBinderTracking()Z
 Landroid/app/IActivityManager;->startInstrumentation(Landroid/content/ComponentName;Ljava/lang/String;ILandroid/os/Bundle;Landroid/app/IInstrumentationWatcher;Landroid/app/IUiAutomationConnection;ILjava/lang/String;)Z
+Landroid/app/IActivityManager;->startRecentsActivity(Landroid/content/Intent;Landroid/app/IAssistDataReceiver;Landroid/view/IRecentsAnimationRunner;)V
 Landroid/app/IActivityManager;->startSystemLockTaskMode(I)V
 Landroid/app/IActivityManager;->startUserInBackground(I)Z
 Landroid/app/IActivityManager;->stopAppSwitches()V
@@ -144,12 +161,16 @@
 Landroid/app/IAlarmManager$Stub;->TRANSACTION_set:I
 Landroid/app/IAlarmManager;->getNextAlarmClock(I)Landroid/app/AlarmManager$AlarmClockInfo;
 Landroid/app/IAlarmManager;->set(Ljava/lang/String;IJJJILandroid/app/PendingIntent;Landroid/app/IAlarmListener;Ljava/lang/String;Landroid/os/WorkSource;Landroid/app/AlarmManager$AlarmClockInfo;)V
+Landroid/app/IAlarmManager;->setTime(J)Z
 Landroid/app/IApplicationThread;->scheduleBindService(Landroid/os/IBinder;Landroid/content/Intent;ZI)V
 Landroid/app/IApplicationThread;->scheduleCreateService(Landroid/os/IBinder;Landroid/content/pm/ServiceInfo;Landroid/content/res/CompatibilityInfo;I)V
 Landroid/app/IApplicationThread;->scheduleStopService(Landroid/os/IBinder;)V
 Landroid/app/IApplicationThread;->scheduleTrimMemory(I)V
 Landroid/app/IApplicationThread;->scheduleUnbindService(Landroid/os/IBinder;Landroid/content/Intent;)V
 Landroid/app/IAppTask;->getTaskInfo()Landroid/app/ActivityManager$RecentTaskInfo;
+Landroid/app/IAssistDataReceiver$Stub;-><init>()V
+Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V
+Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V
 Landroid/app/IInputForwarder;->forwardEvent(Landroid/view/InputEvent;)Z
 Landroid/app/IInstrumentationWatcher$Stub;-><init>()V
 Landroid/app/IInstrumentationWatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IInstrumentationWatcher;
@@ -236,6 +257,7 @@
 Landroid/bluetooth/IBluetooth;->getAddress()Ljava/lang/String;
 Landroid/bluetooth/IBluetooth;->getRemoteAlias(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String;
 Landroid/bluetooth/IBluetooth;->isEnabled()Z
+Landroid/bluetooth/IBluetooth;->sendConnectionStateChange(Landroid/bluetooth/BluetoothDevice;III)V
 Landroid/bluetooth/IBluetoothA2dp$Stub;-><init>()V
 Landroid/bluetooth/IBluetoothA2dp$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothA2dp;
 Landroid/bluetooth/IBluetoothA2dp;->connect(Landroid/bluetooth/BluetoothDevice;)Z
@@ -266,6 +288,10 @@
 Landroid/bluetooth/IBluetoothManagerCallback$Stub;-><init>()V
 Landroid/bluetooth/IBluetoothPbap$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothPbap;
 Landroid/bluetooth/IBluetoothStateChangeCallback$Stub;-><init>()V
+Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
+Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelected(Ljava/lang/String;ILjava/lang/String;)V
+Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelectionCancel()V
+Landroid/companion/IFindDeviceCallback;->onSuccess(Landroid/app/PendingIntent;)V
 Landroid/content/ContentProviderProxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/IClipboard$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard;
@@ -312,11 +338,13 @@
 Landroid/content/pm/IPackageDataObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->onRemoveCompleted(Ljava/lang/String;Z)V
+Landroid/content/pm/IPackageDataObserver$Stub;-><init>()V
 Landroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
 Landroid/content/pm/IPackageDataObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
 Landroid/content/pm/IPackageDataObserver$Stub;->TRANSACTION_onRemoveCompleted:I
 Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
 Landroid/content/pm/IPackageDeleteObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/content/pm/IPackageDeleteObserver$Stub;-><init>()V
 Landroid/content/pm/IPackageDeleteObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver;
 Landroid/content/pm/IPackageDeleteObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
 Landroid/content/pm/IPackageDeleteObserver$Stub;->TRANSACTION_packageDeleted:I
@@ -325,6 +353,7 @@
 Landroid/content/pm/IPackageDeleteObserver2$Stub;-><init>()V
 Landroid/content/pm/IPackageDeleteObserver2$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver2;
 Landroid/content/pm/IPackageDeleteObserver2;->onPackageDeleted(Ljava/lang/String;ILjava/lang/String;)V
+Landroid/content/pm/IPackageDeleteObserver;->packageDeleted(Ljava/lang/String;I)V
 Landroid/content/pm/IPackageInstaller;->uninstall(Landroid/content/pm/VersionedPackage;Ljava/lang/String;ILandroid/content/IntentSender;I)V
 Landroid/content/pm/IPackageInstallerCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IPackageInstallerCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
@@ -364,11 +393,14 @@
 Landroid/content/pm/IPackageManager;->clearPackagePreferredActivities(Ljava/lang/String;)V
 Landroid/content/pm/IPackageManager;->currentToCanonicalPackageNames([Ljava/lang/String;)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager;->deleteApplicationCacheFiles(Ljava/lang/String;Landroid/content/pm/IPackageDataObserver;)V
+Landroid/content/pm/IPackageManager;->getActivityInfo(Landroid/content/ComponentName;II)Landroid/content/pm/ActivityInfo;
 Landroid/content/pm/IPackageManager;->getApplicationEnabledSetting(Ljava/lang/String;I)I
+Landroid/content/pm/IPackageManager;->getApplicationInfo(Ljava/lang/String;II)Landroid/content/pm/ApplicationInfo;
 Landroid/content/pm/IPackageManager;->getAppOpPermissionPackages(Ljava/lang/String;)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager;->getBlockUninstallForUser(Ljava/lang/String;I)Z
 Landroid/content/pm/IPackageManager;->getComponentEnabledSetting(Landroid/content/ComponentName;I)I
 Landroid/content/pm/IPackageManager;->getFlagsForUid(I)I
+Landroid/content/pm/IPackageManager;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
 Landroid/content/pm/IPackageManager;->getInstalledApplications(II)Landroid/content/pm/ParceledListSlice;
 Landroid/content/pm/IPackageManager;->getInstalledPackages(II)Landroid/content/pm/ParceledListSlice;
 Landroid/content/pm/IPackageManager;->getInstallerPackageName(Ljava/lang/String;)Ljava/lang/String;
@@ -376,6 +408,7 @@
 Landroid/content/pm/IPackageManager;->getInstrumentationInfo(Landroid/content/ComponentName;I)Landroid/content/pm/InstrumentationInfo;
 Landroid/content/pm/IPackageManager;->getLastChosenActivity(Landroid/content/Intent;Ljava/lang/String;I)Landroid/content/pm/ResolveInfo;
 Landroid/content/pm/IPackageManager;->getNameForUid(I)Ljava/lang/String;
+Landroid/content/pm/IPackageManager;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
 Landroid/content/pm/IPackageManager;->getPackageInstaller()Landroid/content/pm/IPackageInstaller;
 Landroid/content/pm/IPackageManager;->getPackagesForUid(I)[Ljava/lang/String;
 Landroid/content/pm/IPackageManager;->getPackageUid(Ljava/lang/String;II)I
@@ -415,6 +448,7 @@
 Landroid/content/pm/IPackageStatsObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageStatsObserver;
 Landroid/content/pm/IPackageStatsObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
 Landroid/content/pm/IPackageStatsObserver$Stub;->TRANSACTION_onGetStatsCompleted:I
+Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
 Landroid/content/pm/IShortcutService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IShortcutService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IShortcutService;
 Landroid/content/res/ConfigurationBoundResourceCache;-><init>()V
@@ -438,6 +472,7 @@
 Landroid/hardware/input/IInputManager$Stub;->TRANSACTION_injectInputEvent:I
 Landroid/hardware/input/IInputManager;->injectInputEvent(Landroid/view/InputEvent;I)Z
 Landroid/hardware/location/IActivityRecognitionHardwareClient$Stub;-><init>()V
+Landroid/hardware/location/IActivityRecognitionHardwareClient;->onAvailabilityChanged(ZLandroid/hardware/location/IActivityRecognitionHardware;)V
 Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService;
 Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager;
@@ -447,7 +482,10 @@
 Landroid/location/ICountryListener$Stub;-><init>()V
 Landroid/location/IGeocodeProvider$Stub;-><init>()V
 Landroid/location/IGeocodeProvider$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/IGeocodeProvider;
+Landroid/location/IGeocodeProvider;->getFromLocation(DDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
+Landroid/location/IGeocodeProvider;->getFromLocationName(Ljava/lang/String;DDDDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
 Landroid/location/IGeofenceProvider$Stub;-><init>()V
+Landroid/location/IGeofenceProvider;->setGeofenceHardware(Landroid/hardware/location/IGeofenceHardware;)V
 Landroid/location/ILocationListener$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/location/ILocationListener$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/location/ILocationListener$Stub;-><init>()V
@@ -460,6 +498,10 @@
 Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
 Landroid/location/ILocationManager$Stub;->TRANSACTION_getAllProviders:I
 Landroid/location/ILocationManager;->getAllProviders()Ljava/util/List;
+Landroid/location/ILocationManager;->getNetworkProviderPackage()Ljava/lang/String;
+Landroid/location/ILocationManager;->reportLocation(Landroid/location/Location;Z)V
+Landroid/location/INetInitiatedListener$Stub;-><init>()V
+Landroid/location/INetInitiatedListener;->sendNiResponse(II)Z
 Landroid/location/LocationManager$ListenerTransport;-><init>(Landroid/location/LocationManager;Landroid/location/LocationListener;Landroid/os/Looper;)V
 Landroid/Manifest$permission;->CAPTURE_SECURE_VIDEO_OUTPUT:Ljava/lang/String;
 Landroid/Manifest$permission;->CAPTURE_VIDEO_OUTPUT:Ljava/lang/String;
@@ -486,6 +528,17 @@
 Landroid/media/MediaScanner$MyMediaScannerClient;-><init>(Landroid/media/MediaScanner;)V
 Landroid/media/projection/IMediaProjectionManager;->hasProjectionPermission(ILjava/lang/String;)Z
 Landroid/media/session/ISessionManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/session/ISessionManager;
+Landroid/media/tv/ITvRemoteProvider$Stub;-><init>()V
+Landroid/media/tv/ITvRemoteServiceInput;->clearInputBridge(Landroid/os/IBinder;)V
+Landroid/media/tv/ITvRemoteServiceInput;->closeInputBridge(Landroid/os/IBinder;)V
+Landroid/media/tv/ITvRemoteServiceInput;->openInputBridge(Landroid/os/IBinder;Ljava/lang/String;III)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendKeyDown(Landroid/os/IBinder;I)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendKeyUp(Landroid/os/IBinder;I)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendPointerDown(Landroid/os/IBinder;III)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendPointerSync(Landroid/os/IBinder;)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendPointerUp(Landroid/os/IBinder;I)V
+Landroid/media/tv/ITvRemoteServiceInput;->sendTimestamp(Landroid/os/IBinder;J)V
+Landroid/net/ConnectivityManager$PacketKeepaliveCallback;-><init>()V
 Landroid/net/IConnectivityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveLinkProperties()Landroid/net/LinkProperties;
 Landroid/net/IConnectivityManager$Stub$Proxy;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
@@ -499,6 +552,7 @@
 Landroid/net/IConnectivityManager;->getActiveLinkProperties()Landroid/net/LinkProperties;
 Landroid/net/IConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo;
 Landroid/net/IConnectivityManager;->getAllNetworkInfo()[Landroid/net/NetworkInfo;
+Landroid/net/IConnectivityManager;->getAllNetworkState()[Landroid/net/NetworkState;
 Landroid/net/IConnectivityManager;->getLastTetherError(Ljava/lang/String;)I
 Landroid/net/IConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo;
 Landroid/net/IConnectivityManager;->getTetherableIfaces()[Ljava/lang/String;
@@ -508,9 +562,12 @@
 Landroid/net/IConnectivityManager;->getTetheringErroredIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->reportInetCondition(II)V
 Landroid/net/IConnectivityManager;->startLegacyVpn(Lcom/android/internal/net/VpnProfile;)V
+Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd;
+Landroid/net/INetd;->interfaceAddAddress(Ljava/lang/String;Ljava/lang/String;I)V
 Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V
 Landroid/net/INetworkPolicyListener$Stub;-><init>()V
 Landroid/net/INetworkPolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkPolicyManager;
+Landroid/net/INetworkPolicyManager;->getNetworkQuotaInfo(Landroid/net/NetworkState;)Landroid/net/NetworkQuotaInfo;
 Landroid/net/INetworkPolicyManager;->getRestrictBackground()Z
 Landroid/net/INetworkPolicyManager;->getUidPolicy(I)I
 Landroid/net/INetworkPolicyManager;->setNetworkPolicies([Landroid/net/NetworkPolicy;)V
@@ -520,14 +577,19 @@
 Landroid/net/INetworkScoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkScoreService;
 Landroid/net/INetworkStatsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String;
+Landroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService;
 Landroid/net/INetworkStatsService;->forceUpdate()V
 Landroid/net/INetworkStatsService;->getDataLayerSnapshotForUid(I)Landroid/net/NetworkStats;
 Landroid/net/INetworkStatsService;->getMobileIfaces()[Ljava/lang/String;
 Landroid/net/INetworkStatsService;->openSession()Landroid/net/INetworkStatsSession;
 Landroid/net/INetworkStatsService;->openSessionForUsageStats(ILjava/lang/String;)Landroid/net/INetworkStatsSession;
 Landroid/net/INetworkStatsSession;->close()V
+Landroid/net/INetworkStatsSession;->getHistoryForNetwork(Landroid/net/NetworkTemplate;I)Landroid/net/NetworkStatsHistory;
+Landroid/net/INetworkStatsSession;->getHistoryForUid(Landroid/net/NetworkTemplate;IIII)Landroid/net/NetworkStatsHistory;
 Landroid/net/INetworkStatsSession;->getSummaryForAllUid(Landroid/net/NetworkTemplate;JJZ)Landroid/net/NetworkStats;
 Landroid/net/INetworkStatsSession;->getSummaryForNetwork(Landroid/net/NetworkTemplate;JJ)Landroid/net/NetworkStats;
+Landroid/net/InterfaceConfiguration;-><init>()V
+Landroid/net/LinkProperties$ProvisioningChange;->values()[Landroid/net/LinkProperties$ProvisioningChange;
 Landroid/net/MobileLinkQualityInfo;-><init>()V
 Landroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager;
 Landroid/net/nsd/INsdManager;->getMessenger()Landroid/os/Messenger;
@@ -552,7 +614,12 @@
 Landroid/nfc/INfcAdapterExtras;->open(Ljava/lang/String;Landroid/os/IBinder;)Landroid/os/Bundle;
 Landroid/nfc/INfcAdapterExtras;->setCardEmulationRoute(Ljava/lang/String;I)V
 Landroid/nfc/INfcAdapterExtras;->transceive(Ljava/lang/String;[B)Landroid/os/Bundle;
+Landroid/os/AsyncResult;-><init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Throwable;)V
+Landroid/os/AsyncResult;->exception:Ljava/lang/Throwable;
 Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;)Landroid/os/AsyncResult;
+Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;Ljava/lang/Object;Ljava/lang/Throwable;)Landroid/os/AsyncResult;
+Landroid/os/AsyncResult;->result:Ljava/lang/Object;
+Landroid/os/AsyncResult;->userObj:Ljava/lang/Object;
 Landroid/os/AsyncTask;->mFuture:Ljava/util/concurrent/FutureTask;
 Landroid/os/AsyncTask;->mStatus:Landroid/os/AsyncTask$Status;
 Landroid/os/AsyncTask;->mTaskInvoked:Ljava/util/concurrent/atomic/AtomicBoolean;
@@ -569,18 +636,24 @@
 Landroid/os/BatteryManager;->EXTRA_MAX_CHARGING_VOLTAGE:Ljava/lang/String;
 Landroid/os/BatteryStats$Counter;-><init>()V
 Landroid/os/BatteryStats$Counter;->getCountLocked(I)I
+Landroid/os/BatteryStats$HistoryItem;-><init>()V
 Landroid/os/BatteryStats$HistoryItem;->batteryHealth:B
+Landroid/os/BatteryStats$HistoryItem;->batteryLevel:B
 Landroid/os/BatteryStats$HistoryItem;->batteryPlugType:B
 Landroid/os/BatteryStats$HistoryItem;->batteryStatus:B
 Landroid/os/BatteryStats$HistoryItem;->batteryVoltage:C
 Landroid/os/BatteryStats$HistoryItem;->clear()V
+Landroid/os/BatteryStats$HistoryItem;->cmd:B
 Landroid/os/BatteryStats$HistoryItem;->CMD_UPDATE:B
 Landroid/os/BatteryStats$HistoryItem;->next:Landroid/os/BatteryStats$HistoryItem;
 Landroid/os/BatteryStats$HistoryItem;->same(Landroid/os/BatteryStats$HistoryItem;)Z
 Landroid/os/BatteryStats$HistoryItem;->setTo(JBLandroid/os/BatteryStats$HistoryItem;)V
 Landroid/os/BatteryStats$HistoryItem;->setTo(Landroid/os/BatteryStats$HistoryItem;)V
 Landroid/os/BatteryStats$HistoryItem;->states2:I
+Landroid/os/BatteryStats$HistoryItem;->states:I
+Landroid/os/BatteryStats$HistoryItem;->time:J
 Landroid/os/BatteryStats$Timer;-><init>()V
+Landroid/os/BatteryStats$Timer;->getCountLocked(I)I
 Landroid/os/BatteryStats$Timer;->getTotalTimeLocked(JI)J
 Landroid/os/BatteryStats$Uid$Pkg$Serv;->getLaunches(I)I
 Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStarts(I)I
@@ -604,6 +677,8 @@
 Landroid/os/BatteryStats$Uid$Sensor;->getSensorTime()Landroid/os/BatteryStats$Timer;
 Landroid/os/BatteryStats$Uid$Sensor;->GPS:I
 Landroid/os/BatteryStats$Uid$Wakelock;-><init>()V
+Landroid/os/BatteryStats$Uid$Wakelock;->getWakeTime(I)Landroid/os/BatteryStats$Timer;
+Landroid/os/BatteryStats$Uid;-><init>()V
 Landroid/os/BatteryStats$Uid;->getAudioTurnedOnTimer()Landroid/os/BatteryStats$Timer;
 Landroid/os/BatteryStats$Uid;->getFullWifiLockTime(JI)J
 Landroid/os/BatteryStats$Uid;->getMobileRadioActiveTime(I)J
@@ -616,6 +691,7 @@
 Landroid/os/BatteryStats$Uid;->getWakelockStats()Landroid/util/ArrayMap;
 Landroid/os/BatteryStats$Uid;->getWifiBatchedScanTime(IJI)J
 Landroid/os/BatteryStats$Uid;->getWifiMulticastTime(JI)J
+Landroid/os/BatteryStats$Uid;->getWifiRunningTime(JI)J
 Landroid/os/BatteryStats$Uid;->getWifiScanTime(JI)J
 Landroid/os/BatteryStats;-><init>()V
 Landroid/os/BatteryStats;->computeBatteryRealtime(JI)J
@@ -627,6 +703,7 @@
 Landroid/os/BatteryStats;->getGlobalWifiRunningTime(JI)J
 Landroid/os/BatteryStats;->getMobileRadioActiveTime(JI)J
 Landroid/os/BatteryStats;->getNetworkActivityBytes(II)J
+Landroid/os/BatteryStats;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z
 Landroid/os/BatteryStats;->getPhoneOnTime(JI)J
 Landroid/os/BatteryStats;->getPhoneSignalStrengthTime(IJI)J
 Landroid/os/BatteryStats;->getScreenBrightnessTime(IJI)J
@@ -640,6 +717,10 @@
 Landroid/os/BatteryStats;->WAKE_TYPE_PARTIAL:I
 Landroid/os/Binder;->execTransact(IJJI)Z
 Landroid/os/Binder;->mObject:J
+Landroid/os/Broadcaster;-><init>()V
+Landroid/os/Broadcaster;->broadcast(Landroid/os/Message;)V
+Landroid/os/Broadcaster;->cancelRequest(ILandroid/os/Handler;I)V
+Landroid/os/Broadcaster;->request(ILandroid/os/Handler;I)V
 Landroid/os/Build$VERSION;->ACTIVE_CODENAMES:[Ljava/lang/String;
 Landroid/os/Build;->getLong(Ljava/lang/String;)J
 Landroid/os/Build;->getString(Ljava/lang/String;)Ljava/lang/String;
@@ -713,6 +794,7 @@
 Landroid/os/Environment;->buildExternalStorageAppObbDirs(Ljava/lang/String;)[Ljava/io/File;
 Landroid/os/Environment;->buildPaths([Ljava/io/File;[Ljava/lang/String;)[Ljava/io/File;
 Landroid/os/Environment;->getDataSystemDirectory()Ljava/io/File;
+Landroid/os/Environment;->getLegacyExternalStorageDirectory()Ljava/io/File;
 Landroid/os/Environment;->getLegacyExternalStorageObbDirectory()Ljava/io/File;
 Landroid/os/Environment;->initForCurrentUser()V
 Landroid/os/Environment;->maybeTranslateEmulatedPathToInternal(Ljava/io/File;)Ljava/io/File;
@@ -733,12 +815,15 @@
 Landroid/os/FileUtils;->stringToFile(Ljava/io/File;Ljava/lang/String;)V
 Landroid/os/FileUtils;->stringToFile(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/os/FileUtils;->sync(Ljava/io/FileOutputStream;)Z
+Landroid/os/Handler;-><init>(Landroid/os/Looper;Landroid/os/Handler$Callback;Z)V
 Landroid/os/Handler;-><init>(Z)V
 Landroid/os/Handler;->getIMessenger()Landroid/os/IMessenger;
+Landroid/os/Handler;->getMain()Landroid/os/Handler;
 Landroid/os/Handler;->getPostMessage(Ljava/lang/Runnable;Ljava/lang/Object;)Landroid/os/Message;
 Landroid/os/Handler;->mCallback:Landroid/os/Handler$Callback;
 Landroid/os/Handler;->mLooper:Landroid/os/Looper;
 Landroid/os/Handler;->mMessenger:Landroid/os/IMessenger;
+Landroid/os/HwBinder;->reportSyspropChanged()V
 Landroid/os/HwParcel;-><init>(Z)V
 Landroid/os/HwRemoteBinder;-><init>()V
 Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -749,16 +834,26 @@
 Landroid/os/IDeviceIdleController;->getAppIdTempWhitelist()[I
 Landroid/os/IDeviceIdleController;->getFullPowerWhitelistExceptIdle()[Ljava/lang/String;
 Landroid/os/INetworkManagementService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/os/INetworkManagementService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkManagementService;
+Landroid/os/INetworkManagementService;->clearInterfaceAddresses(Ljava/lang/String;)V
+Landroid/os/INetworkManagementService;->disableIpv6(Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->disableNat(Ljava/lang/String;Ljava/lang/String;)V
+Landroid/os/INetworkManagementService;->enableIpv6(Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->enableNat(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->getInterfaceConfig(Ljava/lang/String;)Landroid/net/InterfaceConfiguration;
 Landroid/os/INetworkManagementService;->getIpForwardingEnabled()Z
+Landroid/os/INetworkManagementService;->isBandwidthControlEnabled()Z
 Landroid/os/INetworkManagementService;->isTetheringStarted()Z
 Landroid/os/INetworkManagementService;->listTetheredInterfaces()[Ljava/lang/String;
+Landroid/os/INetworkManagementService;->registerObserver(Landroid/net/INetworkManagementEventObserver;)V
+Landroid/os/INetworkManagementService;->setInterfaceConfig(Ljava/lang/String;Landroid/net/InterfaceConfiguration;)V
+Landroid/os/INetworkManagementService;->setInterfaceIpv6PrivacyExtensions(Ljava/lang/String;Z)V
 Landroid/os/INetworkManagementService;->setIpForwardingEnabled(Z)V
+Landroid/os/INetworkManagementService;->setIPv6AddrGenMode(Ljava/lang/String;I)V
 Landroid/os/INetworkManagementService;->startTethering([Ljava/lang/String;)V
 Landroid/os/INetworkManagementService;->stopTethering()V
 Landroid/os/INetworkManagementService;->tetherInterface(Ljava/lang/String;)V
+Landroid/os/INetworkManagementService;->unregisterObserver(Landroid/net/INetworkManagementEventObserver;)V
 Landroid/os/INetworkManagementService;->untetherInterface(Ljava/lang/String;)V
 Landroid/os/IPermissionController$Stub$Proxy;->checkPermission(Ljava/lang/String;II)Z
 Landroid/os/IPermissionController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPermissionController;
@@ -767,12 +862,15 @@
 Landroid/os/IPowerManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPowerManager;
 Landroid/os/IPowerManager$Stub;->TRANSACTION_acquireWakeLock:I
 Landroid/os/IPowerManager$Stub;->TRANSACTION_goToSleep:I
+Landroid/os/IPowerManager;->goToSleep(JII)V
 Landroid/os/IPowerManager;->isInteractive()Z
 Landroid/os/IPowerManager;->nap(J)V
+Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V
 Landroid/os/IPowerManager;->releaseWakeLock(Landroid/os/IBinder;I)V
 Landroid/os/IPowerManager;->userActivity(JII)V
 Landroid/os/IPowerManager;->wakeUp(JLjava/lang/String;Ljava/lang/String;)V
 Landroid/os/IRecoverySystem$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IRecoverySystem;
+Landroid/os/IRemoteCallback$Stub;-><init>()V
 Landroid/os/IRemoteCallback;->sendResult(Landroid/os/Bundle;)V
 Landroid/os/IServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/IServiceManager;->getService(Ljava/lang/String;)Landroid/os/IBinder;
@@ -798,6 +896,7 @@
 Landroid/os/Message;->markInUse()V
 Landroid/os/Message;->next:Landroid/os/Message;
 Landroid/os/Message;->recycleUnchecked()V
+Landroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
 Landroid/os/Message;->target:Landroid/os/Handler;
 Landroid/os/Message;->toString(J)Ljava/lang/String;
 Landroid/os/Message;->when:J
@@ -817,13 +916,16 @@
 Landroid/os/Parcel;->mNativePtr:J
 Landroid/os/Parcel;->readArrayMap(Landroid/util/ArrayMap;Ljava/lang/ClassLoader;)V
 Landroid/os/Parcel;->readArraySet(Ljava/lang/ClassLoader;)Landroid/util/ArraySet;
+Landroid/os/Parcel;->readBlob()[B
 Landroid/os/Parcel;->readCharSequence()Ljava/lang/CharSequence;
 Landroid/os/Parcel;->readCreator(Landroid/os/Parcelable$Creator;Ljava/lang/ClassLoader;)Landroid/os/Parcelable;
 Landroid/os/Parcel;->readExceptionCode()I
 Landroid/os/Parcel;->readParcelableCreator(Ljava/lang/ClassLoader;)Landroid/os/Parcelable$Creator;
 Landroid/os/Parcel;->readRawFileDescriptor()Ljava/io/FileDescriptor;
+Landroid/os/Parcel;->readStringArray()[Ljava/lang/String;
 Landroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
 Landroid/os/Parcel;->writeArraySet(Landroid/util/ArraySet;)V
+Landroid/os/Parcel;->writeBlob([B)V
 Landroid/os/Parcel;->writeCharSequence(Ljava/lang/CharSequence;)V
 Landroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V
 Landroid/os/ParcelableParcel;-><init>(Ljava/lang/ClassLoader;)V
@@ -890,15 +992,27 @@
 Landroid/os/Process;->VPN_UID:I
 Landroid/os/Process;->WIFI_UID:I
 Landroid/os/RecoverySystem;->verifyPackageCompatibility(Ljava/io/InputStream;)Z
+Landroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V
+Landroid/os/Registrant;->clear()V
 Landroid/os/Registrant;->getHandler()Landroid/os/Handler;
 Landroid/os/Registrant;->messageForRegistrant()Landroid/os/Message;
+Landroid/os/Registrant;->notifyRegistrant()V
+Landroid/os/Registrant;->notifyRegistrant(Landroid/os/AsyncResult;)V
 Landroid/os/Registrant;->notifyResult(Ljava/lang/Object;)V
+Landroid/os/RegistrantList;-><init>()V
 Landroid/os/RegistrantList;->add(Landroid/os/Handler;ILjava/lang/Object;)V
+Landroid/os/RegistrantList;->add(Landroid/os/Registrant;)V
+Landroid/os/RegistrantList;->addUnique(Landroid/os/Handler;ILjava/lang/Object;)V
 Landroid/os/RegistrantList;->get(I)Ljava/lang/Object;
+Landroid/os/RegistrantList;->notifyRegistrants()V
+Landroid/os/RegistrantList;->notifyRegistrants(Landroid/os/AsyncResult;)V
 Landroid/os/RegistrantList;->notifyResult(Ljava/lang/Object;)V
+Landroid/os/RegistrantList;->remove(Landroid/os/Handler;)V
+Landroid/os/RegistrantList;->removeCleared()V
 Landroid/os/RegistrantList;->size()I
 Landroid/os/RemoteCallback;->mHandler:Landroid/os/Handler;
 Landroid/os/RemoteCallbackList;->mCallbacks:Landroid/util/ArrayMap;
+Landroid/os/RemoteException;->rethrowFromSystemServer()Ljava/lang/RuntimeException;
 Landroid/os/SELinux;->checkSELinuxAccess(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
 Landroid/os/SELinux;->getContext()Ljava/lang/String;
 Landroid/os/SELinux;->getFileContext(Ljava/lang/String;)Ljava/lang/String;
@@ -920,6 +1034,7 @@
 Landroid/os/ServiceManagerProxy;->getService(Ljava/lang/String;)Landroid/os/IBinder;
 Landroid/os/ServiceManagerProxy;->mRemote:Landroid/os/IBinder;
 Landroid/os/ServiceSpecificException;-><init>(ILjava/lang/String;)V
+Landroid/os/ServiceSpecificException;->errorCode:I
 Landroid/os/SharedMemory;->getFd()I
 Landroid/os/ShellCommand;->peekNextArg()Ljava/lang/String;
 Landroid/os/StatFs;->mStat:Landroid/system/StructStatVfs;
@@ -927,6 +1042,7 @@
 Landroid/os/storage/IObbActionListener$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IObbActionListener;
 Landroid/os/storage/IStorageManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/os/storage/IStorageManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/storage/IStorageManager;
+Landroid/os/storage/StorageEventListener;-><init>()V
 Landroid/os/StrictMode$Span;->finish()V
 Landroid/os/StrictMode$ThreadPolicy;->mask:I
 Landroid/os/StrictMode$VmPolicy$Builder;->mMask:I
@@ -954,8 +1070,12 @@
 Landroid/os/SystemProperties;->native_get_long(Ljava/lang/String;J)J
 Landroid/os/SystemProperties;->native_set(Ljava/lang/String;Ljava/lang/String;)V
 Landroid/os/SystemProperties;->PROP_NAME_MAX:I
+Landroid/os/SystemProperties;->reportSyspropChanged()V
 Landroid/os/SystemProperties;->sChangeCallbacks:Ljava/util/ArrayList;
 Landroid/os/SystemProperties;->set(Ljava/lang/String;Ljava/lang/String;)V
+Landroid/os/SystemService;->start(Ljava/lang/String;)V
+Landroid/os/SystemService;->stop(Ljava/lang/String;)V
+Landroid/os/SystemVibrator;-><init>()V
 Landroid/os/SystemVibrator;-><init>(Landroid/content/Context;)V
 Landroid/os/Trace;->asyncTraceBegin(JLjava/lang/String;I)V
 Landroid/os/Trace;->asyncTraceEnd(JLjava/lang/String;I)V
@@ -994,6 +1114,7 @@
 Landroid/os/UserHandle;->getUid(II)I
 Landroid/os/UserHandle;->getUserId(I)I
 Landroid/os/UserHandle;->isIsolated(I)Z
+Landroid/os/UserHandle;->isSameApp(II)Z
 Landroid/os/UserHandle;->mHandle:I
 Landroid/os/UserHandle;->MU_ENABLED:Z
 Landroid/os/UserHandle;->OWNER:Landroid/os/UserHandle;
@@ -1023,6 +1144,7 @@
 Landroid/os/UserManager;->getUserStartRealtime()J
 Landroid/os/UserManager;->getUserUnlockRealtime()J
 Landroid/os/UserManager;->hasBaseUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
+Landroid/os/UserManager;->hasUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
 Landroid/os/UserManager;->isDeviceInDemoMode(Landroid/content/Context;)Z
 Landroid/os/UserManager;->isGuestUser(I)Z
 Landroid/os/UserManager;->isLinkedUser()Z
@@ -1072,6 +1194,7 @@
 Landroid/R$styleable;->CalendarView_weekDayTextAppearance:I
 Landroid/R$styleable;->CalendarView_weekNumberColor:I
 Landroid/R$styleable;->CalendarView_weekSeparatorLineColor:I
+Landroid/R$styleable;->CheckBoxPreference:[I
 Landroid/R$styleable;->CheckedTextView:[I
 Landroid/R$styleable;->CheckedTextView_checkMark:I
 Landroid/R$styleable;->CompoundButton:[I
@@ -1382,7 +1505,18 @@
 Landroid/telecom/Log;->i(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
 Landroid/telecom/Log;->w(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
 Landroid/telephony/CarrierMessagingServiceManager;-><init>()V
+Landroid/telephony/ims/compat/feature/MMTelFeature;-><init>()V
+Landroid/telephony/ims/compat/ImsService;-><init>()V
+Landroid/telephony/ims/compat/stub/ImsCallSessionImplBase;-><init>()V
+Landroid/telephony/ims/compat/stub/ImsUtListenerImplBase;-><init>()V
 Landroid/telephony/JapanesePhoneNumberFormatter;->format(Landroid/text/Editable;)V
+Landroid/telephony/mbms/IMbmsStreamingSessionCallback$Stub;-><init>()V
+Landroid/telephony/mbms/IStreamingServiceCallback$Stub;-><init>()V
+Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService;
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->getPlaybackUri(ILjava/lang/String;)Landroid/net/Uri;
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->initialize(Landroid/telephony/mbms/IMbmsStreamingSessionCallback;I)I
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->requestUpdateStreamingServices(ILjava/util/List;)I
+Landroid/telephony/mbms/vendor/IMbmsStreamingService;->startStreaming(ILjava/lang/String;Landroid/telephony/mbms/IStreamingServiceCallback;)I
 Landroid/telephony/SmsCbCmasInfo;->getCategory()I
 Landroid/telephony/SmsCbCmasInfo;->getCertainty()I
 Landroid/telephony/SmsCbCmasInfo;->getMessageClass()I
@@ -1424,10 +1558,21 @@
 Landroid/view/AccessibilityIterators$AbstractTextSegmentIterator;-><init>()V
 Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/autofill/IAutoFillManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManager;
+Landroid/view/IAppTransitionAnimationSpecsFuture$Stub;-><init>()V
 Landroid/view/IDockedStackListener$Stub;-><init>()V
 Landroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/IGraphicsStats$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IGraphicsStats;
+Landroid/view/IRecentsAnimationController;->finish(Z)V
+Landroid/view/IRecentsAnimationController;->screenshotTask(I)Landroid/app/ActivityManager$TaskSnapshot;
 Landroid/view/IRecentsAnimationController;->setAnimationTargetsBehindSystemBars(Z)V
+Landroid/view/IRecentsAnimationController;->setInputConsumerEnabled(Z)V
+Landroid/view/IRecentsAnimationRunner$Stub;-><init>()V
+Landroid/view/IRecentsAnimationRunner;->onAnimationCanceled()V
+Landroid/view/IRecentsAnimationRunner;->onAnimationStart(Landroid/view/IRecentsAnimationController;[Landroid/view/RemoteAnimationTarget;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
+Landroid/view/IRemoteAnimationFinishedCallback;->onAnimationFinished()V
+Landroid/view/IRemoteAnimationRunner$Stub;-><init>()V
+Landroid/view/IRemoteAnimationRunner;->onAnimationCancelled()V
+Landroid/view/IRemoteAnimationRunner;->onAnimationStart([Landroid/view/RemoteAnimationTarget;Landroid/view/IRemoteAnimationFinishedCallback;)V
 Landroid/view/IRotationWatcher$Stub;-><init>()V
 Landroid/view/IWindow$Stub;-><init>()V
 Landroid/view/IWindow$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindow;
@@ -1439,6 +1584,9 @@
 Landroid/view/IWindowManager$Stub$Proxy;->watchRotation(Landroid/view/IRotationWatcher;I)I
 Landroid/view/IWindowManager$Stub;-><init>()V
 Landroid/view/IWindowManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowManager;
+Landroid/view/IWindowManager;->createInputConsumer(Landroid/os/IBinder;Ljava/lang/String;ILandroid/view/InputChannel;)V
+Landroid/view/IWindowManager;->destroyInputConsumer(Ljava/lang/String;I)Z
+Landroid/view/IWindowManager;->endProlongedAnimations()V
 Landroid/view/IWindowManager;->executeAppTransition()V
 Landroid/view/IWindowManager;->freezeRotation(I)V
 Landroid/view/IWindowManager;->getAnimationScale(I)F
@@ -1447,16 +1595,20 @@
 Landroid/view/IWindowManager;->getDockedStackSide()I
 Landroid/view/IWindowManager;->getInitialDisplayDensity(I)I
 Landroid/view/IWindowManager;->getInitialDisplaySize(ILandroid/graphics/Point;)V
+Landroid/view/IWindowManager;->getStableInsets(ILandroid/graphics/Rect;)V
 Landroid/view/IWindowManager;->hasNavigationBar(I)Z
 Landroid/view/IWindowManager;->isKeyguardLocked()Z
 Landroid/view/IWindowManager;->isKeyguardSecure()Z
 Landroid/view/IWindowManager;->isSafeModeEnabled()Z
 Landroid/view/IWindowManager;->lockNow(Landroid/os/Bundle;)V
+Landroid/view/IWindowManager;->overridePendingAppTransitionMultiThumbFuture(Landroid/view/IAppTransitionAnimationSpecsFuture;Landroid/os/IRemoteCallback;ZI)V
+Landroid/view/IWindowManager;->overridePendingAppTransitionRemote(Landroid/view/RemoteAnimationAdapter;I)V
 Landroid/view/IWindowManager;->registerDockedStackListener(Landroid/view/IDockedStackListener;)V
 Landroid/view/IWindowManager;->removeRotationWatcher(Landroid/view/IRotationWatcher;)V
 Landroid/view/IWindowManager;->setAnimationScale(IF)V
 Landroid/view/IWindowManager;->setAnimationScales([F)V
 Landroid/view/IWindowManager;->setInTouchMode(Z)V
+Landroid/view/IWindowManager;->setNavBarVirtualKeyHapticFeedbackEnabled(Z)V
 Landroid/view/IWindowManager;->setShelfHeight(ZI)V
 Landroid/view/IWindowManager;->setStrictModeVisualIndicatorPreference(Ljava/lang/String;)V
 Landroid/view/IWindowManager;->showStrictModeViolation(Z)V
@@ -1496,6 +1648,7 @@
 Lcom/android/ims/ImsCall;->reject(I)V
 Lcom/android/ims/ImsCall;->terminate(I)V
 Lcom/android/ims/ImsConfigListener$Stub;-><init>()V
+Lcom/android/ims/ImsConfigListener;->onSetFeatureResponse(IIII)V
 Lcom/android/ims/ImsEcbm;->exitEmergencyCallbackMode()V
 Lcom/android/ims/ImsManager;->getConfigInterface()Lcom/android/ims/ImsConfig;
 Lcom/android/ims/ImsManager;->getInstance(Landroid/content/Context;I)Lcom/android/ims/ImsManager;
@@ -1505,12 +1658,48 @@
 Lcom/android/ims/ImsUtInterface;->queryCallForward(ILjava/lang/String;Landroid/os/Message;)V
 Lcom/android/ims/internal/IImsCallSession$Stub;-><init>()V
 Lcom/android/ims/internal/IImsCallSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/ims/internal/IImsCallSession;
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionConferenceStateUpdated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsConferenceState;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandover(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandoverFailed(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHeld(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionInviteParticipantsRequestDelivered(Lcom/android/ims/internal/IImsCallSession;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionInviteParticipantsRequestFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeComplete(Lcom/android/ims/internal/IImsCallSession;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeStarted(Lcom/android/ims/internal/IImsCallSession;Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMultipartyStateChanged(Lcom/android/ims/internal/IImsCallSession;Z)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionProgressing(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsStreamMediaProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumeFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumeReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionStarted(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionStartFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionSuppServiceReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsSuppServiceNotification;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionTerminated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionTtyModeReceived(Lcom/android/ims/internal/IImsCallSession;I)V
+Lcom/android/ims/internal/IImsCallSessionListener;->callSessionUpdated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
 Lcom/android/ims/internal/IImsConfig$Stub;-><init>()V
 Lcom/android/ims/internal/IImsEcbm$Stub;-><init>()V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationAssociatedUriChanged([Landroid/net/Uri;)V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationChangeFailed(ILandroid/telephony/ims/ImsReasonInfo;)V
 Lcom/android/ims/internal/IImsRegistrationListener;->registrationConnected()V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationConnectedWithRadioTech(I)V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationDisconnected(Landroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationFeatureCapabilityChanged(I[I[I)V
+Lcom/android/ims/internal/IImsRegistrationListener;->registrationProgressingWithRadioTech(I)V
+Lcom/android/ims/internal/IImsRegistrationListener;->voiceMessageCountUpdate(I)V
 Lcom/android/ims/internal/IImsService$Stub;-><init>()V
 Lcom/android/ims/internal/IImsService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/ims/internal/IImsService;
 Lcom/android/ims/internal/IImsUt$Stub;-><init>()V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallBarringQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsSsInfo;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallForwardQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsCallForwardInfo;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallWaitingQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsSsInfo;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueried(Lcom/android/ims/internal/IImsUt;ILandroid/os/Bundle;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueryFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdated(Lcom/android/ims/internal/IImsUt;I)V
+Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdateFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
 Lcom/android/ims/internal/IImsVideoCallCallback;->changeCallDataUsage(J)V
 Lcom/android/ims/internal/IImsVideoCallCallback;->changeCameraCapabilities(Landroid/telecom/VideoProfile$CameraCapabilities;)V
 Lcom/android/ims/internal/IImsVideoCallCallback;->changePeerDimensions(II)V
@@ -1521,7 +1710,52 @@
 Lcom/android/ims/internal/IImsVideoCallProvider$Stub;-><init>()V
 Lcom/android/ims/internal/IImsVideoCallProvider;->setCallback(Lcom/android/ims/internal/IImsVideoCallCallback;)V
 Lcom/android/ims/internal/ImsVideoCallProviderWrapper;-><init>(Lcom/android/ims/internal/IImsVideoCallProvider;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->cmdStatus(Lcom/android/ims/internal/uce/options/OptionsCmdStatus;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->getVersionCb(Ljava/lang/String;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->incomingOptions(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;I)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceUnavailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
+Lcom/android/ims/internal/uce/options/IOptionsListener;->sipResponseReceived(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsSipResponse;Lcom/android/ims/internal/uce/options/OptionsCapInfo;)V
+Lcom/android/ims/internal/uce/options/IOptionsService$Stub;-><init>()V
+Lcom/android/ims/internal/uce/options/IOptionsService;->addListener(ILcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->getMyInfo(II)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->getVersion(I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->responseIncomingOptions(IIILjava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;Z)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/options/IOptionsService;->setMyInfo(ILcom/android/ims/internal/uce/common/CapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->capInfoReceived(Ljava/lang/String;[Lcom/android/ims/internal/uce/presence/PresTupleInfo;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->cmdStatus(Lcom/android/ims/internal/uce/presence/PresCmdStatus;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->getVersionCb(Ljava/lang/String;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->listCapInfoReceived(Lcom/android/ims/internal/uce/presence/PresRlmiInfo;[Lcom/android/ims/internal/uce/presence/PresResInfo;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->publishTriggering(Lcom/android/ims/internal/uce/presence/PresPublishTriggerType;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->serviceAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->serviceUnAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->sipResponseReceived(Lcom/android/ims/internal/uce/presence/PresSipResponse;)V
+Lcom/android/ims/internal/uce/presence/IPresenceListener;->unpublishMessageSent()V
+Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
+Lcom/android/ims/internal/uce/presence/IPresenceService;->addListener(ILcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->getVersion(I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->publishMyCap(ILcom/android/ims/internal/uce/presence/PresCapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->reenableService(II)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
+Lcom/android/ims/internal/uce/presence/IPresenceService;->setNewFeatureTag(ILjava/lang/String;Lcom/android/ims/internal/uce/presence/PresServiceInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
 Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
+Lcom/android/ims/internal/uce/uceservice/IUceListener;->setStatus(I)V
+Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
+Lcom/android/ims/internal/uce/uceservice/IUceService;->createOptionsService(Lcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)I
+Lcom/android/ims/internal/uce/uceservice/IUceService;->createPresenceService(Lcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)I
+Lcom/android/ims/internal/uce/uceservice/IUceService;->destroyOptionsService(I)V
+Lcom/android/ims/internal/uce/uceservice/IUceService;->destroyPresenceService(I)V
+Lcom/android/ims/internal/uce/uceservice/IUceService;->getOptionsService()Lcom/android/ims/internal/uce/options/IOptionsService;
+Lcom/android/ims/internal/uce/uceservice/IUceService;->getPresenceService()Lcom/android/ims/internal/uce/presence/IPresenceService;
+Lcom/android/ims/internal/uce/uceservice/IUceService;->getServiceStatus()Z
+Lcom/android/ims/internal/uce/uceservice/IUceService;->isServiceStarted()Z
+Lcom/android/ims/internal/uce/uceservice/IUceService;->startService(Lcom/android/ims/internal/uce/uceservice/IUceListener;)Z
+Lcom/android/ims/internal/uce/uceservice/IUceService;->stopService()Z
 Lcom/android/internal/app/AlertActivity;-><init>()V
 Lcom/android/internal/app/AlertActivity;->mAlert:Lcom/android/internal/app/AlertController;
 Lcom/android/internal/app/AlertActivity;->mAlertParams:Lcom/android/internal/app/AlertController$AlertParams;
@@ -1552,6 +1786,7 @@
 Lcom/android/internal/app/IAppOpsService$Stub;->TRANSACTION_startOperation:I
 Lcom/android/internal/app/IAppOpsService$Stub;->TRANSACTION_startWatchingMode:I
 Lcom/android/internal/app/IAppOpsService$Stub;->TRANSACTION_stopWatchingMode:I
+Lcom/android/internal/app/IAppOpsService;->finishOperation(Landroid/os/IBinder;IILjava/lang/String;)V
 Lcom/android/internal/app/IAppOpsService;->getOpsForPackage(ILjava/lang/String;[I)Ljava/util/List;
 Lcom/android/internal/app/IAppOpsService;->getPackagesForOps([I)Ljava/util/List;
 Lcom/android/internal/app/IAppOpsService;->resetAllModes(ILjava/lang/String;)V
@@ -1599,6 +1834,7 @@
 Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetIds(Landroid/content/ComponentName;)[I
 Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetViews(Ljava/lang/String;I)Landroid/widget/RemoteViews;
 Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
+Lcom/android/internal/content/PackageMonitor;-><init>()V
 Lcom/android/internal/database/SortCursor;-><init>([Landroid/database/Cursor;Ljava/lang/String;)V
 Lcom/android/internal/database/SortCursor;->mCursor:Landroid/database/Cursor;
 Lcom/android/internal/database/SortCursor;->mCursors:[Landroid/database/Cursor;
@@ -1612,6 +1848,14 @@
 Lcom/android/internal/location/GpsNetInitiatedHandler;->handleNiNotification(Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;)V
 Lcom/android/internal/location/GpsNetInitiatedHandler;->mIsHexInput:Z
 Lcom/android/internal/location/ILocationProvider$Stub;-><init>()V
+Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
+Lcom/android/internal/location/ILocationProvider;->disable()V
+Lcom/android/internal/location/ILocationProvider;->enable()V
+Lcom/android/internal/location/ILocationProvider;->getProperties()Lcom/android/internal/location/ProviderProperties;
+Lcom/android/internal/location/ILocationProvider;->getStatus(Landroid/os/Bundle;)I
+Lcom/android/internal/location/ILocationProvider;->getStatusUpdateTime()J
+Lcom/android/internal/location/ILocationProvider;->sendExtraCommand(Ljava/lang/String;Landroid/os/Bundle;)Z
+Lcom/android/internal/location/ILocationProvider;->setRequest(Lcom/android/internal/location/ProviderRequest;Landroid/os/WorkSource;)V
 Lcom/android/internal/logging/MetricsLogger;-><init>()V
 Lcom/android/internal/net/LegacyVpnInfo;-><init>()V
 Lcom/android/internal/net/VpnConfig;-><init>()V
@@ -1981,6 +2225,7 @@
 Lcom/android/internal/R$styleable;->MenuGroup:[I
 Lcom/android/internal/R$styleable;->MenuItem:[I
 Lcom/android/internal/R$styleable;->MenuView:[I
+Lcom/android/internal/R$styleable;->NumberPicker:[I
 Lcom/android/internal/R$styleable;->PopupWindow:[I
 Lcom/android/internal/R$styleable;->PopupWindow_popupAnimationStyle:I
 Lcom/android/internal/R$styleable;->PopupWindow_popupBackground:I
@@ -2106,6 +2351,7 @@
 Lcom/android/internal/R$styleable;->TextView_typeface:I
 Lcom/android/internal/R$styleable;->TextView_width:I
 Lcom/android/internal/R$styleable;->Theme:[I
+Lcom/android/internal/R$styleable;->TwoLineListItem:[I
 Lcom/android/internal/R$styleable;->View:[I
 Lcom/android/internal/R$styleable;->ViewAnimator:[I
 Lcom/android/internal/R$styleable;->ViewFlipper:[I
@@ -3126,6 +3372,7 @@
 Lcom/android/internal/telephony/ITelephony;->getActivePhoneType()I
 Lcom/android/internal/telephony/ITelephony;->getCallState()I
 Lcom/android/internal/telephony/ITelephony;->getDataActivity()I
+Lcom/android/internal/telephony/ITelephony;->getDataEnabled(I)Z
 Lcom/android/internal/telephony/ITelephony;->getDataState()I
 Lcom/android/internal/telephony/ITelephony;->getNetworkType()I
 Lcom/android/internal/telephony/ITelephony;->handlePinMmi(Ljava/lang/String;)Z
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
deleted file mode 100644
index a21fa30..0000000
--- a/config/hiddenapi-vendor-list.txt
+++ /dev/null
@@ -1,247 +0,0 @@
-Landroid/app/IActivityController$Stub;-><init>()V
-Landroid/app/IActivityManager;->cancelRecentsAnimation(Z)V
-Landroid/app/IActivityManager;->cancelTaskWindowTransition(I)V
-Landroid/app/IActivityManager;->closeSystemDialogs(Ljava/lang/String;)V
-Landroid/app/IActivityManager;->getCurrentUser()Landroid/content/pm/UserInfo;
-Landroid/app/IActivityManager;->getFilteredTasks(III)Ljava/util/List;
-Landroid/app/IActivityManager;->getLockTaskModeState()I
-Landroid/app/IActivityManager;->getProcessMemoryInfo([I)[Landroid/os/Debug$MemoryInfo;
-Landroid/app/IActivityManager;->getRecentTasks(III)Landroid/content/pm/ParceledListSlice;
-Landroid/app/IActivityManager;->getRunningAppProcesses()Ljava/util/List;
-Landroid/app/IActivityManager;->getTaskSnapshot(IZ)Landroid/app/ActivityManager$TaskSnapshot;
-Landroid/app/IActivityManager;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
-Landroid/app/IActivityManager;->removeTask(I)Z
-Landroid/app/IActivityManager;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
-Landroid/app/IActivityManager;->startActivityAsUser(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;I)I
-Landroid/app/IActivityManager;->startActivityFromRecents(ILandroid/os/Bundle;)I
-Landroid/app/IActivityManager;->startRecentsActivity(Landroid/content/Intent;Landroid/app/IAssistDataReceiver;Landroid/view/IRecentsAnimationRunner;)V
-Landroid/app/IAlarmManager;->setTime(J)Z
-Landroid/app/IAssistDataReceiver$Stub;-><init>()V
-Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V
-Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V
-Landroid/bluetooth/IBluetooth;->sendConnectionStateChange(Landroid/bluetooth/BluetoothDevice;III)V
-Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
-Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelected(Ljava/lang/String;ILjava/lang/String;)V
-Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelectionCancel()V
-Landroid/companion/IFindDeviceCallback;->onSuccess(Landroid/app/PendingIntent;)V
-Landroid/content/pm/IPackageDataObserver$Stub;-><init>()V
-Landroid/content/pm/IPackageDeleteObserver$Stub;-><init>()V
-Landroid/content/pm/IPackageDeleteObserver;->packageDeleted(Ljava/lang/String;I)V
-Landroid/content/pm/IPackageManager;->getActivityInfo(Landroid/content/ComponentName;II)Landroid/content/pm/ActivityInfo;
-Landroid/content/pm/IPackageManager;->getApplicationInfo(Ljava/lang/String;II)Landroid/content/pm/ApplicationInfo;
-Landroid/content/pm/IPackageManager;->getHomeActivities(Ljava/util/List;)Landroid/content/ComponentName;
-Landroid/content/pm/IPackageManager;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
-Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
-Landroid/hardware/location/IActivityRecognitionHardwareClient;->onAvailabilityChanged(ZLandroid/hardware/location/IActivityRecognitionHardware;)V
-Landroid/location/IGeocodeProvider;->getFromLocation(DDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
-Landroid/location/IGeocodeProvider;->getFromLocationName(Ljava/lang/String;DDDDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
-Landroid/location/IGeofenceProvider;->setGeofenceHardware(Landroid/hardware/location/IGeofenceHardware;)V
-Landroid/location/ILocationManager;->getNetworkProviderPackage()Ljava/lang/String;
-Landroid/location/ILocationManager;->reportLocation(Landroid/location/Location;Z)V
-Landroid/location/INetInitiatedListener$Stub;-><init>()V
-Landroid/location/INetInitiatedListener;->sendNiResponse(II)Z
-Landroid/media/tv/ITvRemoteProvider$Stub;-><init>()V
-Landroid/media/tv/ITvRemoteServiceInput;->clearInputBridge(Landroid/os/IBinder;)V
-Landroid/media/tv/ITvRemoteServiceInput;->closeInputBridge(Landroid/os/IBinder;)V
-Landroid/media/tv/ITvRemoteServiceInput;->openInputBridge(Landroid/os/IBinder;Ljava/lang/String;III)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendKeyDown(Landroid/os/IBinder;I)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendKeyUp(Landroid/os/IBinder;I)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendPointerDown(Landroid/os/IBinder;III)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendPointerSync(Landroid/os/IBinder;)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendPointerUp(Landroid/os/IBinder;I)V
-Landroid/media/tv/ITvRemoteServiceInput;->sendTimestamp(Landroid/os/IBinder;J)V
-Landroid/net/ConnectivityManager$PacketKeepaliveCallback;-><init>()V
-Landroid/net/IConnectivityManager;->getAllNetworkState()[Landroid/net/NetworkState;
-Landroid/net/INetd$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetd;
-Landroid/net/INetd;->interfaceAddAddress(Ljava/lang/String;Ljava/lang/String;I)V
-Landroid/net/INetworkPolicyManager;->getNetworkQuotaInfo(Landroid/net/NetworkState;)Landroid/net/NetworkQuotaInfo;
-Landroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService;
-Landroid/net/INetworkStatsSession;->getHistoryForNetwork(Landroid/net/NetworkTemplate;I)Landroid/net/NetworkStatsHistory;
-Landroid/net/INetworkStatsSession;->getHistoryForUid(Landroid/net/NetworkTemplate;IIII)Landroid/net/NetworkStatsHistory;
-Landroid/net/InterfaceConfiguration;-><init>()V
-Landroid/net/LinkProperties$ProvisioningChange;->values()[Landroid/net/LinkProperties$ProvisioningChange;
-Landroid/os/AsyncResult;-><init>(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Throwable;)V
-Landroid/os/AsyncResult;->exception:Ljava/lang/Throwable;
-Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;Ljava/lang/Object;Ljava/lang/Throwable;)Landroid/os/AsyncResult;
-Landroid/os/AsyncResult;->result:Ljava/lang/Object;
-Landroid/os/AsyncResult;->userObj:Ljava/lang/Object;
-Landroid/os/BatteryStats$HistoryItem;-><init>()V
-Landroid/os/BatteryStats$HistoryItem;->batteryLevel:B
-Landroid/os/BatteryStats$HistoryItem;->cmd:B
-Landroid/os/BatteryStats$HistoryItem;->states:I
-Landroid/os/BatteryStats$HistoryItem;->time:J
-Landroid/os/BatteryStats$Timer;->getCountLocked(I)I
-Landroid/os/BatteryStats$Uid$Wakelock;->getWakeTime(I)Landroid/os/BatteryStats$Timer;
-Landroid/os/BatteryStats$Uid;-><init>()V
-Landroid/os/BatteryStats$Uid;->getWifiRunningTime(JI)J
-Landroid/os/BatteryStats;->getNextHistoryLocked(Landroid/os/BatteryStats$HistoryItem;)Z
-Landroid/os/Broadcaster;-><init>()V
-Landroid/os/Broadcaster;->broadcast(Landroid/os/Message;)V
-Landroid/os/Broadcaster;->cancelRequest(ILandroid/os/Handler;I)V
-Landroid/os/Broadcaster;->request(ILandroid/os/Handler;I)V
-Landroid/os/Environment;->getLegacyExternalStorageDirectory()Ljava/io/File;
-Landroid/os/Handler;-><init>(Landroid/os/Looper;Landroid/os/Handler$Callback;Z)V
-Landroid/os/Handler;->getMain()Landroid/os/Handler;
-Landroid/os/HwBinder;->reportSyspropChanged()V
-Landroid/os/INetworkManagementService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/INetworkManagementService;
-Landroid/os/INetworkManagementService;->clearInterfaceAddresses(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->disableIpv6(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->enableIpv6(Ljava/lang/String;)V
-Landroid/os/INetworkManagementService;->isBandwidthControlEnabled()Z
-Landroid/os/INetworkManagementService;->registerObserver(Landroid/net/INetworkManagementEventObserver;)V
-Landroid/os/INetworkManagementService;->setInterfaceConfig(Ljava/lang/String;Landroid/net/InterfaceConfiguration;)V
-Landroid/os/INetworkManagementService;->setInterfaceIpv6PrivacyExtensions(Ljava/lang/String;Z)V
-Landroid/os/INetworkManagementService;->setIPv6AddrGenMode(Ljava/lang/String;I)V
-Landroid/os/INetworkManagementService;->unregisterObserver(Landroid/net/INetworkManagementEventObserver;)V
-Landroid/os/IPowerManager;->goToSleep(JII)V
-Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V
-Landroid/os/IRemoteCallback$Stub;-><init>()V
-Landroid/os/Message;->setCallback(Ljava/lang/Runnable;)Landroid/os/Message;
-Landroid/os/Parcel;->readBlob()[B
-Landroid/os/Parcel;->readStringArray()[Ljava/lang/String;
-Landroid/os/Parcel;->writeBlob([B)V
-Landroid/os/Registrant;-><init>(Landroid/os/Handler;ILjava/lang/Object;)V
-Landroid/os/Registrant;->clear()V
-Landroid/os/Registrant;->notifyRegistrant()V
-Landroid/os/Registrant;->notifyRegistrant(Landroid/os/AsyncResult;)V
-Landroid/os/RegistrantList;-><init>()V
-Landroid/os/RegistrantList;->add(Landroid/os/Registrant;)V
-Landroid/os/RegistrantList;->addUnique(Landroid/os/Handler;ILjava/lang/Object;)V
-Landroid/os/RegistrantList;->notifyRegistrants()V
-Landroid/os/RegistrantList;->notifyRegistrants(Landroid/os/AsyncResult;)V
-Landroid/os/RegistrantList;->remove(Landroid/os/Handler;)V
-Landroid/os/RegistrantList;->removeCleared()V
-Landroid/os/RemoteException;->rethrowFromSystemServer()Ljava/lang/RuntimeException;
-Landroid/os/ServiceSpecificException;->errorCode:I
-Landroid/os/storage/StorageEventListener;-><init>()V
-Landroid/os/SystemProperties;->reportSyspropChanged()V
-Landroid/os/SystemService;->start(Ljava/lang/String;)V
-Landroid/os/SystemService;->stop(Ljava/lang/String;)V
-Landroid/os/SystemVibrator;-><init>()V
-Landroid/os/UserHandle;->isSameApp(II)Z
-Landroid/os/UserManager;->hasUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
-Landroid/R$styleable;->CheckBoxPreference:[I
-Landroid/telephony/ims/compat/feature/MMTelFeature;-><init>()V
-Landroid/telephony/ims/compat/ImsService;-><init>()V
-Landroid/telephony/ims/compat/stub/ImsCallSessionImplBase;-><init>()V
-Landroid/telephony/ims/compat/stub/ImsUtListenerImplBase;-><init>()V
-Landroid/telephony/mbms/IMbmsStreamingSessionCallback$Stub;-><init>()V
-Landroid/telephony/mbms/IStreamingServiceCallback$Stub;-><init>()V
-Landroid/telephony/mbms/vendor/IMbmsStreamingService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/telephony/mbms/vendor/IMbmsStreamingService;
-Landroid/telephony/mbms/vendor/IMbmsStreamingService;->getPlaybackUri(ILjava/lang/String;)Landroid/net/Uri;
-Landroid/telephony/mbms/vendor/IMbmsStreamingService;->initialize(Landroid/telephony/mbms/IMbmsStreamingSessionCallback;I)I
-Landroid/telephony/mbms/vendor/IMbmsStreamingService;->requestUpdateStreamingServices(ILjava/util/List;)I
-Landroid/telephony/mbms/vendor/IMbmsStreamingService;->startStreaming(ILjava/lang/String;Landroid/telephony/mbms/IStreamingServiceCallback;)I
-Landroid/view/IAppTransitionAnimationSpecsFuture$Stub;-><init>()V
-Landroid/view/IRecentsAnimationController;->finish(Z)V
-Landroid/view/IRecentsAnimationController;->screenshotTask(I)Landroid/app/ActivityManager$TaskSnapshot;
-Landroid/view/IRecentsAnimationController;->setInputConsumerEnabled(Z)V
-Landroid/view/IRecentsAnimationRunner$Stub;-><init>()V
-Landroid/view/IRecentsAnimationRunner;->onAnimationCanceled()V
-Landroid/view/IRecentsAnimationRunner;->onAnimationStart(Landroid/view/IRecentsAnimationController;[Landroid/view/RemoteAnimationTarget;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
-Landroid/view/IRemoteAnimationFinishedCallback;->onAnimationFinished()V
-Landroid/view/IRemoteAnimationRunner$Stub;-><init>()V
-Landroid/view/IRemoteAnimationRunner;->onAnimationCancelled()V
-Landroid/view/IRemoteAnimationRunner;->onAnimationStart([Landroid/view/RemoteAnimationTarget;Landroid/view/IRemoteAnimationFinishedCallback;)V
-Landroid/view/IWindowManager;->createInputConsumer(Landroid/os/IBinder;Ljava/lang/String;ILandroid/view/InputChannel;)V
-Landroid/view/IWindowManager;->destroyInputConsumer(Ljava/lang/String;I)Z
-Landroid/view/IWindowManager;->endProlongedAnimations()V
-Landroid/view/IWindowManager;->getStableInsets(ILandroid/graphics/Rect;)V
-Landroid/view/IWindowManager;->overridePendingAppTransitionMultiThumbFuture(Landroid/view/IAppTransitionAnimationSpecsFuture;Landroid/os/IRemoteCallback;ZI)V
-Landroid/view/IWindowManager;->overridePendingAppTransitionRemote(Landroid/view/RemoteAnimationAdapter;I)V
-Landroid/view/IWindowManager;->setNavBarVirtualKeyHapticFeedbackEnabled(Z)V
-Lcom/android/ims/ImsConfigListener;->onSetFeatureResponse(IIII)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionConferenceStateUpdated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsConferenceState;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandover(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHandoverFailed(Lcom/android/ims/internal/IImsCallSession;IILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHeld(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionHoldReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionInviteParticipantsRequestDelivered(Lcom/android/ims/internal/IImsCallSession;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionInviteParticipantsRequestFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeComplete(Lcom/android/ims/internal/IImsCallSession;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMergeStarted(Lcom/android/ims/internal/IImsCallSession;Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionMultipartyStateChanged(Lcom/android/ims/internal/IImsCallSession;Z)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionProgressing(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsStreamMediaProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumeFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionResumeReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionStarted(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionStartFailed(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionSuppServiceReceived(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsSuppServiceNotification;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionTerminated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionTtyModeReceived(Lcom/android/ims/internal/IImsCallSession;I)V
-Lcom/android/ims/internal/IImsCallSessionListener;->callSessionUpdated(Lcom/android/ims/internal/IImsCallSession;Landroid/telephony/ims/ImsCallProfile;)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationAssociatedUriChanged([Landroid/net/Uri;)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationChangeFailed(ILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationConnectedWithRadioTech(I)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationDisconnected(Landroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationFeatureCapabilityChanged(I[I[I)V
-Lcom/android/ims/internal/IImsRegistrationListener;->registrationProgressingWithRadioTech(I)V
-Lcom/android/ims/internal/IImsRegistrationListener;->voiceMessageCountUpdate(I)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallBarringQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsSsInfo;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallForwardQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsCallForwardInfo;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationCallWaitingQueried(Lcom/android/ims/internal/IImsUt;I[Landroid/telephony/ims/ImsSsInfo;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueried(Lcom/android/ims/internal/IImsUt;ILandroid/os/Bundle;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueryFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdated(Lcom/android/ims/internal/IImsUt;I)V
-Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdateFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->cmdStatus(Lcom/android/ims/internal/uce/options/OptionsCmdStatus;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->getVersionCb(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->incomingOptions(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;I)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->serviceUnavailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/options/IOptionsListener;->sipResponseReceived(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsSipResponse;Lcom/android/ims/internal/uce/options/OptionsCapInfo;)V
-Lcom/android/ims/internal/uce/options/IOptionsService$Stub;-><init>()V
-Lcom/android/ims/internal/uce/options/IOptionsService;->addListener(ILcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->getMyInfo(II)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->getVersion(I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->responseIncomingOptions(IIILjava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;Z)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/IOptionsService;->setMyInfo(ILcom/android/ims/internal/uce/common/CapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->capInfoReceived(Ljava/lang/String;[Lcom/android/ims/internal/uce/presence/PresTupleInfo;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->cmdStatus(Lcom/android/ims/internal/uce/presence/PresCmdStatus;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->getVersionCb(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->listCapInfoReceived(Lcom/android/ims/internal/uce/presence/PresRlmiInfo;[Lcom/android/ims/internal/uce/presence/PresResInfo;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->publishTriggering(Lcom/android/ims/internal/uce/presence/PresPublishTriggerType;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->serviceAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->serviceUnAvailable(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->sipResponseReceived(Lcom/android/ims/internal/uce/presence/PresSipResponse;)V
-Lcom/android/ims/internal/uce/presence/IPresenceListener;->unpublishMessageSent()V
-Lcom/android/ims/internal/uce/presence/IPresenceService$Stub;-><init>()V
-Lcom/android/ims/internal/uce/presence/IPresenceService;->addListener(ILcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactCap(ILjava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->getContactListCap(I[Ljava/lang/String;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->getVersion(I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->publishMyCap(ILcom/android/ims/internal/uce/presence/PresCapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->reenableService(II)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/IPresenceService;->setNewFeatureTag(ILjava/lang/String;Lcom/android/ims/internal/uce/presence/PresServiceInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/uceservice/IUceListener;->setStatus(I)V
-Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
-Lcom/android/ims/internal/uce/uceservice/IUceService;->createOptionsService(Lcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)I
-Lcom/android/ims/internal/uce/uceservice/IUceService;->createPresenceService(Lcom/android/ims/internal/uce/presence/IPresenceListener;Lcom/android/ims/internal/uce/common/UceLong;)I
-Lcom/android/ims/internal/uce/uceservice/IUceService;->destroyOptionsService(I)V
-Lcom/android/ims/internal/uce/uceservice/IUceService;->destroyPresenceService(I)V
-Lcom/android/ims/internal/uce/uceservice/IUceService;->getOptionsService()Lcom/android/ims/internal/uce/options/IOptionsService;
-Lcom/android/ims/internal/uce/uceservice/IUceService;->getPresenceService()Lcom/android/ims/internal/uce/presence/IPresenceService;
-Lcom/android/ims/internal/uce/uceservice/IUceService;->getServiceStatus()Z
-Lcom/android/ims/internal/uce/uceservice/IUceService;->isServiceStarted()Z
-Lcom/android/ims/internal/uce/uceservice/IUceService;->startService(Lcom/android/ims/internal/uce/uceservice/IUceListener;)Z
-Lcom/android/ims/internal/uce/uceservice/IUceService;->stopService()Z
-Lcom/android/internal/app/IAppOpsService;->finishOperation(Landroid/os/IBinder;IILjava/lang/String;)V
-Lcom/android/internal/content/PackageMonitor;-><init>()V
-Lcom/android/internal/location/ILocationProvider$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/location/ILocationProvider;
-Lcom/android/internal/location/ILocationProvider;->disable()V
-Lcom/android/internal/location/ILocationProvider;->enable()V
-Lcom/android/internal/location/ILocationProvider;->getProperties()Lcom/android/internal/location/ProviderProperties;
-Lcom/android/internal/location/ILocationProvider;->getStatus(Landroid/os/Bundle;)I
-Lcom/android/internal/location/ILocationProvider;->getStatusUpdateTime()J
-Lcom/android/internal/location/ILocationProvider;->sendExtraCommand(Ljava/lang/String;Landroid/os/Bundle;)Z
-Lcom/android/internal/location/ILocationProvider;->setRequest(Lcom/android/internal/location/ProviderRequest;Landroid/os/WorkSource;)V
-Lcom/android/internal/R$styleable;->NumberPicker:[I
-Lcom/android/internal/R$styleable;->TwoLineListItem:[I
-Lcom/android/internal/telephony/ITelephony;->getDataEnabled(I)Z
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 446d98e..2c435a2 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -31,7 +31,6 @@
 import android.util.Log;
 import android.view.IWindowManager;
 import android.view.InputDevice;
-import android.view.InputEvent;
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.SurfaceControl;
@@ -291,9 +290,14 @@
         return super.onGenericMotionEvent(event);
     }
 
-    private boolean injectInputEvent(InputEvent event) {
+    private boolean injectInputEvent(MotionEvent event) {
         if (mInputForwarder != null) {
             try {
+                // The touch event that the ActivityView gets is in View space, but the event needs
+                // to get forwarded in screen space. This offsets the touch event by the location
+                // the ActivityView is on screen and sends it to the input forwarder.
+                getLocationOnScreen(mLocationOnScreen);
+                event.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
                 return mInputForwarder.forwardEvent(event);
             } catch (RemoteException e) {
                 e.rethrowAsRuntimeException();
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index e83bcd0..88fb025 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -96,6 +96,7 @@
             String callingPackage);
     void unregisterUidObserver(in IUidObserver observer);
     boolean isUidActive(int uid, String callingPackage);
+    int getUidProcessState(int uid, in String callingPackage);
     // =============== End of transactions used on native side as well ============================
 
     // Special low-level communication with activity manager.
@@ -379,8 +380,6 @@
     void noteAlarmFinish(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag);
     int getPackageProcessState(in String packageName, in String callingPackage);
     void updateDeviceOwner(in String packageName);
-    int getUidProcessState(int uid, in String callingPackage);
-
 
     // Start of N transactions
     // Start Binder transaction tracking for all applications.
diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl
index ce88809..e116d98 100644
--- a/core/java/android/app/IUidObserver.aidl
+++ b/core/java/android/app/IUidObserver.aidl
@@ -43,8 +43,6 @@
      */
     void onUidIdle(int uid, boolean disabled);
 
-    // =============== End of transactions used on native side as well ============================
-
     /**
      * General report of a state change of an uid.
      *
@@ -55,6 +53,8 @@
      */
     void onUidStateChanged(int uid, int procState, long procStateSeq);
 
+    // =============== End of transactions used on native side as well ============================
+
     /**
      * Report when the cached state of a uid has changed.
      * If true, a uid has become cached -- that is, it has some active processes that are
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 3f10754..719bba0 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -696,6 +696,23 @@
         return loaders;
     }
 
+    private StrictMode.ThreadPolicy allowThreadDiskReads() {
+        if (mActivityThread == null) {
+            // When LoadedApk is used without an ActivityThread (usually in a
+            // zygote context), don't call into StrictMode, as it initializes
+            // the binder subsystem, which we don't want.
+            return null;
+        }
+
+        return StrictMode.allowThreadDiskReads();
+    }
+
+    private void setThreadPolicy(StrictMode.ThreadPolicy policy) {
+        if (mActivityThread != null && policy != null) {
+            StrictMode.setThreadPolicy(policy);
+        }
+    }
+
     private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
         if (mPackageName.equals("android")) {
             // Note: This branch is taken for system server and we don't need to setup
@@ -718,8 +735,11 @@
 
         // Avoid the binder call when the package is the current application package.
         // The activity manager will perform ensure that dexopt is performed before
-        // spinning up the process.
-        if (!Objects.equals(mPackageName, ActivityThread.currentPackageName()) && mIncludeCode) {
+        // spinning up the process. Similarly, don't call into binder when we don't
+        // have an ActivityThread object.
+        if (mActivityThread != null
+                && !Objects.equals(mPackageName, ActivityThread.currentPackageName())
+                && mIncludeCode) {
             try {
                 ActivityThread.getPackageManager().notifyPackageUse(mPackageName,
                         PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE);
@@ -790,12 +810,12 @@
         // mIncludeCode == false).
         if (!mIncludeCode) {
             if (mDefaultClassLoader == null) {
-                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+                StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
                 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader(
                         "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
                         librarySearchPath, libraryPermittedPath, mBaseClassLoader,
                         null /* classLoaderName */);
-                StrictMode.setThreadPolicy(oldPolicy);
+                setThreadPolicy(oldPolicy);
                 mAppComponentFactory = AppComponentFactory.DEFAULT;
             }
 
@@ -822,7 +842,7 @@
         if (mDefaultClassLoader == null) {
             // Temporarily disable logging of disk reads on the Looper thread
             // as this is early and necessary.
-            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+            StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
 
             List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
                     mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
@@ -834,18 +854,18 @@
                     mApplicationInfo.classLoaderName, sharedLibraries);
             mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
 
-            StrictMode.setThreadPolicy(oldPolicy);
+            setThreadPolicy(oldPolicy);
             // Setup the class loader paths for profiling.
             needToSetupJitProfiles = true;
         }
 
         if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
             // Temporarily disable logging of disk reads on the Looper thread as this is necessary
-            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+            StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
             try {
                 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, libPaths);
             } finally {
-                StrictMode.setThreadPolicy(oldPolicy);
+                setThreadPolicy(oldPolicy);
             }
         }
 
@@ -879,11 +899,11 @@
             extraLibPaths.add("/product/lib" + abiSuffix);
         }
         if (!extraLibPaths.isEmpty()) {
-            StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+            StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
             try {
                 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, extraLibPaths);
             } finally {
-                StrictMode.setThreadPolicy(oldPolicy);
+                setThreadPolicy(oldPolicy);
             }
         }
 
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0281e6a..aa1b5af 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -8263,7 +8263,7 @@
                 customContent = customContent.clone();
                 remoteViews.removeAllViewsExceptId(R.id.notification_main_column, R.id.progress);
                 remoteViews.addView(R.id.notification_main_column, customContent, 0 /* index */);
-                remoteViews.setReapplyDisallowed();
+                remoteViews.addFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED);
             }
             // also update the end margin if there is an image
             Resources resources = mBuilder.mContext.getResources();
@@ -8394,7 +8394,7 @@
                 customContent.overrideTextColors(mBuilder.getPrimaryTextColor(mBuilder.mParams));
                 remoteViews.removeAllViews(id);
                 remoteViews.addView(id, customContent);
-                remoteViews.setReapplyDisallowed();
+                remoteViews.addFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED);
             }
             return remoteViews;
         }
diff --git a/core/java/android/app/StatsManager.java b/core/java/android/app/StatsManager.java
index 32fc0dc..9dcd122 100644
--- a/core/java/android/app/StatsManager.java
+++ b/core/java/android/app/StatsManager.java
@@ -119,6 +119,7 @@
     /**
      * @deprecated Use {@link #addConfig(long, byte[])}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public boolean addConfiguration(long configKey, byte[] config) {
         try {
@@ -154,6 +155,7 @@
     /**
      * @deprecated Use {@link #removeConfig(long)}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public boolean removeConfiguration(long configKey) {
         try {
@@ -222,6 +224,7 @@
     /**
      * @deprecated Use {@link #setBroadcastSubscriber(PendingIntent, long, long)}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public boolean setBroadcastSubscriber(
             long configKey, long subscriberId, PendingIntent pendingIntent) {
@@ -275,6 +278,7 @@
     /**
      * @deprecated Use {@link #setFetchReportsOperation(PendingIntent, long)}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public boolean setDataFetchOperation(long configKey, PendingIntent pendingIntent) {
         try {
@@ -312,6 +316,7 @@
     /**
      * @deprecated Use {@link #getReports(long)}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public @Nullable byte[] getData(long configKey) {
         try {
@@ -348,6 +353,7 @@
     /**
      * @deprecated Use {@link #getStatsMetadata()}
      */
+    @Deprecated
     @RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
     public @Nullable byte[] getMetadata() {
         try {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index dfe371c..0404e80 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -59,6 +59,7 @@
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.IBiometricService;
 import android.hardware.camera2.CameraManager;
+import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.face.FaceManager;
 import android.hardware.face.IFaceService;
@@ -386,6 +387,14 @@
                 return new DisplayManager(ctx.getOuterContext());
             }});
 
+        registerService(Context.COLOR_DISPLAY_SERVICE, ColorDisplayManager.class,
+                new CachedServiceFetcher<ColorDisplayManager>() {
+                    @Override
+                    public ColorDisplayManager createService(ContextImpl ctx) {
+                        return new ColorDisplayManager();
+                    }
+                });
+
         // InputMethodManager has its own cache strategy based on display id to support apps that
         // still assume InputMethodManager is a per-process singleton and it's safe to directly
         // access internal fields via reflection.  Hence directly use ServiceFetcher instead of
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 78b7d48..257122d 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -75,6 +75,9 @@
     /** The current windowing mode of the configuration. */
     private @WindowingMode int mWindowingMode;
 
+    /** The display windowing mode of the configuration */
+    private @WindowingMode int mDisplayWindowingMode;
+
     /** Windowing mode is currently not defined. */
     public static final int WINDOWING_MODE_UNDEFINED = 0;
     /** Occupies the full area of the screen or the parent container. */
@@ -176,6 +179,10 @@
     /** Bit that indicates that the {@link #mRotation} changed.
      * @hide */
     public static final int WINDOW_CONFIG_ROTATION = 1 << 5;
+    /** Bit that indicates that the {@link #mDisplayWindowingMode} changed.
+     * @hide */
+    public static final int WINDOW_CONFIG_DISPLAY_WINDOWING_MODE = 1 << 6;
+
     /** @hide */
     @IntDef(flag = true, prefix = { "WINDOW_CONFIG_" }, value = {
             WINDOW_CONFIG_BOUNDS,
@@ -184,6 +191,7 @@
             WINDOW_CONFIG_ACTIVITY_TYPE,
             WINDOW_CONFIG_ALWAYS_ON_TOP,
             WINDOW_CONFIG_ROTATION,
+            WINDOW_CONFIG_DISPLAY_WINDOWING_MODE,
     })
     public @interface WindowConfig {}
 
@@ -211,6 +219,7 @@
         dest.writeInt(mActivityType);
         dest.writeInt(mAlwaysOnTop);
         dest.writeInt(mRotation);
+        dest.writeInt(mDisplayWindowingMode);
     }
 
     private void readFromParcel(Parcel source) {
@@ -220,6 +229,7 @@
         mActivityType = source.readInt();
         mAlwaysOnTop = source.readInt();
         mRotation = source.readInt();
+        mDisplayWindowingMode = source.readInt();
     }
 
     @Override
@@ -322,6 +332,12 @@
         return mWindowingMode;
     }
 
+    /** @hide */
+    public void setDisplayWindowingMode(@WindowingMode int windowingMode) {
+        mDisplayWindowingMode = windowingMode;
+    }
+
+
     public void setActivityType(@ActivityType int activityType) {
         if (mActivityType == activityType) {
             return;
@@ -351,6 +367,7 @@
         setActivityType(other.mActivityType);
         setAlwaysOnTop(other.mAlwaysOnTop);
         setRotation(other.mRotation);
+        setDisplayWindowingMode(other.mDisplayWindowingMode);
     }
 
     /** Set this object to completely undefined.
@@ -367,6 +384,7 @@
         setActivityType(ACTIVITY_TYPE_UNDEFINED);
         setAlwaysOnTop(ALWAYS_ON_TOP_UNDEFINED);
         setRotation(ROTATION_UNDEFINED);
+        setDisplayWindowingMode(WINDOWING_MODE_UNDEFINED);
     }
 
     /**
@@ -407,6 +425,11 @@
             changed |= WINDOW_CONFIG_ROTATION;
             setRotation(delta.mRotation);
         }
+        if (delta.mDisplayWindowingMode != WINDOWING_MODE_UNDEFINED
+                && mDisplayWindowingMode != delta.mDisplayWindowingMode) {
+            changed |= WINDOW_CONFIG_DISPLAY_WINDOWING_MODE;
+            setDisplayWindowingMode(delta.mDisplayWindowingMode);
+        }
         return changed;
     }
 
@@ -455,6 +478,11 @@
             changes |= WINDOW_CONFIG_ROTATION;
         }
 
+        if ((compareUndefined || other.mDisplayWindowingMode != WINDOWING_MODE_UNDEFINED)
+                && mDisplayWindowingMode != other.mDisplayWindowingMode) {
+            changes |= WINDOW_CONFIG_DISPLAY_WINDOWING_MODE;
+        }
+
         return changes;
     }
 
@@ -493,6 +521,8 @@
         if (n != 0) return n;
         n = mRotation - that.mRotation;
         if (n != 0) return n;
+        n = mDisplayWindowingMode - that.mDisplayWindowingMode;
+        if (n != 0) return n;
 
         // if (n != 0) return n;
         return n;
@@ -522,6 +552,7 @@
         result = 31 * result + mActivityType;
         result = 31 * result + mAlwaysOnTop;
         result = 31 * result + mRotation;
+        result = 31 * result + mDisplayWindowingMode;
         return result;
     }
 
@@ -531,6 +562,7 @@
         return "{ mBounds=" + mBounds
                 + " mAppBounds=" + mAppBounds
                 + " mWindowingMode=" + windowingModeToString(mWindowingMode)
+                + " mDisplayWindowingMode=" + windowingModeToString(mDisplayWindowingMode)
                 + " mActivityType=" + activityTypeToString(mActivityType)
                 + " mAlwaysOnTop=" + alwaysOnTopToString(mAlwaysOnTop)
                 + " mRotation=" + (mRotation == ROTATION_UNDEFINED
@@ -603,7 +635,8 @@
      * @hide
      */
     public boolean hasWindowDecorCaption() {
-        return mWindowingMode == WINDOWING_MODE_FREEFORM;
+        return mActivityType == ACTIVITY_TYPE_STANDARD && (mWindowingMode == WINDOWING_MODE_FREEFORM
+                || mDisplayWindowingMode == WINDOWING_MODE_FREEFORM);
     }
 
     /**
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 98d2a40..3a97284 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10092,11 +10092,40 @@
         if (mService != null) {
             try {
                 return mService.isPackageAllowedToAccessCalendarForUser(packageName,
-                        mContext.getUserId());
+                        myUserId());
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
         }
         return false;
     }
+
+    /**
+     * Gets a set of package names that are whitelisted to access cross profile calendar APIs.
+     *
+     * <p>To query for a specific user, use
+     * {@link Context#createPackageContextAsUser(String, int, UserHandle)} to create a context for
+     * that user, and get a {@link DevicePolicyManager} from this context.
+     *
+     * @return the set of names of packages that were previously whitelisted via
+     * {@link #addCrossProfileCalendarPackage(ComponentName, String)}, or an
+     * empty set if none have been whitelisted.
+     *
+     * @see #addCrossProfileCalendarPackage(ComponentName, String)
+     * @see #removeCrossProfileCalendarPackage(ComponentName, String)
+     * @see #getCrossProfileCalendarPackages(ComponentName)
+     * @hide
+     */
+    public @NonNull Set<String>  getCrossProfileCalendarPackages() {
+        throwIfParentInstance("getCrossProfileCalendarPackages");
+        if (mService != null) {
+            try {
+                return new ArraySet<>(mService.getCrossProfileCalendarPackagesForUser(
+                        myUserId()));
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+        return Collections.emptySet();
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 297676d..fcf74ee 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -427,4 +427,5 @@
     boolean removeCrossProfileCalendarPackage(in ComponentName admin, String packageName);
     List<String> getCrossProfileCalendarPackages(in ComponentName admin);
     boolean isPackageAllowedToAccessCalendarForUser(String packageName, int userHandle);
+    List<String> getCrossProfileCalendarPackagesForUser(int userHandle);
 }
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index 318dbee..c740c42 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -88,6 +88,7 @@
     int mViewMode = VIEW_MODE_NOINIT;
     int mLayoutId = -1;
     private OnClickHandler mOnClickHandler;
+    private boolean mOnLightBackground;
 
     private Executor mAsyncExecutor;
     private CancellationSignal mLastExecutionSignal;
@@ -374,6 +375,15 @@
     }
 
     /**
+     * Sets whether the widget should is being displayed on a light/white background and use an
+     * alternate UI if available.
+     * @see RemoteViews#setLightBackgroundLayoutId(int)
+     */
+    public void setOnLightBackground(boolean useDarkTextLayout) {
+        mOnLightBackground = useDarkTextLayout;
+    }
+
+    /**
      * Update the AppWidgetProviderInfo for this view, and reset it to the
      * initial layout.
      */
@@ -413,6 +423,10 @@
             mLayoutId = -1;
             mViewMode = VIEW_MODE_DEFAULT;
         } else {
+            if (mOnLightBackground) {
+                remoteViews = remoteViews.getDarkTextViews();
+            }
+
             if (mAsyncExecutor != null && useAsyncIfPossible) {
                 inflateAsync(remoteViews);
                 return;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 68aac64..fe11acb 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3126,6 +3126,7 @@
             //@hide: HDMI_CONTROL_SERVICE,
             INPUT_SERVICE,
             DISPLAY_SERVICE,
+            //@hide COLOR_DISPLAY_SERVICE,
             USER_SERVICE,
             RESTRICTIONS_SERVICE,
             APP_OPS_SERVICE,
@@ -4108,6 +4109,16 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.hardware.display.ColorDisplayManager} for controlling color transforms.
+     *
+     * @see #getSystemService(String)
+     * @see android.hardware.display.ColorDisplayManager
+     * @hide
+     */
+    public static final String COLOR_DISPLAY_SERVICE = "color_display";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a
      * {@link android.os.UserManager} for managing users on devices that support multiple users.
      *
      * @see #getSystemService(String)
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 7c3b5e4..98a135f 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1770,7 +1770,7 @@
      * is on the package whitelist.
      *
      * @param policy configured policy for this app, or {@link #HIDDEN_API_ENFORCEMENT_DEFAULT}
-     *               if nothing configured.
+     *        if nothing configured.
      * @hide
      */
     public void maybeUpdateHiddenApiEnforcementPolicy(@HiddenApiEnforcementPolicy int policy) {
diff --git a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
index 79bc9a3..73addb7 100644
--- a/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
+++ b/core/java/android/content/pm/permission/RuntimePermissionPresenter.java
@@ -16,13 +16,15 @@
 
 package android.content.pm.permission;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -32,7 +34,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.os.SomeArgs;
+import com.android.internal.util.function.pooled.PooledLambda;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -109,13 +111,11 @@
      */
     public void getAppPermissions(@NonNull String packageName,
             @NonNull OnResultCallback callback, @Nullable Handler handler) {
-        SomeArgs args = SomeArgs.obtain();
-        args.arg1 = packageName;
-        args.arg2 = callback;
-        args.arg3 = handler;
-        Message message = mRemoteService.obtainMessage(
-                RemoteService.MSG_GET_APP_PERMISSIONS, args);
-        mRemoteService.processMessage(message);
+        checkNotNull(packageName);
+        checkNotNull(callback);
+
+        mRemoteService.processMessage(obtainMessage(RemoteService::getAppPermissions,
+                mRemoteService, packageName, callback, handler));
     }
 
     /**
@@ -124,24 +124,20 @@
      * @param packageName The package for which to revoke
      * @param permissionName The permission to revoke
      */
-    public void revokeRuntimePermission(String packageName, String permissionName) {
-        SomeArgs args = SomeArgs.obtain();
-        args.arg1 = packageName;
-        args.arg2 = permissionName;
+    public void revokeRuntimePermission(@NonNull String packageName,
+            @NonNull String permissionName) {
+        checkNotNull(packageName);
+        checkNotNull(permissionName);
 
-        Message message = mRemoteService.obtainMessage(
-                RemoteService.MSG_REVOKE_APP_PERMISSIONS, args);
-        mRemoteService.processMessage(message);
+        mRemoteService.processMessage(obtainMessage(RemoteService::revokeAppPermissions,
+                mRemoteService, packageName, permissionName));
     }
 
     private static final class RemoteService
             extends Handler implements ServiceConnection {
         private static final long UNBIND_TIMEOUT_MILLIS = 10000;
 
-        public static final int MSG_GET_APP_PERMISSIONS = 1;
-        public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
-        public static final int MSG_UNBIND = 3;
-        public static final int MSG_REVOKE_APP_PERMISSIONS = 4;
+        public static final int MSG_UNBIND = 0;
 
         private final Object mLock = new Object();
 
@@ -191,82 +187,57 @@
             }
         }
 
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_GET_APP_PERMISSIONS: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    final String packageName = (String) args.arg1;
-                    final OnResultCallback callback = (OnResultCallback) args.arg2;
-                    final Handler handler = (Handler) args.arg3;
-                    args.recycle();
-                    final IRuntimePermissionPresenter remoteInstance;
-                    synchronized (mLock) {
-                        remoteInstance = mRemoteInstance;
-                    }
-                    if (remoteInstance == null) {
-                        return;
-                    }
-                    try {
-                        remoteInstance.getAppPermissions(packageName,
-                                new RemoteCallback(new RemoteCallback.OnResultListener() {
-                            @Override
-                            public void onResult(Bundle result) {
-                                final List<RuntimePermissionPresentationInfo> reportedPermissions;
-                                List<RuntimePermissionPresentationInfo> permissions = null;
-                                if (result != null) {
-                                    permissions = result.getParcelableArrayList(KEY_RESULT);
-                                }
-                                if (permissions == null) {
-                                    permissions = Collections.emptyList();
-                                }
-                                reportedPermissions = permissions;
-                                if (handler != null) {
-                                    handler.post(new Runnable() {
-                                        @Override
-                                        public void run() {
-                                            callback.onGetAppPermissions(reportedPermissions);
-                                        }
-                                    });
-                                } else {
-                                    callback.onGetAppPermissions(reportedPermissions);
-                                }
+        private void getAppPermissions(@NonNull String packageName,
+                @NonNull OnResultCallback callback, @Nullable Handler handler) {
+            final IRuntimePermissionPresenter remoteInstance;
+            synchronized (mLock) {
+                remoteInstance = mRemoteInstance;
+            }
+            if (remoteInstance == null) {
+                return;
+            }
+            try {
+                remoteInstance.getAppPermissions(packageName,
+                        new RemoteCallback(result -> {
+                            final List<RuntimePermissionPresentationInfo> reportedPermissions;
+                            List<RuntimePermissionPresentationInfo> permissions = null;
+                            if (result != null) {
+                                permissions = result.getParcelableArrayList(KEY_RESULT);
+                            }
+                            if (permissions == null) {
+                                permissions = Collections.emptyList();
+                            }
+                            reportedPermissions = permissions;
+                            if (handler != null) {
+                                handler.post(
+                                        () -> callback.onGetAppPermissions(reportedPermissions));
+                            } else {
+                                callback.onGetAppPermissions(reportedPermissions);
                             }
                         }, this));
-                    } catch (RemoteException re) {
-                        Log.e(TAG, "Error getting app permissions", re);
-                    }
-                    scheduleUnbind();
-                } break;
+            } catch (RemoteException re) {
+                Log.e(TAG, "Error getting app permissions", re);
+            }
+            scheduleUnbind();
 
-                case MSG_UNBIND: {
-                    synchronized (mLock) {
-                        if (mBound) {
-                            mContext.unbindService(this);
-                            mBound = false;
-                        }
-                        mRemoteInstance = null;
-                    }
-                } break;
+            synchronized (mLock) {
+                scheduleNextMessageIfNeededLocked();
+            }
+        }
 
-                case MSG_REVOKE_APP_PERMISSIONS: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    final String packageName = (String) args.arg1;
-                    final String permissionName = (String) args.arg2;
-                    args.recycle();
-                    final IRuntimePermissionPresenter remoteInstance;
-                    synchronized (mLock) {
-                        remoteInstance = mRemoteInstance;
-                    }
-                    if (remoteInstance == null) {
-                        return;
-                    }
-                    try {
-                        remoteInstance.revokeRuntimePermission(packageName, permissionName);
-                    } catch (RemoteException re) {
-                        Log.e(TAG, "Error getting app permissions", re);
-                    }
-                } break;
+        private void revokeAppPermissions(@NonNull String packageName,
+                @NonNull String permissionName) {
+            final IRuntimePermissionPresenter remoteInstance;
+            synchronized (mLock) {
+                remoteInstance = mRemoteInstance;
+            }
+            if (remoteInstance == null) {
+                return;
+            }
+            try {
+                remoteInstance.revokeRuntimePermission(packageName, permissionName);
+            } catch (RemoteException re) {
+                Log.e(TAG, "Error getting app permissions", re);
             }
 
             synchronized (mLock) {
@@ -274,6 +245,16 @@
             }
         }
 
+        private void unbind() {
+            synchronized (mLock) {
+                if (mBound) {
+                    mContext.unbindService(this);
+                    mBound = false;
+                }
+                mRemoteInstance = null;
+            }
+        }
+
         @GuardedBy("mLock")
         private void scheduleNextMessageIfNeededLocked() {
             if (mBound && mRemoteInstance != null && !mPendingWork.isEmpty()) {
@@ -284,7 +265,8 @@
 
         private void scheduleUnbind() {
             removeMessages(MSG_UNBIND);
-            sendEmptyMessageDelayed(MSG_UNBIND, UNBIND_TIMEOUT_MILLIS);
+            sendMessageDelayed(PooledLambda.obtainMessage(RemoteService::unbind, this)
+                    .setWhat(MSG_UNBIND), UNBIND_TIMEOUT_MILLIS);
         }
     }
 }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 7148b12..5e402c7 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -393,7 +393,7 @@
      *         doesn't have any recommendation for this use case or the recommended configurations
      *         are invalid.
      */
-    public RecommendedStreamConfigurationMap getRecommendedStreamConfigurationMap(
+    public @Nullable RecommendedStreamConfigurationMap getRecommendedStreamConfigurationMap(
             @RecommendedStreamConfigurationMap.RecommendedUsecase int usecase) {
         if (((usecase >= RecommendedStreamConfigurationMap.USECASE_PREVIEW) &&
                 (usecase <= RecommendedStreamConfigurationMap.USECASE_RAW)) ||
diff --git a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
index 59e4a33..068c0ce 100644
--- a/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/RecommendedStreamConfigurationMap.java
@@ -17,6 +17,7 @@
 package android.hardware.camera2.params;
 
 import android.annotation.IntDef;
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.ImageFormat;
@@ -173,7 +174,7 @@
      *
      * @return Use case id.
      */
-    public int getRecommendedUseCase() {
+    public @RecommendedUsecase int getRecommendedUseCase() {
         return mUsecase;
     }
 
@@ -326,7 +327,7 @@
      * @throws IllegalArgumentException if input size does not exist in the return value of
      *             getHighSpeedVideoSizes
      */
-    public @Nullable Set<Range<Integer>> getHighSpeedVideoFpsRangesFor(Size size) {
+    public @Nullable Set<Range<Integer>> getHighSpeedVideoFpsRangesFor(@NonNull Size size) {
         return getUnmodifiableRangeSet(mRecommendedMap.getHighSpeedVideoFpsRangesFor(size));
     }
 
@@ -349,14 +350,14 @@
      * For further information refer to {@link StreamConfigurationMap#getHighSpeedVideoSizesFor}.
      * </p>
      *
-     * @param fpsRange one of the FPS range returned by {@link #getHighSpeedVideoFpsRanges()}
+     * @param fpsRange one of the FPS ranges returned by {@link #getHighSpeedVideoFpsRanges()}
      * @return A non-modifiable set of video sizes to create high speed capture sessions for high
      *         speed streaming use cases.
      *
      * @throws IllegalArgumentException if input FPS range does not exist in the return value of
      *         getHighSpeedVideoFpsRanges
      */
-    public @Nullable Set<Size> getHighSpeedVideoSizesFor(Range<Integer> fpsRange) {
+    public @Nullable Set<Size> getHighSpeedVideoSizesFor(@NonNull Range<Integer> fpsRange) {
         return getUnmodifiableSizeSet(mRecommendedMap.getHighSpeedVideoSizesFor(fpsRange));
     }
 
@@ -390,10 +391,8 @@
      *          0 if the minimum frame duration is not available.
      *
      * @throws IllegalArgumentException if {@code format} or {@code size} was not supported
-     * @throws NullPointerException if {@code size} was {@code null}
-     *
      */
-    public long getOutputMinFrameDuration(int format, Size size) {
+    public @IntRange(from = 0) long getOutputMinFrameDuration(int format, @NonNull Size size) {
         return mRecommendedMap.getOutputMinFrameDuration(format, size);
     }
 
@@ -409,9 +408,8 @@
      * @return a stall duration {@code >=} 0 in nanoseconds
      *
      * @throws IllegalArgumentException if {@code format} or {@code size} was not supported
-     * @throws NullPointerException if {@code size} was {@code null}
      */
-    public long getOutputStallDuration(int format, Size size) {
+    public @IntRange(from = 0) long getOutputStallDuration(int format, @NonNull Size size) {
         return mRecommendedMap.getOutputStallDuration(format, size);
     }
 
@@ -422,16 +420,12 @@
      * </p>
      *
      * @param klass
-     *          a non-{@code null} {@link Class} object reference
+     *          a {@link Class} object reference
      * @return
      *          a non-modifiable set of supported sizes for {@link ImageFormat#PRIVATE} format,
      *          or {@code null} if the {@code klass} is not a supported output.
-     *
-     *
-     * @throws NullPointerException if {@code klass} was {@code null}
-     *
      */
-    public <T> @Nullable Set<Size> getOutputSizes(Class<T> klass) {
+    public <T> @Nullable Set<Size> getOutputSizes(@NonNull Class<T> klass) {
         if (mSupportsPrivate) {
             return getUnmodifiableSizeSet(mRecommendedMap.getOutputSizes(klass));
         }
@@ -447,16 +441,15 @@
      * {@link StreamConfigurationMap#getOutputMinFrameDuration(Class, Size)}.</p>
      *
      * @param klass
-     *          a class which  has a non-empty array returned by {@link #getOutputSizes(Class)}
+     *          a class which has a non-empty array returned by {@link #getOutputSizes(Class)}
      * @param size an output-compatible size
      * @return a minimum frame duration {@code >} 0 in nanoseconds, or
      *          0 if the minimum frame duration is not available.
      *
      * @throws IllegalArgumentException if {@code klass} or {@code size} was not supported
-     * @throws NullPointerException if {@code size} or {@code klass} was {@code null}
-     *
      */
-    public <T> long getOutputMinFrameDuration(final Class<T> klass, final Size size) {
+    public <T> @IntRange(from = 0) long getOutputMinFrameDuration(@NonNull final Class<T> klass,
+            @NonNull final Size size) {
         if (mSupportsPrivate) {
             return mRecommendedMap.getOutputMinFrameDuration(klass, size);
         }
@@ -473,14 +466,13 @@
      * @param klass
      *          a class which has a non-empty array returned by {@link #getOutputSizes(Class)}.
      * @param size an output-compatible size
-     * @return a minimum frame duration {@code >=} 0 in nanoseconds, or 0 if the stall duration is
+     * @return a minimum frame duration {@code >} 0 in nanoseconds, or 0 if the stall duration is
      *         not available.
      *
      * @throws IllegalArgumentException if {@code klass} or {@code size} was not supported
-     * @throws NullPointerException if {@code size} or {@code klass} was {@code null}
-     *
      */
-    public <T> long getOutputStallDuration(final Class<T> klass, final Size size) {
+    public <T> @IntRange(from = 0) long getOutputStallDuration(@NonNull final Class<T> klass,
+            @NonNull final Size size) {
         if (mSupportsPrivate) {
             return mRecommendedMap.getOutputStallDuration(klass, size);
         }
@@ -495,14 +487,13 @@
      * <p>For more information refer to {@link StreamConfigurationMap#isOutputSupportedFor}.
      * </p>
      *
-     * @param surface a non-{@code null} {@link Surface} object reference
+     * @param surface a {@link Surface} object reference
      * @return {@code true} if this is supported, {@code false} otherwise
      *
-     * @throws NullPointerException if {@code surface} was {@code null}
      * @throws IllegalArgumentException if the Surface endpoint is no longer valid
      *
      */
-    public boolean isOutputSupportedFor(Surface surface) {
+    public boolean isOutputSupportedFor(@NonNull Surface surface) {
         return mRecommendedMap.isOutputSupportedFor(surface);
     }
 
diff --git a/core/java/android/hardware/display/ColorDisplayManager.java b/core/java/android/hardware/display/ColorDisplayManager.java
index 0a76c2b..a4c1332 100644
--- a/core/java/android/hardware/display/ColorDisplayManager.java
+++ b/core/java/android/hardware/display/ColorDisplayManager.java
@@ -16,20 +16,81 @@
 
 package android.hardware.display;
 
+import android.annotation.RequiresPermission;
+import android.annotation.SystemService;
 import android.content.Context;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.ServiceManager.ServiceNotFoundException;
 
 import com.android.internal.R;
 
 /**
  * Manages the display's color transforms and modes.
+ *
  * @hide
  */
+@SystemService(Context.COLOR_DISPLAY_SERVICE)
 public final class ColorDisplayManager {
 
+    private final ColorDisplayManagerInternal mManager;
+
+    /**
+     * @hide
+     */
+    public ColorDisplayManager() {
+        mManager = ColorDisplayManagerInternal.getInstance();
+    }
+
+    /**
+     * Returns whether the device has a wide color gamut display.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
+    public boolean isDeviceColorManaged() {
+        return mManager.isDeviceColorManaged();
+    }
+
     /**
      * Returns {@code true} if Night Display is supported by the device.
      */
     public static boolean isNightDisplayAvailable(Context context) {
         return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable);
     }
+
+    private static class ColorDisplayManagerInternal {
+
+        private static ColorDisplayManagerInternal sInstance;
+
+        private final IColorDisplayManager mCdm;
+
+        private ColorDisplayManagerInternal(IColorDisplayManager colorDisplayManager) {
+            mCdm = colorDisplayManager;
+        }
+
+        public static ColorDisplayManagerInternal getInstance() {
+            synchronized (ColorDisplayManagerInternal.class) {
+                if (sInstance == null) {
+                    try {
+                        IBinder b = ServiceManager.getServiceOrThrow(Context.COLOR_DISPLAY_SERVICE);
+                        sInstance = new ColorDisplayManagerInternal(
+                                IColorDisplayManager.Stub.asInterface(b));
+                    } catch (ServiceNotFoundException e) {
+                        throw new IllegalStateException(e);
+                    }
+                }
+                return sInstance;
+            }
+        }
+
+        boolean isDeviceColorManaged() {
+            try {
+                return mCdm.isDeviceColorManaged();
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
 }
diff --git a/core/java/android/hardware/display/IColorDisplayManager.aidl b/core/java/android/hardware/display/IColorDisplayManager.aidl
new file mode 100644
index 0000000..f786589
--- /dev/null
+++ b/core/java/android/hardware/display/IColorDisplayManager.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2018 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.hardware.display;
+
+/** @hide */
+interface IColorDisplayManager {
+    boolean isDeviceColorManaged();
+}
\ No newline at end of file
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0c1aae8..8904ee6 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -657,6 +657,12 @@
     public static String DIRECTORY_SCREENSHOTS = "Screenshots";
 
     /**
+     * Standard directory in which to place any audio files which are
+     * audiobooks.
+     */
+    public static String DIRECTORY_AUDIOBOOKS = "Audiobooks";
+
+    /**
      * List of standard storage directories.
      * <p>
      * Each of its values have its own constant:
@@ -671,6 +677,7 @@
      *   <li>{@link #DIRECTORY_DOWNLOADS}
      *   <li>{@link #DIRECTORY_DCIM}
      *   <li>{@link #DIRECTORY_DOCUMENTS}
+     *   <li>{@link #DIRECTORY_AUDIOBOOKS}
      * </ul>
      * @hide
      */
@@ -684,7 +691,8 @@
             DIRECTORY_MOVIES,
             DIRECTORY_DOWNLOADS,
             DIRECTORY_DCIM,
-            DIRECTORY_DOCUMENTS
+            DIRECTORY_DOCUMENTS,
+            DIRECTORY_AUDIOBOOKS,
     };
 
     /**
@@ -709,6 +717,7 @@
     /** {@hide} */ public static final int HAS_DOWNLOADS = 1 << 7;
     /** {@hide} */ public static final int HAS_DCIM = 1 << 8;
     /** {@hide} */ public static final int HAS_DOCUMENTS = 1 << 9;
+    /** {@hide} */ public static final int HAS_AUDIOBOOKS = 1 << 10;
 
     /** {@hide} */ public static final int HAS_ANDROID = 1 << 16;
     /** {@hide} */ public static final int HAS_OTHER = 1 << 17;
@@ -738,6 +747,7 @@
                 else if (DIRECTORY_DOWNLOADS.equals(name)) res |= HAS_DOWNLOADS;
                 else if (DIRECTORY_DCIM.equals(name)) res |= HAS_DCIM;
                 else if (DIRECTORY_DOCUMENTS.equals(name)) res |= HAS_DOCUMENTS;
+                else if (DIRECTORY_AUDIOBOOKS.equals(name)) res |= HAS_AUDIOBOOKS;
                 else if (DIRECTORY_ANDROID.equals(name)) res |= HAS_ANDROID;
                 else res |= HAS_OTHER;
             }
diff --git a/core/java/android/os/IThermalService.aidl b/core/java/android/os/IThermalService.aidl
index 8160338..9280cb9 100644
--- a/core/java/android/os/IThermalService.aidl
+++ b/core/java/android/os/IThermalService.aidl
@@ -67,7 +67,7 @@
 
     /**
       * Register a listener for thermal status change.
-      * @param listener the IThermalStatusListener to be notified.
+      * @param listener the {@link android.os.IThermalStatusListener} to be notified.
       * @return true if registered successfully.
       * {@hide}
       */
@@ -75,7 +75,7 @@
 
     /**
       * Unregister a previously-registered listener for thermal status.
-      * @param listener the IThermalStatusListener to no longer be notified.
+      * @param listener the {@link android.os.IThermalStatusListener} to no longer be notified.
       * @return true if unregistered successfully.
       * {@hide}
       */
@@ -86,5 +86,5 @@
       * @return status defined in {@link android.os.Temperature}.
       * {@hide}
       */
-    int getCurrentStatus();
+    int getCurrentThermalStatus();
 }
diff --git a/core/java/android/os/Temperature.java b/core/java/android/os/Temperature.java
index bf85fbd..5499181 100644
--- a/core/java/android/os/Temperature.java
+++ b/core/java/android/os/Temperature.java
@@ -28,7 +28,7 @@
  *
  * @hide
  */
-public class Temperature implements Parcelable {
+public final class Temperature implements Parcelable {
     /** Temperature value */
     private float mValue;
     /** A temperature type from ThermalHAL */
@@ -44,7 +44,7 @@
             THROTTLING_MODERATE,
             THROTTLING_SEVERE,
             THROTTLING_CRITICAL,
-            THROTTLING_WARNING,
+            THROTTLING_EMERGENCY,
             THROTTLING_SHUTDOWN,
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -56,7 +56,7 @@
     public static final int THROTTLING_MODERATE = ThrottlingSeverity.MODERATE;
     public static final int THROTTLING_SEVERE = ThrottlingSeverity.SEVERE;
     public static final int THROTTLING_CRITICAL = ThrottlingSeverity.CRITICAL;
-    public static final int THROTTLING_WARNING = ThrottlingSeverity.WARNING;
+    public static final int THROTTLING_EMERGENCY = ThrottlingSeverity.EMERGENCY;
     public static final int THROTTLING_SHUTDOWN = ThrottlingSeverity.SHUTDOWN;
 
     @IntDef(prefix = { "TYPE_" }, value = {
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 8e11d85..d315383 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -56,6 +56,7 @@
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.SystemProperties;
 import android.provider.Settings;
+import android.sysprop.VoldProperties;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -1495,7 +1496,7 @@
      * framework, so no service needs to check for changes during their lifespan
      */
     public static boolean isBlockEncrypting() {
-        final String state = SystemProperties.get("vold.encrypt_progress", "");
+        final String state = VoldProperties.encrypt_progress().orElse("");
         return !"".equalsIgnoreCase(state);
     }
 
@@ -1511,7 +1512,7 @@
      * framework, so no service needs to check for changes during their lifespan
      */
     public static boolean inCryptKeeperBounce() {
-        final String status = SystemProperties.get("vold.decrypt");
+        final String status = VoldProperties.decrypt().orElse("");
         return "trigger_restart_min_framework".equals(status);
     }
 
diff --git a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
index 18aea03..a41a644 100644
--- a/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
+++ b/core/java/android/permissionpresenterservice/RuntimePermissionPresenterService.java
@@ -16,6 +16,9 @@
 
 package android.permissionpresenterservice;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.app.Service;
@@ -27,12 +30,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
 import android.os.RemoteCallback;
 
-import com.android.internal.os.SomeArgs;
-
 import java.util.List;
 
 /**
@@ -63,7 +62,7 @@
     @Override
     public final void attachBaseContext(Context base) {
         super.attachBaseContext(base);
-        mHandler = new MyHandler(base.getMainLooper());
+        mHandler = new Handler(base.getMainLooper());
     }
 
     /**
@@ -71,7 +70,8 @@
      *
      * @param packageName The package for which to query.
      */
-    public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(String packageName);
+    public abstract List<RuntimePermissionPresentationInfo> onGetAppPermissions(
+            @NonNull String packageName);
 
     /**
      * Revokes the permission {@code permissionName} for app {@code packageName}
@@ -87,61 +87,35 @@
         return new IRuntimePermissionPresenter.Stub() {
             @Override
             public void getAppPermissions(String packageName, RemoteCallback callback) {
-                SomeArgs args = SomeArgs.obtain();
-                args.arg1 = packageName;
-                args.arg2 = callback;
-                mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS,
-                        args).sendToTarget();
+                checkNotNull(packageName, "packageName");
+                checkNotNull(callback, "callback");
+
+                mHandler.sendMessage(
+                        obtainMessage(RuntimePermissionPresenterService::getAppPermissions,
+                                RuntimePermissionPresenterService.this, packageName, callback));
             }
 
             @Override
             public void revokeRuntimePermission(String packageName, String permissionName) {
-                SomeArgs args = SomeArgs.obtain();
-                args.arg1 = packageName;
-                args.arg2 = permissionName;
-                mHandler.obtainMessage(MyHandler.MSG_REVOKE_APP_PERMISSION,
-                        args).sendToTarget();
+                checkNotNull(packageName, "packageName");
+                checkNotNull(permissionName, "permissionName");
+
+                mHandler.sendMessage(
+                        obtainMessage(RuntimePermissionPresenterService::onRevokeRuntimePermission,
+                                RuntimePermissionPresenterService.this, packageName,
+                                permissionName));
             }
         };
     }
 
-    private final class MyHandler extends Handler {
-        public static final int MSG_GET_APP_PERMISSIONS = 1;
-        public static final int MSG_GET_APPS_USING_PERMISSIONS = 2;
-        public static final int MSG_REVOKE_APP_PERMISSION = 3;
-
-        public MyHandler(Looper looper) {
-            super(looper, null, false);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_GET_APP_PERMISSIONS: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    String packageName = (String) args.arg1;
-                    RemoteCallback callback = (RemoteCallback) args.arg2;
-                    args.recycle();
-                    List<RuntimePermissionPresentationInfo> permissions =
-                            onGetAppPermissions(packageName);
-                    if (permissions != null && !permissions.isEmpty()) {
-                        Bundle result = new Bundle();
-                        result.putParcelableList(RuntimePermissionPresenter.KEY_RESULT,
-                                permissions);
-                        callback.sendResult(result);
-                    } else {
-                        callback.sendResult(null);
-                    }
-                } break;
-                case MSG_REVOKE_APP_PERMISSION: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    String packageName = (String) args.arg1;
-                    String permissionName = (String) args.arg2;
-                    args.recycle();
-
-                    onRevokeRuntimePermission(packageName, permissionName);
-                } break;
-            }
+    private void getAppPermissions(@NonNull String packageName, @NonNull RemoteCallback callback) {
+        List<RuntimePermissionPresentationInfo> permissions = onGetAppPermissions(packageName);
+        if (permissions != null && !permissions.isEmpty()) {
+            Bundle result = new Bundle();
+            result.putParcelableList(RuntimePermissionPresenter.KEY_RESULT, permissions);
+            callback.sendResult(result);
+        } else {
+            callback.sendResult(null);
         }
     }
 }
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index e032c18..37c84bd 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -152,6 +152,17 @@
             "android:query-arg-last-modified-after";
 
     /**
+     * Key for {@link DocumentsProvider} to decide whether the files that
+     * have been added to MediaStore should be excluded. If the value is
+     * true, exclude them. Otherwise, include them.
+     *
+     * @see DocumentsProvider#querySearchDocuments(String, String[],
+     *      Bundle)
+     * {@hide}
+     */
+    public static final String QUERY_ARG_EXCLUDE_MEDIA = "android:query-arg-exclude-media";
+
+    /**
      * Sets the desired initial location visible to user when file chooser is shown.
      *
      * <p>Applicable to {@link Intent} with actions:
@@ -1017,6 +1028,7 @@
 
     /**
      * Get the handled query arguments from the query bundle. The handled arguments are
+     * {@link DocumentsContract#QUERY_ARG_EXCLUDE_MEDIA},
      * {@link DocumentsContract#QUERY_ARG_DISPLAY_NAME},
      * {@link DocumentsContract#QUERY_ARG_MIME_TYPES},
      * {@link DocumentsContract#QUERY_ARG_FILE_SIZE_OVER} and
@@ -1032,6 +1044,11 @@
         }
 
         final ArrayList<String> args = new ArrayList<>();
+
+        if (queryArgs.keySet().contains(QUERY_ARG_EXCLUDE_MEDIA)) {
+            args.add(QUERY_ARG_EXCLUDE_MEDIA);
+        }
+
         if (queryArgs.keySet().contains(QUERY_ARG_DISPLAY_NAME)) {
             args.add(QUERY_ARG_DISPLAY_NAME);
         }
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 58f8213..6ab72c7 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -677,6 +677,7 @@
      *            cursor. If {@code null} all supported columns should be
      *            included.
      * @param queryArgs the query arguments.
+     *            {@link DocumentsContract#QUERY_ARG_EXCLUDE_MEDIA},
      *            {@link DocumentsContract#QUERY_ARG_DISPLAY_NAME},
      *            {@link DocumentsContract#QUERY_ARG_MIME_TYPES},
      *            {@link DocumentsContract#QUERY_ARG_FILE_SIZE_OVER},
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index 76607e9..8e37559 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -660,7 +660,22 @@
         if (familyBuilder == null) {
             return null;
         }
-        return new Typeface.CustomFallbackBuilder(familyBuilder.build()).build();
+
+        final FontFamily family = familyBuilder.build();
+
+        final FontStyle normal = new FontStyle(FontStyle.FONT_WEIGHT_NORMAL,
+                FontStyle.FONT_SLANT_UPRIGHT);
+        Font bestFont = family.getFont(0);
+        int bestScore = normal.getMatchScore(bestFont.getStyle());
+        for (int i = 1; i < family.getSize(); ++i) {
+            final Font candidate = family.getFont(i);
+            final int score = normal.getMatchScore(candidate.getStyle());
+            if (score < bestScore) {
+                bestFont = candidate;
+                bestScore = score;
+            }
+        }
+        return new Typeface.CustomFallbackBuilder(family).setStyle(bestFont.getStyle()).build();
     }
 
     /**
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index ec8db1c..0299e41 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -37,6 +37,7 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Point;
+import android.media.ExifInterface;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.CancellationSignal;
@@ -1166,13 +1167,25 @@
             /**
              * The latitude where the image was captured.
              * <P>Type: DOUBLE</P>
+             *
+             * @deprecated location details are no longer indexed for privacy
+             *             reasons, and this value is now always {@code null}.
+             *             You can still manually obtain location metadata using
+             *             {@link ExifInterface#getLatLong(float[])}.
              */
+            @Deprecated
             public static final String LATITUDE = "latitude";
 
             /**
              * The longitude where the image was captured.
              * <P>Type: DOUBLE</P>
+             *
+             * @deprecated location details are no longer indexed for privacy
+             *             reasons, and this value is now always {@code null}.
+             *             You can still manually obtain location metadata using
+             *             {@link ExifInterface#getLatLong(float[])}.
              */
+            @Deprecated
             public static final String LONGITUDE = "longitude";
 
             /**
@@ -1693,6 +1706,12 @@
             public static final String IS_NOTIFICATION = "is_notification";
 
             /**
+             * Non-zero if the audio file is an audiobook
+             * <P>Type: INTEGER (boolean)</P>
+             */
+            public static final String IS_AUDIOBOOK = "is_audiobook";
+
+            /**
              * The genre of the audio file, if any
              * <P>Type: TEXT</P>
              * Does not exist in the database - only used by the media scanner for inserts.
@@ -2404,13 +2423,25 @@
             /**
              * The latitude where the video was captured.
              * <P>Type: DOUBLE</P>
+             *
+             * @deprecated location details are no longer indexed for privacy
+             *             reasons, and this value is now always {@code null}.
+             *             You can still manually obtain location metadata using
+             *             {@link ExifInterface#getLatLong(float[])}.
              */
+            @Deprecated
             public static final String LATITUDE = "latitude";
 
             /**
              * The longitude where the video was captured.
              * <P>Type: DOUBLE</P>
+             *
+             * @deprecated location details are no longer indexed for privacy
+             *             reasons, and this value is now always {@code null}.
+             *             You can still manually obtain location metadata using
+             *             {@link ExifInterface#getLatLong(float[])}.
              */
+            @Deprecated
             public static final String LONGITUDE = "longitude";
 
             /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index c297ef4..74ec0b9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6279,6 +6279,7 @@
          *
          * @hide
          */
+        @SystemApi
         public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED =
                 "accessibility_display_magnification_navbar_enabled";
 
@@ -12837,6 +12838,23 @@
                 "max_sound_trigger_detection_service_ops_per_day";
 
         /**
+         * Property used by {@code com.android.server.SystemServer} on start to decide whether
+         * the Smart Suggestions service should be created or not
+         *
+         * <p>By default it should *NOT* be set (in which case the decision is based on whether
+         * the OEM provides an implementation for the service), but it can be overridden to:
+         *
+         * <ul>
+         *   <li>Provide a "kill switch" so OEMs can disable it remotely in case of emergency.
+         *   <li>Enable the CTS tests to be run on AOSP builds
+         * </ul>
+         *
+         * @hide
+         */
+        public static final String SMART_SUGGESTIONS_SERVICE_EXPLICITLY_ENABLED =
+                "smart_suggestions_service_explicitly_enabled";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          *
@@ -13509,6 +13527,13 @@
          */
         public static final String WARNING_TEMPERATURE = "warning_temperature";
 
+
+        /**
+         * USB Temperature at which the high temperature alarm notification should be shown.
+         * @hide
+         */
+        public static final String USB_ALARM_TEMPERATURE = "usb_alarm_temperature";
+
         /**
          * Whether the diskstats logging task is enabled/disabled.
          * @hide
diff --git a/core/java/android/provider/TEST_MAPPING b/core/java/android/provider/TEST_MAPPING
deleted file mode 100644
index 8e67ce7..0000000
--- a/core/java/android/provider/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "presubmit": [
-        {
-            "name": "FrameworksCoreTests",
-            "options": [
-                {
-                    "include-filter": "android.provider.SettingsBackupTest"
-                }
-            ]
-        }
-    ]
-}
diff --git a/core/java/android/service/intelligence/FillCallback.java b/core/java/android/service/intelligence/FillCallback.java
index af2da79..ddf37f7 100644
--- a/core/java/android/service/intelligence/FillCallback.java
+++ b/core/java/android/service/intelligence/FillCallback.java
@@ -15,8 +15,10 @@
  */
 package android.service.intelligence;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
 
 /**
  * Callback used to indicate at {@link FillRequest} has been fulfilled.
@@ -25,8 +27,11 @@
  */
 @SystemApi
 public final class FillCallback {
+    private final AutofillProxy mProxy;
 
-    FillCallback() {}
+    FillCallback(@NonNull AutofillProxy proxy) {
+        mProxy = proxy;
+    }
 
     /**
      * Sets the response associated with the request.
@@ -35,6 +40,7 @@
      * could not provide autofill for the request.
      */
     public void onSuccess(@Nullable FillResponse response) {
+        mProxy.report(AutofillProxy.REPORT_EVENT_ON_SUCCESS);
         final FillWindow fillWindow = response.getFillWindow();
         if (fillWindow != null) {
             fillWindow.show();
diff --git a/core/java/android/service/intelligence/FillRequest.java b/core/java/android/service/intelligence/FillRequest.java
index f68db9d..53e99a5 100644
--- a/core/java/android/service/intelligence/FillRequest.java
+++ b/core/java/android/service/intelligence/FillRequest.java
@@ -20,6 +20,7 @@
 import android.annotation.SystemApi;
 import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 
 /**
  * Represents a request to augment-fill an activity.
@@ -52,6 +53,14 @@
     }
 
     /**
+     * Gets the current value of the field that triggered the request.
+     */
+    @NonNull
+    public AutofillValue getFocusedAutofillValue() {
+        return mProxy.focusedValue;
+    }
+
+    /**
      * Gets the Smart Suggestions object used to embed the autofill UI.
      *
      * @return object used to embed the autofill UI, or {@code null} if not supported.
diff --git a/core/java/android/service/intelligence/FillWindow.java b/core/java/android/service/intelligence/FillWindow.java
index 309f6a1..39d7e08 100644
--- a/core/java/android/service/intelligence/FillWindow.java
+++ b/core/java/android/service/intelligence/FillWindow.java
@@ -23,6 +23,7 @@
 import android.app.Dialog;
 import android.graphics.Rect;
 import android.service.intelligence.PresentationParams.Area;
+import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
@@ -33,6 +34,8 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 
+import dalvik.system.CloseGuard;
+
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -73,6 +76,7 @@
     @interface Flags{}
 
     private final Object mLock = new Object();
+    private final CloseGuard mCloseGuard = CloseGuard.get();
 
     @GuardedBy("mLock")
     private Dialog mDialog;
@@ -80,6 +84,8 @@
     @GuardedBy("mLock")
     private boolean mDestroyed;
 
+    private AutofillProxy mProxy;
+
     /**
      * Updates the content of the window.
      *
@@ -123,6 +129,8 @@
         synchronized (mLock) {
             checkNotDestroyedLocked();
 
+            mProxy = area.proxy;
+
             // TODO(b/111330312): once we have the SurfaceControl approach, we should update the
             // window instead of destroying. In fact, it might be better to allocate a full window
             // initially, which is transparent (and let touches get through) everywhere but in the
@@ -133,6 +141,7 @@
             // etc.
 
             mDialog = new Dialog(rootView.getContext());
+            mCloseGuard.open("destroy");
             final Window window = mDialog.getWindow();
             window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
 
@@ -156,7 +165,7 @@
                 Log.d(TAG, "Created FillWindow: params= " + smartSuggestion + " view=" + rootView);
             }
 
-            area.proxy.setFillWindow(this);
+            mProxy.setFillWindow(this);
             return true;
         }
     }
@@ -173,6 +182,9 @@
             }
 
             mDialog.show();
+            if (mProxy != null) {
+                mProxy.report(AutofillProxy.REPORT_EVENT_UI_SHOWN);
+            }
         }
     }
 
@@ -182,15 +194,29 @@
      * <p>Once destroyed, this window cannot be used anymore
      */
     public void destroy() {
-        if (DEBUG) Log.d(TAG, "destroy(): mDestroyed = " + mDestroyed);
+        if (DEBUG) Log.d(TAG, "destroy(): mDestroyed=" + mDestroyed + " mDialog=" + mDialog);
 
         synchronized (this) {
-            if (mDestroyed) return;
+            if (mDestroyed || mDialog == null) return;
 
-            if (mDialog != null) {
-                mDialog.dismiss();
-                mDialog = null;
+            mDialog.dismiss();
+            mDialog = null;
+            if (mProxy != null) {
+                mProxy.report(AutofillProxy.REPORT_EVENT_UI_DESTROYED);
             }
+            mCloseGuard.close();
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+            destroy();
+        } finally {
+            super.finalize();
         }
     }
 
diff --git a/core/java/android/service/intelligence/IIntelligenceService.aidl b/core/java/android/service/intelligence/IIntelligenceService.aidl
index d6b3107..2b924fb 100644
--- a/core/java/android/service/intelligence/IIntelligenceService.aidl
+++ b/core/java/android/service/intelligence/IIntelligenceService.aidl
@@ -23,6 +23,7 @@
 import android.service.intelligence.SnapshotData;
 
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 import android.view.intelligence.ContentCaptureEvent;
 
 import java.util.List;
@@ -45,7 +46,8 @@
                             in SnapshotData snapshotData);
 
     void onAutofillRequest(in InteractionSessionId sessionId, in IBinder autofillManagerClient,
-                           int autofilSessionId, in AutofillId focusedId);
+                           int autofilSessionId, in AutofillId focusedId,
+                           in AutofillValue focusedValue, long requestTime);
 
     void onDestroyAutofillWindowsRequest(in InteractionSessionId sessionId);
 }
diff --git a/core/java/android/service/intelligence/SmartSuggestionsService.java b/core/java/android/service/intelligence/SmartSuggestionsService.java
index 90f04ca..b684b02 100644
--- a/core/java/android/service/intelligence/SmartSuggestionsService.java
+++ b/core/java/android/service/intelligence/SmartSuggestionsService.java
@@ -18,6 +18,7 @@
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.annotation.CallSuper;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -30,10 +31,13 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.service.intelligence.PresentationParams.SystemPopupPresentationParams;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
+import android.util.Slog;
+import android.util.TimeUtils;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAugmentedAutofillManagerClient;
@@ -43,6 +47,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -60,6 +66,7 @@
 
     // TODO(b/111330312): STOPSHIP use dynamic value, or change to false
     static final boolean DEBUG = true;
+    static final boolean VERBOSE = false;
 
     /**
      * The {@link Intent} that must be declared as handled by the service.
@@ -109,9 +116,11 @@
 
         @Override
         public void onAutofillRequest(InteractionSessionId sessionId, IBinder client,
-                int autofilSessionId, AutofillId focusedId) {
+                int autofilSessionId, AutofillId focusedId, AutofillValue focusedValue,
+                long requestTime) {
             mHandler.sendMessage(obtainMessage(SmartSuggestionsService::handleOnAutofillRequest,
-                    SmartSuggestionsService.this, sessionId, client, autofilSessionId, focusedId));
+                    SmartSuggestionsService.this, sessionId, client, autofilSessionId, focusedId,
+                    focusedValue, requestTime));
         }
 
         @Override
@@ -209,7 +218,11 @@
      * @param sessionId the session's Id
      */
     public void onCreateInteractionSession(@NonNull InteractionContext context,
-            @NonNull InteractionSessionId sessionId) {}
+            @NonNull InteractionSessionId sessionId) {
+        if (VERBOSE) {
+            Log.v(TAG, "onCreateInteractionSession(id=" + sessionId + ", ctx=" + context + ")");
+        }
+    }
 
     /**
      * Notifies the service of {@link ContentCaptureEvent events} associated with a content capture
@@ -224,13 +237,15 @@
             @NonNull ContentCaptureEventsRequest request);
 
     private void handleOnAutofillRequest(@NonNull InteractionSessionId sessionId,
-            @NonNull IBinder client, int autofillSessionId, @NonNull AutofillId focusedId) {
+            @NonNull IBinder client, int autofillSessionId, @NonNull AutofillId focusedId,
+            @Nullable AutofillValue focusedValue, long requestTime) {
         if (mAutofillProxies == null) {
             mAutofillProxies = new ArrayMap<>();
         }
         AutofillProxy proxy = mAutofillProxies.get(sessionId);
         if (proxy == null) {
-            proxy = new AutofillProxy(sessionId, client, autofillSessionId, focusedId);
+            proxy = new AutofillProxy(sessionId, client, autofillSessionId, focusedId, focusedValue,
+                    requestTime);
             mAutofillProxies.put(sessionId,  proxy);
         } else {
             // TODO(b/111330312): figure out if it's ok to reuse the proxy; add logging
@@ -239,7 +254,7 @@
         // TODO(b/111330312): set cancellation signal
         final CancellationSignal cancellationSignal = null;
         onFillRequest(sessionId, new FillRequest(proxy), cancellationSignal,
-                new FillController(proxy), new FillCallback());
+                new FillController(proxy), new FillCallback(proxy));
     }
 
     /**
@@ -319,15 +334,40 @@
      *
      * @param sessionId the id of the session to destroy
      */
-    public void onDestroyInteractionSession(@NonNull InteractionSessionId sessionId) {}
+    public void onDestroyInteractionSession(@NonNull InteractionSessionId sessionId) {
+        if (VERBOSE) {
+            Log.v(TAG, "onDestroyInteractionSession(id=" + sessionId + ")");
+        }
+    }
 
     /** @hide */
     static final class AutofillProxy {
+
+        static final int REPORT_EVENT_ON_SUCCESS = 1;
+        static final int REPORT_EVENT_UI_SHOWN = 2;
+        static final int REPORT_EVENT_UI_DESTROYED = 3;
+
+        @IntDef(prefix = { "REPORT_EVENT_" }, value = {
+                REPORT_EVENT_ON_SUCCESS,
+                REPORT_EVENT_UI_SHOWN,
+                REPORT_EVENT_UI_DESTROYED
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        @interface ReportEvent{}
+
+
         private final Object mLock = new Object();
         private final IAugmentedAutofillManagerClient mClient;
         private final int mAutofillSessionId;
         public final InteractionSessionId sessionId;
         public final AutofillId focusedId;
+        public final AutofillValue focusedValue;
+
+        // Objects used to log metrics
+        private final long mRequestTime;
+        private long mOnSuccessTime;
+        private long mUiFirstShownTime;
+        private long mUiFirstDestroyedTime;
 
         @GuardedBy("mLock")
         private SystemPopupPresentationParams mSmartSuggestion;
@@ -336,11 +376,14 @@
         private FillWindow mFillWindow;
 
         private AutofillProxy(@NonNull InteractionSessionId sessionId, @NonNull IBinder client,
-                int autofillSessionId, @NonNull AutofillId focusedId) {
+                int autofillSessionId, @NonNull AutofillId focusedId,
+                @Nullable AutofillValue focusedValue, long requestTime) {
             this.sessionId = sessionId;
             mClient = IAugmentedAutofillManagerClient.Stub.asInterface(client);
             mAutofillSessionId = autofillSessionId;
             this.focusedId = focusedId;
+            this.focusedValue = focusedValue;
+            this.mRequestTime = requestTime;
             // TODO(b/111330312): linkToDeath
         }
 
@@ -391,9 +434,50 @@
             }
         }
 
+        // Used for metrics.
+        public void report(@ReportEvent int event) {
+            switch (event) {
+                case REPORT_EVENT_ON_SUCCESS:
+                    if (mOnSuccessTime == 0) {
+                        mOnSuccessTime = SystemClock.elapsedRealtime();
+                        if (DEBUG) {
+                            Slog.d(TAG, "Service responsed in "
+                                    + TimeUtils.formatDuration(mOnSuccessTime - mRequestTime));
+                        }
+                    }
+                    break;
+                case REPORT_EVENT_UI_SHOWN:
+                    if (mUiFirstShownTime == 0) {
+                        mUiFirstShownTime = SystemClock.elapsedRealtime();
+                        if (DEBUG) {
+                            Slog.d(TAG, "UI shown in "
+                                    + TimeUtils.formatDuration(mUiFirstShownTime - mRequestTime));
+                        }
+                    }
+                    break;
+                case REPORT_EVENT_UI_DESTROYED:
+                    if (mUiFirstDestroyedTime == 0) {
+                        mUiFirstDestroyedTime = SystemClock.elapsedRealtime();
+                        if (DEBUG) {
+                            Slog.d(TAG, "UI destroyed in "
+                                    + TimeUtils.formatDuration(
+                                            mUiFirstDestroyedTime - mRequestTime));
+                        }
+                    }
+                    break;
+                default:
+                    Slog.w(TAG, "invalid event reported: " + event);
+            }
+            // TODO(b/111330312): log metrics as well
+        }
+
+
         public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
             pw.print(prefix); pw.print("afSessionId: "); pw.println(mAutofillSessionId);
             pw.print(prefix); pw.print("focusedId: "); pw.println(focusedId);
+            if (focusedValue != null) {
+                pw.print(prefix); pw.print("focusedValue: "); pw.println(focusedValue);
+            }
             pw.print(prefix); pw.print("client: "); pw.println(mClient);
             final String prefix2 = prefix + "  ";
             if (mFillWindow != null) {
@@ -404,6 +488,23 @@
                 pw.print(prefix); pw.println("smartSuggestion:");
                 mSmartSuggestion.dump(prefix2, pw);
             }
+            if (mOnSuccessTime > 0) {
+                final long responseTime = mOnSuccessTime - mRequestTime;
+                pw.print(prefix); pw.print("response time: ");
+                TimeUtils.formatDuration(responseTime, pw); pw.println();
+            }
+
+            if (mUiFirstShownTime > 0) {
+                final long uiRenderingTime = mUiFirstShownTime - mRequestTime;
+                pw.print(prefix); pw.print("UI rendering time: ");
+                TimeUtils.formatDuration(uiRenderingTime, pw); pw.println();
+            }
+
+            if (mUiFirstDestroyedTime > 0) {
+                final long uiTotalTime = mUiFirstDestroyedTime - mRequestTime;
+                pw.print(prefix); pw.print("UI life time: ");
+                TimeUtils.formatDuration(uiTotalTime, pw); pw.println();
+            }
         }
 
         private void destroy() {
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index be47320..433483f7 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -369,10 +369,7 @@
 
     /**
      * @return The color of the underline for that span, or 0 if there is no underline
-     *
-     * @hide
      */
-    @UnsupportedAppUsage
     public int getUnderlineColor() {
         // The order here should match what is used in updateDrawState
         final boolean misspelled = (mFlags & FLAG_MISSPELLED) != 0;
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 5f348c4..dee6d90 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -45,7 +45,6 @@
         DEFAULT_FLAGS.put("settings_systemui_theme", "true");
         DEFAULT_FLAGS.put("settings_dynamic_homepage", "true");
         DEFAULT_FLAGS.put("settings_mobile_network_v2", "true");
-        DEFAULT_FLAGS.put("settings_data_usage_v2", "true");
         DEFAULT_FLAGS.put("settings_seamless_transfer", "false");
         DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
         DEFAULT_FLAGS.put("settings_network_and_internet_v2", "false");
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 3ee5f1f..33b3ff4f 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -18,6 +18,7 @@
 
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 
@@ -225,7 +226,7 @@
     private int mMinimumFlingVelocity;
     private int mMaximumFlingVelocity;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
     private static final int TAP_TIMEOUT = ViewConfiguration.getTapTimeout();
     private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
@@ -592,8 +593,8 @@
 
                 if (mIsLongpressEnabled) {
                     mHandler.removeMessages(LONG_PRESS);
-                    mHandler.sendEmptyMessageAtTime(LONG_PRESS,
-                            mCurrentDownEvent.getDownTime() + LONGPRESS_TIMEOUT);
+                    mHandler.sendEmptyMessageAtTime(LONG_PRESS, mCurrentDownEvent.getDownTime()
+                            + ViewConfiguration.getLongPressTimeout());
                 }
                 mHandler.sendEmptyMessageAtTime(SHOW_PRESS,
                         mCurrentDownEvent.getDownTime() + TAP_TIMEOUT);
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index af41b69..5e6d3d1 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -25,6 +25,7 @@
 import android.view.MotionEvent;
 import android.view.DisplayCutout;
 import android.view.InsetsState;
+import android.view.InsetsSourceControl;
 
 import com.android.internal.os.IResultReceiver;
 import android.util.MergedConfiguration;
@@ -60,6 +61,11 @@
      */
     void insetsChanged(in InsetsState insetsState);
 
+    /**
+     * Called when this window retrieved control over a specified set of inset sources.
+     */
+    void insetsControlChanged(in InsetsState insetsState, in InsetsSourceControl[] activeControls);
+
     void moved(int newX, int newY);
     void dispatchAppVisibility(boolean visible);
     void dispatchGetNewSurface();
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 7841d04..ba5340c 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -16,17 +16,30 @@
 
 package android.view;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.graphics.Rect;
+import android.util.ArraySet;
+import android.util.SparseArray;
+import android.view.SurfaceControl.Transaction;
+import android.view.WindowInsets.Type.InsetType;
+import android.view.InsetsState.InternalInsetType;
+
+import com.android.internal.annotations.VisibleForTesting;
 
 import java.io.PrintWriter;
 
 /**
  * Implements {@link WindowInsetsController} on the client.
+ * @hide
  */
-class InsetsController {
+public class InsetsController implements WindowInsetsController {
 
     private final InsetsState mState = new InsetsState();
     private final Rect mFrame = new Rect();
+    private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>();
+
+    private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>();
 
     void onFrameChanged(Rect frame) {
         mFrame.set(frame);
@@ -48,6 +61,61 @@
         return mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeNavBar, cutout);
     }
 
+    /**
+     * Called when the server has dispatched us a new set of inset controls.
+     */
+    public void onControlsChanged(InsetsSourceControl[] activeControls) {
+        if (activeControls != null) {
+            for (InsetsSourceControl activeControl : activeControls) {
+                mTmpControlArray.put(activeControl.getType(), activeControl);
+            }
+        }
+
+        // Ensure to update all existing source consumers
+        for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
+            final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
+            final InsetsSourceControl control = mTmpControlArray.get(consumer.getType());
+
+            // control may be null, but we still need to update the control to null if it got
+            // revoked.
+            consumer.setControl(control);
+        }
+
+        // Ensure to create source consumers if not available yet.
+        for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
+            final InsetsSourceControl control = mTmpControlArray.valueAt(i);
+            getSourceConsumer(control.getType()).setControl(control);
+        }
+        mTmpControlArray.clear();
+    }
+
+    @Override
+    public void show(@InsetType int types) {
+        final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
+        for (int i = internalTypes.size() - 1; i >= 0; i--) {
+            getSourceConsumer(internalTypes.valueAt(i)).show();
+        }
+    }
+
+    @Override
+    public void hide(@InsetType int types) {
+        final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
+        for (int i = internalTypes.size() - 1; i >= 0; i--) {
+            getSourceConsumer(internalTypes.valueAt(i)).hide();
+        }
+    }
+
+    @VisibleForTesting
+    public @NonNull InsetsSourceConsumer getSourceConsumer(@InternalInsetType int type) {
+        InsetsSourceConsumer controller = mSourceConsumers.get(type);
+        if (controller != null) {
+            return controller;
+        }
+        controller = new InsetsSourceConsumer(type, mState, Transaction::new);
+        mSourceConsumers.put(type, controller);
+        return controller;
+    }
+
     void dump(String prefix, PrintWriter pw) {
         pw.println(prefix); pw.println("InsetsController:");
         mState.dump(prefix + "  ", pw);
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
new file mode 100644
index 0000000..e74aa8d
--- /dev/null
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2018 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;
+
+import android.annotation.Nullable;
+import android.view.SurfaceControl.Transaction;
+import android.view.InsetsState.InternalInsetType;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.function.Supplier;
+
+/**
+ * Controls the visibility and animations of a single window insets source.
+ * @hide
+ */
+public class InsetsSourceConsumer {
+
+    private final Supplier<Transaction> mTransactionSupplier;
+    private final @InternalInsetType int mType;
+    private final InsetsState mState;
+    private @Nullable InsetsSourceControl mControl;
+    private boolean mHidden;
+
+    public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state,
+            Supplier<Transaction> transactionSupplier) {
+        mType = type;
+        mState = state;
+        mTransactionSupplier = transactionSupplier;
+    }
+
+    public void setControl(@Nullable InsetsSourceControl control) {
+        if (mControl == control) {
+            return;
+        }
+        mControl = control;
+        applyHiddenToControl();
+    }
+
+    @VisibleForTesting
+    public InsetsSourceControl getControl() {
+        return mControl;
+    }
+
+    int getType() {
+        return mType;
+    }
+
+    @VisibleForTesting
+    public void show() {
+        setHidden(false);
+    }
+
+    @VisibleForTesting
+    public void hide() {
+        setHidden(true);
+    }
+
+    private void setHidden(boolean hidden) {
+        if (mHidden == hidden) {
+            return;
+        }
+        mHidden = hidden;
+        applyHiddenToControl();
+    }
+
+    private void applyHiddenToControl() {
+        if (mControl == null) {
+            return;
+        }
+
+        // TODO: Animation
+        final Transaction t = mTransactionSupplier.get();
+        if (mHidden) {
+            t.hide(mControl.getLeash());
+        } else {
+            t.show(mControl.getLeash());
+        }
+        t.apply();
+    }
+}
diff --git a/core/java/android/view/InsetsSourceControl.aidl b/core/java/android/view/InsetsSourceControl.aidl
new file mode 100644
index 0000000..755bf45
--- /dev/null
+++ b/core/java/android/view/InsetsSourceControl.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2018, 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;
+
+parcelable InsetsSourceControl;
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
new file mode 100644
index 0000000..9383e6c
--- /dev/null
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 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;
+
+import android.graphics.Point;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.InsetsState.InternalInsetType;
+
+/**
+ * Represents a parcelable object to allow controlling a single {@link InsetsSource}.
+ * @hide
+ */
+public class InsetsSourceControl implements Parcelable {
+
+    private final @InternalInsetType int mType;
+    private final SurfaceControl mLeash;
+
+    public InsetsSourceControl(@InternalInsetType int type, SurfaceControl leash) {
+        mType = type;
+        mLeash = leash;
+    }
+
+    public int getType() {
+        return mType;
+    }
+
+    public SurfaceControl getLeash() {
+        return mLeash;
+    }
+
+    public InsetsSourceControl(Parcel in) {
+        mType = in.readInt();
+        mLeash = in.readParcelable(null /* loader */);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mType);
+        dest.writeParcelable(mLeash, 0 /* flags*/);
+    }
+
+    public static final Creator<InsetsSourceControl> CREATOR
+            = new Creator<InsetsSourceControl>() {
+        public InsetsSourceControl createFromParcel(Parcel in) {
+            return new InsetsSourceControl(in);
+        }
+
+        public InsetsSourceControl[] newArray(int size) {
+            return new InsetsSourceControl[size];
+        }
+    };
+}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 9895adc..689b14f 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -22,6 +22,9 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.view.WindowInsets.Type;
+import android.view.WindowInsets.Type.InsetType;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -148,6 +151,22 @@
         }
     }
 
+    public static @InternalInsetType ArraySet<Integer> toInternalType(@InsetType int insetTypes) {
+        final ArraySet<Integer> result = new ArraySet<>();
+        if ((insetTypes & Type.TOP_BAR) != 0) {
+            result.add(TYPE_TOP_BAR);
+        }
+        if ((insetTypes & Type.SIDE_BARS) != 0) {
+            result.add(TYPE_SIDE_BAR_1);
+            result.add(TYPE_SIDE_BAR_2);
+            result.add(TYPE_SIDE_BAR_3);
+        }
+        if ((insetTypes & Type.IME) != 0) {
+            result.add(TYPE_IME);
+        }
+        return result;
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.println(prefix + "InsetsState");
         for (int i = mSources.size() - 1; i >= 0; i--) {
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 8b39cc7..9cced4e 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1803,6 +1803,28 @@
     }
 
     /**
+     * Returns whether this key will be sent to the
+     * {@link android.media.session.MediaSession.Callback} if not handled.
+     */
+    public static final boolean isMediaSessionKey(int keyCode) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_MEDIA_PLAY:
+            case KeyEvent.KEYCODE_MEDIA_PAUSE:
+            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+            case KeyEvent.KEYCODE_MUTE:
+            case KeyEvent.KEYCODE_HEADSETHOOK:
+            case KeyEvent.KEYCODE_MEDIA_STOP:
+            case KeyEvent.KEYCODE_MEDIA_NEXT:
+            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+            case KeyEvent.KEYCODE_MEDIA_REWIND:
+            case KeyEvent.KEYCODE_MEDIA_RECORD:
+            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+                return true;
+        }
+        return false;
+    }
+
+    /**
      * Returns true if the specified keycode is a gamepad button.
      * @return True if the keycode is a gamepad button, such as {@link #KEYCODE_BUTTON_A}.
      */
@@ -1861,31 +1883,6 @@
         }
     }
 
-    /**
-     * Returns whether this key can be handled by
-     * {@link android.media.session.MediaSession.Callback}.
-     *
-     * @hide
-     */
-    public static final boolean isMediaSessionKey(int keyCode) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_MEDIA_PLAY:
-            case KeyEvent.KEYCODE_MEDIA_PAUSE:
-            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-            case KeyEvent.KEYCODE_MUTE:
-            case KeyEvent.KEYCODE_HEADSETHOOK:
-            case KeyEvent.KEYCODE_MEDIA_STOP:
-            case KeyEvent.KEYCODE_MEDIA_NEXT:
-            case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-            case KeyEvent.KEYCODE_MEDIA_REWIND:
-            case KeyEvent.KEYCODE_MEDIA_RECORD:
-            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
-                return true;
-        }
-        return false;
-    }
-
-
     /** Is this a system key? System keys can not be used for menu shortcuts.
      * @hide
      */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 401e75c..4b9cbff 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10341,6 +10341,20 @@
     }
 
     /**
+     * Retrieves the single {@link WindowInsetsController} of the window this view is attached to.
+     *
+     * @return The {@link WindowInsetsController} or {@code null} if the view isn't attached to a
+     *         a window.
+     * @hide pending unhide
+     */
+    public @Nullable WindowInsetsController getWindowInsetsController() {
+        if (mAttachInfo != null) {
+            return mAttachInfo.mViewRootImpl.getInsetsController();
+        }
+        return null;
+    }
+
+    /**
      * @hide Compute the insets that should be consumed by this view and the ones
      * that should propagate to those under it.
      *
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 937e238..cb47886 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -170,7 +170,12 @@
      * fully migrated over.
      */
     private static final String USE_NEW_INSETS_PROPERTY = "persist.wm.new_insets";
-    private static final boolean USE_NEW_INSETS =
+
+    /**
+     * @see #USE_NEW_INSETS_PROPERTY
+     * @hide
+     */
+    public static final boolean USE_NEW_INSETS =
             SystemProperties.getBoolean(USE_NEW_INSETS_PROPERTY, false);
 
     /**
@@ -1847,6 +1852,10 @@
         host.dispatchApplyWindowInsets(insets);
     }
 
+    InsetsController getInsetsController() {
+        return mInsetsController;
+    }
+
     private static boolean shouldUseDisplaySize(final WindowManager.LayoutParams lp) {
         return lp.type == TYPE_STATUS_BAR_PANEL
                 || lp.type == TYPE_INPUT_METHOD
@@ -1935,7 +1944,6 @@
             // PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888
             // However, windows are now always 32 bits by default, so choose 32 bits
             mAttachInfo.mUse32BitDrawingCache = true;
-            mAttachInfo.mHasWindowFocus = false;
             mAttachInfo.mWindowVisibility = viewVisibility;
             mAttachInfo.mRecomputeGlobalAttributes = false;
             mLastConfigurationFromResources.setTo(config);
@@ -4208,6 +4216,7 @@
     private final static int MSG_POINTER_CAPTURE_CHANGED = 28;
     private final static int MSG_DRAW_FINISHED = 29;
     private final static int MSG_INSETS_CHANGED = 30;
+    private final static int MSG_INSETS_CONTROL_CHANGED = 31;
 
     final class ViewRootHandler extends Handler {
         @Override
@@ -4371,11 +4380,22 @@
                 case MSG_INSETS_CHANGED:
                     mPendingInsets = (InsetsState) msg.obj;
 
-                    // TODO: Full traversal not needed here
+                    // TODO: Full traversal not needed here.
                     if (USE_NEW_INSETS) {
                         requestLayout();
                     }
                     break;
+                case MSG_INSETS_CONTROL_CHANGED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    mPendingInsets = (InsetsState) args.arg1;
+                    mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2);
+
+                    // TODO: Full traversal not necessarily needed here.
+                    if (USE_NEW_INSETS) {
+                        requestLayout();
+                    }
+                    break;
+                }
                 case MSG_WINDOW_MOVED:
                     if (mAdded) {
                         final int w = mWinFrame.width();
@@ -7116,6 +7136,14 @@
         mHandler.obtainMessage(MSG_INSETS_CHANGED, insetsState).sendToTarget();
     }
 
+    private void dispatchInsetsControlChanged(InsetsState insetsState,
+            InsetsSourceControl[] activeControls) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = insetsState;
+        args.arg2 = activeControls;
+        mHandler.obtainMessage(MSG_INSETS_CONTROL_CHANGED, args).sendToTarget();
+    }
+
     public void dispatchMoved(int newX, int newY) {
         if (DEBUG_LAYOUT) Log.v(mTag, "Window moved " + this + ": newX=" + newX + " newY=" + newY);
         if (mTranslator != null) {
@@ -8187,6 +8215,15 @@
         }
 
         @Override
+        public void insetsControlChanged(InsetsState insetsState,
+                InsetsSourceControl[] activeControls) {
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
+            if (viewAncestor != null) {
+                viewAncestor.dispatchInsetsControlChanged(insetsState, activeControls);
+            }
+        }
+
+        @Override
         public void moved(int newX, int newY) {
             final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index c1e94d8..58ab817 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -2410,4 +2410,11 @@
     public boolean isCloseOnSwipeEnabled() {
         return mCloseOnSwipeEnabled;
     }
+
+    /**
+     * @return The {@link WindowInsetsController} associated with this window
+     * @see View#getWindowInsetsController()
+     * @hide pending unhide
+     */
+    public abstract @NonNull WindowInsetsController getInsetsController();
 }
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index a8debbd..572d331 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -18,13 +18,17 @@
 package android.view;
 
 import android.annotation.NonNull;
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.Insets;
 import android.graphics.Rect;
+import android.view.inputmethod.InputMethod;
 
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
@@ -807,4 +811,69 @@
                     mIsRound, mAlwaysConsumeNavBar, mDisplayCutout);
         }
     }
+
+    /**
+     * Class that defines different types of sources causing window insets.
+     * @hide pending unhide
+     */
+    public static final class Type {
+
+        static final int TOP_BAR = 0x1;
+        static final int IME = 0x2;
+        static final int SIDE_BARS = 0x4;
+        static final int WINDOW_DECOR = 0x8;
+
+        private Type() {
+        }
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, value = { TOP_BAR, IME, SIDE_BARS, WINDOW_DECOR })
+        public @interface InsetType {
+        }
+
+        /**
+         * @return An inset type representing the top bar of a window, which can be the status
+         *         bar on handheld-like devices as well as a caption bar.
+         */
+        public static @InsetType int topBar() {
+            return TOP_BAR;
+        }
+
+        /**
+         * @return An inset type representing the window of an {@link InputMethod}.
+         */
+        public static @InsetType int ime() {
+            return IME;
+        }
+
+        /**
+         * @return An inset type representing any system bars that are not {@link #topBar()}.
+         */
+        public static @InsetType int sideBars() {
+            return SIDE_BARS;
+        }
+
+        /**
+         * @return An inset type representing decor that is being app-controlled.
+         */
+        public static @InsetType int windowDecor() {
+            return WINDOW_DECOR;
+        }
+
+        /**
+         * @return All system bars. Includes {@link #topBar()} as well as {@link #sideBars()}, but
+         *         not {@link #ime()}.
+         */
+        public static @InsetType int systemBars() {
+            return TOP_BAR | SIDE_BARS;
+        }
+
+        /**
+         * @return All inset types combined.
+         */
+        public static @InsetType int all() {
+            return 0xFFFFFFFF;
+        }
+    }
 }
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
new file mode 100644
index 0000000..7be5f2e
--- /dev/null
+++ b/core/java/android/view/WindowInsetsController.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 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;
+
+import android.view.WindowInsets.Type.InsetType;
+
+/**
+ * Interface to control windows that generate insets.
+ *
+ * TODO Needs more information and examples once the API is more baked.
+ * @hide pending unhide
+ */
+public interface WindowInsetsController {
+
+    /**
+     * Makes a set of windows that cause insets appear on screen.
+     * <p>
+     * Note that if the window currently doesn't have control over a certain type, it will apply the
+     * change as soon as the window gains control. The app can listen to the event by observing
+     * {@link View#onApplyWindowInsets} and checking visibility with "TODO at method" in
+     * {@link WindowInsets}.
+     *
+     * @param types A bitmask of {@link WindowInsets.Type.InsetType} specifying what windows the app
+     *              would like to make appear on screen.
+     */
+    void show(@InsetType int types);
+
+    /**
+     * Makes a set of windows causing insets disappear.
+     * <p>
+     * Note that if the window currently doesn't have control over a certain type, it will apply the
+     * change as soon as the window gains control. The app can listen to the event by observing
+     * {@link View#onApplyWindowInsets} and checking visibility with "TODO at method" in
+     * {@link WindowInsets}.
+     *
+     * @param types A bitmask of {@link WindowInsets.Type.InsetType} specifying what windows the app
+     *              would like to make disappear.
+     */
+    void hide(@InsetType int types);
+}
diff --git a/core/java/android/view/inspector/ChildTraverser.java b/core/java/android/view/inspector/ChildTraverser.java
deleted file mode 100644
index b775de5..0000000
--- a/core/java/android/view/inspector/ChildTraverser.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 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.inspector;
-
-import android.annotation.NonNull;
-
-/**
- * Interface for visiting all the child nodes of an inspectable object.
- *
- * Inspectable objects may return a collection of children as an array, an {@link Iterable} or an
- * {@link java.util.Iterator}. This provides a unified API for traversing across all the children
- * of an inspectable node.
- *
- * This interface is consumed by {@link InspectionHelper#traverseChildren(Object, ChildTraverser)}
- * and may be implemented as a lambda.
- *
- * @see InspectionHelper#traverseChildren(Object, ChildTraverser)
- * @hide
- */
-@FunctionalInterface
-public interface ChildTraverser {
-    /**
-     * Visit one child object of a parent inspectable object.
-     *
-     * The iteration interface will filter null values out before passing them to this method, but
-     * some child objects may not be inspectable. It is up to the implementor to determine their
-     * inspectablity and what to do with them.
-     *
-     * @param child A child object, guaranteed not to be null.
-     */
-    void traverseChild(@NonNull Object child);
-}
diff --git a/core/java/android/view/inspector/InspectableChildren.java b/core/java/android/view/inspector/InspectableChildren.java
deleted file mode 100644
index de8fa29..0000000
--- a/core/java/android/view/inspector/InspectableChildren.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 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.inspector;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Marks a getter for an inspectable node's inspectable children.
- *
- * This annotation can be applied to any getter that returns a collection of objects, either an
- * array, an {@link Iterable} or a {@link java.util.Iterator}. The getter may return null, which
- * will be treated as an empty collection. Additionally, the inspector will discard any null
- * entries in the collection.
- *
- * By default, this annotation is inherited. At runtime, the inspector introspects on the class
- * hierachy and uses the annotated getter from the bottommost class, if different from any
- * annoated getters of the parent class. If a class inherits from a parent class with an annotated
- * getter, but does not include this annotation, the child class will be traversed using the
- * getter annotated on the parent. This holds true even if the child class overrides the getter.
- *
- * @see InspectionHelper#traverseChildren(Object, ChildTraverser)
- * @see InspectionHelper#hasChildTraversal()
- * @hide
- */
-@Target({METHOD})
-@Retention(SOURCE)
-public @interface InspectableChildren {
-}
diff --git a/core/java/android/view/inspector/InspectableNodeName.java b/core/java/android/view/inspector/InspectableNodeName.java
index 716409c..ea94ad4 100644
--- a/core/java/android/view/inspector/InspectableNodeName.java
+++ b/core/java/android/view/inspector/InspectableNodeName.java
@@ -34,7 +34,7 @@
  * This annotation does not inherit. If a class extends an annotated parent class, but does not
  * annotate itself, its node name will be inferred from its Java name.
  *
- * @see InspectionHelper#getNodeName()
+ * @see InspectionCompanion#getNodeName()
  * @hide
  */
 @Target({TYPE})
diff --git a/core/java/android/view/inspector/InspectableProperty.java b/core/java/android/view/inspector/InspectableProperty.java
index b0fd503..5b957156 100644
--- a/core/java/android/view/inspector/InspectableProperty.java
+++ b/core/java/android/view/inspector/InspectableProperty.java
@@ -17,8 +17,11 @@
 package android.view.inspector;
 
 import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
+import android.content.res.ResourceId;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
@@ -31,8 +34,8 @@
  * but on a different getter, the inspector will use the child's getter when inspecting instances
  * of the child, and the parent's otherwise.
  *
- * @see InspectionHelper#mapProperties(PropertyMapper)
- * @see InspectionHelper#readProperties(Object, PropertyReader)
+ * @see InspectionCompanion#mapProperties(PropertyMapper)
+ * @see InspectionCompanion#readProperties(Object, PropertyReader)
  * @hide
  */
 @Target({METHOD})
@@ -46,5 +49,171 @@
      *
      * @return The name of the property.
      */
-    String value() default "";
+    String name() default "";
+
+    /**
+     * If the property is inflated from XML, the resource ID of its XML attribute.
+     *
+     * If left as {ID_NULL}, and {@link #hasAttributeId()} is true, the attribute ID will be
+     * inferred from {@link #name()}.
+     *
+     * @return The attribute ID of the property or {@link ResourceId#ID_NULL}
+     */
+    int attributeId() default ResourceId.ID_NULL;
+
+    /**
+     * If this property has an attribute ID.
+     *
+     * Set to false if the annotated property does not have an attribute ID, that is, it is not
+     * inflated from an XML attribute. This will prevent the automatic inference of the attribute
+     * ID if {@link #attributeId()} is set to {@link ResourceId#ID_NULL}.
+     *
+     * @return Whether to infer an attribute ID if not supplied
+     */
+    boolean hasAttributeId() default true;
+
+    /**
+     * Specify how to interpret a value type packed into a primitive integer.
+     *
+     * @return A {@link ValueType}
+     */
+    ValueType valueType() default ValueType.INFERRED;
+
+    /**
+     * For enumerations packed into primitive {int} properties, map the values to string names.
+     *
+     * Note that {@link #enumMapping()} cannot be used simultaneously with {@link #flagMapping()}.
+     *
+     * @return An array of {@link EnumMap}, empty if not applicable
+     * @see android.annotation.IntDef
+     * @see IntEnumMapping
+     */
+    EnumMap[] enumMapping() default {};
+
+    /**
+     * For flags packed into primitive {int} properties, model the string names of the flags.
+     *
+     * Note that {@link #flagMapping()} cannot be used simultaneously with {@link #enumMapping()}.
+     *
+     * @return An array of {@link FlagMap}, empty if not applicable
+     * @see android.annotation.IntDef
+     * @see IntFlagMapping
+     */
+    FlagMap[] flagMapping() default {};
+
+
+    /**
+     * One entry in an enumeration packed into a primitive {int}.
+     *
+     * @see IntEnumMapping
+     * @hide
+     */
+    @Target({TYPE})
+    @Retention(SOURCE)
+    @interface EnumMap {
+        /**
+         * The string name of this enumeration value.
+         *
+         * @return A string name
+         */
+        String name();
+
+        /**
+         * The integer value of this enumeration value.
+         *
+         * @return An integer value
+         */
+        int value();
+    }
+
+    /**
+     * One flag value of many that may be packed into a primitive {int}.
+     *
+     * @see IntFlagMapping
+     * @hide
+     */
+    @Target({TYPE})
+    @Retention(SOURCE)
+    @interface FlagMap {
+        /**
+         * The string name of this flag.
+         *
+         * @return A string name
+         */
+        String name();
+
+        /**
+         * A target value that the property's value must equal after masking.
+         *
+         * If a mask is not supplied (i.e., {@link #mask()} is 0), the target will be reused as the
+         * mask. This handles the common case where no flags mutually exclude each other.
+         *
+         * @return The target value to compare against
+         */
+        int target();
+
+        /**
+         * A mask that the property will be bitwise anded with before comparing to the target.
+         *
+         * If set to 0 (the default), the value of {@link #target()} will be used as a mask. Zero
+         * was chosen as the default since bitwise and with zero is always zero.
+         *
+         * @return A mask, or 0 to use the target as a mask
+         */
+        int mask() default 0;
+    }
+
+    /**
+     * The type of value packed into a primitive {int}.
+     *
+     * @hide
+     */
+    enum ValueType {
+        /**
+         * No special handling, property is considered to be a numeric value.
+         */
+        NONE,
+
+        /**
+         * The default the annotation processor infers the value type from context.
+         */
+        INFERRED,
+
+        /**
+         * Value packs an enumeration.
+         *
+         * This is inferred if {@link #enumMapping()} is specified.
+         *
+         * @see EnumMap
+         */
+        INT_ENUM,
+
+        /**
+         * Value packs flags, of which many may be enabled at once.
+         *
+         * This is inferred if {@link #flagMapping()} is specified.
+         *
+         * @see FlagMap
+         */
+        INT_FLAG,
+
+        /**
+         * Value packs color information.
+         *
+         * This is inferred from {@link android.annotation.ColorInt}, or
+         * {@link android.annotation.ColorLong} on the getter method.
+         *
+         * @see android.graphics.Color
+         */
+        COLOR,
+
+        /**
+         * Value packs gravity information.
+         *
+         * This type is not inferred, and is non-trivial to represent using {@link FlagMap}.
+         *
+         * @see android.view.Gravity
+         */
+        GRAVITY
+    }
 }
diff --git a/core/java/android/view/inspector/InspectionCompanion.java b/core/java/android/view/inspector/InspectionCompanion.java
new file mode 100644
index 0000000..62d769b
--- /dev/null
+++ b/core/java/android/view/inspector/InspectionCompanion.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2018 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.inspector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * An interface for companion objects used to inspect views.
+ *
+ * Inspection companions only need to handle the properties and node name of the specific class
+ * they are defined for, not anything from a parent class. At runtime, the inspector instantiates
+ * one instance of each inspection companion, and handles visiting them in the correct inheritance
+ * order for each type it inspects.
+ *
+ * Properties are read from the top of the type tree to the bottom, so that classes that override
+ * a property in their parent class can overwrite it in the reader. In general, properties will
+ * cleanly inherit through their getters, and the inspector runtime will read the properties of a
+ * parent class via the parent's inspection companion, and the child companion will only read
+ * properties added or changed since the parent was defined.
+ *
+ * Only one child traversal is considered for each class. If a descendant class defines a
+ * different child traversal than its parent, only the bottom traversal is used. If a class does
+ * not define its own child traversal, but one of its ancestors does, the bottom-most ancestor's
+ * traversal will be used.
+ *
+ * @param <T> The type of inspectable this is the companion to
+ */
+public interface InspectionCompanion<T> {
+    /**
+     * Map the string names of the properties this companion knows about to integer IDs.
+     *
+     * Each companion is responsible for storing the integer IDs of all its properties. This is the
+     * only method that is allowed to modify the stored IDs.
+     *
+     * Calling {@link #readProperties(T, PropertyReader)} before calling this results in
+     * undefined behavior.
+     *
+     * @param propertyMapper A {@link PropertyMapper} maps string names to IDs.
+     */
+    void mapProperties(@NonNull PropertyMapper propertyMapper);
+
+    /**
+     * Read the values of an instance of this companion's type into a {@link PropertyReader}.
+     *
+     * This method needs to return the property IDs stored by
+     * {@link #mapProperties(PropertyMapper)}. Implementations should track if their properties
+     * have been mapped and throw a {@link UninitializedPropertyMapException} if this method is
+     * called before {mapProperties}.
+     *
+     * @param inspectable A object of type {T} to read the properties of.
+     * @param propertyReader An object which receives the property IDs and values.
+     */
+    void readProperties(@NonNull T inspectable, @NonNull PropertyReader propertyReader);
+
+    /**
+     * Get an optional name to display to developers for inspection nodes of this companion's type.
+     *
+     * The default implementation returns null, which will cause the runtime to use the class's
+     * simple name as defined by {@link Class#getSimpleName()} as the node name.
+     *
+     * If the type of this companion is inflated from XML, this method should be overridden to
+     * return the string used as the tag name for this type in XML.
+     *
+     * @return A string to use as the node name, or null to use the simple class name fallback.
+     */
+    @Nullable
+    default String getNodeName() {
+        return null;
+    }
+
+    /**
+     * Thrown by {@link #readProperties(Object, PropertyReader)} if called before
+     * {@link #mapProperties(PropertyMapper)}.
+     */
+    class UninitializedPropertyMapException extends RuntimeException {
+        public UninitializedPropertyMapException() {
+            super("Unable to read properties of an inspectable before mapping their IDs.");
+        }
+    }
+}
diff --git a/core/java/android/view/inspector/InspectionHelper.java b/core/java/android/view/inspector/InspectionHelper.java
deleted file mode 100644
index 27a9704..0000000
--- a/core/java/android/view/inspector/InspectionHelper.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2018 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.inspector;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-/**
- * An interface for companion objects used to inspect views.
- *
- * Inspection helpers only need to handle the properties, name and traversal of the specific class
- * they are defined for, not anything from a parent class. At runtime, the inspector instantiates
- * one instance of each inspection helper, and handles visiting them in the correct inheritance
- * order for each type it inspects.
- *
- * Properties are read from the top of the type tree to the bottom, so that classes that override
- * a property in their parent class can overwrite it in the reader. In general, properties will
- * cleanly inherit through their getters, and the inspector runtime will read the properties of a
- * parent class via the parent's inspection helper, and the child helper will only read properties
- * added or changed since the parent was defined.
- *
- * Only one child traversal is considered for each class. If a descendant class defines a
- * different child traversal than its parent, only the bottom traversal is used. If a class does
- * not define its own child traversal, but one of its ancestors does, the bottom-most ancestor's
- * traversal will be used.
- *
- * @param <T> The type of inspectable this helper operates on
- * @hide
- */
-public interface InspectionHelper<T> {
-    /**
-     * Map the string names of the properties this helper knows about to integer IDs.
-     *
-     * Each helper is responsible for storing the integer IDs of all its properties. This is the
-     * only method that is allowed to modify the stored IDs.
-     *
-     * Calling {@link #readProperties(T, PropertyReader)} before calling this results in
-     * undefined behavior.
-     *
-     * @param propertyMapper A {@link PropertyMapper} or lambda which maps string names to IDs.
-     */
-    void mapProperties(@NonNull PropertyMapper propertyMapper);
-
-    /**
-     * Read the values of an instance of this helper's type into a {@link PropertyReader}.
-     *
-     * This method needs to return the property IDs stored by
-     * {@link #mapProperties(PropertyMapper)}. Implementations should track if their properties
-     * have been mapped and throw a {@link UninitializedPropertyMapException} if this method is
-     * called before {mapProperties}.
-     *
-     * @param inspectable A object of type {@link T} to read the properties of.
-     * @param propertyReader An object which receives the property IDs and values.
-     */
-    void readProperties(@NonNull T inspectable, @NonNull PropertyReader propertyReader);
-
-    /**
-     * Query if this inspectable type can potentially have child nodes.
-     *
-     * E.g.: any descendant of {@link android.view.ViewGroup} can have child nodes, but a leaf
-     * view like {@link android.widget.ImageView} may not.
-     *
-     * The default implementation always returns false. If an implementing class overrides this, it
-     * should also define {@link #traverseChildren(T, ChildTraverser)}.
-     *
-     * @return True if this inspectable type can potentially have child nodes, false otherwise.
-     */
-    default boolean hasChildTraversal() {
-        return false;
-    }
-
-    /**
-     * Traverse the child nodes of an instance of this helper's type into a {@link ChildTraverser}.
-     *
-     * This provides the ability to traverse over a variety of collection APIs (e.g.: arrays,
-     * {@link Iterable}, or {@link java.util.Iterator}) in a uniform fashion. The traversal must be
-     * in the order defined by this helper's type. If the getter returns null, the helper must
-     * treat it as an empty collection.
-     *
-     * The default implementation throws a {@link NoChildTraversalException}. If
-     * {@link #hasChildTraversal()} returns is overriden to return true, it is expected that the
-     * implementing class will also override this method and provide a traversal.
-     *
-     * @param inspectable An object of type {@link T} to traverse the child nodes of.
-     * @param childTraverser A {@link ChildTraverser} or lamba to receive the children in order.
-     * @throws NoChildTraversalException If there is no defined child traversal
-     */
-    default void traverseChildren(
-            @NonNull T inspectable,
-            @SuppressWarnings("unused") @NonNull ChildTraverser childTraverser) {
-        throw new NoChildTraversalException(inspectable.getClass());
-    }
-
-    /**
-     * Get an optional name to display to developers for inspection nodes of this helper's type.
-     *
-     * The default implementation returns null, which will cause the runtime to use the class's
-     * simple name as defined by {@link Class#getSimpleName()} as the node name.
-     *
-     * If the type of this helper is inflated from XML, this method should be overridden to return
-     * the string used as the tag name for this type in XML.
-     *
-     * @return A string to use as the node name, or null to use the simple class name fallback.
-     */
-    @Nullable
-    default String getNodeName() {
-        return null;
-    }
-
-    /**
-     * Thrown by {@link #readProperties(Object, PropertyReader)} if called before
-     * {@link #mapProperties(PropertyMapper)}.
-     */
-    class UninitializedPropertyMapException extends RuntimeException {
-        public UninitializedPropertyMapException() {
-            super("Unable to read properties of an inspectable before mapping their IDs.");
-        }
-    }
-
-    /**
-     * Thrown by {@link #traverseChildren(Object, ChildTraverser)} if no child traversal exists.
-     */
-    class NoChildTraversalException extends RuntimeException {
-        public NoChildTraversalException(Class cls) {
-            super(String.format(
-                    "Class %s does not have a defined child traversal. Cannot traverse children.",
-                    cls.getCanonicalName()
-            ));
-        }
-    }
-}
diff --git a/core/java/android/view/inspector/IntEnumMapping.java b/core/java/android/view/inspector/IntEnumMapping.java
new file mode 100644
index 0000000..69f6dce
--- /dev/null
+++ b/core/java/android/view/inspector/IntEnumMapping.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2018 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.inspector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.ArrayList;
+
+/**
+ * Maps the values of an {int} property to string names for properties that encode enumerations.
+ *
+ * An {@link InspectionCompanion} may provide an instance of this class to a {@link PropertyMapper}
+ * for enumerations packed into primitive {int} properties.
+ *
+ * This class is immutable, and must be constructed by a {@link Builder}.
+ *
+ * @see PropertyMapper#mapIntEnum(String, int, IntEnumMapping)
+ */
+public final class IntEnumMapping {
+    private final Value[] mValues;
+
+    /**
+     * Map from a property value to a string name.
+     *
+     * @param value The value of a property
+     * @return The name of the enumeration value, null if the value is not mapped
+     */
+    @Nullable
+    public String nameOf(int value) {
+        for (Value valueTuple : mValues) {
+            if (valueTuple.mValue == value) {
+                return valueTuple.mName;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Create a new instance from a builder.
+     *
+     * This constructor is private, use {@link Builder#build()} instead.
+     *
+     * @param builder A builder to create from
+     */
+    private IntEnumMapping(Builder builder) {
+        mValues = builder.mValues.toArray(new Value[builder.mValues.size()]);
+    }
+
+    /**
+     * A builder for {@link IntEnumMapping}
+     */
+    public static final class Builder {
+        private final ArrayList<Value> mValues;
+
+        public Builder() {
+            mValues = new ArrayList<>();
+        }
+
+        /**
+         * Add a new entry to this mapping.
+         *
+         * @param name Name of the enumeration value
+         * @param value Int value of the enumeration value
+         * @return This builder
+         */
+        @NonNull
+        public Builder addValue(@NonNull String name, int value) {
+            mValues.add(new Value(name, value));
+            return this;
+        }
+
+        /**
+         * Clear the builder, allowing for recycling.
+         */
+        public void clear() {
+            mValues.clear();
+        }
+
+        /**
+         * Build a new {@link IntEnumMapping} from this builder
+         *
+         * @return A new mapping
+         */
+        @NonNull
+        public IntEnumMapping build() {
+            return new IntEnumMapping(this);
+        }
+    }
+
+    /**
+     * Inner class that holds the name and value of an enumeration value.
+     */
+    private static final class Value {
+        @NonNull private final String mName;
+        private final int mValue;
+
+        private Value(@NonNull String name, int value) {
+            mName = name;
+            mValue = value;
+        }
+    }
+}
diff --git a/core/java/android/view/inspector/IntFlagMapping.java b/core/java/android/view/inspector/IntFlagMapping.java
new file mode 100644
index 0000000..dcb87e1
--- /dev/null
+++ b/core/java/android/view/inspector/IntFlagMapping.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2018 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.inspector;
+
+import android.annotation.NonNull;
+
+import java.util.ArrayList;
+
+/**
+ * Maps the values of an {int} property to arrays of string for properties that encode flags.
+ *
+ * An {@link InspectionCompanion} may provide an instance of this class to a {@link PropertyMapper}
+ * for flag values packed into primitive {int} properties.
+ *
+ * Each flag has a
+ *
+ * This class is immutable, and must be constructed by a {@link Builder}.
+ *
+ * @see PropertyMapper#mapIntFlag(String, int, IntFlagMapping)
+ */
+public final class IntFlagMapping {
+    private final Flag[] mFlags;
+
+    /**
+     * Get an array of the names of enabled flags for a given property value.
+     *
+     * @param value The value of the property
+     * @return The names of the enabled flags
+     */
+    @NonNull
+    public String[] namesOf(int value) {
+        ArrayList<String> enabledFlagNames = new ArrayList<>(mFlags.length);
+
+        for (Flag flag : mFlags) {
+            if (flag.isEnabledFor(value)) {
+                enabledFlagNames.add(flag.mName);
+            }
+        }
+
+        return enabledFlagNames.toArray(new String[enabledFlagNames.size()]);
+    }
+
+    /**
+     * Create a new instance from a builder.
+     *
+     * This constructor is private, use {@link Builder#build()} instead.
+     *
+     * @param builder A builder to create from
+     */
+    private IntFlagMapping(Builder builder) {
+        mFlags = builder.mFlags.toArray(new Flag[builder.mFlags.size()]);
+    }
+
+    /**
+     * A builder for {@link IntFlagMapping}.
+     */
+    public static final class Builder {
+        private ArrayList<Flag> mFlags;
+
+        public Builder() {
+            mFlags = new ArrayList<>();
+        }
+
+        /**
+         * Add a new flag without a mask.
+         *
+         * The target value will be used as a mask, to handle the common case where flag values
+         * are not mutually exclusive. The flag will be considered enabled for a property value if
+         * the result of bitwise anding the target and the value equals the target, that is:
+         * {(value & target) == target}.
+         *
+         * @param name The name of the flag
+         * @param target The value to compare against
+         * @return This builder
+         */
+        @NonNull
+        public Builder addFlag(@NonNull String name, int target) {
+            mFlags.add(new Flag(name, target, target));
+            return this;
+        }
+
+        /**
+         * Add a new flag with a mask.
+         *
+         * The flag will be considered enabled for a property value if the result of bitwise anding
+         * the value and the mask equals the target, that is: {(value & mask) == target}.
+         *
+         * @param name The name of the flag
+         * @param target The value to compare against
+         * @param mask A bit mask
+         * @return This builder
+         */
+        @NonNull
+        public Builder addFlag(@NonNull String name, int target, int mask) {
+            mFlags.add(new Flag(name, target, mask));
+            return this;
+        }
+
+        /**
+         * Clear the builder, allowing for recycling.
+         */
+        public void clear() {
+            mFlags.clear();
+        }
+
+        /**
+         * Build a new {@link IntFlagMapping} from this builder.
+         *
+         * @return A new mapping
+         */
+        @NonNull
+        public IntFlagMapping build() {
+            return new IntFlagMapping(this);
+        }
+    }
+
+    /**
+     * Inner class that holds the name, mask, and target value of a flag
+     */
+    private static final class Flag {
+        @NonNull private final String mName;
+        private final int mTarget;
+        private final int mMask;
+
+        private Flag(@NonNull String name, int target, int mask) {
+            mName = name;
+            mTarget = target;
+            mMask = mask;
+        }
+
+        /**
+         * Compare the supplied property value against the mask and taget.
+         *
+         * @param value The value to check
+         * @return True if this flag is enabled
+         */
+        private boolean isEnabledFor(int value) {
+            return (value & mMask) == mTarget;
+        }
+    }
+}
diff --git a/core/java/android/view/inspector/PropertyMapper.java b/core/java/android/view/inspector/PropertyMapper.java
index 35550bd..5fb291b 100644
--- a/core/java/android/view/inspector/PropertyMapper.java
+++ b/core/java/android/view/inspector/PropertyMapper.java
@@ -16,102 +16,160 @@
 
 package android.view.inspector;
 
+import android.annotation.AttrRes;
 import android.annotation.NonNull;
 
 /**
  * An interface for mapping the string names of inspectable properties to integer identifiers.
  *
- * This interface is consumed by {@link InspectionHelper#mapProperties(PropertyMapper)}.
+ * This interface is consumed by {@link InspectionCompanion#mapProperties(PropertyMapper)}.
  *
  * Mapping properties to IDs enables quick comparisons against shadow copies of inspectable
  * objects without performing a large number of string comparisons.
  *
- * @see InspectionHelper#mapProperties(PropertyMapper)
- * @hide
+ * @see InspectionCompanion#mapProperties(PropertyMapper)
  */
 public interface PropertyMapper {
     /**
      * Map a string name to an integer ID for a primitive boolean property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapBoolean(@NonNull String name);
+    int mapBoolean(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive byte property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapByte(@NonNull String name);
+    int mapByte(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive char property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapChar(@NonNull String name);
+    int mapChar(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive double property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapDouble(@NonNull String name);
+    int mapDouble(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive float property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapFloat(@NonNull String name);
+    int mapFloat(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive int property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapInt(@NonNull String name);
+    int mapInt(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive long property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapLong(@NonNull String name);
+    int mapLong(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for a primitive short property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapShort(@NonNull String name);
+    int mapShort(@NonNull String name, @AttrRes int attributeId);
 
     /**
      * Map a string name to an integer ID for an object property.
      *
      * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
      * @return An integer ID for the property
      * @throws PropertyConflictException If the property name is already mapped as another type.
      */
-    int mapObject(@NonNull String name);
+    int mapObject(@NonNull String name, @AttrRes int attributeId);
 
     /**
+     * Map a string name to an integer ID for a color property.
+     *
+     * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
+     * @return An integer ID for the property
+     * @throws PropertyConflictException If the property name is already mapped as another type.
+     * @see android.graphics.Color
+     */
+    int mapColor(@NonNull String name, @AttrRes int attributeId);
+
+    /**
+     * Map a string name to an integer ID for a gravity property.
+     *
+     * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
+     * @return An integer ID for the property
+     * @throws PropertyConflictException If the property name is already mapped as another type.
+     * @see android.view.Gravity
+     */
+    int mapGravity(@NonNull String name, @AttrRes int attributeId);
+
+    /**
+     * Map a string name to an integer ID for an enumeration packed into an int property.
+     *
+     * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
+     * @param mapping A mapping from int to String
+     * @return An integer ID for the property
+     * @throws PropertyConflictException If the property name is already mapped as another type.
+     */
+    int mapIntEnum(
+            @NonNull String name,
+            @AttrRes int attributeId,
+            @NonNull IntEnumMapping mapping);
+
+    /**
+     * Map a string name to an integer ID for a flag set packed into an int property.
+     *
+     * @param name The name of the property
+     * @param attributeId If the property is from an XML attribute, the resource ID of the property
+     * @param mapping A mapping from int to an array of strings
+     * @return An integer ID for the property
+     * @throws PropertyConflictException If the property name is already mapped as another type.
+     */
+    int mapIntFlag(
+            @NonNull String name,
+            @AttrRes int attributeId,
+            @NonNull IntFlagMapping mapping);
+    /**
      * Thrown from a map method if a property name is already mapped as different type.
      */
     class PropertyConflictException extends RuntimeException {
diff --git a/core/java/android/view/inspector/PropertyReader.java b/core/java/android/view/inspector/PropertyReader.java
index df81c10..fd83e8d 100644
--- a/core/java/android/view/inspector/PropertyReader.java
+++ b/core/java/android/view/inspector/PropertyReader.java
@@ -16,19 +16,21 @@
 
 package android.view.inspector;
 
+import android.annotation.ColorInt;
+import android.annotation.ColorLong;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.graphics.Color;
 
 /**
  * An interface for reading the properties of an inspectable object.
  *
- * Used as the parameter for {@link InspectionHelper#readProperties(Object, PropertyReader)}.
+ * Used as the parameter for {@link InspectionCompanion#readProperties(Object, PropertyReader)}.
  * It has separate methods for all primitive types to avoid autoboxing overhead if a concrete
  * implementation is able to work with primitives. Implementations should be prepared to accept
  * {null} as the value of {@link PropertyReader#readObject(int, Object)}.
  *
- * @see InspectionHelper#readProperties(Object, PropertyReader)
- * @hide
+ * @see InspectionCompanion#readProperties(Object, PropertyReader)
  */
 public interface PropertyReader {
     /**
@@ -115,6 +117,60 @@
     void readObject(int id, @Nullable Object value);
 
     /**
+     * Read a color packed into a {@link ColorInt} as a property.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
+     */
+    void readColor(int id, @ColorInt int value);
+
+    /**
+     * Read a color packed into a {@link ColorLong} as a property.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
+     */
+    void readColor(int id, @ColorLong long value);
+
+    /**
+     * Read a {@link Color} object as a property.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
+     */
+    void readColor(int id, @Nullable Color value);
+
+    /**
+     * Read {@link android.view.Gravity} packed into an primitive {int}.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as a gravity property
+     */
+    void readGravity(int id, int value);
+
+    /**
+     * Read an enumeration packed into a primitive {int}.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as an object
+     */
+    void readIntEnum(int id, int value);
+
+    /**
+     * Read a flag packed into a primitive {int}.
+     *
+     * @param id Identifier of the property from a {@link PropertyMapper}
+     * @param value Value of the property
+     * @throws PropertyTypeMismatchException If the property ID is not mapped as an object
+     */
+    void readIntFlag(int id, int value);
+
+    /**
      * Thrown if a client calls a typed read method for a property of a different type.
      */
     class PropertyTypeMismatchException extends RuntimeException {
diff --git a/core/java/android/view/intelligence/ContentCaptureManager.java b/core/java/android/view/intelligence/ContentCaptureManager.java
index 9023cd0..45518d5 100644
--- a/core/java/android/view/intelligence/ContentCaptureManager.java
+++ b/core/java/android/view/intelligence/ContentCaptureManager.java
@@ -189,7 +189,7 @@
         }
     }
 
-    private  void handleSessionStarted(int resultCode) {
+    private void handleSessionStarted(int resultCode) {
         mState = resultCode;
         mDisabled.set(mState == STATE_DISABLED);
         if (VERBOSE) {
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 7b39efe..3b916d1 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -18,6 +18,8 @@
 
 import android.annotation.ColorInt;
 import android.annotation.DimenRes;
+import android.annotation.IntDef;
+import android.annotation.LayoutRes;
 import android.annotation.NonNull;
 import android.annotation.StyleRes;
 import android.annotation.UnsupportedAppUsage;
@@ -131,6 +133,12 @@
     static final String EXTRA_REMOTEADAPTER_APPWIDGET_ID = "remoteAdapterAppWidgetId";
 
     /**
+     * The intent extra that contains {@code true} if inflating as dak text theme.
+     * @hide
+     */
+    static final String EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND = "remoteAdapterOnLightBackground";
+
+    /**
      * The intent extra that contains the bounds for all shared elements.
      */
     public static final String EXTRA_SHARED_ELEMENT_BOUNDS =
@@ -163,6 +171,36 @@
     private static final int SET_RIPPLE_DRAWABLE_COLOR_TAG = 21;
     private static final int SET_INT_TAG_TAG = 22;
 
+    /** @hide **/
+    @IntDef(flag = true, value = {
+            FLAG_REAPPLY_DISALLOWED,
+            FLAG_WIDGET_IS_COLLECTION_CHILD,
+            FLAG_USE_LIGHT_BACKGROUND_LAYOUT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ApplyFlags {}
+    /**
+     * Whether reapply is disallowed on this remoteview. This maybe be true if some actions modify
+     * the layout in a way that isn't recoverable, since views are being removed.
+     * @hide
+     */
+    public static final int FLAG_REAPPLY_DISALLOWED = 1;
+    /**
+     * This flag indicates whether this RemoteViews object is being created from a
+     * RemoteViewsService for use as a child of a widget collection. This flag is used
+     * to determine whether or not certain features are available, in particular,
+     * setting on click extras and setting on click pending intents. The former is enabled,
+     * and the latter disabled when this flag is true.
+     * @hide
+     */
+    public static final int FLAG_WIDGET_IS_COLLECTION_CHILD = 2;
+    /**
+     * When this flag is set, the views is inflated with {@link #mLightBackgroundLayoutId} instead
+     * of {link #mLayoutId}
+     * @hide
+     */
+    public static final int FLAG_USE_LIGHT_BACKGROUND_LAYOUT = 4;
+
     /**
      * Application that hosts the remote views.
      *
@@ -178,6 +216,11 @@
     private final int mLayoutId;
 
     /**
+     * The resource ID of the layout file in dark text mode. (Added to the parcel)
+     */
+    private int mLightBackgroundLayoutId = 0;
+
+    /**
      * An array of actions to perform on the view tree once it has been
      * inflated
      */
@@ -197,12 +240,6 @@
     private boolean mIsRoot = true;
 
     /**
-     * Whether reapply is disallowed on this remoteview. This maybe be true if some actions modify
-     * the layout in a way that isn't recoverable, since views are being removed.
-     */
-    private boolean mReapplyDisallowed;
-
-    /**
      * Constants to whether or not this RemoteViews is composed of a landscape and portrait
      * RemoteViews.
      */
@@ -218,14 +255,8 @@
     @UnsupportedAppUsage
     private RemoteViews mPortrait = null;
 
-    /**
-     * This flag indicates whether this RemoteViews object is being created from a
-     * RemoteViewsService for use as a child of a widget collection. This flag is used
-     * to determine whether or not certain features are available, in particular,
-     * setting on click extras and setting on click pending intents. The former is enabled,
-     * and the latter disabled when this flag is true.
-     */
-    private boolean mIsWidgetCollectionChild = false;
+    @ApplyFlags
+    private int mApplyFlags = 0;
 
     /** Class cookies of the Parcel this instance was read from. */
     private final Map<Class, Object> mClassCookies;
@@ -289,18 +320,15 @@
      *
      * @hide
      */
-    public void setReapplyDisallowed() {
-        mReapplyDisallowed = true;
+    public void addFlags(@ApplyFlags int flags) {
+        mApplyFlags = mApplyFlags | flags;
     }
 
     /**
-     * @return Whether it is disallowed to reapply another remoteview with the same layout as this
-     * view. True if this remoteview has actions that destroyed view tree of the base layout.
-     *
      * @hide
      */
-    public boolean isReapplyDisallowed() {
-        return mReapplyDisallowed;
+    public boolean hasFlags(@ApplyFlags int flag) {
+        return (mApplyFlags & flag) == flag;
     }
 
     /**
@@ -768,7 +796,10 @@
             // Embed the AppWidget Id for use in RemoteViewsAdapter when connecting to the intent
             // RemoteViewsService
             AppWidgetHostView host = (AppWidgetHostView) rootParent;
-            intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, host.getAppWidgetId());
+            intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, host.getAppWidgetId())
+                    .putExtra(EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND,
+                            hasFlags(FLAG_USE_LIGHT_BACKGROUND_LAYOUT));
+
             if (target instanceof AbsListView) {
                 AbsListView v = (AbsListView) target;
                 v.setRemoteViewsAdapter(intent, isAsync);
@@ -829,7 +860,7 @@
                 // If the view is an AdapterView, setting a PendingIntent on click doesn't make
                 // much sense, do they mean to set a PendingIntent template for the
                 // AdapterView's children?
-                if (mIsWidgetCollectionChild) {
+                if (hasFlags(FLAG_WIDGET_IS_COLLECTION_CHILD)) {
                     Log.w(LOG_TAG, "Cannot SetOnClickResponse for collection item "
                             + "(id: " + viewId + ")");
                     ApplicationInfo appInfo = root.getContext().getApplicationInfo();
@@ -843,7 +874,7 @@
                 }
                 target.setTagInternal(R.id.pending_intent_tag, mResponse.mPendingIntent);
             } else if (mResponse.mFillIntent != null) {
-                if (!mIsWidgetCollectionChild) {
+                if (!hasFlags(FLAG_WIDGET_IS_COLLECTION_CHILD)) {
                     Log.e(LOG_TAG, "The method setOnClickFillInIntent is available "
                             + "only from RemoteViewsFactory (ie. on collection items).");
                     return;
@@ -1545,6 +1576,7 @@
             viewId = parcel.readInt();
             mIndex = parcel.readInt();
             mNestedViews = new RemoteViews(parcel, bitmapCache, info, depth, classCookies);
+            mNestedViews.addFlags(mApplyFlags);
         }
 
         public void writeToParcel(Parcel dest, int flags) {
@@ -2190,7 +2222,7 @@
      *
      * @hide
      */
-    public RemoteViews(String packageName, int userId, int layoutId) {
+    public RemoteViews(String packageName, int userId, @LayoutRes int layoutId) {
         this(getApplicationInfo(packageName, userId), layoutId);
     }
 
@@ -2203,7 +2235,7 @@
      *
      * @hide
      */
-    protected RemoteViews(ApplicationInfo application, int layoutId) {
+    protected RemoteViews(ApplicationInfo application, @LayoutRes int layoutId) {
         mApplication = application;
         mLayoutId = layoutId;
         mBitmapCache = new BitmapCache();
@@ -2229,7 +2261,8 @@
             throw new RuntimeException("Both RemoteViews must share the same package and user");
         }
         mApplication = portrait.mApplication;
-        mLayoutId = portrait.getLayoutId();
+        mLayoutId = portrait.mLayoutId;
+        mLightBackgroundLayoutId = portrait.mLightBackgroundLayoutId;
 
         mLandscape = landscape;
         mPortrait = portrait;
@@ -2250,8 +2283,8 @@
         mApplication = src.mApplication;
         mIsRoot = src.mIsRoot;
         mLayoutId = src.mLayoutId;
-        mIsWidgetCollectionChild = src.mIsWidgetCollectionChild;
-        mReapplyDisallowed = src.mReapplyDisallowed;
+        mLightBackgroundLayoutId = src.mLightBackgroundLayoutId;
+        mApplyFlags = src.mApplyFlags;
         mClassCookies = src.mClassCookies;
 
         if (src.hasLandscapeAndPortraitLayouts()) {
@@ -2309,7 +2342,7 @@
             mApplication = parcel.readInt() == 0 ? info :
                     ApplicationInfo.CREATOR.createFromParcel(parcel);
             mLayoutId = parcel.readInt();
-            mIsWidgetCollectionChild = parcel.readInt() == 1;
+            mLightBackgroundLayoutId = parcel.readInt();
 
             readActionsFromParcel(parcel, depth);
         } else {
@@ -2318,9 +2351,10 @@
             mPortrait = new RemoteViews(parcel, mBitmapCache, mLandscape.mApplication, depth,
                     mClassCookies);
             mApplication = mPortrait.mApplication;
-            mLayoutId = mPortrait.getLayoutId();
+            mLayoutId = mPortrait.mLayoutId;
+            mLightBackgroundLayoutId = mPortrait.mLightBackgroundLayoutId;
         }
-        mReapplyDisallowed = parcel.readInt() == 0;
+        mApplyFlags = parcel.readInt();
     }
 
     private void readActionsFromParcel(Parcel parcel, int depth) {
@@ -2409,19 +2443,8 @@
      * @return the layout id.
      */
     public int getLayoutId() {
-        return mLayoutId;
-    }
-
-    /*
-     * This flag indicates whether this RemoteViews object is being created from a
-     * RemoteViewsService for use as a child of a widget collection. This flag is used
-     * to determine whether or not certain features are available, in particular,
-     * setting on click extras and setting on click pending intents. The former is enabled,
-     * and the latter disabled when this flag is true.
-     */
-    @UnsupportedAppUsage
-    void setIsWidgetCollectionChild(boolean isWidgetCollectionChild) {
-        mIsWidgetCollectionChild = isWidgetCollectionChild;
+        return hasFlags(FLAG_USE_LIGHT_BACKGROUND_LAYOUT) && (mLightBackgroundLayoutId != 0)
+                ? mLightBackgroundLayoutId : mLayoutId;
     }
 
     /**
@@ -3292,6 +3315,33 @@
         setInt(viewId, "setLabelFor", labeledId);
     }
 
+    /**
+     * Provides an alternate layout ID, which can be used to inflate this view. This layout will be
+     * used by the host when the widgets displayed on a light-background where foreground elements
+     * and text can safely draw using a dark color without any additional background protection.
+     */
+    public void setLightBackgroundLayoutId(@LayoutRes int layoutId) {
+        mLightBackgroundLayoutId = layoutId;
+    }
+
+    /**
+     * If this view supports dark text versions, creates a copy representing that version,
+     * otherwise returns itself.
+     * @hide
+     */
+    public RemoteViews getDarkTextViews() {
+        if (hasFlags(FLAG_USE_LIGHT_BACKGROUND_LAYOUT)) {
+            return this;
+        }
+
+        try {
+            addFlags(FLAG_USE_LIGHT_BACKGROUND_LAYOUT);
+            return new RemoteViews(this);
+        } finally {
+            mApplyFlags &= ~FLAG_USE_LIGHT_BACKGROUND_LAYOUT;
+        }
+    }
+
     private RemoteViews getRemoteViewsToApply(Context context) {
         if (hasLandscapeAndPortraitLayouts()) {
             int orientation = context.getResources().getConfiguration().orientation;
@@ -3652,7 +3702,7 @@
                 mApplication.writeToParcel(dest, flags);
             }
             dest.writeInt(mLayoutId);
-            dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
+            dest.writeInt(mLightBackgroundLayoutId);
             writeActionsToParcel(dest);
         } else {
             dest.writeInt(MODE_HAS_LANDSCAPE_AND_PORTRAIT);
@@ -3665,7 +3715,7 @@
             // Both RemoteViews already share the same package and user
             mPortrait.writeToParcel(dest, flags | PARCELABLE_ELIDE_DUPLICATES);
         }
-        dest.writeInt(mReapplyDisallowed ? 1 : 0);
+        dest.writeInt(mApplyFlags);
     }
 
     private void writeActionsToParcel(Parcel parcel) {
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index d17c7c5..c5cd1a1 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -16,6 +16,9 @@
 
 package android.widget;
 
+import static android.widget.RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID;
+import static android.widget.RemoteViews.EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND;
+
 import android.annotation.UnsupportedAppUsage;
 import android.annotation.WorkerThread;
 import android.app.IServiceConnection;
@@ -97,6 +100,7 @@
     private final Context mContext;
     private final Intent mIntent;
     private final int mAppWidgetId;
+    private final boolean mOnLightBackground;
     private final Executor mAsyncViewLoadExecutor;
 
     private OnClickHandler mRemoteViewsOnClickHandler;
@@ -817,13 +821,13 @@
             throw new IllegalArgumentException("Non-null Intent must be specified.");
         }
 
-        mAppWidgetId = intent.getIntExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID, -1);
+        mAppWidgetId = intent.getIntExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, -1);
         mRequestedViews = new RemoteViewsFrameLayoutRefSet();
+        mOnLightBackground = intent.getBooleanExtra(EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND, false);
 
         // Strip the previously injected app widget id from service intent
-        if (intent.hasExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID)) {
-            intent.removeExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID);
-        }
+        intent.removeExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID);
+        intent.removeExtra(EXTRA_REMOTEADAPTER_ON_LIGHT_BACKGROUND);
 
         // Initialize the worker thread
         mWorkerThread = new HandlerThread("RemoteViewsCache-loader");
@@ -1107,6 +1111,7 @@
             } else {
                 layout = new RemoteViewsFrameLayout(parent.getContext(), mCache);
                 layout.setExecutor(mAsyncViewLoadExecutor);
+                layout.setOnLightBackground(mOnLightBackground);
             }
 
             if (isInCache) {
diff --git a/core/java/android/widget/RemoteViewsListAdapter.java b/core/java/android/widget/RemoteViewsListAdapter.java
index e490458..b80fe48 100644
--- a/core/java/android/widget/RemoteViewsListAdapter.java
+++ b/core/java/android/widget/RemoteViewsListAdapter.java
@@ -85,7 +85,7 @@
     public View getView(int position, View convertView, ViewGroup parent) {
         if (position < getCount()) {
             RemoteViews rv = mRemoteViewsList.get(position);
-            rv.setIsWidgetCollectionChild(true);
+            rv.addFlags(RemoteViews.FLAG_WIDGET_IS_COLLECTION_CHILD);
             View v;
             if (convertView != null && rv != null &&
                     convertView.getId() == rv.getLayoutId()) {
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index 2827f63..214e5cc 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -163,7 +163,7 @@
             try {
                 rv = mFactory.getViewAt(position);
                 if (rv != null) {
-                    rv.setIsWidgetCollectionChild(true);
+                    rv.addFlags(RemoteViews.FLAG_WIDGET_IS_COLLECTION_CHILD);
                 }
             } catch (Exception ex) {
                 Thread t = Thread.currentThread();
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 875d7c9..a87bbf3 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Binder;
+import android.os.Process;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.text.format.DateFormat;
@@ -78,8 +79,10 @@
     private final Random mRandom;
     private long mStartTime = System.currentTimeMillis();
     private long mCallStatsCount = 0;
+    private boolean mAddDebugEntries = false;
 
     private CachedDeviceState.Readonly mDeviceState;
+    private CachedDeviceState.TimeInStateStopwatch mBatteryStopwatch;
 
     /** Injector for {@link BinderCallsStats}. */
     public static class Injector {
@@ -93,7 +96,11 @@
     }
 
     public void setDeviceState(@NonNull CachedDeviceState.Readonly deviceState) {
+        if (mBatteryStopwatch != null) {
+            mBatteryStopwatch.close();
+        }
         mDeviceState = deviceState;
+        mBatteryStopwatch = deviceState.createTimeOnBatteryStopwatch();
     }
 
     @Override
@@ -317,9 +324,30 @@
             exported.methodName = methodName;
         }
 
+        // Debug entries added to help validate the data.
+        if (mAddDebugEntries && mBatteryStopwatch != null) {
+            resultCallStats.add(createDebugEntry("start_time_millis", mStartTime));
+            resultCallStats.add(createDebugEntry("end_time_millis", System.currentTimeMillis()));
+            resultCallStats.add(
+                    createDebugEntry("battery_time_millis", mBatteryStopwatch.getMillis()));
+        }
+
         return resultCallStats;
     }
 
+    private ExportedCallStat createDebugEntry(String variableName, long value) {
+        final int uid = Process.myUid();
+        final ExportedCallStat callStat = new ExportedCallStat();
+        callStat.className = "";
+        callStat.workSourceUid = uid;
+        callStat.callingUid = uid;
+        callStat.recordedCallCount = 1;
+        callStat.callCount = 1;
+        callStat.methodName = "__DEBUG_" + variableName;
+        callStat.maxReplySizeBytes = value;
+        return callStat;
+    }
+
     /** @hide */
     public ArrayMap<String, Integer> getExportedExceptionStats() {
         synchronized (mLock) {
@@ -341,6 +369,8 @@
         long totalCpuTime = 0;
         pw.print("Start time: ");
         pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStartTime));
+        pw.print("On battery time (ms): ");
+        pw.println(mBatteryStopwatch != null ? mBatteryStopwatch.getMillis() : 0);
         pw.println("Sampling interval period: " + mPeriodicSamplingInterval);
         final List<UidEntry> entries = new ArrayList<>();
 
@@ -457,6 +487,10 @@
         }
     }
 
+    public void setAddDebugEntries(boolean addDebugEntries) {
+        mAddDebugEntries = addDebugEntries;
+    }
+
     /**
      * Sets the maximum number of items to track.
      */
@@ -496,6 +530,9 @@
             mUidEntries.clear();
             mExceptionCounts.clear();
             mStartTime = System.currentTimeMillis();
+            if (mBatteryStopwatch != null) {
+                mBatteryStopwatch.reset();
+            }
         }
     }
 
diff --git a/core/java/com/android/internal/os/CachedDeviceState.java b/core/java/com/android/internal/os/CachedDeviceState.java
index 8c90682..334cca3 100644
--- a/core/java/com/android/internal/os/CachedDeviceState.java
+++ b/core/java/com/android/internal/os/CachedDeviceState.java
@@ -16,8 +16,14 @@
 
 package com.android.internal.os;
 
+
+import android.os.SystemClock;
+
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.util.ArrayList;
+
 /**
  * Stores the device state (e.g. charging/on battery, screen on/off) to be shared with
  * the System Server telemetry services.
@@ -27,6 +33,9 @@
 public class CachedDeviceState {
     private volatile boolean mScreenInteractive;
     private volatile boolean mCharging;
+    private final Object mStopwatchesLock = new Object();
+    @GuardedBy("mStopwatchLock")
+    private final ArrayList<TimeInStateStopwatch> mOnBatteryStopwatches = new ArrayList<>();
 
     public CachedDeviceState() {
         mCharging = true;
@@ -44,7 +53,23 @@
     }
 
     public void setCharging(boolean charging) {
-        mCharging = charging;
+        if (mCharging != charging) {
+            mCharging = charging;
+            updateStopwatches(/* shouldStart= */ !charging);
+        }
+    }
+
+    private void updateStopwatches(boolean shouldStart) {
+        synchronized (mStopwatchesLock) {
+            final int size = mOnBatteryStopwatches.size();
+            for (int i = 0; i < size; i++) {
+                if (shouldStart) {
+                    mOnBatteryStopwatches.get(i).start();
+                } else {
+                    mOnBatteryStopwatches.get(i).stop();
+                }
+            }
+        }
     }
 
     public Readonly getReadonlyClient() {
@@ -62,5 +87,74 @@
         public boolean isScreenInteractive() {
             return mScreenInteractive;
         }
+
+        /** Creates a {@link TimeInStateStopwatch stopwatch} that tracks the time on battery. */
+        public TimeInStateStopwatch createTimeOnBatteryStopwatch() {
+            synchronized (mStopwatchesLock) {
+                final TimeInStateStopwatch stopwatch = new TimeInStateStopwatch();
+                mOnBatteryStopwatches.add(stopwatch);
+                if (!mCharging) {
+                    stopwatch.start();
+                }
+                return stopwatch;
+            }
+        }
+    }
+
+    /** Tracks the time the device spent in a given state. */
+    public class TimeInStateStopwatch implements AutoCloseable {
+        private final Object mLock = new Object();
+        @GuardedBy("mLock")
+        private long mStartTimeMillis;
+        @GuardedBy("mLock")
+        private long mTotalTimeMillis;
+
+        /** Returns the time in state since the last call to {@link TimeInStateStopwatch#reset}. */
+        public long getMillis() {
+            synchronized (mLock) {
+                return mTotalTimeMillis + elapsedTime();
+            }
+        }
+
+        /** Resets the time in state to 0 without stopping the timer if it's started. */
+        public void reset() {
+            synchronized (mLock) {
+                mTotalTimeMillis = 0;
+                mStartTimeMillis = isRunning() ? SystemClock.elapsedRealtime() : 0;
+            }
+        }
+
+        private void start() {
+            synchronized (mLock) {
+                if (!isRunning()) {
+                    mStartTimeMillis = SystemClock.elapsedRealtime();
+                }
+            }
+        }
+
+        private void stop() {
+            synchronized (mLock) {
+                if (isRunning()) {
+                    mTotalTimeMillis += elapsedTime();
+                    mStartTimeMillis = 0;
+                }
+            }
+        }
+
+        private long elapsedTime() {
+            return isRunning() ? SystemClock.elapsedRealtime() - mStartTimeMillis : 0;
+        }
+
+        @VisibleForTesting
+        public boolean isRunning() {
+            return mStartTimeMillis > 0;
+        }
+
+        @Override
+        public void close() {
+            synchronized (mStopwatchesLock) {
+                mOnBatteryStopwatches.remove(this);
+            }
+        }
     }
 }
diff --git a/core/java/com/android/internal/os/LooperStats.java b/core/java/com/android/internal/os/LooperStats.java
index cf2a297..de85c1f 100644
--- a/core/java/com/android/internal/os/LooperStats.java
+++ b/core/java/com/android/internal/os/LooperStats.java
@@ -49,6 +49,7 @@
     private final int mEntriesSizeCap;
     private int mSamplingInterval;
     private CachedDeviceState.Readonly mDeviceState;
+    private CachedDeviceState.TimeInStateStopwatch mBatteryStopwatch;
     private long mStartTime = System.currentTimeMillis();
     private boolean mAddDebugEntries = false;
 
@@ -58,7 +59,12 @@
     }
 
     public void setDeviceState(@NonNull CachedDeviceState.Readonly deviceState) {
+        if (mBatteryStopwatch != null) {
+            mBatteryStopwatch.close();
+        }
+
         mDeviceState = deviceState;
+        mBatteryStopwatch = deviceState.createTimeOnBatteryStopwatch();
     }
 
     public void setAddDebugEntries(boolean addDebugEntries) {
@@ -148,9 +154,11 @@
         maybeAddSpecialEntry(exportedEntries, mOverflowEntry);
         maybeAddSpecialEntry(exportedEntries, mHashCollisionEntry);
         // Debug entries added to help validate the data.
-        if (mAddDebugEntries) {
+        if (mAddDebugEntries && mBatteryStopwatch != null) {
             exportedEntries.add(createDebugEntry("start_time_millis", mStartTime));
             exportedEntries.add(createDebugEntry("end_time_millis", System.currentTimeMillis()));
+            exportedEntries.add(
+                    createDebugEntry("battery_time_millis", mBatteryStopwatch.getMillis()));
         }
         return exportedEntries;
     }
@@ -168,6 +176,10 @@
         return mStartTime;
     }
 
+    public long getBatteryTimeMillis() {
+        return mBatteryStopwatch != null ? mBatteryStopwatch.getMillis() : 0;
+    }
+
     private void maybeAddSpecialEntry(List<ExportedEntry> exportedEntries, Entry specialEntry) {
         synchronized (specialEntry) {
             if (specialEntry.messageCount > 0 || specialEntry.exceptionCount > 0) {
@@ -188,6 +200,9 @@
             mOverflowEntry.reset();
         }
         mStartTime = System.currentTimeMillis();
+        if (mBatteryStopwatch != null) {
+            mBatteryStopwatch.reset();
+        }
     }
 
     public void setSamplingInterval(int samplingInterval) {
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 488b991..d8ee643 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -91,6 +91,7 @@
 import android.view.ViewRootImpl;
 import android.view.ViewRootImpl.ActivityConfigCallback;
 import android.view.Window;
+import android.view.WindowInsetsController;
 import android.view.WindowManager;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -3877,4 +3878,9 @@
             mDecor.updateLogTag(params);
         }
     }
+
+    @Override
+    public WindowInsetsController getInsetsController() {
+        return mDecor.getWindowInsetsController();
+    }
 }
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 600b1b3..53b56f2 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -29,7 +29,7 @@
 {
     void setIcon(String slot, in StatusBarIcon icon);
     void removeIcon(String slot);
-    void disable(int state1, int state2);
+    void disable(int displayId, int state1, int state2);
     void animateExpandNotificationsPanel();
     void animateExpandSettingsPanel(String subPanel);
     void animateCollapsePanels();
@@ -38,8 +38,9 @@
     void showWirelessChargingAnimation(int batteryLevel);
 
     /**
-     * Notifies the status bar of a System UI visibility flag change.
+     * Notifies System UI side of a visibility flag change on the specified display.
      *
+     * @param displayId the id of the display to notify
      * @param vis the visibility flags except SYSTEM_UI_FLAG_LIGHT_STATUS_BAR which will be reported
      *            separately in fullscreenStackVis and dockedStackVis
      * @param fullscreenStackVis the flags which only apply in the region of the fullscreen stack,
@@ -50,13 +51,13 @@
      * @param fullscreenBounds the current bounds of the fullscreen stack, in screen coordinates
      * @param dockedBounds the current bounds of the docked stack, in screen coordinates
      */
-    void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask,
-            in Rect fullscreenBounds, in Rect dockedBounds);
+    void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis, int dockedStackVis,
+            int mask, in Rect fullscreenBounds, in Rect dockedBounds);
 
-    void topAppWindowChanged(boolean menuVisible);
-    void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
+    void topAppWindowChanged(int displayId, boolean menuVisible);
+    void setImeWindowStatus(int displayId, in IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher);
-    void setWindowState(int window, int state);
+    void setWindowState(int display, int window, int state);
 
     void showRecentApps(boolean triggeredFromAltTab);
     void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
@@ -70,30 +71,38 @@
     void toggleKeyboardShortcutsMenu(int deviceId);
 
     /**
-     * Notifies the status bar that an app transition is pending to delay applying some flags with
-     * visual impact until {@link #appTransitionReady} is called.
-     */
-    void appTransitionPending();
-
-    /**
-     * Notifies the status bar that a pending app transition has been cancelled.
-     */
-    void appTransitionCancelled();
-
-    /**
-     * Notifies the status bar that an app transition is now being executed.
+     * Notifies System UI on the specified display that an app transition is pending to delay
+     * applying some flags with visual impact until {@link #appTransitionReady} is called.
      *
+     * @param displayId the id of the display to notify
+     */
+    void appTransitionPending(int displayId);
+
+    /**
+     * Notifies System UI on the specified display that a pending app transition has been cancelled.
+     *
+     * @param displayId the id of the display to notify
+     */
+    void appTransitionCancelled(int displayId);
+
+    /**
+     * Notifies System UI on the specified display that an app transition is now being executed.
+     *
+     * @param displayId the id of the display to notify
      * @param statusBarAnimationsStartTime the desired start time for all visual animations in the
      *        status bar caused by this app transition in uptime millis
      * @param statusBarAnimationsDuration the duration for all visual animations in the status
      *        bar caused by this app transition in millis
      */
-    void appTransitionStarting(long statusBarAnimationsStartTime, long statusBarAnimationsDuration);
+    void appTransitionStarting(int displayId, long statusBarAnimationsStartTime,
+            long statusBarAnimationsDuration);
 
     /**
-     * Notifies the status bar that an app transition is done.
+     * Notifies System UI on the specified display that an app transition is done.
+     *
+     * @param displayId the id of the display to notify
      */
-    void appTransitionFinished();
+    void appTransitionFinished(int displayId);
 
     void showAssistDisclosure();
     void startAssist(in Bundle args);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index bf82dc61..5118e5f 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -41,6 +41,7 @@
     void setIcon(String slot, String iconPackage, int iconId, int iconLevel, String contentDescription);
     void setIconVisibility(String slot, boolean visible);
     void removeIcon(String slot);
+    // TODO(b/117478341): support back button change when IME is showing on a external display.
     void setImeWindowStatus(in IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher);
     void expandSettingsPanel(String subPanel);
@@ -69,7 +70,7 @@
     void onNotificationSmartRepliesAdded(in String key, in int replyCount);
     void onNotificationSmartReplySent(in String key, in int replyIndex, in CharSequence reply, boolean generatedByAssistant);
     void onNotificationSettingsViewed(String key);
-    void setSystemUiVisibility(int vis, int mask, String cause);
+    void setSystemUiVisibility(int displayId, int vis, int mask, String cause);
 
     void onGlobalActionsShown();
     void onGlobalActionsHidden();
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 4b66267..f669e94 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -32,6 +32,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.function.IntFunction;
 
 /**
  * ArrayUtils contains some methods that you can call to find out
@@ -656,4 +657,30 @@
             throw new ArrayIndexOutOfBoundsException("length=" + len + "; index=" + index);
         }
     }
+
+    /**
+     * Returns an array with values from {@code val} minus {@code null} values
+     *
+     * @param arrayConstructor typically {@code T[]::new} e.g. {@code String[]::new}
+     */
+    public static <T> T[] filterNotNull(T[] val, IntFunction<T[]> arrayConstructor) {
+        int nullCount = 0;
+        int size = size(val);
+        for (int i = 0; i < size; i++) {
+            if (val[i] == null) {
+                nullCount++;
+            }
+        }
+        if (nullCount == 0) {
+            return val;
+        }
+        T[] result = arrayConstructor.apply(size - nullCount);
+        int outIdx = 0;
+        for (int i = 0; i < size; i++) {
+            if (val[i] != null) {
+                result[outIdx++] = val[i];
+            }
+        }
+        return result;
+    }
 }
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 36fe4fc..c8834a8 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -27,6 +27,7 @@
 import android.view.IWindow;
 import android.view.IWindowSession;
 import android.view.PointerIcon;
+import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 
 import com.android.internal.os.IResultReceiver;
@@ -58,6 +59,11 @@
     }
 
     @Override
+    public void insetsControlChanged(InsetsState insetsState,
+            InsetsSourceControl[] activeControls) throws RemoteException {
+    }
+
+    @Override
     public void moved(int newX, int newY) {
     }
 
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index bc1d5cc..f9879cc 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -1056,12 +1056,18 @@
     if (rootDir == NULL) {
         rootDir = "/system";
         if (!hasDir("/system")) {
-            LOG_FATAL("No root directory specified, and /android does not exist.");
+            LOG_FATAL("No root directory specified, and /system does not exist.");
             return;
         }
         setenv("ANDROID_ROOT", rootDir, 1);
     }
 
+    const char* runtimeRootDir = getenv("ANDROID_RUNTIME_ROOT");
+    if (runtimeRootDir == NULL) {
+        LOG_FATAL("No runtime directory specified with ANDROID_RUNTIME_ROOT environment variable.");
+        return;
+    }
+
     //const char* kernelHack = getenv("LD_ASSUME_KERNEL");
     //ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
 
diff --git a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
index dcb7874..cfe742d 100644
--- a/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
+++ b/core/jni/android/graphics/HarfBuzzNGFaceSkia.cpp
@@ -59,7 +59,7 @@
 static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint, hb_position_t* width, hb_glyph_extents_t* extents)
 {
     ALOG_ASSERT(codepoint <= 0xFFFF);
-    paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    paint->setTextEncoding(kGlyphID_SkTextEncoding);
 
     SkScalar skWidth;
     SkRect skBounds;
@@ -84,7 +84,7 @@
 {
     HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData);
     SkPaint* paint = hbFontData->m_paint;
-    paint->setTextEncoding(SkPaint::kUTF32_TextEncoding);
+    paint->setTextEncoding(kUTF32_SkTextEncoding);
 
     if (unicode > 0x10ffff) {
         unicode = 0xfffd;
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index a8b0640..c249e20 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -71,7 +71,7 @@
 
 static void defaultSettingsForAndroid(Paint* paint) {
     // GlyphID encoding is required because we are using Harfbuzz shaping
-    paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
+    paint->setTextEncoding(kGlyphID_SkTextEncoding);
 }
 
 namespace PaintGlue {
@@ -321,7 +321,7 @@
         x += MinikinUtils::xOffsetForTextAlign(paint, layout);
         Paint::Align align = paint->getTextAlign();
         paint->setTextAlign(Paint::kLeft_Align);
-        paint->setTextEncoding(Paint::kGlyphID_TextEncoding);
+        paint->setTextEncoding(kGlyphID_SkTextEncoding);
         GetTextFunctor f(layout, path, x, y, paint, glyphs, pos);
         MinikinUtils::forFontRun(layout, paint, f);
         paint->setTextAlign(align);
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 1ea4ed1..12a8343b4 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -842,6 +842,18 @@
 }
 
 // ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_get_port_id(JNIEnv *env,  jobject thiz) {
+    sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
+    if (lpRecorder == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "Unable to retrieve AudioRecord pointer for getId()");
+        return (jint)AUDIO_PORT_HANDLE_NONE;
+    }
+    return (jint)lpRecorder->getPortId();
+}
+
+
+// ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 static const JNINativeMethod gMethods[] = {
     // name,               signature,  funcPtr
@@ -883,6 +895,7 @@
                                        (void *)android_media_AudioRecord_get_timestamp},
     {"native_get_active_microphones", "(Ljava/util/ArrayList;)I",
                                         (void *)android_media_AudioRecord_get_active_microphones},
+    {"native_getPortId", "()I", (void *)android_media_AudioRecord_get_port_id},
 };
 
 // field names found in android/media/AudioRecord.java
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 04f0a53..d927972 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -1284,6 +1284,17 @@
 }
 
 // ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_get_port_id(JNIEnv *env,  jobject thiz) {
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+    if (lpTrack == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                          "AudioTrack not initialized");
+        return (jint)AUDIO_PORT_HANDLE_NONE;
+    }
+    return (jint)lpTrack->getPortId();
+}
+
+// ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 static const JNINativeMethod gMethods[] = {
     // name,              signature,     funcPtr
@@ -1354,6 +1365,7 @@
             "(I)Landroid/media/VolumeShaper$State;",
                                         (void *)android_media_AudioTrack_get_volume_shaper_state},
     {"native_setPresentation", "(II)I", (void *)android_media_AudioTrack_setPresentation},
+    {"native_getPortId", "()I", (void *)android_media_AudioTrack_get_port_id},
 };
 
 
@@ -1379,7 +1391,6 @@
     }
 }
 
-
 // ----------------------------------------------------------------------------
 int register_android_media_AudioTrack(JNIEnv *env)
 {
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index d917536..4c1fc5c 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -761,6 +761,13 @@
     }
     optional SmartSelection smart_selection = 108;
 
+    message SmartSuggestions {
+      option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+      optional SettingProto service_explicitly_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+    optional SmartSuggestions smart_suggestions = 145;
+
     message Sms {
         option (android.msg_privacy).dest = DEST_EXPLICIT;
 
@@ -869,6 +876,8 @@
         // Temperature at which the high temperature warning notification should
         // be shown.
         optional SettingProto warning_temperature_level = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+        // USB temperature at which the high temperature alarm notification should be shown.
+        optional SettingProto usb_alarm_temperature_level = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional TemperatureWarning temperature_warning = 119;
 
@@ -991,5 +1000,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 145;
+    // Next tag = 146;
 }
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index 679a1d2..3767ed5 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -211,7 +211,7 @@
     repeated AppWindowTokenProto app_window_tokens = 3;
     optional bool fills_parent = 4;
     optional .android.graphics.RectProto bounds = 5;
-    optional .android.graphics.RectProto temp_inset_bounds = 6;
+    optional .android.graphics.RectProto displayed_bounds = 6;
     optional bool defer_removal = 7;
     optional int32 surface_width = 8;
     optional int32 surface_height = 9;
diff --git a/core/proto/android/service/runtime.proto b/core/proto/android/service/runtime.proto
new file mode 100644
index 0000000..ecbccef
--- /dev/null
+++ b/core/proto/android/service/runtime.proto
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 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 = "proto2";
+package android.service.runtime;
+
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "RuntimeServiceProto";
+
+// Represents dumpsys info from RuntimeService.
+message RuntimeServiceInfoProto {
+  option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  // Generic debug information to include.
+  repeated DebugEntryProto debug_entry = 1;
+}
+
+// A piece of key / value debug information.
+message DebugEntryProto {
+  option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+  optional string key = 1;
+
+  optional string string_value = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 91b9869..3018614 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3387,6 +3387,13 @@
     <permission android:name="android.permission.CONTROL_DISPLAY_SATURATION"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Allows an application to control display color transformations.
+         <p>Not for use by third-party applications.</p>
+         @hide
+         @SystemApi -->
+    <permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Allows an application to collect usage infomation about brightness slider changes.
          <p>Not for use by third-party applications.</p>
          @hide
@@ -4170,6 +4177,11 @@
     <permission android:name="android.permission.MANAGE_AUTO_FILL"
         android:protectionLevel="signature" />
 
+    <!-- @SystemApi Allows an application to manage the smart suggestions service.
+         @hide  <p>Not for use by third-party applications.</p> -->
+    <permission android:name="android.permission.MANAGE_SMART_SUGGESTIONS"
+        android:protectionLevel="signature" />
+
     <!-- Allows an app to set the theme overlay in /vendor/overlay
          being used.
          @hide  <p>Not for use by third-party applications.</p> -->
@@ -4611,6 +4623,13 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name="com.android.server.WallpaperUpdateReceiver"
+                  android:permission="android.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY">
+            <intent-filter>
+                <action android:name="android.intent.action.DEVICE_CUSTOMIZATION_READY"/>
+            </intent-filter>
+        </receiver>
+
         <service android:name="android.hardware.location.GeofenceHardwareService"
             android:permission="android.permission.LOCATION_HARDWARE"
             android:exported="false" />
diff --git a/core/res/res/layout/notification_material_reply_text.xml b/core/res/res/layout/notification_material_reply_text.xml
index 71632a2..2b15dce 100644
--- a/core/res/res/layout/notification_material_reply_text.xml
+++ b/core/res/res/layout/notification_material_reply_text.xml
@@ -39,7 +39,7 @@
             android:layout_height="wrap_content"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:visibility="gone"
-            android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
+            android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
             android:singleLine="true" />
 
     <TextView
@@ -48,7 +48,7 @@
             android:layout_height="wrap_content"
             android:layout_marginEnd="@dimen/notification_content_margin_end"
             android:visibility="gone"
-            android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
+            android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
             android:singleLine="true" />
 
     <LinearLayout
@@ -64,7 +64,7 @@
                 android:layout_weight="1"
                 android:layout_marginEnd="@dimen/notification_content_margin_end"
                 android:layout_gravity="center"
-                android:textAppearance="@style/TextAppearance.Material.Notification.Reply"
+                android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
                 android:singleLine="true" />
         <ProgressBar
             android:id="@+id/notification_material_reply_progress"
diff --git a/core/res/res/layout/notification_template_ambient_header.xml b/core/res/res/layout/notification_template_ambient_header.xml
index c00acd5..be5d9b4 100644
--- a/core/res/res/layout/notification_template_ambient_header.xml
+++ b/core/res/res/layout/notification_template_ambient_header.xml
@@ -24,5 +24,5 @@
     android:layout_height="wrap_content">
     <include
         layout="@layout/notification_template_header"
-        android:theme="@style/Theme.Material.Notification.Ambient"/>
+        android:theme="@style/Theme.DeviceDefault.Notification.Ambient"/>
 </FrameLayout>
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 4bf1ad6..5ba1cf2 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -17,7 +17,7 @@
 <!-- extends ViewGroup -->
 <NotificationHeaderView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:theme="@style/Theme.Material.Notification"
+    android:theme="@style/Theme.DeviceDefault.Notification"
     android:id="@+id/notification_header"
     android:orientation="horizontal"
     android:layout_width="wrap_content"
diff --git a/core/res/res/layout/notification_template_material_ambient.xml b/core/res/res/layout/notification_template_material_ambient.xml
index c8864c2..2c6064e 100644
--- a/core/res/res/layout/notification_template_material_ambient.xml
+++ b/core/res/res/layout/notification_template_material_ambient.xml
@@ -24,7 +24,7 @@
     android:paddingEnd="@dimen/notification_extra_margin_ambient"
     >
     <include layout="@layout/notification_template_ambient_header"
-             android:theme="@style/Theme.Material.Notification.Ambient" />
+             android:theme="@style/Theme.DeviceDefault.Notification.Ambient" />
 
     <LinearLayout
             android:id="@+id/notification_action_list_margin_target"
@@ -51,8 +51,7 @@
             android:orientation="vertical"
             >
             <TextView android:id="@+id/title"
-                android:textAppearance="@style/TextAppearance.Material.Notification.Title"
-                android:fontFamily="sans-serif"
+                android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="top|center_horizontal"
@@ -65,7 +64,7 @@
             <TextView android:id="@+id/text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
-                android:textAppearance="@style/TextAppearance.Material.Notification"
+                android:textAppearance="@style/TextAppearance.DeviceDefault.Notification"
                 android:singleLine="false"
                 android:layout_weight="1"
                 android:gravity="top|center_horizontal"
diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
index 26eb4e7..d5ea96f 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -53,7 +53,7 @@
                 android:layout_marginTop="@dimen/notification_progress_margin_top"
                 android:layout_marginBottom="6dp"/>
             <com.android.internal.widget.ImageFloatingTextView android:id="@+id/big_text"
-                style="@style/Widget.Material.Notification.Text"
+                style="@style/Widget.DeviceDefault.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="@dimen/notification_text_margin_top"
diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml
index d6f0e1d..eb89258 100644
--- a/core/res/res/layout/notification_template_material_inbox.xml
+++ b/core/res/res/layout/notification_template_material_inbox.xml
@@ -53,7 +53,7 @@
                 android:layout_marginTop="@dimen/notification_progress_margin_top"
                 android:layout_marginBottom="2dp"/>
             <TextView android:id="@+id/inbox_text0"
-                style="@style/Widget.Material.Notification.Text"
+                style="@style/Widget.DeviceDefault.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -62,7 +62,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text1"
-                style="@style/Widget.Material.Notification.Text"
+                style="@style/Widget.DeviceDefault.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -71,7 +71,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text2"
-                style="@style/Widget.Material.Notification.Text"
+                style="@style/Widget.DeviceDefault.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -80,7 +80,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text3"
-                style="@style/Widget.Material.Notification.Text"
+                style="@style/Widget.DeviceDefault.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -89,7 +89,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text4"
-                style="@style/Widget.Material.Notification.Text"
+                style="@style/Widget.DeviceDefault.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -98,7 +98,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text5"
-                style="@style/Widget.Material.Notification.Text"
+                style="@style/Widget.DeviceDefault.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
@@ -107,7 +107,7 @@
                 android:layout_weight="1"
                 />
             <TextView android:id="@+id/inbox_text6"
-                style="@style/Widget.Material.Notification.Text"
+                style="@style/Widget.DeviceDefault.Notification.Text"
                 android:layout_width="match_parent"
                 android:layout_height="0dp"
                 android:singleLine="true"
diff --git a/core/res/res/layout/notification_template_messaging_group.xml b/core/res/res/layout/notification_template_messaging_group.xml
index 0717d96..483b479 100644
--- a/core/res/res/layout/notification_template_messaging_group.xml
+++ b/core/res/res/layout/notification_template_messaging_group.xml
@@ -34,7 +34,7 @@
         android:orientation="vertical">
         <com.android.internal.widget.ImageFloatingTextView
             android:id="@+id/message_name"
-            style="@style/Widget.Material.Notification.MessagingName"
+            style="@style/Widget.DeviceDefault.Notification.MessagingName"
             android:layout_width="wrap_content"
             android:textAlignment="viewStart"
         />
diff --git a/core/res/res/layout/notification_template_messaging_text_message.xml b/core/res/res/layout/notification_template_messaging_text_message.xml
index 3611186..26c081e 100644
--- a/core/res/res/layout/notification_template_messaging_text_message.xml
+++ b/core/res/res/layout/notification_template_messaging_text_message.xml
@@ -18,5 +18,5 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/message_text"
     android:textAlignment="viewStart"
-    style="@style/Widget.Material.Notification.MessagingText"
+    style="@style/Widget.DeviceDefault.Notification.MessagingText"
 />
diff --git a/core/res/res/layout/notification_template_part_line1.xml b/core/res/res/layout/notification_template_part_line1.xml
index 6459bb8..622f080 100644
--- a/core/res/res/layout/notification_template_part_line1.xml
+++ b/core/res/res/layout/notification_template_part_line1.xml
@@ -22,7 +22,7 @@
     android:orientation="horizontal"
     >
     <TextView android:id="@+id/title"
-        android:textAppearance="@style/TextAppearance.Material.Notification.Title"
+        android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:singleLine="true"
@@ -31,7 +31,7 @@
         android:textAlignment="viewStart"
         />
     <TextView android:id="@+id/text_line_1"
-        style="@style/Widget.Material.Notification.Text"
+        style="@style/Widget.DeviceDefault.Notification.Text"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="end|bottom"
diff --git a/core/res/res/layout/notification_template_text.xml b/core/res/res/layout/notification_template_text.xml
index 3b27666..01b14ae 100644
--- a/core/res/res/layout/notification_template_text.xml
+++ b/core/res/res/layout/notification_template_text.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 <com.android.internal.widget.ImageFloatingTextView xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/Widget.Material.Notification.Text"
+    style="@style/Widget.DeviceDefault.Notification.Text"
     android:id="@+id/text"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1d80961..c62071b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2125,6 +2125,9 @@
          during initialization when the setting is still null. -->
     <bool name="config_dozeAlwaysOnEnabled">true</bool>
 
+    <!-- If AOD can show an ambient version of the wallpaper -->
+    <bool name="config_dozeSupportsAodWallpaper">true</bool>
+
     <!-- Whether the display blanks itself when transitioning from a doze to a non-doze state -->
     <bool name="config_displayBlanksAfterDoze">false</bool>
 
@@ -3347,6 +3350,14 @@
     -->
     <string name="config_defaultTextClassifierPackage" translatable="false"></string>
 
+    <!-- The package name for the system's smart suggestion service.
+         This service must be trusted, as it can be activated without explicit consent of the user.
+         If no service with the specified name exists on the device, content capture and
+         smart suggestions will be disabled.
+         Example: "com.android.intelligence/.SmartSuggestionsService"
+    -->
+    <string name="config_defaultSmartSuggestionsService" translatable="false"></string>
+
     <!-- Whether the device uses the default focus highlight when focus state isn't specified. -->
     <bool name="config_useDefaultFocusHighlight">true</bool>
 
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index d722961..c03d570 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -113,6 +113,15 @@
     <style name="Widget.DeviceDefault.ListView.White" parent="Widget.Material.ListView.White"/>
     <style name="Widget.DeviceDefault.MediaRouteButton" parent="Widget.Material.MediaRouteButton" />
     <style name="Widget.DeviceDefault.NumberPicker" parent="Widget.Material.NumberPicker"/>
+    <style name="Widget.DeviceDefault.Notification.Text" parent="Widget.Material.Notification.Text">
+        <item name="textAppearance">@style/TextAppearance.DeviceDefault.Notification</item>
+    </style>
+    <style name="Widget.DeviceDefault.Notification.MessagingText" parent="Widget.Material.Notification.MessagingText">
+        <item name="textAppearance">@style/TextAppearance.DeviceDefault.Notification</item>
+    </style>
+    <style name="Widget.DeviceDefault.Notification.MessagingName" parent="Widget.Material.Notification.MessagingName">
+        <item name="textAppearance">@style/TextAppearance.DeviceDefault.Notification.Title</item>
+    </style>
     <style name="Widget.DeviceDefault.PreferenceFrameLayout" parent="Widget.Material.PreferenceFrameLayout"/>
     <style name="Widget.DeviceDefault.ProgressBar.Inverse" parent="Widget.Material.ProgressBar.Inverse"/>
     <style name="Widget.DeviceDefault.ProgressBar.Large.Inverse" parent="Widget.Material.ProgressBar.Large.Inverse"/>
@@ -250,6 +259,16 @@
     <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" parent="TextAppearance.Material.Widget.ActionBar.Title">
         <item name="fontFamily">@string/config_headlineFontFamilyMedium</item>
     </style>
+
+    <!-- Notification Styles -->
+    <style name="TextAppearance.DeviceDefault.Notification" parent="TextAppearance.Material.Notification">
+        <item name="fontFamily">@string/config_headlineFontFamily</item>
+    </style>
+    <style name="TextAppearance.DeviceDefault.Notification.Title" parent="TextAppearance.Material.Notification.Title">
+        <item name="fontFamily">@string/config_headlineFontFamilyMedium</item>
+    </style>
+    <style name="TextAppearance.DeviceDefault.Notification.Reply" parent="TextAppearance.Material.Notification.Reply" />
+
     <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" parent="TextAppearance.Material.Widget.ActionBar.Subtitle"/>
     <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title" parent="TextAppearance.Material.Widget.ActionMode.Title"/>
     <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle" parent="TextAppearance.Material.Widget.ActionMode.Subtitle"/>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 67b3c92..5a7199d 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -1313,4 +1313,5 @@
         <item name="gravity">top|center_horizontal</item>
     </style>
 
+
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 783f1f3..6854a84e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3265,6 +3265,7 @@
   <java-symbol type="string" name="notification_channel_do_not_disturb" />
   <java-symbol type="string" name="config_defaultAutofillService" />
   <java-symbol type="string" name="config_defaultTextClassifierPackage" />
+  <java-symbol type="string" name="config_defaultSmartSuggestionsService" />
 
   <java-symbol type="string" name="notification_channel_foreground_service" />
   <java-symbol type="string" name="foreground_service_app_in_background" />
@@ -3310,6 +3311,7 @@
   <java-symbol type="integer" name="config_autoGroupAtCount" />
   <java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
   <java-symbol type="bool" name="config_dozeAlwaysOnEnabled" />
+  <java-symbol type="bool" name="config_dozeSupportsAodWallpaper" />
   <java-symbol type="bool" name="config_displayBlanksAfterDoze" />
   <java-symbol type="bool" name="config_displayBrightnessBucketsInDoze" />
   <java-symbol type="integer" name="config_storageManagerDaystoRetainDefault" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index fa009bd..fec101a 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1724,4 +1724,10 @@
         <item name="layout_gravity">center</item>
     </style>
 
+    <style name="Theme.DeviceDefault.Notification" parent="@style/Theme.Material.Notification">
+    </style>
+
+    <style name="Theme.DeviceDefault.Notification.Ambient" parent="@style/Theme.Material.Notification.Ambient">
+    </style>
+
 </resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 3b650e5..46d4a47 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -91,6 +91,8 @@
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
     <uses-permission android:name="android.permission.KILL_UID" />
 
+    <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+
     <!-- location test permissions -->
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index a8f9e8a..ed9c3d5 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -415,6 +415,7 @@
                     Settings.Global.SHOW_TEMPERATURE_WARNING,
                     Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
                     Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
+                    Settings.Global.SMART_SUGGESTIONS_SERVICE_EXPLICITLY_ENABLED,
                     Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED,
                     Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
                     Settings.Global.SMS_OUTGOING_CHECK_MAX_COUNT,
@@ -477,6 +478,7 @@
                     Settings.Global.USER_SWITCHER_ENABLED,
                     Settings.Global.NETWORK_ACCESS_TIMEOUT_MS,
                     Settings.Global.WARNING_TEMPERATURE,
+                    Settings.Global.USB_ALARM_TEMPERATURE,
                     Settings.Global.WEBVIEW_DATA_REDUCTION_PROXY_KEY,
                     Settings.Global.WEBVIEW_FALLBACK_LOGIC_ENABLED,
                     Settings.Global.WEBVIEW_MULTIPROCESS,
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
new file mode 100644
index 0000000..ed80cd7
--- /dev/null
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 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;
+
+import static android.view.InsetsState.TYPE_TOP_BAR;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@FlakyTest(detail = "Promote once confirmed non-flaky")
+@RunWith(AndroidJUnit4.class)
+public class InsetsControllerTest {
+
+    private InsetsController mController = new InsetsController();
+
+    private SurfaceSession mSession = new SurfaceSession();
+    private SurfaceControl mLeash;
+
+    @Before
+    public void setup() {
+        mLeash = new SurfaceControl.Builder(mSession)
+                .setName("testSurface")
+                .build();
+    }
+
+    @Test
+    public void testControlsChanged() {
+        InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+        mController.onControlsChanged(new InsetsSourceControl[] { control });
+        assertEquals(mLeash,
+                mController.getSourceConsumer(TYPE_TOP_BAR).getControl().getLeash());
+    }
+
+    @Test
+    public void testControlsRevoked() {
+        InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+        mController.onControlsChanged(new InsetsSourceControl[] { control });
+        mController.onControlsChanged(new InsetsSourceControl[0]);
+        assertNull(mController.getSourceConsumer(TYPE_TOP_BAR).getControl());
+    }
+}
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
new file mode 100644
index 0000000..5a20ba2
--- /dev/null
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 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;
+
+import static android.view.InsetsState.TYPE_TOP_BAR;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.SurfaceControl.Transaction;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@Presubmit
+@FlakyTest(detail = "Promote once confirmed non-flaky")
+@RunWith(AndroidJUnit4.class)
+public class InsetsSourceConsumerTest {
+
+    private InsetsSourceConsumer mConsumer;
+
+    private SurfaceSession mSession = new SurfaceSession();
+    private SurfaceControl mLeash;
+    @Mock Transaction mMockTransaction;
+    @Mock InsetsController mMockController;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mLeash = new SurfaceControl.Builder(mSession)
+                .setName("testSurface")
+                .build();
+        mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(),
+                () -> mMockTransaction);
+        mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+    }
+
+    @Test
+    public void testHide() {
+        mConsumer.hide();
+        verify(mMockTransaction).hide(eq(mLeash));
+    }
+
+    @Test
+    public void testShow() {
+        mConsumer.hide();
+        mConsumer.show();
+        verify(mMockTransaction, atLeastOnce()).show(eq(mLeash));
+    }
+
+    @Test
+    public void testRestore() {
+        mConsumer.setControl(null);
+        reset(mMockTransaction);
+        mConsumer.hide();
+        verifyZeroInteractions(mMockTransaction);
+        mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+        verify(mMockTransaction).hide(eq(mLeash));
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 8691e73..02a76f8 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -17,6 +17,7 @@
 package com.android.internal.os;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.os.Binder;
 import android.platform.test.annotations.Presubmit;
@@ -387,8 +388,7 @@
 
     @Test
     public void testNoDataCollectedBeforeInitialDeviceStateSet() {
-        TestBinderCallsStats bcs = new TestBinderCallsStats();
-        bcs.setDeviceState(null);
+        TestBinderCallsStats bcs = new TestBinderCallsStats(null);
         bcs.setDetailedTracking(true);
         Binder binder = new Binder();
         CallSession callSession = bcs.callStarted(binder, 1);
@@ -613,6 +613,27 @@
         assertEquals(CALLING_UID, callStats.callingUid);
     }
 
+    @Test
+    public void testAddsDebugEntries() {
+        long startTime = System.currentTimeMillis();
+        TestBinderCallsStats bcs = new TestBinderCallsStats();
+        bcs.setAddDebugEntries(true);
+        ArrayList<BinderCallsStats.ExportedCallStat> callStats = bcs.getExportedCallStats();
+        assertEquals(3, callStats.size());
+        BinderCallsStats.ExportedCallStat debugEntry1 = callStats.get(0);
+        assertEquals("", debugEntry1.className);
+        assertEquals("__DEBUG_start_time_millis", debugEntry1.methodName);
+        assertTrue(startTime <= debugEntry1.maxReplySizeBytes);
+        BinderCallsStats.ExportedCallStat debugEntry2 = callStats.get(1);
+        assertEquals("", debugEntry2.className);
+        assertEquals("__DEBUG_end_time_millis", debugEntry2.methodName);
+        assertTrue(debugEntry1.maxReplySizeBytes <= debugEntry2.maxReplySizeBytes);
+        BinderCallsStats.ExportedCallStat debugEntry3 = callStats.get(2);
+        assertEquals("", debugEntry3.className);
+        assertEquals("__DEBUG_battery_time_millis", debugEntry3.methodName);
+        assertTrue(debugEntry3.maxReplySizeBytes >= 0);
+    }
+
     class TestBinderCallsStats extends BinderCallsStats {
         public int callingUid = CALLING_UID;
         public int workSourceUid = WORKSOURCE_UID;
@@ -620,6 +641,10 @@
         public long elapsedTime = 0;
 
         TestBinderCallsStats() {
+            this(mDeviceState);
+        }
+
+        TestBinderCallsStats(CachedDeviceState deviceState) {
             // Make random generator not random.
             super(new Injector() {
                 public Random getRandomGenerator() {
@@ -633,7 +658,10 @@
                 }
             });
             setSamplingInterval(1);
-            setDeviceState(mDeviceState.getReadonlyClient());
+            setAddDebugEntries(false);
+            if (deviceState != null) {
+                setDeviceState(deviceState.getReadonlyClient());
+            }
         }
 
         @Override
diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
index 31dde5c..3d7801c 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -273,8 +273,7 @@
 
     @Test
     public void testDataNotCollectedBeforeDeviceStateSet() {
-        TestableLooperStats looperStats = new TestableLooperStats(1, 100);
-        looperStats.setDeviceState(null);
+        TestableLooperStats looperStats = new TestableLooperStats(1, 100, null);
 
         Object token1 = looperStats.messageDispatchStarting();
         looperStats.messageDispatched(token1, mHandlerFirst.obtainMessage(1000));
@@ -439,7 +438,7 @@
         looperStats.messageDispatched(token, message);
 
         List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
-        assertThat(entries).hasSize(3);
+        assertThat(entries).hasSize(4);
         LooperStats.ExportedEntry debugEntry1 = entries.get(1);
         assertThat(debugEntry1.handlerClassName).isEqualTo("");
         assertThat(debugEntry1.messageName).isEqualTo("__DEBUG_start_time_millis");
@@ -448,6 +447,10 @@
         assertThat(debugEntry2.handlerClassName).isEqualTo("");
         assertThat(debugEntry2.messageName).isEqualTo("__DEBUG_end_time_millis");
         assertThat(debugEntry2.maxDelayMillis).isAtLeast(looperStats.getStartTimeMillis());
+        LooperStats.ExportedEntry debugEntry3 = entries.get(3);
+        assertThat(debugEntry3.handlerClassName).isEqualTo("");
+        assertThat(debugEntry3.messageName).isEqualTo("__DEBUG_battery_time_millis");
+        assertThat(debugEntry3.maxDelayMillis).isAtLeast(0L);
     }
 
     private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) {
@@ -468,10 +471,16 @@
         private int mSamplingInterval;
 
         TestableLooperStats(int samplingInterval, int sizeCap) {
+            this(samplingInterval, sizeCap, mDeviceState);
+        }
+
+        TestableLooperStats(int samplingInterval, int sizeCap, CachedDeviceState deviceState) {
             super(samplingInterval, sizeCap);
-            this.mSamplingInterval = samplingInterval;
-            this.setDeviceState(mDeviceState.getReadonlyClient());
-            this.setAddDebugEntries(false);
+            mSamplingInterval = samplingInterval;
+            setAddDebugEntries(false);
+            if (deviceState != null) {
+                setDeviceState(deviceState.getReadonlyClient());
+            }
         }
 
         void tickRealtime(long micros) {
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 9e4ea32..f237344 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -281,6 +281,7 @@
         <permission name="android.permission.WRITE_APN_SETTINGS"/>
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+        <permission name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.settings.intelligence">
@@ -408,6 +409,7 @@
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
         <permission name="android.permission.WRITE_SECURE_SETTINGS"/>
         <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"/>
+        <permission name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.tv">
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index bf114b9..2227cf5 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -1779,6 +1779,36 @@
     }
 
     /**
+     * <p>Computes the chromaticity coordinates of a CIE series D illuminant
+     * from the specified correlated color temperature (CCT). The specified CCT
+     * must be greater than 0. A meaningful CCT range is [4000, 25000].</p>
+     *
+     * <p>The transform is computed using the methods referred to in Kang et
+     * al., <i>Design of Advanced Color - Temperature Control System for HDTV
+     * Applications</i>, Journal of Korean Physical Society 41, 865-871
+     * (2002).</p>
+     *
+     * @param cct The correlated color temperature, in Kelvin
+     * @return Corresponding XYZ values
+     * @throws IllegalArgumentException If cct is invalid
+     */
+    @NonNull
+    @Size(3)
+    public static float[] cctToIlluminantdXyz(@IntRange(from = 1) int cct) {
+        if (cct < 1) {
+            throw new IllegalArgumentException("Temperature must be greater than 0");
+        }
+
+        final float icct = 1.0f / cct;
+        final float icct2 = icct * icct;
+        final float x = cct <= 7000.0f ?
+            0.244063f + 0.09911e3f * icct + 2.9678e6f * icct2 - 4.6070e9f * icct2 * icct :
+            0.237040f + 0.24748e3f * icct + 1.9018e6f * icct2 - 2.0064e9f * icct2 * icct;
+        final float y = -3.0f * x * x + 2.87f * x - 0.275f;
+        return xyYToXyz(new float[] {x, y});
+    }
+
+    /**
      * <p>Computes the chromatic adaptation transform from the specified
      * source white point to the specified destination white point.</p>
      *
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index dbe6e8f..9b86b77 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -249,7 +249,22 @@
             if (familyBuilder == null) {
                 return Typeface.DEFAULT;
             }
-            typeface = new Typeface.CustomFallbackBuilder(familyBuilder.build()).build();
+            final FontFamily family = familyBuilder.build();
+            final FontStyle normal = new FontStyle(FontStyle.FONT_WEIGHT_NORMAL,
+                    FontStyle.FONT_SLANT_UPRIGHT);
+            Font bestFont = family.getFont(0);
+            int bestScore = normal.getMatchScore(bestFont.getStyle());
+            for (int i = 1; i < family.getSize(); ++i) {
+                final Font candidate = family.getFont(i);
+                final int score = normal.getMatchScore(candidate.getStyle());
+                if (score < bestScore) {
+                    bestFont = candidate;
+                    bestScore = score;
+                }
+            }
+            typeface = new Typeface.CustomFallbackBuilder(family)
+                    .setStyle(bestFont.getStyle())
+                    .build();
         } catch (IOException e) {
             typeface = Typeface.DEFAULT;
         }
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index dea2f45..cb12a7c 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.app.ActivityThread;
 import android.content.pm.ActivityInfo.Config;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -150,11 +151,14 @@
      */
     AdaptiveIconDrawable(@Nullable LayerState state, @Nullable Resources res) {
         mLayerState = createConstantState(state, res);
-
-        if (sMask == null) {
-            sMask = PathParser.createPathFromPathData(
-                Resources.getSystem().getString(R.string.config_icon_mask));
-        }
+        // config_icon_mask from context bound resource may have been chaged using
+        // OverlayManager. Read that one first.
+        Resources r = ActivityThread.currentActivityThread() == null
+                ? Resources.getSystem()
+                : ActivityThread.currentActivityThread().getApplication().getResources();
+        // TODO: either make sMask update only when config_icon_mask changes OR
+        // get rid of it all-together in layoutlib
+        sMask = PathParser.createPathFromPathData(r.getString(R.string.config_icon_mask));
         mMask = new Path(sMask);
         mMaskScaleOnly = new Path(mMask);
         mMaskMatrix = new Matrix();
diff --git a/graphics/java/android/graphics/fonts/FontStyle.java b/graphics/java/android/graphics/fonts/FontStyle.java
index 82fc7ac..af517d6 100644
--- a/graphics/java/android/graphics/fonts/FontStyle.java
+++ b/graphics/java/android/graphics/fonts/FontStyle.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.IntRange;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 
 import com.android.internal.util.Preconditions;
@@ -232,6 +233,16 @@
         return mSlant;
     }
 
+    /**
+     * Compute the matching score for another style.
+     *
+     * The smaller is better.
+     * @hide
+     */
+    public int getMatchScore(@NonNull FontStyle o) {
+        return Math.abs((getWeight() - o.getWeight())) / 100 + (getSlant() == o.getSlant() ? 0 : 2);
+    }
+
     @Override
     public boolean equals(@Nullable Object o) {
         if (o == this) {
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 7ab12b1..ad9ec02 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -217,10 +217,19 @@
   ATRACE_NAME("AssetManager::GetResourceConfigurations");
   std::set<ResTable_config> configurations;
   for (const PackageGroup& package_group : package_groups_) {
+    bool found_system_package = false;
     for (const ConfiguredPackage& package : package_group.packages_) {
       if (exclude_system && package.loaded_package_->IsSystem()) {
+        found_system_package = true;
         continue;
       }
+
+      if (exclude_system && package.loaded_package_->IsOverlay() && found_system_package) {
+        // Overlays must appear after the target package to take effect. Any overlay found in the
+        // same package as a system package is able to overlay system resources.
+        continue;
+      }
+
       package.loaded_package_->CollectConfigurations(exclude_mipmap, &configurations);
     }
   }
@@ -232,10 +241,19 @@
   ATRACE_NAME("AssetManager::GetResourceLocales");
   std::set<std::string> locales;
   for (const PackageGroup& package_group : package_groups_) {
+    bool found_system_package = false;
     for (const ConfiguredPackage& package : package_group.packages_) {
       if (exclude_system && package.loaded_package_->IsSystem()) {
+        found_system_package = true;
         continue;
       }
+
+      if (exclude_system && package.loaded_package_->IsOverlay() && found_system_package) {
+        // Overlays must appear after the target package to take effect. Any overlay found in the
+        // same package as a system package is able to overlay system resources.
+        continue;
+      }
+
       package.loaded_package_->CollectLocales(merge_equivalent_languages, &locales);
     }
   }
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index 68d216d..c20c720 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -583,7 +583,65 @@
           loaded_package->dynamic_package_map_.emplace_back(std::move(package_name),
                                                             dtohl(entry_iter->packageId));
         }
+      } break;
 
+      case RES_TABLE_OVERLAYABLE_TYPE: {
+        const ResTable_overlayable_header* header =
+            child_chunk.header<ResTable_overlayable_header>();
+        if (header == nullptr) {
+          LOG(ERROR) << "RES_TABLE_OVERLAYABLE_TYPE too small.";
+          return {};
+        }
+
+        // Iterate over the overlayable policy chunks
+        ChunkIterator overlayable_iter(child_chunk.data_ptr(), child_chunk.data_size());
+        while (overlayable_iter.HasNext()) {
+          const Chunk overlayable_child_chunk = overlayable_iter.Next();
+
+          switch (overlayable_child_chunk.type()) {
+            case RES_TABLE_OVERLAYABLE_POLICY_TYPE: {
+              const ResTable_overlayable_policy_header* policy_header =
+                  overlayable_child_chunk.header<ResTable_overlayable_policy_header>();
+              if (policy_header == nullptr) {
+                LOG(ERROR) << "RES_TABLE_OVERLAYABLE_POLICY_TYPE too small.";
+                return {};
+              }
+
+              if ((overlayable_child_chunk.data_size() / sizeof(ResTable_ref))
+                  < dtohl(policy_header->entry_count)) {
+                LOG(ERROR) <<  "RES_TABLE_OVERLAYABLE_POLICY_TYPE too small to hold entries.";
+                return {};
+              }
+
+              // Retrieve all the ids belonging to this policy
+              std::unordered_set<uint32_t> ids;
+              const auto ids_begin =
+                  reinterpret_cast<const ResTable_ref*>(overlayable_child_chunk.data_ptr());
+              const auto ids_end = ids_begin + dtohl(policy_header->entry_count);
+              for (auto id_iter = ids_begin; id_iter != ids_end; ++id_iter) {
+                ids.insert(dtohl(id_iter->ident));
+              }
+
+              // Add the pairing of overlayable properties to resource ids to the package
+              OverlayableInfo overlayable_info;
+              overlayable_info.policy_flags = policy_header->policy_flags;
+              loaded_package->overlayable_infos_.push_back(std::make_pair(overlayable_info, ids));
+              break;
+            }
+
+            default:
+              LOG(WARNING) << StringPrintf("Unknown chunk type '%02x'.", chunk.type());
+              break;
+          }
+        }
+
+        if (overlayable_iter.HadError()) {
+          LOG(ERROR) << StringPrintf("Error parsing RES_TABLE_OVERLAYABLE_POLICY_TYPE: %s",
+                                     overlayable_iter.GetLastError().c_str());
+          if (overlayable_iter.HadFatalError()) {
+            return {};
+          }
+        }
       } break;
 
       default:
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 2fe98b0..63b2527 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -7076,7 +7076,7 @@
         }
     }
 
-    const auto& getTypeMapping() const {
+    const std::map<uint8_t, std::set<std::pair<uint32_t, uint32_t>>>& getTypeMapping() const {
         return mTypeMapping->mData;
     }
 
@@ -7137,9 +7137,6 @@
 
     const PackageGroup* packageGroup = mPackageGroups[0];
 
-    // the number of resources overlaid that were not explicitly marked overlayable
-    size_t forcedOverlayCount = 0u;
-
     // find the resources that exist in both packages
     auto typeMapping = std::make_unique<IdmapTypeMapping>();
     for (size_t typeIndex = 0; typeIndex < packageGroup->types.size(); ++typeIndex) {
@@ -7170,11 +7167,6 @@
                 continue;
             }
 
-            if ((dtohl(typeConfigs->typeSpecFlags[entryIndex]) &
-                    ResTable_typeSpec::SPEC_OVERLAYABLE) == 0) {
-                ++forcedOverlayCount;
-            }
-
             typeMapping->add(target_resid, overlay_resid);
         }
     }
@@ -7243,10 +7235,6 @@
         typeData += entryCount * 2;
     }
 
-    if (forcedOverlayCount > 0) {
-        ALOGW("idmap: overlaid %zu resources not marked overlayable", forcedOverlayCount);
-    }
-
     return NO_ERROR;
 }
 
diff --git a/libs/androidfw/include/androidfw/Chunk.h b/libs/androidfw/include/androidfw/Chunk.h
index 99a52dc..a0f2343 100644
--- a/libs/androidfw/include/androidfw/Chunk.h
+++ b/libs/androidfw/include/androidfw/Chunk.h
@@ -89,7 +89,9 @@
         len_(len),
         last_error_(nullptr) {
     CHECK(next_chunk_ != nullptr) << "data can't be nullptr";
-    VerifyNextChunk();
+    if (len_ != 0) {
+      VerifyNextChunk();
+    }
   }
 
   Chunk Next();
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index 349b379..8c5c3b7 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -20,6 +20,7 @@
 #include <memory>
 #include <set>
 #include <vector>
+#include <unordered_set>
 
 #include "android-base/macros.h"
 
@@ -76,6 +77,10 @@
 // TypeSpecPtr is a managed pointer that knows how to delete itself.
 using TypeSpecPtr = util::unique_cptr<TypeSpec>;
 
+struct OverlayableInfo {
+  uint32_t policy_flags;
+};
+
 class LoadedPackage {
  public:
   class iterator {
@@ -216,6 +221,18 @@
     }
   }
 
+  // Retrieve the overlayable properties of the specified resource. If the resource is not
+  // overlayable, this will return a null pointer.
+  const OverlayableInfo* GetOverlayableInfo(uint32_t resid) const {
+    for (const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>& overlayable_info_ids
+        : overlayable_infos_) {
+      if (overlayable_info_ids.second.find(resid) != overlayable_info_ids.second.end()) {
+        return &overlayable_info_ids.first;
+      }
+    }
+    return nullptr;
+  }
+
  private:
   DISALLOW_COPY_AND_ASSIGN(LoadedPackage);
 
@@ -233,6 +250,7 @@
   ByteBucketArray<TypeSpecPtr> type_specs_;
   ByteBucketArray<uint32_t> resource_ids_;
   std::vector<DynamicPackageEntry> dynamic_package_map_;
+  std::vector<const std::pair<OverlayableInfo, std::unordered_set<uint32_t>>> overlayable_infos_;
 };
 
 // Read-only view into a resource table. This class validates all data
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index ad33fcf..91261aa 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -234,7 +234,9 @@
     RES_TABLE_PACKAGE_TYPE      = 0x0200,
     RES_TABLE_TYPE_TYPE         = 0x0201,
     RES_TABLE_TYPE_SPEC_TYPE    = 0x0202,
-    RES_TABLE_LIBRARY_TYPE      = 0x0203
+    RES_TABLE_LIBRARY_TYPE      = 0x0203,
+    RES_TABLE_OVERLAYABLE_TYPE  = 0x0204,
+    RES_TABLE_OVERLAYABLE_POLICY_TYPE = 0x0205,
 };
 
 /**
@@ -1354,10 +1356,6 @@
     enum : uint32_t {
         // Additional flag indicating an entry is public.
         SPEC_PUBLIC = 0x40000000u,
-
-        // Additional flag indicating an entry is overlayable at runtime.
-        // Added in Android-P.
-        SPEC_OVERLAYABLE = 0x80000000u,
     };
 };
 
@@ -1607,6 +1605,49 @@
     uint16_t packageName[128];
 };
 
+/**
+ * Specifies the set of resources that are explicitly allowed to be overlaid by RROs.
+ */
+struct ResTable_overlayable_header
+{
+  struct ResChunk_header header;
+};
+
+/**
+ * Holds a list of resource ids that are protected from being overlaid by a set of policies. If
+ * the overlay fulfils at least one of the policies, then the overlay can overlay the list of
+ * resources.
+ */
+struct ResTable_overlayable_policy_header
+{
+  struct ResChunk_header header;
+
+  enum PolicyFlags {
+    // Any overlay can overlay these resources.
+    POLICY_PUBLIC = 0x00000001,
+
+    // The overlay must reside of the system partition or must have existed on the system partition
+    // before an upgrade to overlay these resources.
+    POLICY_SYSTEM_PARTITION = 0x00000002,
+
+    // The overlay must reside of the vendor partition or must have existed on the vendor partition
+    // before an upgrade to overlay these resources.
+    POLICY_VENDOR_PARTITION = 0x00000004,
+
+    // The overlay must reside of the product partition or must have existed on the product
+    // partition before an upgrade to overlay these resources.
+    POLICY_PRODUCT_PARTITION = 0x00000008,
+
+    // The overlay must reside of the product services partition or must have existed on the product
+    // services partition before an upgrade to overlay these resources.
+    POLICY_PRODUCT_SERVICES_PARTITION = 0x00000010,
+  };
+  uint32_t policy_flags;
+
+  // The number of ResTable_ref that follow this header.
+  uint32_t entry_count;
+};
+
 struct alignas(uint32_t) Idmap_header {
   // Always 0x504D4449 ('IDMP')
   uint32_t magic;
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index ffa4836..441356b 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -22,12 +22,14 @@
 #include "TestHelpers.h"
 #include "data/basic/R.h"
 #include "data/libclient/R.h"
+#include "data/overlayable/R.h"
 #include "data/sparse/R.h"
 #include "data/styles/R.h"
 
 namespace app = com::android::app;
 namespace basic = com::android::basic;
 namespace libclient = com::android::libclient;
+namespace overlayable = com::android::overlayable;
 namespace sparse = com::android::sparse;
 
 using ::android::base::ReadFileToString;
@@ -273,10 +275,44 @@
   ASSERT_THAT(LoadedPackage::GetEntry(type_spec->types[0], 0x0000), NotNull());
 }
 
-// structs with size fields (like Res_value, ResTable_entry) should be
-// backwards and forwards compatible (aka checking the size field against
-// sizeof(Res_value) might not be backwards compatible.
-TEST(LoadedArscTest, LoadingShouldBeForwardsAndBackwardsCompatible) { ASSERT_TRUE(false); }
+TEST(LoadedArscTest, LoadOverlayable) {
+  std::string contents;
+  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlayable/overlayable.apk",
+                                      "resources.arsc", &contents));
+
+  std::unique_ptr<const LoadedArsc> loaded_arsc =
+      LoadedArsc::Load(StringPiece(contents), nullptr /*loaded_idmap*/, false /*system*/,
+                       false /*load_as_shared_library*/);
+
+  ASSERT_THAT(loaded_arsc, NotNull());
+  const LoadedPackage* package = loaded_arsc->GetPackageById(
+      get_package_id(overlayable::R::string::not_overlayable));
+
+  const OverlayableInfo* info = package->GetOverlayableInfo(
+      overlayable::R::string::not_overlayable);
+  ASSERT_THAT(info, IsNull());
+
+  info = package->GetOverlayableInfo(overlayable::R::string::overlayable1);
+  ASSERT_THAT(info, NotNull());
+  EXPECT_THAT(info->policy_flags, Eq(ResTable_overlayable_policy_header::POLICY_PUBLIC));
+
+  info = package->GetOverlayableInfo(overlayable::R::string::overlayable2);
+  ASSERT_THAT(info, NotNull());
+  EXPECT_THAT(info->policy_flags,
+              Eq(ResTable_overlayable_policy_header::POLICY_SYSTEM_PARTITION
+                 | ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION));
+
+  info = package->GetOverlayableInfo(overlayable::R::string::overlayable3);
+  ASSERT_THAT(info, NotNull());
+  EXPECT_THAT(info->policy_flags,
+              Eq(ResTable_overlayable_policy_header::POLICY_VENDOR_PARTITION
+                 | ResTable_overlayable_policy_header::POLICY_PRODUCT_SERVICES_PARTITION
+                 | ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION));
+
+  info = package->GetOverlayableInfo(overlayable::R::string::overlayable4);
+  ASSERT_THAT(info, NotNull());
+  EXPECT_THAT(info->policy_flags, Eq(ResTable_overlayable_policy_header::POLICY_PUBLIC));
+}
 
 TEST(LoadedArscTest, ResourceIdentifierIterator) {
   std::string contents;
@@ -326,4 +362,9 @@
   ASSERT_EQ(end, iter);
 }
 
+// structs with size fields (like Res_value, ResTable_entry) should be
+// backwards and forwards compatible (aka checking the size field against
+// sizeof(Res_value) might not be backwards compatible.
+TEST(LoadedArscTest, LoadingShouldBeForwardsAndBackwardsCompatible) { ASSERT_TRUE(false); }
+
 }  // namespace android
diff --git a/libs/androidfw/tests/data/overlay/overlay.apk b/libs/androidfw/tests/data/overlay/overlay.apk
index 33f9611..d37874d 100644
--- a/libs/androidfw/tests/data/overlay/overlay.apk
+++ b/libs/androidfw/tests/data/overlay/overlay.apk
Binary files differ
diff --git a/packages/SystemUI/res/anim/system_in.xml b/libs/androidfw/tests/data/overlayable/AndroidManifest.xml
similarity index 69%
rename from packages/SystemUI/res/anim/system_in.xml
rename to libs/androidfw/tests/data/overlayable/AndroidManifest.xml
index 630fd72..abc2a45 100644
--- a/packages/SystemUI/res/anim/system_in.xml
+++ b/libs/androidfw/tests/data/overlayable/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
@@ -14,9 +14,8 @@
      limitations under the License.
 -->
 
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.overlayable">
+    <application>
+    </application>
+</manifest>
diff --git a/libs/androidfw/tests/data/overlayable/R.h b/libs/androidfw/tests/data/overlayable/R.h
new file mode 100644
index 0000000..e46e264d
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/R.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef TESTS_DATA_OVERLAYABLE_R_H_
+#define TESTS_DATA_OVERLAYABLE_R_H_
+
+#include <cstdint>
+
+namespace com {
+namespace android {
+namespace overlayable {
+
+struct R {
+  struct string {
+    enum : uint32_t {
+      not_overlayable = 0x7f010000,
+      overlayable1 = 0x7f010001,
+      overlayable2 = 0x7f010002,
+      overlayable3 = 0x7f010003,
+      overlayable4 = 0x7f010004,
+    };
+  };
+};
+
+}  // namespace overlayable
+}  // namespace android
+}  // namespace com
+
+#endif /* TESTS_DATA_OVERLAYABLE_R_H_ */
diff --git a/libs/androidfw/tests/data/overlayable/build b/libs/androidfw/tests/data/overlayable/build
new file mode 100755
index 0000000..98fdc51
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/build
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# Copyright (C) 2018 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.
+#
+
+set -e
+
+aapt2 compile --dir res -o compiled.flata
+aapt2 link --manifest AndroidManifest.xml -o overlayable.apk compiled.flata
+rm compiled.flata
diff --git a/libs/androidfw/tests/data/overlayable/overlayable.apk b/libs/androidfw/tests/data/overlayable/overlayable.apk
new file mode 100644
index 0000000..85ab4be
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/overlayable.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml b/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml
new file mode 100644
index 0000000..11aa735
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/res/values/overlayable.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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>
+<overlayable>
+    <!-- Any overlay can overlay the value of @string/overlayable1 -->
+    <item type="string" name="overlayable1" />
+
+    <!-- Any overlay on the product or system partition can overlay the value of
+        @string/overlayable2 -->
+    <policy type="product|system">
+        <item type="string" name="overlayable2" />
+    </policy>
+
+    <!-- Any overlay can overlay the value of @string/overlayable4 -->
+    <policy type="public">
+        <item type="string" name="overlayable4" />
+    </policy>
+</overlayable>
+
+<overlayable>
+    <!-- Any overlay on the product_services, vendor, or product partition can overlay the value of
+   @string/overlayable3 -->
+    <policy type="product_services|vendor|product">
+        <item type="string" name="overlayable3" />
+    </policy>
+</overlayable>
+</resources>
\ No newline at end of file
diff --git a/libs/androidfw/tests/data/overlayable/res/values/public.xml b/libs/androidfw/tests/data/overlayable/res/values/public.xml
new file mode 100644
index 0000000..5676d7c
--- /dev/null
+++ b/libs/androidfw/tests/data/overlayable/res/values/public.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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>
+    <public type="string" name="not_overlayable" id="0x7f010000" />
+    <public type="string" name="overlayable1" id="0x7f010001" />
+    <public type="string" name="overlayable2" id="0x7f010002" />
+    <public type="string" name="overlayable3" id="0x7f010003" />
+    <public type="string" name="overlayable4" id="0x7f010004" />
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/system_in.xml b/libs/androidfw/tests/data/overlayable/res/values/values.xml
similarity index 61%
copy from packages/SystemUI/res/anim/system_in.xml
copy to libs/androidfw/tests/data/overlayable/res/values/values.xml
index 630fd72..a86b312 100644
--- a/packages/SystemUI/res/anim/system_in.xml
+++ b/libs/androidfw/tests/data/overlayable/res/values/values.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
@@ -14,9 +14,10 @@
      limitations under the License.
 -->
 
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
+<resources>
+    <string name="not_overlayable">Not overlayable</string>
+    <string name="overlayable1">Overlayable One</string>
+    <string name="overlayable2">Overlayable Two</string>
+    <string name="overlayable3">Overlayable Three</string>
+    <string name="overlayable4">Overlayable Four</string>
+</resources>
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 4a3e10c..8067313 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -29,8 +29,6 @@
 namespace android {
 namespace uirenderer {
 
-bool Properties::drawDeferDisabled = false;
-bool Properties::drawReorderDisabled = false;
 bool Properties::debugLayersUpdates = false;
 bool Properties::debugOverdraw = false;
 bool Properties::showDirtyRegions = false;
@@ -40,7 +38,6 @@
 
 DebugLevel Properties::debugLevel = kDebugDisabled;
 OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
-StencilClipDebug Properties::debugStencilClip = StencilClipDebug::Hide;
 
 float Properties::overrideLightRadius = -1.0f;
 float Properties::overrideLightPosY = -1.0f;
@@ -85,7 +82,6 @@
     char property[PROPERTY_VALUE_MAX];
     bool prevDebugLayersUpdates = debugLayersUpdates;
     bool prevDebugOverdraw = debugOverdraw;
-    StencilClipDebug prevDebugStencilClip = debugStencilClip;
 
     debugOverdraw = false;
     if (property_get(PROPERTY_DEBUG_OVERDRAW, property, nullptr) > 0) {
@@ -99,20 +95,6 @@
         }
     }
 
-    // See Properties.h for valid values
-    if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, nullptr) > 0) {
-        INIT_LOGD("  Stencil clip debug enabled: %s", property);
-        if (!strcmp(property, "hide")) {
-            debugStencilClip = StencilClipDebug::Hide;
-        } else if (!strcmp(property, "highlight")) {
-            debugStencilClip = StencilClipDebug::ShowHighlight;
-        } else if (!strcmp(property, "region")) {
-            debugStencilClip = StencilClipDebug::ShowRegion;
-        }
-    } else {
-        debugStencilClip = StencilClipDebug::Hide;
-    }
-
     sProfileType = ProfileType::None;
     if (property_get(PROPERTY_PROFILE, property, "") > 0) {
         if (!strcmp(property, PROPERTY_PROFILE_VISUALIZE_BARS)) {
@@ -125,12 +107,6 @@
     debugLayersUpdates = property_get_bool(PROPERTY_DEBUG_LAYERS_UPDATES, false);
     INIT_LOGD("  Layers updates debug enabled: %d", debugLayersUpdates);
 
-    drawDeferDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_DEFER, false);
-    INIT_LOGD("  Draw defer %s", drawDeferDisabled ? "disabled" : "enabled");
-
-    drawReorderDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_REORDER, false);
-    INIT_LOGD("  Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled");
-
     showDirtyRegions = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false);
 
     debugLevel = (DebugLevel)property_get_int(PROPERTY_DEBUG, kDebugDisabled);
@@ -152,8 +128,7 @@
 
     enableForceDarkSupport = property_get_bool(PROPERTY_ENABLE_FORCE_DARK, true);
 
-    return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw) ||
-           (prevDebugStencilClip != debugStencilClip);
+    return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
 }
 
 void Properties::overrideProperty(const char* name, const char* value) {
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index da53f66..0a7f4e7 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -95,20 +95,6 @@
 #define PROPERTY_PROFILE_VISUALIZE_BARS "visual_bars"
 
 /**
- * Used to enable/disable non-rectangular clipping debugging.
- *
- * The accepted values are:
- * "highlight", drawing commands clipped by the stencil will
- *              be colored differently
- * "region", renders the clipping region on screen whenever
- *           the stencil is set
- * "hide", don't show the clip
- *
- * The default value is "hide".
- */
-#define PROPERTY_DEBUG_STENCIL_CLIP "debug.hwui.show_non_rect_clip"
-
-/**
  * Turn on to draw dirty regions every other frame.
  *
  * Possible values:
@@ -118,19 +104,6 @@
 #define PROPERTY_DEBUG_SHOW_DIRTY_REGIONS "debug.hwui.show_dirty_regions"
 
 /**
- * Disables draw operation deferral if set to "true", forcing draw
- * commands to be issued to OpenGL in order, and processed in sequence
- * with state-manipulation canvas commands.
- */
-#define PROPERTY_DISABLE_DRAW_DEFER "debug.hwui.disable_draw_defer"
-
-/**
- * Used to disable draw operation reordering when deferring draw operations
- * Has no effect if PROPERTY_DISABLE_DRAW_DEFER is set to "true"
- */
-#define PROPERTY_DISABLE_DRAW_REORDER "debug.hwui.disable_draw_reorder"
-
-/**
  * Setting this property will enable or disable the dropping of frames with
  * empty damage. Default is "true".
  */
@@ -207,8 +180,6 @@
 
 enum class OverdrawColorSet { Default = 0, Deuteranomaly };
 
-enum class StencilClipDebug { Hide, ShowHighlight, ShowRegion };
-
 enum class RenderPipelineType { SkiaGL, SkiaVulkan, NotInitialized = 128 };
 
 /**
@@ -220,8 +191,6 @@
 public:
     static bool load();
 
-    static bool drawDeferDisabled;
-    static bool drawReorderDisabled;
     static bool debugLayersUpdates;
     static bool debugOverdraw;
     static bool showDirtyRegions;
@@ -235,7 +204,6 @@
 
     static DebugLevel debugLevel;
     static OverdrawColorSet overdrawColorSet;
-    static StencilClipDebug debugStencilClip;
 
     // Override the value for a subset of properties in this class
     static void overrideProperty(const char* name, const char* value);
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index ba34384..6be7ef7 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -681,7 +681,7 @@
     if (mPaintFilter) {
         mPaintFilter->filter(&paintCopy);
     }
-    SkASSERT(paintCopy.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
+    SkASSERT(paintCopy.getTextEncoding() == kGlyphID_SkTextEncoding);
     // Stroke with a hairline is drawn on HW with a fill style for compatibility with Android O and
     // older.
     if (!mCanvasOwned && sApiLevel <= 27 && paintCopy.getStrokeWidth() <= 0 &&
@@ -708,7 +708,7 @@
     if (mPaintFilter) {
         mPaintFilter->filter(&paintCopy);
     }
-    SkASSERT(paintCopy.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
+    SkASSERT(paintCopy.getTextEncoding() == kGlyphID_SkTextEncoding);
 
     const int N = end - start;
     SkAutoSTMalloc<1024, uint8_t> storage(N * (sizeof(uint16_t) + sizeof(SkRSXform)));
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index 769fce4..84292c8 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -43,7 +43,7 @@
 static void MinikinFontSkia_SetSkiaPaint(const minikin::MinikinFont* font, SkPaint* skPaint,
                                          const minikin::MinikinPaint& paint,
                                          const minikin::FontFakery& fakery) {
-    skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    skPaint->setTextEncoding(kGlyphID_SkTextEncoding);
     skPaint->setTextSize(paint.size);
     skPaint->setTextScaleX(paint.scaleX);
     skPaint->setTextSkewX(paint.skewX);
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index a494e49..3607b23 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -122,8 +122,9 @@
         mVkSurface = nullptr;
     }
 
+    mSurfaceColorSpace = SkColorSpace::MakeSRGB();
     if (surface) {
-        mVkSurface = mVkManager.createSurface(surface, colorMode);
+        mVkSurface = mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace);
     }
 
     if (colorMode == ColorMode::SRGB) {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f1a522e..6869972 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -323,25 +323,6 @@
             // the deadline for RT animations
             info.out.canDrawThisFrame = false;
         }
-        /* This logic exists to try and recover from a display latch miss, which essentially
-         * results in the bufferqueue being double-buffered instead of triple-buffered.
-         * SurfaceFlinger itself now tries to handle & recover from this situation, so this
-         * logic should no longer be necessary. As it's occasionally triggering when
-         * undesired disable it.
-         * TODO: Remove this entirely if the results are solid.
-        else if (vsyncDelta >= mRenderThread.timeLord().frameIntervalNanos() * 3 ||
-                   (latestVsync - mLastDropVsync) < 500_ms) {
-            // It's been several frame intervals, assume the buffer queue is fine
-            // or the last drop was too recent
-            info.out.canDrawThisFrame = true;
-        } else {
-            info.out.canDrawThisFrame = !isSwapChainStuffed();
-            if (!info.out.canDrawThisFrame) {
-                // dropping frame
-                mLastDropVsync = mRenderThread.timeLord().latestVsync();
-            }
-        }
-        */
     } else {
         info.out.canDrawThisFrame = true;
     }
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 9a6df75..2abb3d5 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -472,8 +472,9 @@
     window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight);
     if (windowWidth != surface->mWindowWidth || windowHeight != surface->mWindowHeight) {
         ColorMode colorMode = surface->mColorMode;
+        sk_sp<SkColorSpace> colorSpace = surface->mColorSpace;
         destroySurface(surface);
-        *surfaceOut = createSurface(window, colorMode);
+        *surfaceOut = createSurface(window, colorMode, colorSpace);
         surface = *surfaceOut;
     }
 
@@ -647,7 +648,7 @@
         imageInfo.mSurface = SkSurface::MakeFromBackendRenderTarget(
                 mRenderThread.getGrContext(), backendRT, kTopLeft_GrSurfaceOrigin,
                 surface->mColorMode == ColorMode::WideColorGamut ? kRGBA_F16_SkColorType
-                : kRGBA_8888_SkColorType, nullptr, &props);
+                : kRGBA_8888_SkColorType, surface->mColorSpace, &props);
     }
 
     SkASSERT(mCommandPool != VK_NULL_HANDLE);
@@ -744,7 +745,7 @@
     surface->mWindowWidth = extent.width;
     surface->mWindowHeight = extent.height;
 
-    uint32_t imageCount = caps.minImageCount + 2;
+    uint32_t imageCount = std::max<uint32_t>(3, caps.minImageCount);
     if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) {
         // Application must settle for fewer images than desired:
         imageCount = caps.maxImageCount;
@@ -833,14 +834,15 @@
     return true;
 }
 
-VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode) {
+VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode,
+        sk_sp<SkColorSpace> surfaceColorSpace) {
     initialize();
 
     if (!window) {
         return nullptr;
     }
 
-    VulkanSurface* surface = new VulkanSurface(colorMode, window);
+    VulkanSurface* surface = new VulkanSurface(colorMode, window, surfaceColorSpace);
 
     VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
     memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 8594a1b..d67d2c8 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -38,8 +38,8 @@
 
 class VulkanSurface {
 public:
-    VulkanSurface(ColorMode colorMode, ANativeWindow* window)
-            : mColorMode(colorMode), mNativeWindow(window) {}
+    VulkanSurface(ColorMode colorMode, ANativeWindow* window, sk_sp<SkColorSpace> colorSpace)
+            : mColorMode(colorMode), mNativeWindow(window), mColorSpace(colorSpace) {}
 
     sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; }
 
@@ -79,6 +79,7 @@
     ANativeWindow* mNativeWindow;
     int mWindowWidth = 0;
     int mWindowHeight = 0;
+    sk_sp<SkColorSpace> mColorSpace;
 };
 
 // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue,
@@ -96,7 +97,8 @@
 
     // Given a window this creates a new VkSurfaceKHR and VkSwapchain and stores them inside a new
     // VulkanSurface object which is returned.
-    VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode);
+    VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode,
+            sk_sp<SkColorSpace> surfaceColorSpace);
 
     // Destroy the VulkanSurface and all associated vulkan objects.
     void destroySurface(VulkanSurface* surface);
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 8a1bc4d..f812022 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -81,7 +81,7 @@
     auto utf16 = asciiToUtf16(text);
     uint32_t length = strlen(text);
     SkPaint glyphPaint(paint);
-    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    glyphPaint.setTextEncoding(kGlyphID_SkTextEncoding);
     canvas->drawText(
             utf16.get(), length,  // text buffer
             0, length,  // draw range
@@ -94,7 +94,7 @@
                                  const SkPath& path) {
     auto utf16 = asciiToUtf16(text);
     SkPaint glyphPaint(paint);
-    glyphPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    glyphPaint.setTextEncoding(kGlyphID_SkTextEncoding);
     canvas->drawTextOnPath(utf16.get(), strlen(text), minikin::Bidi::LTR, path, 0, 0, glyphPaint,
             nullptr);
 }
diff --git a/media/OWNERS b/media/OWNERS
index 0abf9ae..03b751c 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -1,12 +1,13 @@
+chz@google.com
+dwkang@google.com
 elaurent@google.com
 etalvala@google.com
 gkasten@google.com
 hunga@google.com
+jaewan@google.com
 jmtrivi@google.com
+jsharkey@android.com
 lajos@google.com
 marcone@google.com
 sungsoo@google.com
 wjia@google.com
-jaewan@google.com
-chz@google.com
-dwkang@google.com
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 2a575b6..4b2353c 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -16,16 +16,6 @@
 
 package android.media;
 
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.ArrayList;
-import java.util.List;
-
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
@@ -39,13 +29,21 @@
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 /**
  * The AudioRecord class manages the audio resources for Java applications
  * to record audio from the audio input hardware of the platform. This is
@@ -1807,6 +1805,8 @@
     private native final int native_get_active_microphones(
             ArrayList<MicrophoneInfo> activeMicrophones);
 
+    private native int native_getPortId();
+
     //---------------------------------------------------------
     // Utility methods
     //------------------
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 71736dd..2c4ec3a 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -3423,6 +3423,8 @@
     private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id);
     private native final int native_setPresentation(int presentationId, int programId);
 
+    private native int native_getPortId();
+
     //---------------------------------------------------------
     // Utility methods
     //------------------
diff --git a/media/java/android/media/CloseGuard.java b/media/java/android/media/CloseGuard.java
new file mode 100644
index 0000000..2014673
--- /dev/null
+++ b/media/java/android/media/CloseGuard.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2010 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.media;
+
+import android.util.Log;
+
+/**
+ * Note: This file is copied from dalvik.system package with the following modifications:
+ *       - Remove @CorePlatformApi, @IntraCoreApi and @UnsupportedAppUsage annotations.
+ *       - Replace System.logW() with android.util.Log.w().
+ *       This file should be used only within media mainline module.
+ * TODO: Remove this file and use dalvik.system.CloseGuard once
+ *       @CorePlatformApi becomes stable or we have a replacement in SDK API.
+ *       b/120419300
+ *
+ * CloseGuard is a mechanism for flagging implicit finalizer cleanup of
+ * resources that should have been cleaned up by explicit close
+ * methods (aka "explicit termination methods" in Effective Java).
+ * <p>
+ * A simple example: <pre>   {@code
+ *   class Foo {
+ *
+ *       {@literal @}ReachabilitySensitive
+ *       private final CloseGuard guard = CloseGuard.get();
+ *
+ *       ...
+ *
+ *       public Foo() {
+ *           ...;
+ *           guard.open("cleanup");
+ *       }
+ *
+ *       public void cleanup() {
+ *          guard.close();
+ *          ...;
+ *       }
+ *
+ *       protected void finalize() throws Throwable {
+ *           try {
+ *               // Note that guard could be null if the constructor threw.
+ *               if (guard != null) {
+ *                   guard.warnIfOpen();
+ *               }
+ *               cleanup();
+ *           } finally {
+ *               super.finalize();
+ *           }
+ *       }
+ *   }
+ * }</pre>
+ *
+ * In usage where the resource to be explicitly cleaned up is
+ * allocated after object construction, CloseGuard protection can
+ * be deferred. For example: <pre>   {@code
+ *   class Bar {
+ *
+ *       {@literal @}ReachabilitySensitive
+ *       private final CloseGuard guard = CloseGuard.get();
+ *
+ *       ...
+ *
+ *       public Bar() {
+ *           ...;
+ *       }
+ *
+ *       public void connect() {
+ *          ...;
+ *          guard.open("cleanup");
+ *       }
+ *
+ *       public void cleanup() {
+ *          guard.close();
+ *          ...;
+ *       }
+ *
+ *       protected void finalize() throws Throwable {
+ *           try {
+ *               // Note that guard could be null if the constructor threw.
+ *               if (guard != null) {
+ *                   guard.warnIfOpen();
+ *               }
+ *               cleanup();
+ *           } finally {
+ *               super.finalize();
+ *           }
+ *       }
+ *   }
+ * }</pre>
+ *
+ * When used in a constructor, calls to {@code open} should occur at
+ * the end of the constructor since an exception that would cause
+ * abrupt termination of the constructor will mean that the user will
+ * not have a reference to the object to cleanup explicitly. When used
+ * in a method, the call to {@code open} should occur just after
+ * resource acquisition.
+ *
+ * The @ReachabilitySensitive annotation ensures that finalize() cannot be
+ * called during the explicit call to cleanup(), prior to the guard.close call.
+ * There is an extremely small chance that, for code that neglects to call
+ * cleanup(), finalize() and thus cleanup() will be called while a method on
+ * the object is still active, but the "this" reference is no longer required.
+ * If missing cleanup() calls are expected, additional @ReachabilitySensitive
+ * annotations or reachabilityFence() calls may be required.
+ *
+ * @hide
+ */
+final class CloseGuard {
+
+    /**
+     * True if collection of call-site information (the expensive operation
+     * here)  and tracking via a Tracker (see below) are enabled.
+     * Enabled by default so we can diagnose issues early in VM startup.
+     * Note, however, that Android disables this early in its startup,
+     * but enables it with DropBoxing for system apps on debug builds.
+     */
+    private static volatile boolean stackAndTrackingEnabled = true;
+
+    /**
+     * Hook for customizing how CloseGuard issues are reported.
+     * Bypassed if stackAndTrackingEnabled was false when open was called.
+     */
+    private static volatile Reporter reporter = new DefaultReporter();
+
+    /**
+     * Hook for customizing how CloseGuard issues are tracked.
+     */
+    private static volatile Tracker currentTracker = null; // Disabled by default.
+
+    /**
+     * Returns a CloseGuard instance. {@code #open(String)} can be used to set
+     * up the instance to warn on failure to close.
+     */
+    public static CloseGuard get() {
+        return new CloseGuard();
+    }
+
+    /**
+     * Enables/disables stack capture and tracking. A call stack is captured
+     * during open(), and open/close events are reported to the Tracker, only
+     * if enabled is true. If a stack trace was captured, the {@link
+     * #getReporter() reporter} is informed of unclosed resources; otherwise a
+     * one-line warning is logged.
+     */
+    public static void setEnabled(boolean enabled) {
+        CloseGuard.stackAndTrackingEnabled = enabled;
+    }
+
+    /**
+     * True if CloseGuard stack capture and tracking are enabled.
+     */
+    public static boolean isEnabled() {
+        return stackAndTrackingEnabled;
+    }
+
+    /**
+     * Used to replace default Reporter used to warn of CloseGuard
+     * violations when stack tracking is enabled. Must be non-null.
+     */
+    public static void setReporter(Reporter rep) {
+        if (rep == null) {
+            throw new NullPointerException("reporter == null");
+        }
+        CloseGuard.reporter = rep;
+    }
+
+    /**
+     * Returns non-null CloseGuard.Reporter.
+     */
+    public static Reporter getReporter() {
+        return reporter;
+    }
+
+    /**
+     * Sets the {@link Tracker} that is notified when resources are allocated and released.
+     * The Tracker is invoked only if CloseGuard {@link #isEnabled()} held when {@link #open()}
+     * was called. A null argument disables tracking.
+     *
+     * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+     * MUST NOT be used for any other purposes.
+     */
+    public static void setTracker(Tracker tracker) {
+        currentTracker = tracker;
+    }
+
+    /**
+     * Returns {@link #setTracker(Tracker) last Tracker that was set}, or null to indicate
+     * there is none.
+     *
+     * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+     * MUST NOT be used for any other purposes.
+     */
+    public static Tracker getTracker() {
+        return currentTracker;
+    }
+
+    private CloseGuard() {}
+
+    /**
+     * {@code open} initializes the instance with a warning that the caller
+     * should have explicitly called the {@code closer} method instead of
+     * relying on finalization.
+     *
+     * @param closer non-null name of explicit termination method. Printed by warnIfOpen.
+     * @throws NullPointerException if closer is null.
+     */
+    public void open(String closer) {
+        // always perform the check for valid API usage...
+        if (closer == null) {
+            throw new NullPointerException("closer == null");
+        }
+        // ...but avoid allocating an allocation stack if "disabled"
+        if (!stackAndTrackingEnabled) {
+            closerNameOrAllocationInfo = closer;
+            return;
+        }
+        String message = "Explicit termination method '" + closer + "' not called";
+        Throwable stack = new Throwable(message);
+        closerNameOrAllocationInfo = stack;
+        Tracker tracker = currentTracker;
+        if (tracker != null) {
+            tracker.open(stack);
+        }
+    }
+
+    // We keep either an allocation stack containing the closer String or, when
+    // in disabled state, just the closer String.
+    // We keep them in a single field only to minimize overhead.
+    private Object /* String or Throwable */ closerNameOrAllocationInfo;
+
+    /**
+     * Marks this CloseGuard instance as closed to avoid warnings on
+     * finalization.
+     */
+    public void close() {
+        Tracker tracker = currentTracker;
+        if (tracker != null && closerNameOrAllocationInfo instanceof Throwable) {
+            // Invoke tracker on close only if we invoked it on open. Tracker may have changed.
+            tracker.close((Throwable) closerNameOrAllocationInfo);
+        }
+        closerNameOrAllocationInfo = null;
+    }
+
+    /**
+     * Logs a warning if the caller did not properly cleanup by calling an
+     * explicit close method before finalization. If CloseGuard was enabled
+     * when the CloseGuard was created, passes the stacktrace associated with
+     * the allocation to the current reporter. If it was not enabled, it just
+     * directly logs a brief message.
+     */
+    public void warnIfOpen() {
+        if (closerNameOrAllocationInfo != null) {
+            if (closerNameOrAllocationInfo instanceof String) {
+                Log.w("CloseGuard", "A resource failed to call "
+                        + (String) closerNameOrAllocationInfo + ". ");
+            } else {
+                String message =
+                        "A resource was acquired at attached stack trace but never released. ";
+                message += "See java.io.Closeable for information on avoiding resource leaks.";
+                Throwable stack = (Throwable) closerNameOrAllocationInfo;
+                reporter.report(message, stack);
+            }
+        }
+    }
+
+    /**
+     * Interface to allow customization of tracking behaviour.
+     *
+     * <p>This is only intended for use by {@code dalvik.system.CloseGuardSupport} class and so
+     * MUST NOT be used for any other purposes.
+     */
+    public interface Tracker {
+        void open(Throwable allocationSite);
+        void close(Throwable allocationSite);
+    }
+
+    /**
+     * Interface to allow customization of reporting behavior.
+     * @hide
+     */
+    public interface Reporter {
+        void report(String message, Throwable allocationSite);
+    }
+
+    /**
+     * Default Reporter which reports CloseGuard violations to the log.
+     */
+    private static final class DefaultReporter implements Reporter {
+        private DefaultReporter() {}
+
+        @Override public void report (String message, Throwable allocationSite) {
+            Log.w("CloseGuard", message, allocationSite);
+        }
+    }
+}
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index 284e422..b7743c9 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -17,20 +17,29 @@
 package android.media;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.nio.ByteBuffer;
+import java.util.AbstractSet;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
- * Encapsulates the information describing the format of media data,
- * be it audio or video.
- *
- * The format of the media data is specified as string/value pairs.
- *
+ * Encapsulates the information describing the format of media data, be it audio or video, as
+ * well as optional feature metadata.
+ * <p>
+ * The format of the media data is specified as key/value pairs. Keys are strings. Values can
+ * be integer, long, float, String or ByteBuffer.
+ * <p>
+ * The feature metadata is specificed as string/boolean pairs.
+ * <p>
  * Keys common to all audio/video formats, <b>all keys not marked optional are mandatory</b>:
  *
  * <table>
@@ -938,7 +947,6 @@
      */
     public static final String KEY_CA_SESSION_ID = "ca-session-id";
 
-
     /**
      * A key describing the private data in the CA_descriptor associated with a media track.
      * <p>
@@ -950,7 +958,7 @@
      */
     public static final String KEY_CA_PRIVATE_DATA = "ca-private-data";
 
-    /* package private */ MediaFormat(Map<String, Object> map) {
+    /* package private */ MediaFormat(@NonNull Map<String, Object> map) {
         mMap = map;
     }
 
@@ -969,11 +977,58 @@
     /**
      * Returns true iff a key of the given name exists in the format.
      */
-    public final boolean containsKey(String name) {
+    public final boolean containsKey(@NonNull String name) {
         return mMap.containsKey(name);
     }
 
     /**
+     * Returns true iff a feature of the given name exists in the format.
+     */
+    public final boolean containsFeature(@NonNull String name) {
+        return mMap.containsKey(KEY_FEATURE_ + name);
+    }
+
+    public static final int TYPE_NULL = 0;
+    public static final int TYPE_INTEGER = 1;
+    public static final int TYPE_LONG = 2;
+    public static final int TYPE_FLOAT = 3;
+    public static final int TYPE_STRING = 4;
+    public static final int TYPE_BYTE_BUFFER = 5;
+
+    /** @hide */
+    @IntDef({
+        TYPE_NULL,
+        TYPE_INTEGER,
+        TYPE_LONG,
+        TYPE_FLOAT,
+        TYPE_STRING,
+        TYPE_BYTE_BUFFER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    /**
+     * Returns the value type for a key. If the key does not exist, it returns TYPE_NULL.
+     */
+    public final @Type int getValueTypeForKey(@NonNull String name) {
+        Object value = mMap.get(name);
+        if (value == null) {
+            return TYPE_NULL;
+        } else if (value instanceof Integer) {
+            return TYPE_INTEGER;
+        } else if (value instanceof Long) {
+            return TYPE_LONG;
+        } else if (value instanceof Float) {
+            return TYPE_FLOAT;
+        } else if (value instanceof String) {
+            return TYPE_STRING;
+        } else if (value instanceof ByteBuffer) {
+            return TYPE_BYTE_BUFFER;
+        }
+        throw new RuntimeException("invalid value for key");
+    }
+
+    /**
      * A key prefix used together with a {@link MediaCodecInfo.CodecCapabilities}
      * feature name describing a required or optional feature for a codec capabilities
      * query.
@@ -989,64 +1044,165 @@
     public static final String KEY_FEATURE_ = "feature-";
 
     /**
-     * Returns the value of an integer key.
+     * Returns the value of a numeric key. This is provided as a convenience method for keys
+     * that may take multiple numeric types, such as {@link #KEY_FRAME_RATE}, or {@link
+     * #KEY_I_FRAME_INTERVAL}.
+     *
+     * @return null if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is ByteBuffer or String
      */
-    public final int getInteger(String name) {
+    public final @Nullable Number getNumber(@NonNull String name) {
+        return ((Number)mMap.get(name));
+    }
+
+    /**
+     * Returns the value of a numeric key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is ByteBuffer or String
+     */
+    public final @NonNull Number getNumber(@NonNull String name, @NonNull Number defaultValue) {
+        Number ret = getNumber(name);
+        return ret == null ? defaultValue : ret;
+    }
+
+    /**
+     * Returns the value of an integer key.
+     *
+     * @throws NullPointerException if the key does not exist or the stored value for the key is
+     *         null
+     * @throws ClassCastException if the stored value for the key is long, float, ByteBuffer or
+     *         String
+     */
+    public final int getInteger(@NonNull String name) {
         return ((Integer)mMap.get(name)).intValue();
     }
 
     /**
-     * Returns the value of an integer key, or the default value if the
-     * key is missing or is for another type value.
-     * @hide
+     * Returns the value of an integer key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is long, float, ByteBuffer or
+     *         String
      */
-    public final int getInteger(String name, int defaultValue) {
+    public final int getInteger(@NonNull String name, int defaultValue) {
         try {
             return getInteger(name);
+        } catch (NullPointerException  e) {
+            /* no such field or field is null */
+            return defaultValue;
         }
-        catch (NullPointerException  e) { /* no such field */ }
-        catch (ClassCastException e) { /* field of different type */ }
-        return defaultValue;
     }
 
     /**
      * Returns the value of a long key.
+     *
+     * @throws NullPointerException if the key does not exist or the stored value for the key is
+     *         null
+     * @throws ClassCastException if the stored value for the key is int, float, ByteBuffer or
+     *         String
      */
-    public final long getLong(String name) {
+    public final long getLong(@NonNull String name) {
         return ((Long)mMap.get(name)).longValue();
     }
 
     /**
-     * Returns the value of a float key.
+     * Returns the value of an long key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, float, ByteBuffer or
+     *         String
      */
-    public final float getFloat(String name) {
+    public final long getLong(@NonNull String name, long defaultValue) {
+        try {
+            return getLong(name);
+        } catch (NullPointerException  e) {
+            /* no such field or field is null */
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value of a float key.
+     *
+     * @throws NullPointerException if the key does not exist or the stored value for the key is
+     *         null
+     * @throws ClassCastException if the stored value for the key is int, long, ByteBuffer or
+     *         String
+     */
+    public final float getFloat(@NonNull String name) {
         return ((Float)mMap.get(name)).floatValue();
     }
 
     /**
-     * Returns the value of a string key.
+     * Returns the value of an float key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, ByteBuffer or
+     *         String
      */
-    public final String getString(String name) {
+    public final float getFloat(@NonNull String name, float defaultValue) {
+        try {
+            return getFloat(name);
+        } catch (NullPointerException  e) {
+            /* no such field or field is null */
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value of a string key.
+     *
+     * @return null if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or ByteBuffer
+     */
+    public final @Nullable String getString(@NonNull String name) {
         return (String)mMap.get(name);
     }
 
     /**
-     * Returns the value of a ByteBuffer key.
+     * Returns the value of an string key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or ByteBuffer
      */
-    public final ByteBuffer getByteBuffer(String name) {
+    public final @NonNull String getString(@NonNull String name, @NonNull String defaultValue) {
+        String ret = getString(name);
+        return ret == null ? defaultValue : ret;
+    }
+
+    /**
+     * Returns the value of a ByteBuffer key.
+     *
+     * @return null if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or String
+     */
+    public final @Nullable ByteBuffer getByteBuffer(@NonNull String name) {
         return (ByteBuffer)mMap.get(name);
     }
 
     /**
+     * Returns the value of a ByteBuffer key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or String
+     */
+    public final @NonNull ByteBuffer getByteBuffer(
+            @NonNull String name, @NonNull ByteBuffer defaultValue) {
+        ByteBuffer ret = getByteBuffer(name);
+        return ret == null ? defaultValue : ret;
+    }
+
+    /**
      * Returns whether a feature is to be enabled ({@code true}) or disabled
      * ({@code false}).
      *
      * @param feature the name of a {@link MediaCodecInfo.CodecCapabilities} feature.
      *
      * @throws IllegalArgumentException if the feature was neither set to be enabled
-     *        nor to be disabled.
+     *         nor to be disabled.
      */
-    public boolean getFeatureEnabled(String feature) {
+    public boolean getFeatureEnabled(@NonNull String feature) {
         Integer enabled = (Integer)mMap.get(KEY_FEATURE_ + feature);
         if (enabled == null) {
             throw new IllegalArgumentException("feature is not specified");
@@ -1057,39 +1213,239 @@
     /**
      * Sets the value of an integer key.
      */
-    public final void setInteger(String name, int value) {
+    public final void setInteger(@NonNull String name, int value) {
         mMap.put(name, Integer.valueOf(value));
     }
 
     /**
      * Sets the value of a long key.
      */
-    public final void setLong(String name, long value) {
+    public final void setLong(@NonNull String name, long value) {
         mMap.put(name, Long.valueOf(value));
     }
 
     /**
      * Sets the value of a float key.
      */
-    public final void setFloat(String name, float value) {
+    public final void setFloat(@NonNull String name, float value) {
         mMap.put(name, new Float(value));
     }
 
     /**
      * Sets the value of a string key.
+     * <p>
+     * If value is {@code null}, it sets a null value that behaves similarly to a missing key.
+     * This could be used prior to API level {@link android os.Build.VERSION_CODES#Q} to effectively
+     * remove a key.
      */
-    public final void setString(String name, String value) {
+    public final void setString(@NonNull String name, @Nullable String value) {
         mMap.put(name, value);
     }
 
     /**
      * Sets the value of a ByteBuffer key.
+     * <p>
+     * If value is {@code null}, it sets a null value that behaves similarly to a missing key.
+     * This could be used prior to API level {@link android os.Build.VERSION_CODES#Q} to effectively
+     * remove a key.
      */
-    public final void setByteBuffer(String name, ByteBuffer bytes) {
+    public final void setByteBuffer(@NonNull String name, @Nullable ByteBuffer bytes) {
         mMap.put(name, bytes);
     }
 
     /**
+     * Removes a value of a given key if present. Has no effect if the key is not present.
+     */
+    public final void removeKey(@NonNull String name) {
+        // exclude feature mappings
+        if (!name.startsWith(KEY_FEATURE_)) {
+            mMap.remove(name);
+        }
+    }
+
+    /**
+     * Removes a given feature setting if present. Has no effect if the feature setting is not
+     * present.
+     */
+    public final void removeFeature(@NonNull String name) {
+        mMap.remove(KEY_FEATURE_ + name);
+    }
+
+    /**
+     * A Partial set view for a portion of the keys in a MediaFormat object.
+     *
+     * This class is needed as we want to return a portion of the actual format keys in getKeys()
+     * and another portion of the keys in getFeatures(), and still allow the view properties.
+     */
+    private abstract class FilteredMappedKeySet extends AbstractSet<String> {
+        private Set<String> mKeys;
+
+        // Returns true if this set should include this key
+        abstract protected boolean keepKey(String key);
+
+        // Maps a key from the underlying key set into its new value in this key set
+        abstract protected String mapKeyToItem(String key);
+
+        // Maps a key from this key set into its original value in the underlying key set
+        abstract protected String mapItemToKey(String item);
+
+        public FilteredMappedKeySet() {
+            mKeys = mMap.keySet();
+        }
+
+        // speed up contains and remove from abstract implementation (that would iterate
+        // over each element)
+        @Override
+        public boolean contains(Object o) {
+            if (o instanceof String) {
+                String key = mapItemToKey((String)o);
+                return keepKey(key) && mKeys.contains(key);
+            }
+            return false;
+        }
+
+        @Override
+        public boolean remove(Object o) {
+            if (o instanceof String) {
+                String key = mapItemToKey((String)o);
+                if (keepKey(key) && mKeys.remove(key)) {
+                    mMap.remove(key);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private class KeyIterator implements Iterator<String> {
+            Iterator<String> mIterator;
+            String mLast;
+
+            public KeyIterator() {
+                // We must create a copy of the filtered stream, as remove operation has to modify
+                // the underlying data structure (mMap), so the iterator's operation is undefined.
+                // Use a list as it is likely less memory consuming than the other alternative: set.
+                mIterator =
+                    mKeys.stream().filter(k -> keepKey(k)).collect(Collectors.toList()).iterator();
+            }
+
+            @Override
+            public boolean hasNext() {
+                return mIterator.hasNext();
+            }
+
+            @Override
+            public String next() {
+                mLast = mIterator.next();
+                return mapKeyToItem(mLast);
+            }
+
+            @Override
+            public void remove() {
+                mIterator.remove();
+                mMap.remove(mLast);
+            }
+        }
+
+        @Override
+        public Iterator<String> iterator() {
+            return new KeyIterator();
+        }
+
+        @Override
+        public int size() {
+            return (int)mKeys.stream().filter(k -> keepKey(k)).count();
+        }
+    }
+
+    /**
+     * A Partial set view for a portion of the keys in a MediaFormat object for keys that
+     * don't start with a prefix, such as "feature-"
+     */
+    private class UnprefixedKeySet extends FilteredMappedKeySet {
+        private String mPrefix;
+
+        public UnprefixedKeySet(String prefix) {
+            super();
+            mPrefix = prefix;
+        }
+
+        protected boolean keepKey(String key) {
+            return !key.startsWith(mPrefix);
+        }
+
+        protected String mapKeyToItem(String key) {
+            return key;
+        }
+
+        protected String mapItemToKey(String item) {
+            return item;
+        }
+    }
+
+    /**
+     * A Partial set view for a portion of the keys in a MediaFormat object for keys that
+     * start with a prefix, such as "feature-", with the prefix removed
+     */
+    private class PrefixedKeySetWithPrefixRemoved extends FilteredMappedKeySet {
+        private String mPrefix;
+        private int mPrefixLength;
+
+        public PrefixedKeySetWithPrefixRemoved(String prefix) {
+            super();
+            mPrefix = prefix;
+            mPrefixLength = prefix.length();
+        }
+
+        protected boolean keepKey(String key) {
+            return key.startsWith(mPrefix);
+        }
+
+        protected String mapKeyToItem(String key) {
+            return key.substring(mPrefixLength);
+        }
+
+        protected String mapItemToKey(String item) {
+            return mPrefix + item;
+        }
+    }
+
+
+   /**
+     * Returns a {@link java.util.Set Set} view of the keys contained in this MediaFormat.
+     *
+     * The set is backed by the MediaFormat object, so changes to the format are reflected in the
+     * set, and vice-versa. If the format is modified while an iteration over the set is in progress
+     * (except through the iterator's own remove operation), the results of the iteration are
+     * undefined. The set supports element removal, which removes the corresponding mapping from the
+     * format, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations.
+     * It does not support the add or addAll operations.
+     */
+    public final @NonNull java.util.Set<String> getKeys() {
+        return new UnprefixedKeySet(KEY_FEATURE_);
+    }
+
+   /**
+     * Returns a {@link java.util.Set Set} view of the features contained in this MediaFormat.
+     *
+     * The set is backed by the MediaFormat object, so changes to the format are reflected in the
+     * set, and vice-versa. If the format is modified while an iteration over the set is in progress
+     * (except through the iterator's own remove operation), the results of the iteration are
+     * undefined. The set supports element removal, which removes the corresponding mapping from the
+     * format, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations.
+     * It does not support the add or addAll operations.
+     */
+    public final @NonNull java.util.Set<String> getFeatures() {
+        return new PrefixedKeySetWithPrefixRemoved(KEY_FEATURE_);
+    }
+
+    /**
+     * Create a copy of a media format object.
+     */
+    public MediaFormat(@NonNull MediaFormat other) {
+        mMap.putAll(other.mMap);
+    }
+
+    /**
      * Sets whether a feature is to be enabled ({@code true}) or disabled
      * ({@code false}).
      *
@@ -1102,7 +1458,7 @@
      * @see MediaCodecList#findEncoderForFormat
      * @see MediaCodecInfo.CodecCapabilities#isFormatSupported
      */
-    public void setFeatureEnabled(String feature, boolean enabled) {
+    public void setFeatureEnabled(@NonNull String feature, boolean enabled) {
         setInteger(KEY_FEATURE_ + feature, enabled ? 1 : 0);
     }
 
@@ -1112,8 +1468,8 @@
      * @param sampleRate The sampling rate of the content.
      * @param channelCount The number of audio channels in the content.
      */
-    public static final MediaFormat createAudioFormat(
-            String mime,
+    public static final @NonNull MediaFormat createAudioFormat(
+            @NonNull String mime,
             int sampleRate,
             int channelCount) {
         MediaFormat format = new MediaFormat();
@@ -1132,8 +1488,8 @@
      *        in the content.  (This will also work if there are multiple language
      *        tracks in the content.)
      */
-    public static final MediaFormat createSubtitleFormat(
-            String mime,
+    public static final @NonNull MediaFormat createSubtitleFormat(
+            @NonNull String mime,
             String language) {
         MediaFormat format = new MediaFormat();
         format.setString(KEY_MIME, mime);
@@ -1148,8 +1504,8 @@
      * @param width The width of the content (in pixels)
      * @param height The height of the content (in pixels)
      */
-    public static final MediaFormat createVideoFormat(
-            String mime,
+    public static final @NonNull MediaFormat createVideoFormat(
+            @NonNull String mime,
             int width,
             int height) {
         MediaFormat format = new MediaFormat();
@@ -1161,7 +1517,7 @@
     }
 
     @Override
-    public String toString() {
+    public @NonNull String toString() {
         return mMap.toString();
     }
 }
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 111dd0f..4b99a13 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -48,8 +48,6 @@
 import com.android.framework.protobuf.InvalidProtocolBufferException;
 import com.android.internal.annotations.GuardedBy;
 
-import dalvik.system.CloseGuard;
-
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
@@ -3503,7 +3501,7 @@
         }
     }
 
-    private native void native_releaseDrm();
+    private native void native_releaseDrm(long mSrcId);
 
     /**
      * A key request/response exchange occurs between the app and a license server
@@ -3823,7 +3821,8 @@
         }
     }
 
-    private native void native_prepareDrm(@NonNull byte[] uuid, @NonNull byte[] drmSessionId);
+    private native void native_prepareDrm(
+            long srcId, @NonNull byte[] uuid, @NonNull byte[] drmSessionId);
 
     // Instantiated from the native side
     @SuppressWarnings("unused")
@@ -4066,6 +4065,7 @@
         static final int PROVISION_TIMEOUT_MS = 60000;
 
         final DataSourceDesc mDSD;
+        final long mSrcId;
 
         //--- guarded by |this| start
         MediaDrm mDrmObj;
@@ -4077,8 +4077,9 @@
         Future<?> mProvisionResult;
         //--- guarded by |this| end
 
-        DrmHandle(DataSourceDesc dsd) {
+        DrmHandle(DataSourceDesc dsd, long srcId) {
             mDSD = dsd;
+            mSrcId = srcId;
         }
 
         void prepare(UUID uuid) throws UnsupportedSchemeException,
@@ -4188,7 +4189,8 @@
 
                 // Sending it down to native/mediaserver to create the crypto object
                 // This call could simply fail due to bad player state, e.g., after play().
-                MediaPlayer2.this.native_prepareDrm(getByteArrayFromUUID(uuid), mDrmSessionId);
+                final MediaPlayer2 mp2 = MediaPlayer2.this;
+                mp2.native_prepareDrm(mSrcId, getByteArrayFromUUID(uuid), mDrmSessionId);
                 Log.v(TAG, "prepareDrm_openSessionStep: native_prepareDrm/Crypto succeeded");
 
             } catch (Exception e) { //ResourceBusyException, NotProvisionedException
@@ -4369,7 +4371,7 @@
                     // exception if we're in a non-stopped/prepared state.
 
                     // for cleaning native/mediaserver crypto object
-                    native_releaseDrm();
+                    native_releaseDrm(mSrcId);
 
                     // for cleaning client-side MediaDrm object; only called if above has succeeded
                     cleanDrmObj();
@@ -4575,7 +4577,7 @@
 
         SourceInfo(DataSourceDesc dsd) {
             this.mDSD = dsd;
-            mDrmHandle = new DrmHandle(dsd);
+            mDrmHandle = new DrmHandle(dsd, mId);
         }
 
         void close() {
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 3a64f43..90cfc53 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -156,7 +156,8 @@
     private static final String NOTIFICATIONS_DIR = "/notifications/";
     private static final String ALARMS_DIR = "/alarms/";
     private static final String MUSIC_DIR = "/music/";
-    private static final String PODCAST_DIR = "/podcasts/";
+    private static final String PODCASTS_DIR = "/podcasts/";
+    private static final String AUDIOBOOKS_DIR = "/audiobooks/";
 
     public static final String SCANNED_BUILD_PREFS_NAME = "MediaScanBuild";
     public static final String LAST_INTERNAL_SCAN_FINGERPRINT = "lastScanFingerprint";
@@ -654,7 +655,7 @@
                 // rescan for metadata if file was modified since last scan
                 if (entry != null && (entry.mLastModifiedChanged || scanAlways)) {
                     if (noMedia) {
-                        result = endFile(entry, false, false, false, false, false);
+                        result = endFile(entry, false, false, false, false, false, false);
                     } else {
                         boolean isaudio = MediaFile.isAudioMimeType(mMimeType);
                         boolean isvideo = MediaFile.isVideoMimeType(mMimeType);
@@ -679,11 +680,13 @@
                         boolean notifications = mScanSuccess &&
                                 (lowpath.indexOf(NOTIFICATIONS_DIR) > 0);
                         boolean alarms = mScanSuccess && (lowpath.indexOf(ALARMS_DIR) > 0);
-                        boolean podcasts = mScanSuccess && (lowpath.indexOf(PODCAST_DIR) > 0);
+                        boolean podcasts = mScanSuccess && (lowpath.indexOf(PODCASTS_DIR) > 0);
+                        boolean audiobooks = mScanSuccess && (lowpath.indexOf(AUDIOBOOKS_DIR) > 0);
                         boolean music = mScanSuccess && ((lowpath.indexOf(MUSIC_DIR) > 0) ||
-                            (!ringtones && !notifications && !alarms && !podcasts));
+                            (!ringtones && !notifications && !alarms && !podcasts && !audiobooks));
 
-                        result = endFile(entry, ringtones, notifications, alarms, music, podcasts);
+                        result = endFile(entry, ringtones, notifications, alarms, podcasts,
+                                audiobooks, music);
                     }
                 }
             } catch (RemoteException e) {
@@ -957,7 +960,7 @@
 
         @UnsupportedAppUsage
         private Uri endFile(FileEntry entry, boolean ringtones, boolean notifications,
-                boolean alarms, boolean music, boolean podcasts)
+                boolean alarms, boolean podcasts, boolean audiobooks, boolean music)
                 throws RemoteException {
             // update database
 
@@ -1003,6 +1006,7 @@
                 values.put(Audio.Media.IS_ALARM, alarms);
                 values.put(Audio.Media.IS_MUSIC, music);
                 values.put(Audio.Media.IS_PODCAST, podcasts);
+                values.put(Audio.Media.IS_AUDIOBOOK, audiobooks);
             } else if (MediaFile.isExifMimeType(mMimeType) && !mNoMedia) {
                 ExifInterface exif = null;
                 try {
@@ -1011,12 +1015,6 @@
                     // exif is null
                 }
                 if (exif != null) {
-                    float[] latlng = new float[2];
-                    if (exif.getLatLong(latlng)) {
-                        values.put(Images.Media.LATITUDE, latlng[0]);
-                        values.put(Images.Media.LONGITUDE, latlng[1]);
-                    }
-
                     long time = exif.getGpsDateTime();
                     if (time != -1) {
                         values.put(Images.Media.DATE_TAKEN, time);
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index a7bdf4f..89a509f 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -18,11 +18,12 @@
 
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
-import android.util.Log;
-import java.lang.ref.WeakReference;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
 
 /**
  * The Visualizer class enables application to retrieve part of the currently playing audio for
@@ -455,7 +456,7 @@
      *   <li> Rfk, Ifk are respectively  the real and imaginary parts of the kth frequency
      *   component</li>
      *   <li> If Fs is the sampling frequency retuned by getSamplingRate() the kth frequency is:
-     *   (k*Fs)/(n/2) </li>
+     *   k * Fs / n </li>
      * </ul>
      * <table border="0" cellspacing="0" cellpadding="0">
      * <tr><td>Index </p></td>
@@ -476,9 +477,23 @@
      *     <td>Rf2 </p></td>
      *     <td>If2 </p></td>
      *     <td>... </p></td>
-     *     <td>Rf(n-1)/2 </p></td>
-     *     <td>If(n-1)/2 </p></td></tr>
+     *     <td>Rf(n/2-1) </p></td>
+     *     <td>If(n/2-1) </p></td></tr>
      * </table>
+     * <p>In order to obtain magnitude and phase values the following code can
+     * be used:
+     *    <pre class="prettyprint">
+     *       int n = fft.size();
+     *       float[] magnitudes = new float[n / 2 + 1];
+     *       float[] phases = new float[n / 2 + 1];
+     *       magnitudes[0] = (float)Math.abs(fft[0]);      // DC
+     *       magnitudes[n / 2] = (float)Math.abs(fft[1]);  // Nyquist
+     *       phases[0] = phases[n / 2] = 0;
+     *       for (int k = 1; k &lt; n / 2; k++) {
+     *           int i = k * 2;
+     *           magnitudes[k] = (float)Math.hypot(fft[i], fft[i + 1]);
+     *           phases[k] = (float)Math.atan2(fft[i + 1], fft[i]);
+     *       }</pre>
      * @param fft array of bytes where the FFT should be returned
      * @return {@link #SUCCESS} in case of success,
      * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
@@ -561,25 +576,11 @@
          * <p>Data in the fft buffer is valid only within the scope of the callback.
          * Applications which need access to the fft data after returning from the callback
          * should make a copy of the data instead of holding a reference.
+         * <p>For the explanation of the fft data array layout, and the example
+         * code for processing it, please see the documentation for {@link #getFft(byte[])} method.
          *
-         * <p>In order to obtain magnitude and phase values the following formulas can
-         * be used:
-         *    <pre class="prettyprint">
-         *       for (int i = 0; i &lt; fft.size(); i += 2) {
-         *           float magnitude = (float)Math.hypot(fft[i], fft[i + 1]);
-         *           float phase = (float)Math.atan2(fft[i + 1], fft[i]);
-         *       }</pre>
          * @param visualizer Visualizer object on which the listener is registered.
          * @param fft array of bytes containing the frequency representation.
-         *    The fft array only contains the first half of the actual
-         *    FFT spectrum (frequencies up to Nyquist frequency), exploiting
-         *    the symmetry of the spectrum. For each frequencies bin <code>i</code>:
-         *    <ul>
-         *      <li>the element at index <code>2*i</code> in the array contains
-         *          the real part of a complex number,</li>
-         *      <li>the element at index <code>2*i+1</code> contains the imaginary
-         *          part of the complex number.</li>
-         *    </ul>
          * @param samplingRate sampling rate of the visualized audio.
          */
         void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate);
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 8215779..d91cf87 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -96,9 +96,15 @@
      * @return The binder object from the system
      * @hide
      */
+    @SystemApi
     public @NonNull ISession createSession(@NonNull MediaSession.CallbackStub cbStub,
-            @NonNull String tag, int userId) throws RemoteException {
-        return mService.createSession(mContext.getPackageName(), cbStub, tag, userId);
+            @NonNull String tag, int userId) {
+        try {
+            return mService.createSession(mContext.getPackageName(), cbStub, tag, userId);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return null;
     }
 
     /**
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index 4567492..8b6009e 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -1192,7 +1192,7 @@
 }
 
 static void android_media_MediaPlayer2_prepareDrm(JNIEnv *env, jobject thiz,
-                    jbyteArray uuidObj, jbyteArray drmSessionIdObj)
+                    jlong srcId, jbyteArray uuidObj, jbyteArray drmSessionIdObj)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
     if (mp == NULL) {
@@ -1225,7 +1225,7 @@
         return;
     }
 
-    status_t err = mp->prepareDrm(uuid.array(), drmSessionId);
+    status_t err = mp->prepareDrm(srcId, uuid.array(), drmSessionId);
     if (err != OK) {
         if (err == INVALID_OPERATION) {
             jniThrowException(
@@ -1243,7 +1243,7 @@
     }
 }
 
-static void android_media_MediaPlayer2_releaseDrm(JNIEnv *env, jobject thiz)
+static void android_media_MediaPlayer2_releaseDrm(JNIEnv *env, jobject thiz, jlong srcId)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
     if (mp == NULL ) {
@@ -1251,7 +1251,7 @@
         return;
     }
 
-    status_t err = mp->releaseDrm();
+    status_t err = mp->releaseDrm(srcId);
     if (err != OK) {
         if (err == INVALID_OPERATION) {
             jniThrowException(
@@ -1425,8 +1425,8 @@
     {"native_setAuxEffectSendLevel", "(F)V",                    (void *)android_media_MediaPlayer2_setAuxEffectSendLevel},
     {"native_attachAuxEffect", "(I)V",                          (void *)android_media_MediaPlayer2_attachAuxEffect},
     // Modular DRM
-    { "native_prepareDrm", "([B[B)V",                           (void *)android_media_MediaPlayer2_prepareDrm },
-    { "native_releaseDrm", "()V",                               (void *)android_media_MediaPlayer2_releaseDrm },
+    { "native_prepareDrm", "(J[B[B)V",                          (void *)android_media_MediaPlayer2_prepareDrm },
+    { "native_releaseDrm", "(J)V",                              (void *)android_media_MediaPlayer2_releaseDrm },
 
     // AudioRouting
     {"native_setPreferredDevice", "(Landroid/media/AudioDeviceInfo;)Z", (void *)android_media_MediaPlayer2_setPreferredDevice},
diff --git a/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_down.xml b/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
similarity index 100%
rename from packages/SystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
rename to packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_down.xml
diff --git a/packages/SystemUI/res/anim/car_arrow_fade_in_rotate_up.xml b/packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
similarity index 100%
rename from packages/SystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
rename to packages/CarSystemUI/res/anim/car_arrow_fade_in_rotate_up.xml
diff --git a/packages/SystemUI/res/anim/car_arrow_fade_out.xml b/packages/CarSystemUI/res/anim/car_arrow_fade_out.xml
similarity index 100%
rename from packages/SystemUI/res/anim/car_arrow_fade_out.xml
rename to packages/CarSystemUI/res/anim/car_arrow_fade_out.xml
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_animation.xml
index ed637a7..6f12338 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_icon_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_icon_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_icon_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_icon_animation.xml
index 227c981..9f8c12e 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_icon_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_icon_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_name_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_name_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_name_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_name_animation.xml
index 5901ff4..adc1f72 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_name_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_name_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_pages_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_pages_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_pages_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_pages_animation.xml
index 41cbe4b..dec5c05 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_pages_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_pages_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_close_pod_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_close_pod_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_close_pod_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_close_pod_animation.xml
index 341e7e0..986a9cb 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_close_pod_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_close_pod_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_open_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_animation.xml
index 6ae7413..80b38b3 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_icon_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_icon_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_open_icon_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_icon_animation.xml
index 06ac9e3..721376c 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_icon_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_icon_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_name_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_name_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_open_name_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_name_animation.xml
index 4baefb8..246099e 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_name_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_name_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_pages_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_pages_animation.xml
similarity index 93%
rename from packages/SystemUI/res/anim/car_user_switcher_open_pages_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_pages_animation.xml
index 2d0deb9..9a1c642 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_pages_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_pages_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/anim/car_user_switcher_open_pod_animation.xml b/packages/CarSystemUI/res/anim/car_user_switcher_open_pod_animation.xml
similarity index 95%
rename from packages/SystemUI/res/anim/car_user_switcher_open_pod_animation.xml
rename to packages/CarSystemUI/res/anim/car_user_switcher_open_pod_animation.xml
index 3315220..1414b66 100644
--- a/packages/SystemUI/res/anim/car_user_switcher_open_pod_animation.xml
+++ b/packages/CarSystemUI/res/anim/car_user_switcher_open_pod_animation.xml
@@ -1,4 +1,4 @@
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/drawable/car_add_circle_round.xml b/packages/CarSystemUI/res/drawable/car_add_circle_round.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/car_add_circle_round.xml
rename to packages/CarSystemUI/res/drawable/car_add_circle_round.xml
diff --git a/packages/SystemUI/res/drawable/car_ic_add_white.xml b/packages/CarSystemUI/res/drawable/car_ic_add_white.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/car_ic_add_white.xml
rename to packages/CarSystemUI/res/drawable/car_ic_add_white.xml
diff --git a/packages/SystemUI/res/drawable/car_ic_arrow.xml b/packages/CarSystemUI/res/drawable/car_ic_arrow.xml
similarity index 94%
rename from packages/SystemUI/res/drawable/car_ic_arrow.xml
rename to packages/CarSystemUI/res/drawable/car_ic_arrow.xml
index d400ed8..cfacbf9 100644
--- a/packages/SystemUI/res/drawable/car_ic_arrow.xml
+++ b/packages/CarSystemUI/res/drawable/car_ic_arrow.xml
@@ -1,5 +1,5 @@
 <!--
-  ~ Copyright (C) 2017 The Android Open Source Project
+  ~ Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/drawable/car_ic_arrow_drop_up.xml b/packages/CarSystemUI/res/drawable/car_ic_arrow_drop_up.xml
similarity index 93%
rename from packages/SystemUI/res/drawable/car_ic_arrow_drop_up.xml
rename to packages/CarSystemUI/res/drawable/car_ic_arrow_drop_up.xml
index 33a512e..81e7262 100644
--- a/packages/SystemUI/res/drawable/car_ic_arrow_drop_up.xml
+++ b/packages/CarSystemUI/res/drawable/car_ic_arrow_drop_up.xml
@@ -1,5 +1,5 @@
 <!--
-  ~ Copyright (C) 2015 The Android Open Source Project
+  ~ Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/drawable/car_ic_hvac.xml b/packages/CarSystemUI/res/drawable/car_ic_hvac.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/car_ic_hvac.xml
rename to packages/CarSystemUI/res/drawable/car_ic_hvac.xml
diff --git a/packages/SystemUI/res/drawable/car_ic_keyboard_arrow_down.xml b/packages/CarSystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
similarity index 100%
rename from packages/SystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
rename to packages/CarSystemUI/res/drawable/car_ic_keyboard_arrow_down.xml
diff --git a/packages/CarSystemUI/res/drawable/car_rounded_bg_bottom.xml b/packages/CarSystemUI/res/drawable/car_rounded_bg_bottom.xml
new file mode 100644
index 0000000..eb501e5
--- /dev/null
+++ b/packages/CarSystemUI/res/drawable/car_rounded_bg_bottom.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 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
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <solid android:color="?android:attr/colorBackgroundFloating" />
+    <corners
+        android:bottomLeftRadius="@dimen/car_radius_3"
+        android:topLeftRadius="0dp"
+        android:bottomRightRadius="@dimen/car_radius_3"
+        android:topRightRadius="0dp"
+        />
+</shape>
diff --git a/packages/CarSystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml b/packages/CarSystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
new file mode 100644
index 0000000..34578fe
--- /dev/null
+++ b/packages/CarSystemUI/res/drawable/car_stat_sys_data_bluetooth_indicator.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2018 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="17dp"
+        android:height="17dp"
+        android:viewportWidth="18.0"
+        android:viewportHeight="18.0">
+    <group
+        android:translateY="0.5"
+        android:translateX="0.5" >
+        <path
+            android:pathData="M9.57,8.5l2.79,-2.78c0.3,-0.3 0.3,-0.8 0,-1.1L9.04,1.29L9.02,1.27C8.7,0.98 8.21,1 7.91,1.31C7.78,1.45 7.71,1.64 7.71,1.84v4.79L4.69,3.61c-0.3,-0.3 -0.79,-0.3 -1.09,0s-0.3,0.79 0,1.09L7.39,8.5L3.6,12.29c-0.3,0.3 -0.3,0.79 0,1.09s0.79,0.3 1.09,0l3.01,-3.01v4.8c0,0.42 0.35,0.77 0.77,0.77c0.19,0 0.39,-0.07 0.53,-0.21l0.04,-0.04l3.32,-3.32c0.3,-0.3 0.3,-0.8 0,-1.1L9.57,8.5zM9.19,6.77v-3.2l1.6,1.6L9.19,6.77zM9.19,13.42v-3.2l1.6,1.6L9.19,13.42zM4.03,9.29c-0.44,0.44 -1.15,0.44 -1.58,0C2.02,8.86 2.02,8.16 2.45,7.72l0.01,-0.01C2.89,7.27 3.59,7.27 4.02,7.7l0.01,0.01C4.47,8.15 4.47,8.85 4.03,9.29zM14.44,7.71c0.44,0.44 0.44,1.15 0,1.58c-0.44,0.44 -1.15,0.44 -1.58,0c-0.44,-0.43 -0.44,-1.13 -0.01,-1.57l0.01,-0.01C13.3,7.28 14,7.27 14.43,7.7C14.44,7.7 14.44,7.71 14.44,7.71z"
+            android:fillColor="#FFFFFF"/>
+    </group>
+</vector>
diff --git a/packages/CarSystemUI/res/drawable/ic_mic_white.xml b/packages/CarSystemUI/res/drawable/ic_mic_white.xml
index f5a91b5..e1e389d 100644
--- a/packages/CarSystemUI/res/drawable/ic_mic_white.xml
+++ b/packages/CarSystemUI/res/drawable/ic_mic_white.xml
@@ -1,3 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2018 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="48dp"
         android:height="48dp"
diff --git a/packages/SystemUI/res/layout/car_facet_button.xml b/packages/CarSystemUI/res/layout/car_facet_button.xml
similarity index 97%
rename from packages/SystemUI/res/layout/car_facet_button.xml
rename to packages/CarSystemUI/res/layout/car_facet_button.xml
index ad86049..8e7ebad 100644
--- a/packages/SystemUI/res/layout/car_facet_button.xml
+++ b/packages/CarSystemUI/res/layout/car_facet_button.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2017, The Android Open Source Project
+** Copyright 2018, 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.
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/CarSystemUI/res/layout/car_fullscreen_user_pod.xml
similarity index 96%
rename from packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
rename to packages/CarSystemUI/res/layout/car_fullscreen_user_pod.xml
index ee8d357..1d67286 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/CarSystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
similarity index 96%
rename from packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
rename to packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
index c9f5148..6cd70d6 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_switcher.xml
+++ b/packages/CarSystemUI/res/layout/car_fullscreen_user_switcher.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     Copyright (C) 2015 The Android Open Source Project
+     Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
similarity index 98%
rename from packages/SystemUI/res/layout/car_left_navigation_bar.xml
rename to packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
index 02be457..141b28a 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2016, The Android Open Source Project
+** Copyright 2018, 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.
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
similarity index 100%
rename from packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
rename to packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
diff --git a/packages/SystemUI/res/layout/car_navigation_button.xml b/packages/CarSystemUI/res/layout/car_navigation_button.xml
similarity index 95%
rename from packages/SystemUI/res/layout/car_navigation_button.xml
rename to packages/CarSystemUI/res/layout/car_navigation_button.xml
index 4062eb8..6d8cca9 100644
--- a/packages/SystemUI/res/layout/car_navigation_button.xml
+++ b/packages/CarSystemUI/res/layout/car_navigation_button.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2016, The Android Open Source Project
+** Copyright 2018, 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.
diff --git a/packages/SystemUI/res/layout/car_qs_footer.xml b/packages/CarSystemUI/res/layout/car_qs_footer.xml
similarity index 98%
rename from packages/SystemUI/res/layout/car_qs_footer.xml
rename to packages/CarSystemUI/res/layout/car_qs_footer.xml
index 3afd4ea..6f19cfc 100644
--- a/packages/SystemUI/res/layout/car_qs_footer.xml
+++ b/packages/CarSystemUI/res/layout/car_qs_footer.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/layout/car_qs_panel.xml b/packages/CarSystemUI/res/layout/car_qs_panel.xml
similarity index 96%
rename from packages/SystemUI/res/layout/car_qs_panel.xml
rename to packages/CarSystemUI/res/layout/car_qs_panel.xml
index e7413de..dfa48c3 100644
--- a/packages/SystemUI/res/layout/car_qs_panel.xml
+++ b/packages/CarSystemUI/res/layout/car_qs_panel.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
similarity index 98%
copy from packages/SystemUI/res/layout/car_left_navigation_bar.xml
copy to packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
index 02be457..141b28a 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2016, The Android Open Source Project
+** Copyright 2018, 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.
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
similarity index 100%
rename from packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
rename to packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
diff --git a/packages/SystemUI/res/values/colors_car.xml b/packages/CarSystemUI/res/values/colors_car.xml
similarity index 95%
rename from packages/SystemUI/res/values/colors_car.xml
rename to packages/CarSystemUI/res/values/colors_car.xml
index 49bfb25..2f720f5 100644
--- a/packages/SystemUI/res/values/colors_car.xml
+++ b/packages/CarSystemUI/res/values/colors_car.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /*
- * Copyright 2017, The Android Open Source Project
+ * Copyright 2018, 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.
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/CarSystemUI/res/values/dimens_car.xml
similarity index 97%
rename from packages/SystemUI/res/values/dimens_car.xml
rename to packages/CarSystemUI/res/values/dimens_car.xml
index afbe176..c027f81 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/CarSystemUI/res/values/dimens_car.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- * Copyright (c) 2016, The Android Open Source Project
+ * Copyright (c) 2018, 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.
diff --git a/packages/SystemUI/res/values/ids_car.xml b/packages/CarSystemUI/res/values/ids_car.xml
similarity index 100%
rename from packages/SystemUI/res/values/ids_car.xml
rename to packages/CarSystemUI/res/values/ids_car.xml
diff --git a/packages/SystemUI/res/values/integers_car.xml b/packages/CarSystemUI/res/values/integers_car.xml
similarity index 95%
rename from packages/SystemUI/res/values/integers_car.xml
rename to packages/CarSystemUI/res/values/integers_car.xml
index fc3623c..472c957 100644
--- a/packages/SystemUI/res/values/integers_car.xml
+++ b/packages/CarSystemUI/res/values/integers_car.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-  Copyright (c) 2017, The Android Open Source Project
+  Copyright (c) 2018, 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.
diff --git a/packages/SystemUI/res/values/strings_car.xml b/packages/CarSystemUI/res/values/strings_car.xml
similarity index 96%
rename from packages/SystemUI/res/values/strings_car.xml
rename to packages/CarSystemUI/res/values/strings_car.xml
index 2890cf2..83e91c5 100644
--- a/packages/SystemUI/res/values/strings_car.xml
+++ b/packages/CarSystemUI/res/values/strings_car.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /**
- * Copyright (c) 2016, The Android Open Source Project
+ * Copyright (c) 2018, 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.
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
index dfe5704..f57f26d 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
@@ -28,6 +28,8 @@
 import com.android.systemui.statusbar.car.hvac.HvacController;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.volume.CarVolumeDialogComponent;
+import com.android.systemui.volume.VolumeDialogComponent;
 
 /**
  * Class factory to provide car specific SystemUI components.
@@ -39,6 +41,10 @@
         return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
     }
 
+    public VolumeDialogComponent createVolumeDialogComponent(SystemUI systemUi, Context context) {
+        return new CarVolumeDialogComponent(systemUi, context);
+    }
+
     @Override
     public void injectDependencies(ArrayMap<Object, DependencyProvider> providers,
         Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
rename to packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
index 50fefe9..0563418 100644
--- a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,8 +11,9 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
+
 package com.android.systemui.car;
 
 import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
rename to packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
index 0389030..b74f199 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
+++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
@@ -1,16 +1,19 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 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
  *
- * 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.
  */
+
 package com.android.systemui.qs.car;
 
 import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
rename to packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
index 3e82c54..41c37d3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
+++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
@@ -1,16 +1,19 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 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
  *
- * 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.
  */
+
 package com.android.systemui.qs.car;
 
 import android.animation.Animator;
@@ -223,7 +226,7 @@
 
     private void animateHeightChange(boolean opening) {
         // Animation in progress; cancel it to avoid contention.
-        if (mAnimatorSet != null){
+        if (mAnimatorSet != null) {
             mAnimatorSet.cancel();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
similarity index 81%
rename from packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
rename to packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
index 083a747..d5dd3c3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
+++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarStatusBarHeader.java
@@ -1,16 +1,19 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 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
  *
- * 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.
  */
+
 package com.android.systemui.qs.car;
 
 import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
index fc39648..58f80a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
@@ -58,28 +58,31 @@
     private final Context mContext;
 
     private final BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
-    private BluetoothHeadsetClient mBluetoothHeadsetClient;
-
     private final ArrayList<BatteryStateChangeCallback> mChangeCallbacks = new ArrayList<>();
+    private BluetoothHeadsetClient mBluetoothHeadsetClient;
+    private final ServiceListener mHfpServiceListener = new ServiceListener() {
+        @Override
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            if (profile == BluetoothProfile.HEADSET_CLIENT) {
+                mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
+            }
+        }
 
+        @Override
+        public void onServiceDisconnected(int profile) {
+            if (profile == BluetoothProfile.HEADSET_CLIENT) {
+                mBluetoothHeadsetClient = null;
+            }
+        }
+    };
     private int mLevel;
-
-    /**
-     * An interface indicating the container of a View that will display what the information
-     * in the {@link CarBatteryController}.
-     */
-    public interface BatteryViewHandler {
-        void hideBatteryView();
-        void showBatteryView();
-    }
-
     private BatteryViewHandler mBatteryViewHandler;
 
     public CarBatteryController(Context context) {
         mContext = context;
 
         if (mAdapter == null) {
-           return;
+            return;
         }
 
         mAdapter.getProfileProxy(context.getApplicationContext(), mHfpServiceListener,
@@ -159,7 +162,7 @@
 
             }
             BluetoothDevice device =
-                    (BluetoothDevice)intent.getExtra(BluetoothDevice.EXTRA_DEVICE);
+                    (BluetoothDevice) intent.getExtra(BluetoothDevice.EXTRA_DEVICE);
             updateBatteryIcon(device, newState);
         }
     }
@@ -261,20 +264,14 @@
         }
     }
 
-    private final ServiceListener mHfpServiceListener = new ServiceListener() {
-        @Override
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (profile == BluetoothProfile.HEADSET_CLIENT) {
-                mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
-            }
-        }
+    /**
+     * An interface indicating the container of a View that will display what the information
+     * in the {@link CarBatteryController}.
+     */
+    public interface BatteryViewHandler {
+        void hideBatteryView();
 
-        @Override
-        public void onServiceDisconnected(int profile) {
-            if (profile == BluetoothProfile.HEADSET_CLIENT) {
-                mBluetoothHeadsetClient = null;
-            }
-        }
-    };
+        void showBatteryView();
+    }
 
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
index 20986ad..56db242 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 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.car;
 
 import android.app.ActivityManager;
@@ -34,7 +50,6 @@
      * Add facet button to this controller. The expected use is for the facet button
      * to get a reference to this controller via {@link com.android.systemui.Dependency}
      * and self add.
-     * @param facetButton
      */
     public void addFacetButton(CarFacetButton facetButton) {
         String[] categories = facetButton.getCategories();
@@ -70,15 +85,16 @@
      * They will then be compared with the supplied StackInfo list.
      * The StackInfo is expected to be supplied in order of recency and StackInfo will only be used
      * for consideration if it has the same displayId as the CarFacetButtons.
-     * @param taskInfo of the currently running application
+     *
+     * @param stackInfoList of the currently running application
      */
     public void taskChanged(List<ActivityManager.StackInfo> stackInfoList) {
         int displayId = getDisplayId();
         ActivityManager.StackInfo validStackInfo = null;
-        for (ActivityManager.StackInfo stackInfo :stackInfoList) {
+        for (ActivityManager.StackInfo stackInfo : stackInfoList) {
             // If the display id is unknown or it matches the stack, it's valid for use
-            if ((displayId == -1 || displayId == stackInfo.displayId) &&
-                    stackInfo.topActivity != null) {
+            if ((displayId == -1 || displayId == stackInfo.displayId)
+                    && stackInfo.topActivity != null) {
                 validStackInfo = stackInfo;
                 break;
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index 084c136..e640baa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 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.car;
 
 import android.content.Context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 4bff5ba..2d90f8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2018 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.
@@ -35,6 +35,8 @@
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.statusbar.StatusBarState;
@@ -252,6 +254,11 @@
         addTemperatureViewToController(mStatusBarWindow);
     }
 
+    @Override
+    protected QS createDefaultQSFragment() {
+        return new CarQSFragment();
+    }
+
     private BatteryController createBatteryController() {
         mCarBatteryController = new CarBatteryController(mContext);
         mCarBatteryController.addBatteryViewHandler(this);
@@ -549,7 +556,7 @@
      */
     public void dismissKeyguard() {
         executeRunnableDismissingKeyguard(null/* runnable */, null /* cancelAction */,
-            true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
+                true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
similarity index 70%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
index d0f0629..8c6b9b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 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.car;
 
 import android.content.Context;
@@ -16,13 +32,13 @@
             ViewMediatorCallback callback,
             LockPatternUtils lockPatternUtils) {
         super(context, callback, lockPatternUtils);
-        mShouldHideNavBar =context.getResources()
+        mShouldHideNavBar = context.getResources()
                 .getBoolean(R.bool.config_hideNavWhenKeyguardBouncerShown);
     }
 
     @Override
     protected void updateNavigationBarVisibility(boolean navBarVisible) {
-        if(!mShouldHideNavBar) {
+        if (!mShouldHideNavBar) {
             return;
         }
         CarStatusBar statusBar = (CarStatusBar) mStatusBar;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
index f2923f7..3288927 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 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.car;
 
 import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
@@ -29,7 +45,7 @@
  */
 public class ConnectedDeviceSignalController extends BroadcastReceiver implements
         BluetoothController.Callback {
-    private final static String TAG = "DeviceSignalCtlr";
+    private static final String TAG = "DeviceSignalCtlr";
 
     /**
      * The value that indicates if a network is unavailable. This value is according ot the
@@ -70,6 +86,21 @@
     private final SignalDrawable mSignalDrawable;
 
     private BluetoothHeadsetClient mBluetoothHeadsetClient;
+    private final ServiceListener mHfpServiceListener = new ServiceListener() {
+        @Override
+        public void onServiceConnected(int profile, BluetoothProfile proxy) {
+            if (profile == BluetoothProfile.HEADSET_CLIENT) {
+                mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(int profile) {
+            if (profile == BluetoothProfile.HEADSET_CLIENT) {
+                mBluetoothHeadsetClient = null;
+            }
+        }
+    };
 
     public ConnectedDeviceSignalController(Context context, View signalsView) {
         mContext = context;
@@ -87,7 +118,7 @@
                 new ScalingDrawableWrapper(mSignalDrawable, mIconScaleFactor));
 
         if (mAdapter == null) {
-          return;
+            return;
         }
 
         mAdapter.getProfileProxy(context.getApplicationContext(), mHfpServiceListener,
@@ -236,20 +267,4 @@
             mSignalsView.setVisibility(View.GONE);
         }
     }
-
-    private final ServiceListener mHfpServiceListener = new ServiceListener() {
-        @Override
-        public void onServiceConnected(int profile, BluetoothProfile proxy) {
-            if (profile == BluetoothProfile.HEADSET_CLIENT) {
-                mBluetoothHeadsetClient = (BluetoothHeadsetClient) proxy;
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(int profile) {
-            if (profile == BluetoothProfile.HEADSET_CLIENT) {
-                mBluetoothHeadsetClient = null;
-            }
-        }
-    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
similarity index 99%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
index 47941bf..730c3e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
@@ -124,4 +124,4 @@
             Log.d(TAG, message);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index 2ebf5eb..23fe594 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2018 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.systemui.statusbar.car;
@@ -44,7 +44,7 @@
         // Initialize user grid.
         mUserGridView = container.findViewById(R.id.user_grid);
         GridLayoutManager layoutManager = new GridLayoutManager(context,
-            context.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col));
+                context.getResources().getInteger(R.integer.user_fullscreen_switcher_num_col));
         mUserGridView.getRecyclerView().setLayoutManager(layoutManager);
         mUserGridView.buildAdapter();
         mUserGridView.setUserSelectionListener(this::onUserSelected);
@@ -54,7 +54,7 @@
         hide();
 
         mShortAnimDuration = container.getResources()
-            .getInteger(android.R.integer.config_shortAnimTime);
+                .getInteger(android.R.integer.config_shortAnimTime);
     }
 
     /**
@@ -108,4 +108,4 @@
                 });
 
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/SwitchToGuestTimer.java
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index d802ed8..fb2b57b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -11,7 +11,7 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.systemui.statusbar.car;
@@ -210,7 +210,7 @@
         public void onBindViewHolder(UserAdapterViewHolder holder, int position) {
             UserRecord userRecord = mUsers.get(position);
             RoundedBitmapDrawable circleIcon = RoundedBitmapDrawableFactory.create(mRes,
-                getUserRecordIcon(userRecord));
+                    getUserRecordIcon(userRecord));
             circleIcon.setCircular(true);
             holder.mUserAvatarImageView.setImageDrawable(circleIcon);
             holder.mUserNameTextView.setText(userRecord.mInfo.name);
@@ -254,13 +254,13 @@
 
         private void showMaxUserLimitReachedDialog() {
             AlertDialog maxUsersDialog = new Builder(mContext, R.style.Theme_Car_Dark_Dialog_Alert)
-                .setTitle(R.string.user_limit_reached_title)
-                .setMessage(getResources().getQuantityString(
-                    R.plurals.user_limit_reached_message,
-                    mCarUserManagerHelper.getMaxSupportedRealUsers(),
-                    mCarUserManagerHelper.getMaxSupportedRealUsers()))
-                .setPositiveButton(android.R.string.ok, null)
-                .create();
+                    .setTitle(R.string.user_limit_reached_title)
+                    .setMessage(getResources().getQuantityString(
+                            R.plurals.user_limit_reached_message,
+                            mCarUserManagerHelper.getMaxSupportedRealUsers(),
+                            mCarUserManagerHelper.getMaxSupportedRealUsers()))
+                    .setPositiveButton(android.R.string.ok, null)
+                    .create();
             // Sets window flags for the SysUI dialog
             SystemUIDialog.applyFlags(maxUsersDialog);
             maxUsersDialog.show();
@@ -268,17 +268,17 @@
 
         private void showConfirmAddUserDialog() {
             String message = mRes.getString(R.string.user_add_user_message_setup)
-                .concat(System.getProperty("line.separator"))
-                .concat(System.getProperty("line.separator"))
-                .concat(mRes.getString(R.string.user_add_user_message_update));
+                    .concat(System.getProperty("line.separator"))
+                    .concat(System.getProperty("line.separator"))
+                    .concat(mRes.getString(R.string.user_add_user_message_update));
 
             AlertDialog addUserDialog = new Builder(mContext, R.style.Theme_Car_Dark_Dialog_Alert)
-                .setTitle(R.string.user_add_user_title)
-                .setMessage(message)
-                .setNegativeButton(android.R.string.cancel, this)
-                .setPositiveButton(android.R.string.ok, this)
-                .setOnCancelListener(this)
-                .create();
+                    .setTitle(R.string.user_add_user_title)
+                    .setMessage(message)
+                    .setNegativeButton(android.R.string.cancel, this)
+                    .setPositiveButton(android.R.string.ok, this)
+                    .setOnCancelListener(this)
+                    .create();
             // Sets window flags for the SysUI dialog
             SystemUIDialog.applyFlags(addUserDialog);
             addUserDialog.show();
@@ -298,7 +298,7 @@
 
             if (userRecord.mIsAddUser) {
                 return UserIcons.convertToBitmap(mContext
-                    .getDrawable(R.drawable.car_add_circle_round));
+                        .getDrawable(R.drawable.car_add_circle_round));
             }
 
             return mCarUserManagerHelper.getUserIcon(userRecord.mInfo);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
index 6c924e3..aec31ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
@@ -41,117 +41,13 @@
 public class HvacController {
 
     public static final String TAG = "HvacController";
-    public final static int BIND_TO_HVAC_RETRY_DELAY = 5000;
+    public static final int BIND_TO_HVAC_RETRY_DELAY = 5000;
 
     private Context mContext;
     private Handler mHandler;
     private Car mCar;
     private CarHvacManager mHvacManager;
     private HashMap<HvacKey, List<TemperatureView>> mTempComponents = new HashMap<>();
-
-    public HvacController(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * Create connection to the Car service. Note: call backs from the Car service
-     * ({@link CarHvacManager}) will happen on the same thread this method was called from.
-     */
-    public void connectToCarService() {
-        mHandler = new Handler();
-        mCar = Car.createCar(mContext, mServiceConnection, mHandler);
-        if (mCar != null) {
-            // note: this connect call handles the retries
-            mCar.connect();
-        }
-    }
-
-    /**
-     * Registers callbacks and initializes components upon connection.
-     */
-    private ServiceConnection mServiceConnection = new ServiceConnection() {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            try {
-                service.linkToDeath(mRestart, 0);
-                mHvacManager = (CarHvacManager) mCar.getCarManager(Car.HVAC_SERVICE);
-                mHvacManager.registerCallback(mHardwareCallback);
-                initComponents();
-            } catch (Exception e) {
-                Log.e(TAG, "Failed to correctly connect to HVAC", e);
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            destroyHvacManager();
-        }
-    };
-
-    private void destroyHvacManager() {
-        if (mHvacManager != null) {
-            mHvacManager.unregisterCallback(mHardwareCallback);
-            mHvacManager = null;
-        }
-    }
-
-    /**
-     * If the connection to car service goes away then restart it.
-     */
-    private final IBinder.DeathRecipient mRestart = new IBinder.DeathRecipient() {
-        @Override
-        public void binderDied() {
-            Log.d(TAG, "Death of HVAC triggering a restart");
-            if (mCar != null) {
-                mCar.disconnect();
-            }
-            destroyHvacManager();
-            mHandler.postDelayed(() -> mCar.connect(), BIND_TO_HVAC_RETRY_DELAY);
-        }
-    };
-
-    /**
-     * Add component to list and initialize it if the connection is up.
-     * @param temperatureView
-     */
-    public void addHvacTextView(TemperatureView temperatureView) {
-
-        HvacKey hvacKey = new HvacKey(temperatureView.getPropertyId(), temperatureView.getAreaId());
-        if (!mTempComponents.containsKey(hvacKey)) {
-            mTempComponents.put(hvacKey, new ArrayList<>());
-        }
-        mTempComponents.get(hvacKey).add(temperatureView);
-        initComponent(temperatureView);
-    }
-
-    private void initComponents() {
-        Iterator<Map.Entry<HvacKey, List<TemperatureView>>> iterator =
-                mTempComponents.entrySet().iterator();
-        while (iterator.hasNext()) {
-            Map.Entry<HvacKey, List<TemperatureView>> next = iterator.next();
-            List<TemperatureView> temperatureViews = next.getValue();
-            for (TemperatureView view : temperatureViews) {
-                initComponent(view);
-            }
-        }
-    }
-
-
-    private void initComponent(TemperatureView view) {
-        int id = view.getPropertyId();
-        int zone = view.getAreaId();
-        try {
-            if (mHvacManager == null || !mHvacManager.isPropertyAvailable(id, zone)) {
-                view.setTemp(Float.NaN);
-                return;
-            }
-            view.setTemp(mHvacManager.getFloatProperty(id, zone));
-        } catch (Exception e) {
-            view.setTemp(Float.NaN);
-            Log.e(TAG, "Failed to get value from hvac service", e);
-        }
-    }
-
     /**
      * Callback for getting changes from {@link CarHvacManager} and setting the UI elements to
      * match.
@@ -179,10 +75,109 @@
 
         @Override
         public void onErrorEvent(final int propertyId, final int zone) {
-            Log.d(TAG, "HVAC error event, propertyId: " + propertyId +
-                    " zone: " + zone);
+            Log.d(TAG, "HVAC error event, propertyId: " + propertyId
+                    + " zone: " + zone);
         }
     };
+    /**
+     * If the connection to car service goes away then restart it.
+     */
+    private final IBinder.DeathRecipient mRestart = new IBinder.DeathRecipient() {
+        @Override
+        public void binderDied() {
+            Log.d(TAG, "Death of HVAC triggering a restart");
+            if (mCar != null) {
+                mCar.disconnect();
+            }
+            destroyHvacManager();
+            mHandler.postDelayed(() -> mCar.connect(), BIND_TO_HVAC_RETRY_DELAY);
+        }
+    };
+    /**
+     * Registers callbacks and initializes components upon connection.
+     */
+    private ServiceConnection mServiceConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            try {
+                service.linkToDeath(mRestart, 0);
+                mHvacManager = (CarHvacManager) mCar.getCarManager(Car.HVAC_SERVICE);
+                mHvacManager.registerCallback(mHardwareCallback);
+                initComponents();
+            } catch (Exception e) {
+                Log.e(TAG, "Failed to correctly connect to HVAC", e);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            destroyHvacManager();
+        }
+    };
+
+    public HvacController(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Create connection to the Car service. Note: call backs from the Car service
+     * ({@link CarHvacManager}) will happen on the same thread this method was called from.
+     */
+    public void connectToCarService() {
+        mHandler = new Handler();
+        mCar = Car.createCar(mContext, mServiceConnection, mHandler);
+        if (mCar != null) {
+            // note: this connect call handles the retries
+            mCar.connect();
+        }
+    }
+
+    private void destroyHvacManager() {
+        if (mHvacManager != null) {
+            mHvacManager.unregisterCallback(mHardwareCallback);
+            mHvacManager = null;
+        }
+    }
+
+    /**
+     * Add component to list and initialize it if the connection is up.
+     */
+    public void addHvacTextView(TemperatureView temperatureView) {
+
+        HvacKey hvacKey = new HvacKey(temperatureView.getPropertyId(), temperatureView.getAreaId());
+        if (!mTempComponents.containsKey(hvacKey)) {
+            mTempComponents.put(hvacKey, new ArrayList<>());
+        }
+        mTempComponents.get(hvacKey).add(temperatureView);
+        initComponent(temperatureView);
+    }
+
+    private void initComponents() {
+        Iterator<Map.Entry<HvacKey, List<TemperatureView>>> iterator =
+                mTempComponents.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<HvacKey, List<TemperatureView>> next = iterator.next();
+            List<TemperatureView> temperatureViews = next.getValue();
+            for (TemperatureView view : temperatureViews) {
+                initComponent(view);
+            }
+        }
+    }
+
+    private void initComponent(TemperatureView view) {
+        int id = view.getPropertyId();
+        int zone = view.getAreaId();
+        try {
+            if (mHvacManager == null || !mHvacManager.isPropertyAvailable(id, zone)) {
+                view.setTemp(Float.NaN);
+                return;
+            }
+            view.setTemp(mHvacManager.getFloatProperty(id, zone));
+        } catch (Exception e) {
+            view.setTemp(Float.NaN);
+            Log.e(TAG, "Failed to get value from hvac service", e);
+        }
+    }
 
     /**
      * Removes all registered components. This is useful if you need to rebuild the UI since
@@ -200,7 +195,7 @@
         int mPropertyId;
         int mAreaId;
 
-        public HvacKey(int propertyId, int areaId) {
+        private HvacKey(int propertyId, int areaId) {
             mPropertyId = propertyId;
             mAreaId = areaId;
         }
@@ -210,8 +205,8 @@
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
             HvacKey hvacKey = (HvacKey) o;
-            return mPropertyId == hvacKey.mPropertyId &&
-                    mAreaId == hvacKey.mAreaId;
+            return mPropertyId == hvacKey.mPropertyId
+                    && mAreaId == hvacKey.mAreaId;
         }
 
         @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
index 4d8ce43..507c60f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
@@ -40,7 +40,7 @@
     public TemperatureTextView(Context context, AttributeSet attrs) {
         super(context, attrs);
         TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TemperatureView);
-        mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId,-1);
+        mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId, -1);
         mPropertyId = typedArray.getInt(R.styleable.TemperatureView_hvacPropertyId, -1);
         String format = typedArray.getString(R.styleable.TemperatureView_hvacTempFormat);
         mTempFormat = (format == null) ? "%.1f\u00B0" : format;
@@ -48,6 +48,7 @@
 
     /**
      * Formats the float for display
+     *
      * @param temp - The current temp or NaN
      */
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java
rename to packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureView.java
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java
new file mode 100644
index 0000000..71cc19b
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 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.volume;
+
+import android.content.Context;
+
+import com.android.systemui.SystemUI;
+import com.android.systemui.plugins.VolumeDialog;
+
+/**
+ * Allows for adding car specific dialog when the volume dialog is created.
+ */
+public class CarVolumeDialogComponent extends VolumeDialogComponent {
+
+    public CarVolumeDialogComponent(SystemUI sysui, Context context) {
+        super(sysui, context);
+    }
+
+    protected VolumeDialog createDefault() {
+        return new CarVolumeDialogImpl(mContext);
+    }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
new file mode 100644
index 0000000..12df263
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2018 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.volume;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.annotation.DrawableRes;
+import android.annotation.Nullable;
+import android.app.Dialog;
+import android.app.KeyguardManager;
+import android.car.Car;
+import android.car.CarNotConnectedException;
+import android.car.media.CarAudioManager;
+import android.car.media.ICarVolumeCallback;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.ServiceConnection;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.Xml;
+import android.view.ContextThemeWrapper;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+
+import androidx.car.widget.ListItem;
+import androidx.car.widget.ListItemAdapter;
+import androidx.car.widget.ListItemAdapter.BackgroundStyle;
+import androidx.car.widget.ListItemProvider.ListProvider;
+import androidx.car.widget.PagedListView;
+import androidx.car.widget.SeekbarListItem;
+
+import com.android.systemui.R;
+import com.android.systemui.plugins.VolumeDialog;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Car version of the volume dialog.
+ *
+ * Methods ending in "H" must be called on the (ui) handler.
+ */
+public class CarVolumeDialogImpl implements VolumeDialog {
+
+    private static final String TAG = Util.logTag(CarVolumeDialogImpl.class);
+
+    private static final String XML_TAG_VOLUME_ITEMS = "carVolumeItems";
+    private static final String XML_TAG_VOLUME_ITEM = "item";
+    private static final int HOVERING_TIMEOUT = 16000;
+    private static final int NORMAL_TIMEOUT = 3000;
+    private static final int LISTVIEW_ANIMATION_DURATION_IN_MILLIS = 250;
+    private static final int DISMISS_DELAY_IN_MILLIS = 50;
+    private static final int ARROW_FADE_IN_START_DELAY_IN_MILLIS = 100;
+
+    private final Context mContext;
+    private final H mHandler = new H();
+    // All the volume items.
+    private final SparseArray<VolumeItem> mVolumeItems = new SparseArray<>();
+    // Available volume items in car audio manager.
+    private final List<VolumeItem> mAvailableVolumeItems = new ArrayList<>();
+    // Volume items in the PagedListView.
+    private final List<ListItem> mVolumeLineItems = new ArrayList<>();
+    private final KeyguardManager mKeyguard;
+    private Window mWindow;
+    private CustomDialog mDialog;
+    private PagedListView mListView;
+    private ListItemAdapter mPagedListAdapter;
+    private Car mCar;
+    private CarAudioManager mCarAudioManager;
+    private final ICarVolumeCallback mVolumeChangeCallback = new ICarVolumeCallback.Stub() {
+        @Override
+        public void onGroupVolumeChanged(int groupId, int flags) {
+            VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
+            int value = getSeekbarValue(mCarAudioManager, groupId);
+            // Do not update the progress if it is the same as before. When car audio manager sets
+            // its group volume caused by the seekbar progress changed, it also triggers this
+            // callback. Updating the seekbar at the same time could block the continuous seeking.
+            if (value != volumeItem.progress) {
+                volumeItem.listItem.setProgress(value);
+                volumeItem.progress = value;
+            }
+            if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
+                mHandler.obtainMessage(H.SHOW, Events.SHOW_REASON_VOLUME_CHANGED).sendToTarget();
+            }
+        }
+
+        @Override
+        public void onMasterMuteChanged(int flags) {
+            // ignored
+        }
+    };
+    private boolean mHovering;
+    private boolean mShowing;
+    private boolean mExpanded;
+    private final ServiceConnection mServiceConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            try {
+                mExpanded = false;
+                mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
+                int volumeGroupCount = mCarAudioManager.getVolumeGroupCount();
+                // Populates volume slider items from volume groups to UI.
+                for (int groupId = 0; groupId < volumeGroupCount; groupId++) {
+                    VolumeItem volumeItem = getVolumeItemForUsages(
+                            mCarAudioManager.getUsagesForVolumeGroupId(groupId));
+                    mAvailableVolumeItems.add(volumeItem);
+                    // The first one is the default item.
+                    if (groupId == 0) {
+                        volumeItem.defaultItem = true;
+                        addSeekbarListItem(volumeItem, groupId,
+                                R.drawable.car_ic_keyboard_arrow_down,
+                                new ExpandIconListener());
+                    }
+                }
+
+                // If list is already initiated, update its content.
+                if (mPagedListAdapter != null) {
+                    mPagedListAdapter.notifyDataSetChanged();
+                }
+                mCarAudioManager.registerVolumeCallback(mVolumeChangeCallback.asBinder());
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Car is not connected!", e);
+            }
+        }
+
+        /**
+         * This does not get called when service is properly disconnected.
+         * So we need to also handle cleanups in destroy().
+         */
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            cleanupAudioManager();
+        }
+    };
+
+    public CarVolumeDialogImpl(Context context) {
+        mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
+        mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        mCar = Car.createCar(mContext, mServiceConnection);
+    }
+
+    private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
+        try {
+            return carAudioManager.getGroupVolume(volumeGroupId);
+        } catch (CarNotConnectedException e) {
+            Log.e(TAG, "Car is not connected!", e);
+        }
+        return 0;
+    }
+
+    private static int getMaxSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
+        try {
+            return carAudioManager.getGroupMaxVolume(volumeGroupId);
+        } catch (CarNotConnectedException e) {
+            Log.e(TAG, "Car is not connected!", e);
+        }
+        return 0;
+    }
+
+    /**
+     * Build the volume window and connect to the CarService which registers with car audio
+     * manager.
+     */
+    @Override
+    public void init(int windowType, Callback callback) {
+        initDialog();
+
+        mCar.connect();
+    }
+
+    @Override
+    public void destroy() {
+        mHandler.removeCallbacksAndMessages(null);
+
+        cleanupAudioManager();
+        // unregisterVolumeCallback is not being called when disconnect car, so we manually cleanup
+        // audio manager beforehand.
+        mCar.disconnect();
+    }
+
+    private void initDialog() {
+        loadAudioUsageItems();
+        mVolumeLineItems.clear();
+        mDialog = new CustomDialog(mContext);
+
+        mHovering = false;
+        mShowing = false;
+        mExpanded = false;
+        mWindow = mDialog.getWindow();
+        mWindow.requestFeature(Window.FEATURE_NO_TITLE);
+        mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+        mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
+                | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
+        mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
+                | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
+                | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
+        mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+        mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
+        final WindowManager.LayoutParams lp = mWindow.getAttributes();
+        lp.format = PixelFormat.TRANSLUCENT;
+        lp.setTitle(VolumeDialogImpl.class.getSimpleName());
+        lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
+        lp.windowAnimations = -1;
+        mWindow.setAttributes(lp);
+        mWindow.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        mDialog.setCanceledOnTouchOutside(true);
+        mDialog.setContentView(R.layout.car_volume_dialog);
+        mDialog.setOnShowListener(dialog -> {
+            mListView.setTranslationY(-mListView.getHeight());
+            mListView.setAlpha(0);
+            mListView.animate()
+                    .alpha(1)
+                    .translationY(0)
+                    .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
+                    .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
+                    .start();
+        });
+        mListView = (PagedListView) mWindow.findViewById(R.id.volume_list);
+        mListView.setOnHoverListener((v, event) -> {
+            int action = event.getActionMasked();
+            mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
+                    || (action == MotionEvent.ACTION_HOVER_MOVE);
+            rescheduleTimeoutH();
+            return true;
+        });
+
+        mPagedListAdapter = new ListItemAdapter(mContext, new ListProvider(mVolumeLineItems),
+                BackgroundStyle.PANEL);
+        mListView.setAdapter(mPagedListAdapter);
+        mListView.setMaxPages(PagedListView.UNLIMITED_PAGES);
+    }
+
+
+    private void showH(int reason) {
+        if (D.BUG) {
+            Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
+        }
+
+        mHandler.removeMessages(H.SHOW);
+        mHandler.removeMessages(H.DISMISS);
+        rescheduleTimeoutH();
+        // Refresh the data set before showing.
+        mPagedListAdapter.notifyDataSetChanged();
+        if (mShowing) {
+            return;
+        }
+        mShowing = true;
+
+        mDialog.show();
+        Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
+    }
+
+    private void rescheduleTimeoutH() {
+        mHandler.removeMessages(H.DISMISS);
+        final int timeout = computeTimeoutH();
+        mHandler.sendMessageDelayed(mHandler
+                .obtainMessage(H.DISMISS, Events.DISMISS_REASON_TIMEOUT), timeout);
+
+        if (D.BUG) {
+            Log.d(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller());
+        }
+    }
+
+    private int computeTimeoutH() {
+        return mHovering ? HOVERING_TIMEOUT : NORMAL_TIMEOUT;
+    }
+
+    private void dismissH(int reason) {
+        if (D.BUG) {
+            Log.d(TAG, "dismissH r=" + Events.DISMISS_REASONS[reason]);
+        }
+
+        mHandler.removeMessages(H.DISMISS);
+        mHandler.removeMessages(H.SHOW);
+        if (!mShowing) {
+            return;
+        }
+
+        mListView.animate().cancel();
+
+        mListView.setTranslationY(0);
+        mListView.setAlpha(1);
+        mListView.animate()
+                .alpha(0)
+                .translationY(-mListView.getHeight())
+                .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
+                .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
+                .withEndAction(() -> mHandler.postDelayed(() -> {
+                    if (D.BUG) {
+                        Log.d(TAG, "mDialog.dismiss()");
+                    }
+                    mDialog.dismiss();
+                    mShowing = false;
+                }, DISMISS_DELAY_IN_MILLIS))
+                .start();
+
+        Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason);
+    }
+
+    private void loadAudioUsageItems() {
+        try (XmlResourceParser parser = mContext.getResources().getXml(R.xml.car_volume_items)) {
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+            int type;
+            // Traverse to the first start tag
+            while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT
+                    && type != XmlResourceParser.START_TAG) {
+                // Do Nothing (moving parser to start element)
+            }
+
+            if (!XML_TAG_VOLUME_ITEMS.equals(parser.getName())) {
+                throw new RuntimeException("Meta-data does not start with carVolumeItems tag");
+            }
+            int outerDepth = parser.getDepth();
+            int rank = 0;
+            while ((type = parser.next()) != XmlResourceParser.END_DOCUMENT
+                    && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) {
+                if (type == XmlResourceParser.END_TAG) {
+                    continue;
+                }
+                if (XML_TAG_VOLUME_ITEM.equals(parser.getName())) {
+                    TypedArray item = mContext.getResources().obtainAttributes(
+                            attrs, R.styleable.carVolumeItems_item);
+                    int usage = item.getInt(R.styleable.carVolumeItems_item_usage, -1);
+                    if (usage >= 0) {
+                        VolumeItem volumeItem = new VolumeItem();
+                        volumeItem.rank = rank;
+                        volumeItem.icon = item.getResourceId(R.styleable.carVolumeItems_item_icon,
+                                0);
+                        mVolumeItems.put(usage, volumeItem);
+                        rank++;
+                    }
+                    item.recycle();
+                }
+            }
+        } catch (XmlPullParserException | IOException e) {
+            Log.e(TAG, "Error parsing volume groups configuration", e);
+        }
+    }
+
+    private VolumeItem getVolumeItemForUsages(int[] usages) {
+        int rank = Integer.MAX_VALUE;
+        VolumeItem result = null;
+        for (int usage : usages) {
+            VolumeItem volumeItem = mVolumeItems.get(usage);
+            if (volumeItem.rank < rank) {
+                rank = volumeItem.rank;
+                result = volumeItem;
+            }
+        }
+        return result;
+    }
+
+    private SeekbarListItem addSeekbarListItem(VolumeItem volumeItem,
+            int volumeGroupId,
+            int supplementalIconId,
+            @Nullable View.OnClickListener supplementalIconOnClickListener) {
+        SeekbarListItem listItem = new SeekbarListItem(mContext);
+        listItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
+        int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint);
+        int progress = getSeekbarValue(mCarAudioManager, volumeGroupId);
+        listItem.setProgress(progress);
+        listItem.setOnSeekBarChangeListener(new CarVolumeDialogImpl
+                .VolumeSeekBarChangeListener(volumeGroupId, mCarAudioManager));
+        Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon);
+        primaryIcon.mutate().setTint(color);
+        listItem.setPrimaryActionIcon(primaryIcon);
+        if (supplementalIconId != 0) {
+            Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId);
+            supplementalIcon.mutate().setTint(color);
+            listItem.setSupplementalIcon(supplementalIcon, true);
+            listItem.setSupplementalIconListener(supplementalIconOnClickListener);
+        } else {
+            listItem.setSupplementalEmptyIcon(true);
+            listItem.setSupplementalIconListener(null);
+        }
+
+        mVolumeLineItems.add(listItem);
+        volumeItem.listItem = listItem;
+        volumeItem.progress = progress;
+        return listItem;
+    }
+
+    private VolumeItem findVolumeItem(SeekbarListItem targetItem) {
+        for (int i = 0; i < mVolumeItems.size(); ++i) {
+            VolumeItem volumeItem = mVolumeItems.valueAt(i);
+            if (volumeItem.listItem == targetItem) {
+                return volumeItem;
+            }
+        }
+        return null;
+    }
+
+    private void cleanupAudioManager() {
+        try {
+            mCarAudioManager.unregisterVolumeCallback(mVolumeChangeCallback.asBinder());
+        } catch (CarNotConnectedException e) {
+            Log.e(TAG, "Car is not connected!", e);
+        }
+        mVolumeLineItems.clear();
+        mCarAudioManager = null;
+    }
+
+    /**
+     * Wrapper class which contains information of each volume group.
+     */
+    private static class VolumeItem {
+
+        private int rank;
+        private boolean defaultItem = false;
+        private @DrawableRes int icon;
+        private SeekbarListItem listItem;
+        private int progress;
+    }
+
+    private final class H extends Handler {
+
+        private static final int SHOW = 1;
+        private static final int DISMISS = 2;
+
+        private H() {
+            super(Looper.getMainLooper());
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case SHOW:
+                    showH(msg.arg1);
+                    break;
+                case DISMISS:
+                    dismissH(msg.arg1);
+                    break;
+                default:
+            }
+        }
+    }
+
+    private final class CustomDialog extends Dialog implements DialogInterface {
+
+        private CustomDialog(Context context) {
+            super(context, com.android.systemui.R.style.qs_theme);
+        }
+
+        @Override
+        public boolean dispatchTouchEvent(MotionEvent ev) {
+            rescheduleTimeoutH();
+            return super.dispatchTouchEvent(ev);
+        }
+
+        @Override
+        protected void onStart() {
+            super.setCanceledOnTouchOutside(true);
+            super.onStart();
+        }
+
+        @Override
+        protected void onStop() {
+            super.onStop();
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            if (isShowing()) {
+                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+                    mHandler.obtainMessage(
+                            H.DISMISS, Events.DISMISS_REASON_TOUCH_OUTSIDE).sendToTarget();
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    private final class ExpandIconListener implements View.OnClickListener {
+
+        @Override
+        public void onClick(final View v) {
+            mExpanded = !mExpanded;
+            Animator inAnimator;
+            if (mExpanded) {
+                for (int groupId = 0; groupId < mAvailableVolumeItems.size(); ++groupId) {
+                    // Adding the items which are not coming from the default item.
+                    VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
+                    if (volumeItem.defaultItem) {
+                        // Set progress here due to the progress of seekbar may not be updated.
+                        volumeItem.listItem.setProgress(volumeItem.progress);
+                    } else {
+                        addSeekbarListItem(volumeItem, groupId, 0, null);
+                    }
+                }
+                inAnimator = AnimatorInflater.loadAnimator(
+                        mContext, R.anim.car_arrow_fade_in_rotate_up);
+            } else {
+                // Only keeping the default stream if it is not expended.
+                Iterator itr = mVolumeLineItems.iterator();
+                while (itr.hasNext()) {
+                    SeekbarListItem seekbarListItem = (SeekbarListItem) itr.next();
+                    VolumeItem volumeItem = findVolumeItem(seekbarListItem);
+                    if (!volumeItem.defaultItem) {
+                        itr.remove();
+                    } else {
+                        // Set progress here due to the progress of seekbar may not be updated.
+                        seekbarListItem.setProgress(volumeItem.progress);
+                    }
+                }
+                inAnimator = AnimatorInflater.loadAnimator(
+                        mContext, R.anim.car_arrow_fade_in_rotate_down);
+            }
+
+            Animator outAnimator = AnimatorInflater.loadAnimator(
+                    mContext, R.anim.car_arrow_fade_out);
+            inAnimator.setStartDelay(ARROW_FADE_IN_START_DELAY_IN_MILLIS);
+            AnimatorSet animators = new AnimatorSet();
+            animators.playTogether(outAnimator, inAnimator);
+            animators.setTarget(v);
+            animators.start();
+            mPagedListAdapter.notifyDataSetChanged();
+        }
+    }
+
+    private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {
+
+        private final int mVolumeGroupId;
+        private final CarAudioManager mCarAudioManager;
+
+        private VolumeSeekBarChangeListener(int volumeGroupId, CarAudioManager carAudioManager) {
+            mVolumeGroupId = volumeGroupId;
+            mCarAudioManager = carAudioManager;
+        }
+
+        @Override
+        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+            if (!fromUser) {
+                // For instance, if this event is originated from AudioService,
+                // we can ignore it as it has already been handled and doesn't need to be
+                // sent back down again.
+                return;
+            }
+            try {
+                if (mCarAudioManager == null) {
+                    Log.w(TAG, "Ignoring volume change event because the car isn't connected");
+                    return;
+                }
+                mAvailableVolumeItems.get(mVolumeGroupId).progress = progress;
+                mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Car is not connected!", e);
+            }
+        }
+
+        @Override
+        public void onStartTrackingTouch(SeekBar seekBar) {
+        }
+
+        @Override
+        public void onStopTrackingTouch(SeekBar seekBar) {
+        }
+    }
+}
diff --git a/packages/CarrierDefaultApp/OWNERS b/packages/CarrierDefaultApp/OWNERS
index 7057ce6..aef6a3c 100644
--- a/packages/CarrierDefaultApp/OWNERS
+++ b/packages/CarrierDefaultApp/OWNERS
@@ -9,4 +9,5 @@
 jminjie@google.com
 satk@google.com
 shuoq@google.com
-refuhoo@google.com
\ No newline at end of file
+refuhoo@google.com
+nazaninb@google.com
\ No newline at end of file
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index 4b212c2..0cad5af 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -19,8 +19,7 @@
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
 import static android.service.notification.Adjustment.KEY_IMPORTANCE;
-import static android.service.notification.NotificationListenerService.Ranking
-        .USER_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -241,7 +240,7 @@
             signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, smartReplies);
         }
         if (Settings.Secure.getInt(getContentResolver(),
-                Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 0) == 1) {
+                Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 1) == 1) {
             if (mNotificationCategorizer.shouldSilence(entry)) {
                 final int importance = entry.getImportance() < IMPORTANCE_LOW
                         ? entry.getImportance() : IMPORTANCE_LOW;
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
index b2fc417..892267b 100644
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
@@ -48,7 +48,7 @@
                     | Notification.FLAG_NO_CLEAR;
     private static final int MAX_ACTION_EXTRACTION_TEXT_LENGTH = 400;
     private static final int MAX_ACTIONS_PER_LINK = 1;
-    private static final int MAX_SMART_ACTIONS = Notification.MAX_ACTION_BUTTONS;
+    private static final int MAX_SMART_ACTIONS = 3;
     private static final int MAX_SUGGESTED_REPLIES = 3;
 
     private static final ConversationActions.TypeConfig TYPE_CONFIG =
@@ -81,12 +81,9 @@
         if (tcm == null) {
             return EMPTY_ACTION_LIST;
         }
-        Notification.Action[] actions = entry.getNotification().actions;
-        int numOfExistingActions = actions == null ? 0: actions.length;
-        int maxSmartActions = MAX_SMART_ACTIONS - numOfExistingActions;
         return suggestActionsFromText(
                 tcm,
-                getMostSalientActionText(entry.getNotification()), maxSmartActions);
+                getMostSalientActionText(entry.getNotification()), MAX_SMART_ACTIONS);
     }
 
     ArrayList<CharSequence> suggestReplies(
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index c9ee5c8..1eb4b74 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -224,7 +224,7 @@
                 root.flags |= Root.FLAG_REMOVABLE_USB;
             }
 
-            if (!VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
+            if (volume.getType() != VolumeInfo.TYPE_EMULATED) {
                 root.flags |= Root.FLAG_SUPPORTS_EJECT;
             }
 
diff --git a/packages/PrintSpooler/res/layout/print_activity.xml b/packages/PrintSpooler/res/layout/print_activity.xml
index 0ccf13e..9e16f5e 100644
--- a/packages/PrintSpooler/res/layout/print_activity.xml
+++ b/packages/PrintSpooler/res/layout/print_activity.xml
@@ -107,7 +107,7 @@
         android:layout_height="wrap_content"
         android:layout_marginStart="16dip"
         android:elevation="@dimen/preview_controls_elevation"
-        android:tint="?android:attr/textColorPrimaryInverse"
+        android:tint="@android:color/white"
         android:background="@drawable/print_button">
     </ImageButton>
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java
deleted file mode 100644
index e9c5238..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2018 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.settingslib.net;
-
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.SET_FOREGROUND;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
-import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-
-import android.content.Context;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import androidx.loader.content.AsyncTaskLoader;
-
-import com.android.settingslib.AppItem;
-
-/**
- * Loader for historical chart data for both network and UID details.
- *
- * Deprecated in favor of {@link NetworkCycleChartDataLoader} and
- * {@link NetworkCycleDataForUidLoader}
- *
- * @deprecated
- */
-@Deprecated
-public class ChartDataLoaderCompat extends AsyncTaskLoader<ChartData> {
-    private static final String KEY_TEMPLATE = "template";
-    private static final String KEY_APP = "app";
-    private static final String KEY_FIELDS = "fields";
-
-    private final INetworkStatsSession mSession;
-    private final Bundle mArgs;
-
-    public static Bundle buildArgs(NetworkTemplate template, AppItem app) {
-        return buildArgs(template, app, FIELD_RX_BYTES | FIELD_TX_BYTES);
-    }
-
-    public static Bundle buildArgs(NetworkTemplate template, AppItem app, int fields) {
-        final Bundle args = new Bundle();
-        args.putParcelable(KEY_TEMPLATE, template);
-        args.putParcelable(KEY_APP, app);
-        args.putInt(KEY_FIELDS, fields);
-        return args;
-    }
-
-    public ChartDataLoaderCompat(Context context, INetworkStatsSession session, Bundle args) {
-        super(context);
-        mSession = session;
-        mArgs = args;
-    }
-
-    @Override
-    protected void onStartLoading() {
-        super.onStartLoading();
-        forceLoad();
-    }
-
-    @Override
-    public ChartData loadInBackground() {
-        final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
-        final AppItem app = mArgs.getParcelable(KEY_APP);
-        final int fields = mArgs.getInt(KEY_FIELDS);
-
-        try {
-            return loadInBackground(template, app, fields);
-        } catch (RemoteException e) {
-            // since we can't do much without history, and we don't want to
-            // leave with half-baked UI, we bail hard.
-            throw new RuntimeException("problem reading network stats", e);
-        }
-    }
-
-    private ChartData loadInBackground(NetworkTemplate template, AppItem app, int fields)
-            throws RemoteException {
-        final ChartData data = new ChartData();
-        data.network = mSession.getHistoryForNetwork(template, fields);
-
-        if (app != null) {
-            // load stats for current uid and template
-            final int size = app.uids.size();
-            for (int i = 0; i < size; i++) {
-                final int uid = app.uids.keyAt(i);
-                data.detailDefault = collectHistoryForUid(
-                        template, uid, SET_DEFAULT, data.detailDefault);
-                data.detailForeground = collectHistoryForUid(
-                        template, uid, SET_FOREGROUND, data.detailForeground);
-            }
-
-            if (size > 0) {
-                data.detail = new NetworkStatsHistory(data.detailForeground.getBucketDuration());
-                data.detail.recordEntireHistory(data.detailDefault);
-                data.detail.recordEntireHistory(data.detailForeground);
-            } else {
-                data.detailDefault = new NetworkStatsHistory(HOUR_IN_MILLIS);
-                data.detailForeground = new NetworkStatsHistory(HOUR_IN_MILLIS);
-                data.detail = new NetworkStatsHistory(HOUR_IN_MILLIS);
-            }
-        }
-
-        return data;
-    }
-
-    @Override
-    protected void onStopLoading() {
-        super.onStopLoading();
-        cancelLoad();
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-        cancelLoad();
-    }
-
-    /**
-     * Collect {@link NetworkStatsHistory} for the requested UID, combining with
-     * an existing {@link NetworkStatsHistory} if provided.
-     */
-    private NetworkStatsHistory collectHistoryForUid(
-            NetworkTemplate template, int uid, int set, NetworkStatsHistory existing)
-            throws RemoteException {
-        final NetworkStatsHistory history = mSession.getHistoryForUid(
-                template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
-
-        if (existing != null) {
-            existing.recordEntireHistory(history);
-            return existing;
-        } else {
-            return history;
-        }
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 183d485..180b77e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -32,30 +32,24 @@
 import android.net.INetworkStatsSession;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
-import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
-import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.util.Range;
 
 import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
 
 import java.time.ZonedDateTime;
-import java.util.Date;
 import java.util.Iterator;
 import java.util.Locale;
 
 public class DataUsageController {
 
     private static final String TAG = "DataUsageController";
-    @VisibleForTesting
-    static final String DATA_USAGE_V2 = "settings_data_usage_v2";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final int FIELDS = FIELD_RX_BYTES | FIELD_TX_BYTES;
     private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50);
@@ -95,21 +89,6 @@
                 * mContext.getResources().getInteger(R.integer.default_data_warning_level_mb);
     }
 
-    @VisibleForTesting
-    @Deprecated
-    INetworkStatsSession getSession() {
-        if (mSession == null) {
-            try {
-                mSession = mStatsService.openSession();
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to open stats session", e);
-            } catch (RuntimeException e) {
-                Log.w(TAG, "Failed to open stats session", e);
-            }
-        }
-        return mSession;
-    }
-
     public void setCallback(Callback callback) {
         mCallback = callback;
     }
@@ -149,13 +128,7 @@
             end = now;
             start = now - DateUtils.WEEK_IN_MILLIS * 4;
         }
-        final long totalBytes;
-        final long callStart = System.currentTimeMillis();
-        if (FeatureFlagUtils.isEnabled(mContext, DATA_USAGE_V2)) {
-            totalBytes = getUsageLevel(template, start, end);
-        } else {
-            totalBytes = getUsageLevel(template, start, end, now);
-        }
+        final long totalBytes = getUsageLevel(template, start, end);
         if (totalBytes < 0L) {
             return warn("no entry data");
         }
@@ -185,32 +158,7 @@
      * retrieving the data.
      */
     public long getHistoricalUsageLevel(NetworkTemplate template) {
-        if (FeatureFlagUtils.isEnabled(mContext, DATA_USAGE_V2)) {
-            return getUsageLevel(template, 0L /* start */, System.currentTimeMillis() /* end */);
-        } else {
-            final long now = System.currentTimeMillis();
-            return getUsageLevel(template, 0L /* start */, now /* end */, now);
-        }
-    }
-
-    @Deprecated
-    private long getUsageLevel(NetworkTemplate template, long start, long end, long now) {
-        final INetworkStatsSession session = getSession();
-        if (session != null) {
-            try {
-                final NetworkStatsHistory history =
-                    session.getHistoryForNetwork(template, FIELDS);
-                final NetworkStatsHistory.Entry entry = history.getValues(
-                        start, end, System.currentTimeMillis() /* now */, null /* recycle */);
-                if (entry != null) {
-                    return entry.rxBytes + entry.txBytes;
-                }
-                Log.w(TAG, "Failed to get data usage, no entry data");
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to get data usage, remote call failed");
-            }
-        }
-        return -1L;
+        return getUsageLevel(template, 0L /* start */, System.currentTimeMillis() /* end */);
     }
 
     private long getUsageLevel(NetworkTemplate template, long start, long end) {
@@ -241,20 +189,6 @@
         return null;
     }
 
-    @Deprecated
-    private static String historyEntryToString(NetworkStatsHistory.Entry entry) {
-        return entry == null ? null : new StringBuilder("Entry[")
-                .append("bucketDuration=").append(entry.bucketDuration)
-                .append(",bucketStart=").append(entry.bucketStart)
-                .append(",activeTime=").append(entry.activeTime)
-                .append(",rxBytes=").append(entry.rxBytes)
-                .append(",rxPackets=").append(entry.rxPackets)
-                .append(",txBytes=").append(entry.txBytes)
-                .append(",txPackets=").append(entry.txPackets)
-                .append(",operations=").append(entry.operations)
-                .append(']').toString();
-    }
-
     private static String statsBucketToString(Bucket bucket) {
         return bucket == null ? null : new StringBuilder("Entry[")
             .append("bucketDuration=").append(bucket.getEndTimeStamp() - bucket.getStartTimeStamp())
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoaderCompat.java
deleted file mode 100644
index 82bb011..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoaderCompat.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2018 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.settingslib.net;
-
-import android.content.Context;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStats;
-import android.net.NetworkTemplate;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import androidx.loader.content.AsyncTaskLoader;
-
-/**
- * Deprecated in favor of {@link NetworkStatsDetailLoader}
- *
- * @deprecated
- */
-@Deprecated
-public class SummaryForAllUidLoaderCompat extends AsyncTaskLoader<NetworkStats> {
-    private static final String KEY_TEMPLATE = "template";
-    private static final String KEY_START = "start";
-    private static final String KEY_END = "end";
-
-    private final INetworkStatsSession mSession;
-    private final Bundle mArgs;
-
-    public static Bundle buildArgs(NetworkTemplate template, long start, long end) {
-        final Bundle args = new Bundle();
-        args.putParcelable(KEY_TEMPLATE, template);
-        args.putLong(KEY_START, start);
-        args.putLong(KEY_END, end);
-        return args;
-    }
-
-    public SummaryForAllUidLoaderCompat(Context context, INetworkStatsSession session,
-            Bundle args) {
-        super(context);
-        mSession = session;
-        mArgs = args;
-    }
-
-    @Override
-    protected void onStartLoading() {
-        super.onStartLoading();
-        forceLoad();
-    }
-
-    @Override
-    public NetworkStats loadInBackground() {
-        final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
-        final long start = mArgs.getLong(KEY_START);
-        final long end = mArgs.getLong(KEY_END);
-
-        try {
-            return mSession.getSummaryForAllUid(template, start, end, false);
-        } catch (RemoteException e) {
-            return null;
-        }
-    }
-
-    @Override
-    protected void onStopLoading() {
-        super.onStopLoading();
-        cancelLoad();
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-        cancelLoad();
-    }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index 72ed5e1..acf99a2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyLong;
@@ -35,12 +34,10 @@
 import android.net.ConnectivityManager;
 import android.net.INetworkStatsSession;
 import android.net.NetworkStatsHistory;
-import android.net.NetworkStatsHistory.Entry;
 import android.net.NetworkTemplate;
 import android.os.RemoteException;
 import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
-import android.util.FeatureFlagUtils;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,7 +45,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 @RunWith(RobolectricTestRunner.class)
 public class DataUsageControllerTest {
@@ -61,16 +57,18 @@
     private TelephonyManager mTelephonyManager;
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
-
+    @Mock
     private Context mContext;
+
     private DataUsageController mController;
     private NetworkStatsHistory mNetworkStatsHistory;
 
     @Before
     public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
-        mController = spy(new DataUsageController(mContext));
+        when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+        mController = new DataUsageController(mContext);
         mNetworkStatsHistory = spy(
                 new NetworkStatsHistory(DateUtils.DAY_IN_MILLIS /* bucketDuration */));
         doReturn(mNetworkStatsHistory)
@@ -79,75 +77,25 @@
     }
 
     @Test
-    public void getHistoricalUsageLevel_v1_noNetworkSession_shouldReturnNegative1() {
-        FeatureFlagUtils.setEnabled(mContext, DataUsageController.DATA_USAGE_V2, false);
-        doReturn(null).when(mController).getSession();
+    public void getHistoricalUsageLevel_shouldQuerySummaryForDevice() throws Exception {
 
-        assertThat(mController.getHistoricalUsageLevel(null /* template */)).isEqualTo(-1L);
-    }
-
-    @Test
-    public void getHistoriclUsageLevel_v1_noUsageData_shouldReturn0() {
-        FeatureFlagUtils.setEnabled(mContext, DataUsageController.DATA_USAGE_V2, false);
-        doReturn(mSession).when(mController).getSession();
-
-        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
-                .isEqualTo(0L);
-    }
-
-    @Test
-    public void getHistoricalUsageLevel_v1_hasUsageData_shouldReturnTotalUsage() {
-        FeatureFlagUtils.setEnabled(mContext, DataUsageController.DATA_USAGE_V2, false);
-        doReturn(mSession).when(mController).getSession();
-        final long receivedBytes = 743823454L;
-        final long transmittedBytes = 16574289L;
-        final Entry entry = new Entry();
-        entry.bucketStart = 1521583200000L;
-        entry.rxBytes = receivedBytes;
-        entry.txBytes = transmittedBytes;
-        when(mNetworkStatsHistory.getValues(eq(0L), anyLong(), anyLong(), nullable(Entry.class)))
-                .thenReturn(entry);
-
-        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
-                .isEqualTo(receivedBytes + transmittedBytes);
-    }
-
-    @Test
-    public void getHistoricalUsageLevel_v2_shouldQuerySummaryForDevice() throws Exception {
-        final Context context = mock(Context.class);
-        FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
-        when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
-        final DataUsageController controller = new DataUsageController(context);
-
-        controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard());
+        mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard());
 
         verify(mNetworkStatsManager).querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
                 eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */);
     }
 
     @Test
-    public void getHistoricalUsageLevel_v2NoUsageData_shouldReturn0() throws Exception {
-        final Context context = mock(Context.class);
-        FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
-        when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+    public void getHistoricalUsageLevel_noUsageData_shouldReturn0() throws Exception {
         when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
                 eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */))
                 .thenReturn(mock(NetworkStats.Bucket.class));
-        final DataUsageController controller = new DataUsageController(context);
-
-        assertThat(controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
             .isEqualTo(0L);
     }
 
     @Test
-    public void getHistoricalUsageLevel_v2HasUsageData_shouldReturnTotalUsage()
-            throws Exception {
-        final Context context = mock(Context.class);
-        FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
-        when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
-        when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+    public void getHistoricalUsageLevel_hasUsageData_shouldReturnTotalUsage() throws Exception {
         final long receivedBytes = 743823454L;
         final long transmittedBytes = 16574289L;
         final NetworkStats.Bucket bucket = mock(NetworkStats.Bucket.class);
@@ -155,9 +103,8 @@
         when(bucket.getTxBytes()).thenReturn(transmittedBytes);
         when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
                 eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */)).thenReturn(bucket);
-        final DataUsageController controller = new DataUsageController(context);
 
-        assertThat(controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
                 .isEqualTo(receivedBytes + transmittedBytes);
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 56b768f..df5b146 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1165,6 +1165,12 @@
                 GlobalSettingsProto.SmartSelection.UPDATE_METADATA_URL);
         p.end(smartSelectToken);
 
+        final long smartSuggestionsToken = p.start(GlobalSettingsProto.SMART_SUGGESTIONS);
+        dumpSetting(s, p,
+                Settings.Global.SMART_SUGGESTIONS_SERVICE_EXPLICITLY_ENABLED,
+                GlobalSettingsProto.SmartSuggestions.SERVICE_EXPLICITLY_ENABLED);
+        p.end(smartSuggestionsToken);
+
         final long smsToken = p.start(GlobalSettingsProto.SMS);
         dumpSetting(s, p,
                 Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
@@ -1306,6 +1312,9 @@
         dumpSetting(s, p,
                 Settings.Global.WARNING_TEMPERATURE,
                 GlobalSettingsProto.TemperatureWarning.WARNING_TEMPERATURE_LEVEL);
+        dumpSetting(s, p,
+                Settings.Global.USB_ALARM_TEMPERATURE,
+                GlobalSettingsProto.TemperatureWarning.USB_ALARM_TEMPERATURE_LEVEL);
         p.end(tempWarningToken);
 
         final long tetherToken = p.start(GlobalSettingsProto.TETHER);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index cb55231..83e8369 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -130,6 +130,7 @@
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
     <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
     <uses-permission android:name="android.permission.MANAGE_AUTO_FILL" />
+    <uses-permission android:name="android.permission.MANAGE_SMART_SUGGESTIONS" />
     <uses-permission android:name="android.permission.NETWORK_SETTINGS" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.SET_TIME" />
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 0b9b27f..7d53c2f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -223,6 +223,9 @@
 
     <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" />
 
+    <!-- Permission to change the display color -->
+    <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
+
     <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml
deleted file mode 100644
index 3cc98d8..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="500"
-        android:propertyXName="translateX"
-        android:propertyYName="translateY"
-        android:pathData="M 0,0 c 31.33333,0 156.66667,0 188,0 "
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml
deleted file mode 100644
index eda843d..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="33"
-            android:propertyXName="translateX"
-            android:propertyYName="translateY"
-            android:pathData="M -12,18 L -12,18" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyXName="translateX"
-            android:propertyYName="translateY"
-            android:pathData="M -12,18 c 31.33333,0 156.66667,0 188,0 "
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml
deleted file mode 100644
index cab3d5c..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="67"
-            android:propertyXName="translateX"
-            android:propertyYName="translateY"
-            android:pathData="M -24,36 L -24,36" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyXName="translateX"
-            android:propertyYName="translateY"
-            android:pathData="M -24,36 c 31.33333,0 156.66667,0 188,0 "
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml
deleted file mode 100644
index e435d9a..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="150"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml
deleted file mode 100644
index e31a7db..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="183"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml
deleted file mode 100644
index 2409612..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="217"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="1"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="100"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1"
-            android:valueTo="0"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/fab_elevation.xml b/packages/SystemUI/res/anim/fab_elevation.xml
deleted file mode 100644
index 2c76a86..0000000
--- a/packages/SystemUI/res/anim/fab_elevation.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_enabled="true" android:state_pressed="true">
-        <set>
-            <objectAnimator
-                android:duration="@android:integer/config_shortAnimTime"
-                android:propertyName="translationZ"
-                android:valueTo="@dimen/fab_press_translation_z"
-                android:valueType="floatType" />
-        </set>
-    </item>
-    <item>
-        <set>
-            <objectAnimator
-                android:duration="@android:integer/config_shortAnimTime"
-                android:propertyName="translationZ"
-                android:valueTo="0"
-                android:valueType="floatType" />
-        </set>
-    </item>
-</selector>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
deleted file mode 100644
index 8fdad80..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="-90.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
deleted file mode 100644
index 3c3c131..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
deleted file mode 100644
index 57132e1..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="466"
-        android:propertyName="scaleX"
-        android:valueFrom="1.0"
-        android:valueTo="0.909"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
-    <objectAnimator
-        android:duration="466"
-        android:propertyName="scaleY"
-        android:valueFrom="1.0"
-        android:valueTo="0.909"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="rotation"
-            android:valueFrom="0.0"
-            android:valueTo="45.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
deleted file mode 100644
index ad2a5fa..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.9"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.9"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
deleted file mode 100644
index cdb7890..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="0.0"
-        android:valueTo="-221.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
deleted file mode 100644
index 46100b4..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
deleted file mode 100644
index 8f6d24d..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="400"
-        android:propertyName="rotation"
-        android:valueFrom="0.0"
-        android:valueTo="-135.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
deleted file mode 100644
index 300ed53..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="66"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="216"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
deleted file mode 100644
index ad2a5fa..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleX"
-            android:valueFrom="1.0"
-            android:valueTo="0.9"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="333"
-            android:propertyName="scaleY"
-            android:valueFrom="1.0"
-            android:valueTo="0.9"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
deleted file mode 100644
index c152152..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="0.0"
-        android:valueTo="-180.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
deleted file mode 100644
index b2c1eb8..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="200"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="1.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
deleted file mode 100644
index 2a9bbe3..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleX"
-            android:valueFrom="0.909"
-            android:valueTo="0.909"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="scaleX"
-            android:valueFrom="0.909"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
-    </set>
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="116"
-            android:propertyName="scaleY"
-            android:valueFrom="0.909"
-            android:valueTo="0.909"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="166"
-            android:propertyName="scaleY"
-            android:valueFrom="0.909"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
-    </set>
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="45.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
deleted file mode 100644
index ce26770..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="466"
-        android:propertyName="scaleX"
-        android:valueFrom="0.9"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
-    <objectAnimator
-        android:duration="466"
-        android:propertyName="scaleY"
-        android:valueFrom="0.9"
-        android:valueTo="1.0"
-        android:valueType="floatType"
-        android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
deleted file mode 100644
index 6e8941d..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <objectAnimator
-        android:duration="616"
-        android:propertyName="rotation"
-        android:valueFrom="-221.0"
-        android:valueTo="0.0"
-        android:valueType="floatType"
-        android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
deleted file mode 100644
index 3c3c131..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="83"
-            android:propertyName="fillAlpha"
-            android:valueFrom="0.0"
-            android:valueTo="1.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
deleted file mode 100644
index fd8e4f8..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="rotation"
-            android:valueFrom="-135.0"
-            android:valueTo="-135.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="400"
-            android:propertyName="rotation"
-            android:valueFrom="-135.0"
-            android:valueTo="0.0"
-            android:valueType="floatType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
deleted file mode 100644
index a77a536..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?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.
--->
-<set
-    xmlns:android="http://schemas.android.com/apk/res/android" >
-    <set
-        android:ordering="sequentially" >
-        <objectAnimator
-            android:duration="50"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/linear" />
-        <objectAnimator
-            android:duration="500"
-            android:propertyName="pathData"
-            android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
-            android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
-            android:valueType="pathType"
-            android:interpolator="@android:interpolator/fast_out_slow_in" />
-    </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_blink_1.xml b/packages/SystemUI/res/anim/ic_signal_blink_1.xml
deleted file mode 100644
index 64580d1..0000000
--- a/packages/SystemUI/res/anim/ic_signal_blink_1.xml
+++ /dev/null
@@ -1,38 +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.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:duration="@integer/carrier_network_change_anim_time"
-    android:repeatCount="-1">
-
-    <propertyValuesHolder
-        android:propertyName="fillColor"
-        android:valueType="colorType">
-        <keyframe
-            android:fraction="0.0"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="0.32"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="0.33"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="1.0"
-            android:value="?attr/backgroundColor"/>
-    </propertyValuesHolder>
-
-</objectAnimator>
diff --git a/packages/SystemUI/res/anim/ic_signal_blink_2.xml b/packages/SystemUI/res/anim/ic_signal_blink_2.xml
deleted file mode 100644
index f055cd07..0000000
--- a/packages/SystemUI/res/anim/ic_signal_blink_2.xml
+++ /dev/null
@@ -1,44 +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.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:duration="@integer/carrier_network_change_anim_time"
-    android:repeatCount="-1">
-
-    <propertyValuesHolder
-        android:propertyName="fillColor"
-        android:valueType="colorType">
-        <keyframe
-            android:fraction="0.0"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="0.32"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="0.33"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="0.66"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="0.67"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="1.0"
-            android:value="?attr/backgroundColor"/>
-    </propertyValuesHolder>
-
-</objectAnimator>
diff --git a/packages/SystemUI/res/anim/ic_signal_blink_3.xml b/packages/SystemUI/res/anim/ic_signal_blink_3.xml
deleted file mode 100644
index abcd774..0000000
--- a/packages/SystemUI/res/anim/ic_signal_blink_3.xml
+++ /dev/null
@@ -1,38 +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.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@android:anim/linear_interpolator"
-    android:duration="@integer/carrier_network_change_anim_time"
-    android:repeatCount="-1">
-
-    <propertyValuesHolder
-        android:propertyName="fillColor"
-        android:valueType="colorType">
-        <keyframe
-            android:fraction="0.0"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="0.66"
-            android:value="?attr/backgroundColor"/>
-        <keyframe
-            android:fraction="0.67"
-            android:value="?attr/fillColor"/>
-        <keyframe
-            android:fraction="1.0"
-            android:value="?attr/fillColor"/>
-    </propertyValuesHolder>
-
-</objectAnimator>
diff --git a/packages/SystemUI/res/anim/system_out.xml b/packages/SystemUI/res/anim/system_out.xml
deleted file mode 100644
index 4717e47..0000000
--- a/packages/SystemUI/res/anim/system_out.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <alpha android:toAlpha="0.0" android:fromAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/drawable/car_ic_music.xml b/packages/SystemUI/res/drawable/car_ic_music.xml
deleted file mode 100644
index f90cd69..0000000
--- a/packages/SystemUI/res/drawable/car_ic_music.xml
+++ /dev/null
@@ -1,30 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="56dp"
-    android:height="56dp"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
-
-  <path
-      android:fillAlpha=".1"
-      android:strokeAlpha=".1"
-      android:pathData="M0 0h48v48H0z" />
-  <path
-      android:fillColor="@color/car_grey_50"
-      android:pathData="M24 2C14.06 2 6 10.06 6 20v14c0 3.31 2.69 6 6 6h6V24h-8v-4c0-7.73 6.27-14
-14-14s14 6.27 14 14v4h-8v16h6c3.31 0 6-2.69 6-6V20c0-9.94-8.06-18-18-18z" />
-</vector>
diff --git a/packages/SystemUI/res/drawable/car_ic_navigation.xml b/packages/SystemUI/res/drawable/car_ic_navigation.xml
deleted file mode 100644
index 328efa0..0000000
--- a/packages/SystemUI/res/drawable/car_ic_navigation.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2018 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="32dp"
-    android:height="37dp"
-    android:viewportWidth="32.0"
-    android:viewportHeight="37.0">
-  <path
-      android:pathData="M16.62,0.61L31.33,35.21C31.55,35.72 31.31,36.3 30.8,36.52C30.48,36.66 30.12,36.62 29.83,36.42L15.7,26.44L1.58,36.42C1.13,36.73 0.5,36.63 0.18,36.18C-0.02,35.89 -0.06,35.53 0.08,35.21L14.78,0.61C15,0.1 15.59,-0.14 16.1,0.08C16.33,0.18 16.52,0.37 16.62,0.61Z"
-      android:strokeColor="#00000000"
-      android:fillType="evenOdd"
-      android:fillColor="@color/car_grey_50"
-      android:strokeWidth="1"/>
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/car_ic_notification.xml b/packages/SystemUI/res/drawable/car_ic_notification.xml
deleted file mode 100644
index 61d937b90..0000000
--- a/packages/SystemUI/res/drawable/car_ic_notification.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
-    Copyright (C) 2018 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="56dp"
-    android:height="56dp"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
-
-    <path
-        android:fillColor="#FFFFFF"
-        android:pathData="M24 44c2.21 0 4-1.79 4-4h-8c0 2.21 1.79 4 4
-4zm12-12V22c0-6.15-3.27-11.28-9-12.64V8c0-1.66-1.34-3-3-3s-3 1.34-3 3v1.36c-5.73
-1.36-9 6.49-9 12.64v10l-4 4v2h32v-2l-4-4zm-4 2H16V22c0-4.97 3.03-9 8-9s8 4.03 8
-9v12z" />
-</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/car_ic_overview.xml b/packages/SystemUI/res/drawable/car_ic_overview.xml
deleted file mode 100644
index 4651dcb..0000000
--- a/packages/SystemUI/res/drawable/car_ic_overview.xml
+++ /dev/null
@@ -1,28 +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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="56dp"
-    android:height="56dp"
-    android:viewportWidth="48"
-    android:viewportHeight="48">
-
-    <path
-        android:pathData="M0 0h48v48H0z" />
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm0 36c-8.82
-0-16-7.18-16-16S15.18 8 24 8s16 7.18 16 16-7.18 16-16 16z" />
-</vector>
diff --git a/packages/SystemUI/res/drawable/car_rounded_bg_bottom.xml b/packages/SystemUI/res/drawable/car_rounded_bg_bottom.xml
deleted file mode 100644
index 25b449a..0000000
--- a/packages/SystemUI/res/drawable/car_rounded_bg_bottom.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-    <solid android:color="?android:attr/colorBackgroundFloating" />
-    <corners
-        android:bottomLeftRadius="@dimen/car_radius_3"
-        android:topLeftRadius="0dp"
-        android:bottomRightRadius="@dimen/car_radius_3"
-        android:topRightRadius="0dp"
-        />
-</shape>
diff --git a/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml b/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml
deleted file mode 100644
index 9e71cbe..0000000
--- a/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/dismiss_all_shape" >
-    <target
-        android:name="3"
-        android:animation="@anim/dismiss_all_shape_animation_3" />
-    <target
-        android:name="rectangle_path_1_2"
-        android:animation="@anim/dismiss_all_shape_animation_rectangle_path_1_2" />
-    <target
-        android:name="2"
-        android:animation="@anim/dismiss_all_shape_animation_2" />
-    <target
-        android:name="rectangle_path_1_1"
-        android:animation="@anim/dismiss_all_shape_animation_rectangle_path_1_1" />
-    <target
-        android:name="1"
-        android:animation="@anim/dismiss_all_shape_animation_1" />
-    <target
-        android:name="rectangle_path_1"
-        android:animation="@anim/dismiss_all_shape_animation_rectangle_path_1" />
-</animated-vector>
diff --git a/packages/SystemUI/res/layout/car_navigation_bar.xml b/packages/SystemUI/res/layout/car_navigation_bar.xml
deleted file mode 100644
index d568d0d..0000000
--- a/packages/SystemUI/res/layout/car_navigation_bar.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2016, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<com.android.systemui.statusbar.car.CarNavigationBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@drawable/system_bar_background">
-
-    <LinearLayout
-        android:layout_height="match_parent"
-        android:layout_width="wrap_content"
-        android:orientation="horizontal"
-        android:id="@+id/nav_buttons"
-        android:gravity="left"
-        android:paddingLeft="30dp"
-        android:layout_weight="1"
-        android:animateLayoutChanges="true">
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/home"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
-            android:src="@drawable/car_ic_overview"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="30dp"
-            android:paddingRight="30dp"
-        />
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/hvac"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
-            systemui:broadcast="true"
-            android:src="@drawable/car_ic_hvac"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="30dp"
-            android:paddingRight="30dp"
-        />
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:gravity="right"
-        android:orientation="horizontal">
-
-        <com.android.keyguard.AlphaOptimizedImageButton
-            android:id="@+id/notifications"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            android:src="@drawable/car_ic_notification"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="20dp"
-            android:paddingRight="20dp"
-            android:alpha="0.7"
-        />
-
-        <com.android.systemui.statusbar.policy.Clock
-            android:id="@+id/clock"
-            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:singleLine="true"
-            android:paddingStart="@dimen/status_bar_clock_starting_padding"
-            android:paddingEnd="@dimen/status_bar_clock_end_padding"
-            android:gravity="center_vertical"
-            android:paddingRight="20dp"
-        />
-
-        <Space
-            android:layout_width="10dp"
-            android:layout_height="match_parent"/>
-
-    </LinearLayout>
-
-</com.android.systemui.statusbar.car.CarNavigationBarView>
-
diff --git a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
deleted file mode 100644
index 4ba6c06..0000000
--- a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.systemui.statusbar.car.CarNavigationBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@drawable/system_bar_background">
-
-    <LinearLayout
-        android:layout_height="match_parent"
-        android:layout_width="wrap_content"
-        android:orientation="horizontal"
-        android:id="@+id/nav_buttons"
-        android:gravity="left"
-        android:paddingLeft="30dp"
-        android:layout_weight="1"
-        android:animateLayoutChanges="true">
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/home"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
-            android:src="@drawable/car_ic_overview"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="30dp"
-            android:paddingRight="30dp"
-        />
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/hvac"
-            android:layout_height="match_parent"
-            android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
-            systemui:broadcast="true"
-            android:src="@drawable/car_ic_hvac"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingLeft="30dp"
-            android:paddingRight="30dp"
-        />
-    </LinearLayout>
-</com.android.systemui.statusbar.car.CarNavigationBarView>
-
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar.xml b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
deleted file mode 100644
index 91ba026..0000000
--- a/packages/SystemUI/res/layout/car_right_navigation_bar.xml
+++ /dev/null
@@ -1,101 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2016, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<com.android.systemui.statusbar.car.CarNavigationBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:systemui="http://schemas.android.com/apk/res-auto"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:orientation="vertical"
-    android:background="@drawable/system_bar_background">
-
-    <LinearLayout
-        android:layout_height="match_parent"
-        android:layout_width="match_parent"
-        android:id="@+id/nav_buttons"
-        android:orientation="vertical"
-        android:gravity="top"
-        android:paddingTop="30dp"
-        android:layout_weight="1"
-        android:background="@drawable/system_bar_background"
-        android:animateLayoutChanges="true">
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/home"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
-            android:src="@drawable/car_ic_overview"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingTop="30dp"
-            android:paddingBottom="30dp"
-        />
-
-        <com.android.systemui.statusbar.car.CarNavigationButton
-            android:id="@+id/hvac"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
-            systemui:broadcast="true"
-            android:src="@drawable/car_ic_hvac"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingTop="30dp"
-            android:paddingBottom="30dp"
-        />
-
-    </LinearLayout>
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:gravity="bottom"
-        android:orientation="vertical">
-
-        <com.android.keyguard.AlphaOptimizedImageButton
-            android:id="@+id/notifications"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:src="@drawable/car_ic_notification"
-            android:background="?android:attr/selectableItemBackground"
-            android:paddingTop="20dp"
-            android:paddingBottom="20dp"
-            android:alpha="0.7"
-        />
-
-
-        <com.android.systemui.statusbar.policy.Clock
-            android:id="@+id/clock"
-            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-            android:layout_height="wrap_content"
-            android:layout_width="match_parent"
-            android:singleLine="true"
-            android:paddingStart="@dimen/status_bar_clock_starting_padding"
-            android:paddingEnd="@dimen/status_bar_clock_end_padding"
-            android:gravity="center_horizontal"
-            android:paddingBottom="20dp"
-        />
-
-        <Space
-            android:layout_height="10dp"
-            android:layout_width="match_parent"/>
-
-    </LinearLayout>
-
-</com.android.systemui.statusbar.car.CarNavigationBarView>
diff --git a/packages/SystemUI/res/layout/car_status_bar_header.xml b/packages/SystemUI/res/layout/car_status_bar_header.xml
deleted file mode 100644
index f2ef301..0000000
--- a/packages/SystemUI/res/layout/car_status_bar_header.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?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.
--->
-<!-- Extends LinearLayout -->
-<com.android.systemui.qs.car.CarStatusBarHeader
-    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/car_qs_header_system_icons_area_height"
-    android:paddingStart="8dp"
-    android:paddingEnd="8dp" >
-
-    <include layout="@layout/system_icons"
-             android:layout_width="wrap_content"
-             android:layout_height="match_parent"
-             android:gravity="center_vertical|end"
-             android:layout_weight="1"
-    />
-
-    <com.android.systemui.statusbar.policy.Clock
-        android:id="@+id/clock"
-        android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:singleLine="true"
-        android:paddingStart="@dimen/status_bar_clock_starting_padding"
-        android:paddingEnd="@dimen/status_bar_clock_end_padding"
-        android:gravity="center_vertical|end"
-    />
-</com.android.systemui.qs.car.CarStatusBarHeader>
diff --git a/packages/SystemUI/res/layout/car_top_navigation_bar.xml b/packages/SystemUI/res/layout/car_top_navigation_bar.xml
deleted file mode 100644
index e16014b..0000000
--- a/packages/SystemUI/res/layout/car_top_navigation_bar.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/**
-** Copyright 2018, 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.
-*/
--->
-
-<com.android.systemui.statusbar.car.CarNavigationBarView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="match_parent"
-    android:layout_width="match_parent"
-    android:background="@drawable/system_bar_background">
-
-    <com.android.systemui.statusbar.policy.Clock
-        android:id="@+id/clock"
-        android:textAppearance="@style/TextAppearance.StatusBar.Clock"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:singleLine="true"
-        android:paddingStart="@dimen/status_bar_clock_starting_padding"
-        android:paddingEnd="@dimen/status_bar_clock_end_padding"
-        android:gravity="center_vertical"
-    />
-
-</com.android.systemui.statusbar.car.CarNavigationBarView>
-
diff --git a/packages/SystemUI/res/layout/car_volume_dialog.xml b/packages/SystemUI/res/layout/car_volume_dialog.xml
deleted file mode 100644
index a6beaa1..0000000
--- a/packages/SystemUI/res/layout/car_volume_dialog.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-     Copyright (C) 2018 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.
--->
-<androidx.car.widget.PagedListView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:background="@drawable/car_card_rounded_background"
-    android:id="@+id/volume_list"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginStart="@dimen/car_margin"
-    android:layout_marginEnd="@dimen/car_margin"
-    android:minWidth="@dimen/volume_dialog_panel_width"
-    android:theme="@style/Theme.Car.NoActionBar"
-    app:dividerStartMargin="@dimen/car_keyline_1"
-    app:dividerEndMargin="@dimen/car_keyline_1"
-    app:gutter="none"
-    app:showPagedListViewDivider="true"
-    app:scrollBarEnabled="false" />
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 0cc3c9e..34c208a 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -56,11 +56,6 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
 
-    <ViewStub android:id="@+id/fullscreen_user_switcher_stub"
-              android:layout="@layout/car_fullscreen_user_switcher"
-              android:layout_width="match_parent"
-              android:layout_height="match_parent"/>
-
     <include layout="@layout/status_bar_expanded"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/values/arrays_car.xml b/packages/SystemUI/res/values/arrays_car.xml
deleted file mode 100644
index 8c760fc..0000000
--- a/packages/SystemUI/res/values/arrays_car.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 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.
-*/
--->
-<resources>
-    <!-- These should be overriden in an overlay. The default implementation is empty.
-         There needs to be correspondence per index between these arrays, which means that if there
-         isn't a longpress action associated with a shortcut item, put in an empty item to make
-         sure everything lines up.
-    -->
-    <array name="car_facet_icons" />
-    <array name="car_facet_intent_uris" />
-    <array name="car_facet_longpress_intent_uris" />
-    <array name="car_facet_package_filters"/>
-    <array name="car_facet_category_filters"/>
-</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b0a519c..8e0bfb6 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -881,6 +881,7 @@
     <dimen name="smart_reply_button_stroke_width">1dp</dimen>
     <dimen name="smart_reply_button_font_size">14sp</dimen>
     <dimen name="smart_reply_button_line_spacing_extra">6sp</dimen> <!-- Total line height 20sp. -->
+    <dimen name="smart_action_button_icon_size">24dp</dimen>
     <dimen name="smart_action_button_icon_padding">10dp</dimen>
 
     <!-- A reasonable upper bound for the height of the smart reply button. The measuring code
diff --git a/packages/SystemUI/res/xml/car_volume_items.xml b/packages/SystemUI/res/xml/car_volume_items.xml
deleted file mode 100644
index 742dfdd..0000000
--- a/packages/SystemUI/res/xml/car_volume_items.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- *
- * Copyright 2018, 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.
-*/
--->
-
-<!--
-  Defines all possible items on car volume settings UI, keyed by usage.
-
-  This enables the CarSettings UI to associate VolumeGroups surfaced by
-  CarAudioManager.getVolumeGroupCount with renderable assets (ie: title, icon)
-  for presentation.
-
-  Order matters in this configuration. If one volume group contains multiple
-  audio usages, the first one appears in this file would be picked to be
-  presented on UI.
-
-  When overriding this configuration, please consult also the
-  car_volume_groups.xml, which is read by car audio service.
--->
-<carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto">
-  <item car:usage="unknown"
-        car:icon="@drawable/car_ic_music"/>
-  <item car:usage="media"
-        car:icon="@drawable/car_ic_music"/>
-  <item car:usage="voice_communication"
-        car:icon="@*android:drawable/ic_audio_ring_notif"/>
-  <item car:usage="voice_communication_signalling"
-        car:icon="@*android:drawable/ic_audio_ring_notif"/>
-  <item car:usage="alarm"
-        car:icon="@*android:drawable/ic_audio_alarm"/>
-  <item car:usage="notification"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="notification_ringtone"
-        car:icon="@*android:drawable/ic_audio_ring_notif"/>
-  <item car:usage="notification_communication_request"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="notification_communication_instant"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="notification_communication_delayed"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="notification_event"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="assistance_accessibility"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="assistance_navigation_guidance"
-        car:icon="@drawable/car_ic_navigation"/>
-  <item car:usage="assistance_sonification"
-        car:icon="@drawable/car_ic_notification"/>
-  <item car:usage="game"
-        car:icon="@drawable/car_ic_music"/>
-  <item car:usage="assistant"
-        car:icon="@drawable/car_ic_music"/>
-</carVolumeItems>
-
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java
index 12699d5..18dc185 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityCompat.java
@@ -58,4 +58,8 @@
         encoder.endStream();
         return true;
     }
+
+    public int getDisplayId() {
+        return mWrapped.getDisplayId();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 417d516..867c917 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -62,6 +62,7 @@
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
 import com.android.systemui.statusbar.policy.SmartReplyConstants;
+import com.android.systemui.volume.VolumeDialogComponent;
 
 import java.util.function.Consumer;
 
@@ -132,6 +133,10 @@
         return new QSTileHost(context, statusBar, iconController);
     }
 
+    public VolumeDialogComponent createVolumeDialogComponent(SystemUI systemUi, Context context) {
+        return new VolumeDialogComponent(systemUi, context);
+    }
+
     public void injectDependencies(ArrayMap<Object, DependencyProvider> providers,
             Context context) {
         providers.put(StatusBarStateController.class, StatusBarStateController::new);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index a90a7d2..ba89fe6 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -140,7 +140,7 @@
         createDialogs();
 
         if (!mDialogs.isEmpty()) {
-            getComponent(CommandQueue.class).addCallbacks(this);
+            getComponent(CommandQueue.class).addCallback(this);
             mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
deleted file mode 100644
index 09c000b..0000000
--- a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
+++ /dev/null
@@ -1,53 +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 com.android.systemui.car;
-
-import android.content.Context;
-import android.util.ArrayMap;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.Dependency.DependencyProvider;
-import com.android.systemui.SystemUIFactory;
-import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.statusbar.car.CarFacetButtonController;
-import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.car.hvac.HvacController;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-
-/**
- * Class factory to provide car specific SystemUI components.
- */
-public class CarSystemUIFactory extends SystemUIFactory {
-
-    public StatusBarKeyguardViewManager createStatusBarKeyguardViewManager(Context context,
-            ViewMediatorCallback viewMediatorCallback, LockPatternUtils lockPatternUtils) {
-        return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
-    }
-
-    @Override
-    public void injectDependencies(ArrayMap<Object, DependencyProvider> providers,
-            Context context) {
-        super.injectDependencies(providers, context);
-        providers.put(NotificationEntryManager.class,
-                () -> new CarNotificationEntryManager(context));
-        providers.put(CarFacetButtonController.class, () -> new CarFacetButtonController(context));
-        providers.put(HvacController.class, () -> new HvacController(context));
-        providers.put(NotificationMediaManager.class,
-                () -> new CarNotificationMediaManager(context));
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 2c61da3..1718cff 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -108,7 +108,7 @@
                 UserHandle.USER_ALL);
 
         updateConfiguration();
-        Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).addCallback(mStateListener);
     }
 
     public static FalsingManager getInstance(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index bf8e04d..7e77843 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -401,7 +401,9 @@
                 }
                 mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck, screenX, screenY,
                         event.values);
-                updateListener();  // reregister, this sensor only fires once
+                if (!mRegistered) {
+                    updateListener();  // reregister, this sensor only fires once
+                }
             }));
         }
 
@@ -440,7 +442,9 @@
                 mRegistered = false;
                 mCallback.onSensorPulse(mPulseReason, true /* sensorPerformsProxCheck */, -1, -1,
                         event.getValues());
-                updateListener();  // reregister, this sensor only fires once
+                if (!mRegistered) {
+                    updateListener();  // reregister, this sensor only fires once
+                }
             }));
         };
 
@@ -487,7 +491,6 @@
             }
             return sb.append(']').toString();
         }
-
     }
 
     public interface Callback {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index bad0148..afe9a74 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -184,6 +184,7 @@
             if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
             mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
         }
+
         if (far && (paused || pausing)) {
             if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
             mMachine.requestState(DozeMachine.State.DOZE_AOD);
@@ -205,13 +206,13 @@
                     // In pocket, drop event.
                     return;
                 }
-                if (pausing || paused) {
+                if (mMachine.getState() == DozeMachine.State.DOZE) {
                     mMachine.requestState(DozeMachine.State.DOZE_AOD);
                 }
             }, false /* alreadyPerformedProxCheck */, DozeLog.REASON_SENSOR_WAKE_UP);
         } else {
             if (!pausing && !paused) {
-                mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSING);
+                mMachine.requestState(DozeMachine.State.DOZE);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
index aa08562..e8ef454 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
@@ -45,7 +45,7 @@
                 .withCallback(this::onExtensionCallback)
                 .build();
         mPlugin = mExtension.get();
-        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
+        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this);
     }
 
     private void onExtensionCallback(GlobalActions newPlugin) {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 0394998..dc11b4c 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -55,12 +55,12 @@
         mContext = context;
         mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
-        SysUiServiceProvider.getComponent(context, CommandQueue.class).addCallbacks(this);
+        SysUiServiceProvider.getComponent(context, CommandQueue.class).addCallback(this);
     }
 
     @Override
     public void destroy() {
-        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
+        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallback(this);
         if (mGlobalActions != null) {
             mGlobalActions.destroy();
             mGlobalActions = null;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
index 7792e17..37c8163 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipUI.java
@@ -58,7 +58,7 @@
                 : com.android.systemui.pip.phone.PipManager.getInstance();
         mPipManager.initialize(mContext);
 
-        getComponent(CommandQueue.class).addCallbacks(this);
+        getComponent(CommandQueue.class).addCallback(this);
         putComponent(PipUI.class, this);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 953eb70..2acbea4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -108,12 +108,12 @@
                 mQSPanel.getTileLayout().restoreInstanceState(savedInstanceState);
             }
         }
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
+        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallback(this);
     }
 
     @Override
     public void onDestroyView() {
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this);
+        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallback(this);
         super.onDestroyView();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index d1c2df5..ca8e824 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -308,7 +308,7 @@
     protected static List<String> loadTileSpecs(Context context, String tileList) {
         final Resources res = context.getResources();
         final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);
-        if (tileList == null) {
+        if (TextUtils.isEmpty(tileList)) {
             tileList = res.getString(R.string.quick_settings_tiles);
             if (DEBUG) Log.d(TAG, "Loaded tile specs from config: " + tileList);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 0702d74..f13b565 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -37,7 +37,7 @@
 
     @Override
     public void start() {
-        getComponent(CommandQueue.class).addCallbacks(this);
+        getComponent(CommandQueue.class).addCallback(this);
         putComponent(Recents.class, this);
         mImpl = createRecentsImplementationFromConfig();
         mImpl.onStart(mContext, this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 8b93995..95019ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -35,6 +35,8 @@
 import com.android.internal.statusbar.IStatusBar;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.CommandQueue.Callbacks;
+import com.android.systemui.statusbar.policy.CallbackController;
 
 import java.util.ArrayList;
 
@@ -45,7 +47,7 @@
  * coalescing these calls so they don't stack up.  For the calls
  * are coalesced, note that they are all idempotent.
  */
-public class CommandQueue extends IStatusBar.Stub {
+public class CommandQueue extends IStatusBar.Stub implements CallbackController<Callbacks> {
     private static final int INDEX_MASK = 0xffff;
     private static final int MSG_SHIFT  = 16;
     private static final int MSG_MASK   = 0xffff << MSG_SHIFT;
@@ -183,12 +185,12 @@
                 && !ONLY_CORE_APPS;
     }
 
-    public void addCallbacks(Callbacks callbacks) {
+    public void addCallback(Callbacks callbacks) {
         mCallbacks.add(callbacks);
         callbacks.disable(mDisable1, mDisable2, false /* animate */);
     }
 
-    public void removeCallbacks(Callbacks callbacks) {
+    public void removeCallback(Callbacks callbacks) {
         mCallbacks.remove(callbacks);
     }
 
@@ -223,7 +225,9 @@
         }
     }
 
-    public void disable(int state1, int state2) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void disable(int displayId, int state1, int state2) {
         disable(state1, state2, true);
     }
 
@@ -266,8 +270,10 @@
         }
     }
 
-    public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
-            int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
+            int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds) {
         synchronized (mLock) {
             // Don't coalesce these, since it might have one time flags set such as
             // STATUS_BAR_UNHIDE which might get lost.
@@ -282,7 +288,9 @@
         }
     }
 
-    public void topAppWindowChanged(boolean menuVisible) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void topAppWindowChanged(int displayId, boolean menuVisible) {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_TOP_APP_WINDOW_CHANGED);
             mHandler.obtainMessage(MSG_TOP_APP_WINDOW_CHANGED, menuVisible ? 1 : 0, 0,
@@ -290,7 +298,9 @@
         }
     }
 
-    public void setImeWindowStatus(IBinder token, int vis, int backDisposition,
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher) {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_SHOW_IME_BUTTON);
@@ -371,7 +381,9 @@
         }
     }
 
-    public void setWindowState(int window, int state) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void setWindowState(int displayId, int window, int state) {
         synchronized (mLock) {
             // don't coalesce these
             mHandler.obtainMessage(MSG_SET_WINDOW_STATE, window, state, null).sendToTarget();
@@ -385,7 +397,9 @@
         }
     }
 
-    public void appTransitionPending() {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void appTransitionPending(int displayId) {
         appTransitionPending(false /* forced */);
     }
 
@@ -395,13 +409,17 @@
         }
     }
 
-    public void appTransitionCancelled() {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void appTransitionCancelled(int displayId) {
         synchronized (mLock) {
             mHandler.sendEmptyMessage(MSG_APP_TRANSITION_CANCELLED);
         }
     }
 
-    public void appTransitionStarting(long startTime, long duration) {
+    // TODO(b/117478341): Add multi-display support.
+    @Override
+    public void appTransitionStarting(int displayId, long startTime, long duration) {
         appTransitionStarting(startTime, duration, false /* forced */);
     }
 
@@ -412,8 +430,9 @@
         }
     }
 
+    // TODO(b/117478341): Add multi-display support.
     @Override
-    public void appTransitionFinished() {
+    public void appTransitionFinished(int displayId) {
         synchronized (mLock) {
             mHandler.sendEmptyMessage(MSG_APP_TRANSITION_FINISHED);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 960d221..7d1b640 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -156,7 +156,7 @@
                 new IntentFilter(Intent.ACTION_TIME_TICK), null,
                 Dependency.get(Dependency.TIME_TICK_HANDLER));
 
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     /**
@@ -167,7 +167,7 @@
      */
     public void destroy() {
         mContext.unregisterReceiver(mTickReceiver);
-        Dependency.get(StatusBarStateController.class).removeListener(this);
+        Dependency.get(StatusBarStateController.class).removeCallback(this);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index b0724b1..bba4369 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -165,7 +165,7 @@
         mCurrentUserId = ActivityManager.getCurrentUser();
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
         mLockPatternUtils = new LockPatternUtils(context);
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 7be5461..ecadf96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -141,7 +141,7 @@
                 ActivityManager.getService().resumeAppSwitches();
             } catch (RemoteException e) {
             }
-            return mCallback.handleRemoteViewClick(pendingIntent, () -> {
+            return mCallback.handleRemoteViewClick(view, pendingIntent, () -> {
                 Pair<Intent, ActivityOptions> options = response.getLaunchOptions(view);
                 options.second.setLaunchWindowingMode(
                         WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
@@ -666,11 +666,13 @@
          * Performs any special handling for a remote view click. The default behaviour can be
          * called through the defaultHandler parameter.
          *
+         * @param view
          * @param pendingIntent
          * @param defaultHandler
          * @return  true iff the click was handled
          */
-        boolean handleRemoteViewClick(PendingIntent pendingIntent, ClickHandler defaultHandler);
+        boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
+                ClickHandler defaultHandler);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index e7b4904..6cec36a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -121,13 +121,13 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         Dependency.get(StatusBarStateController.class)
-                .addListener(mStateListener, StatusBarStateController.RANK_SHELF);
+                .addCallback(mStateListener, StatusBarStateController.RANK_SHELF);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        Dependency.get(StatusBarStateController.class).removeListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
     }
 
     public void bind(AmbientState ambientState, NotificationStackScrollLayout hostLayout) {
@@ -225,7 +225,7 @@
             }
             viewState.hasItemsInStableShelf = lastViewState.inShelf;
             viewState.hidden = !mAmbientState.isShadeExpanded()
-                    || mAmbientState.isQsCustomizerShowing();
+                    || mAmbientState.isQsCustomizerShowing() || mAmbientState.isFullyDark();
             viewState.maxShelfEnd = maxShelfEnd;
         } else {
             viewState.hidden = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index daa2fd4..dc3a607 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -129,7 +129,7 @@
                 res.getBoolean(R.bool.config_alwaysExpandNonGroupedNotifications);
         mStatusBarStateListener = new StatusBarStateListener(mBubbleController);
         mEntryManager.setStatusBarStateListener(mStatusBarStateListener);
-        Dependency.get(StatusBarStateController.class).addListener(mStatusBarStateListener);
+        Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener);
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
index eaf52cb..3f84416 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
@@ -26,8 +26,10 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.systemui.Interpolators;
+import com.android.systemui.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.CallbackController;
 
 import java.lang.annotation.Retention;
 import java.util.ArrayList;
@@ -36,7 +38,7 @@
 /**
  * Tracks and reports on {@link StatusBarState}.
  */
-public class StatusBarStateController {
+public class StatusBarStateController implements CallbackController<StateListener> {
     private static final String TAG = "SbStateController";
 
     private static final int MAX_STATE = StatusBarState.FULLSCREEN_USER_SWITCHER;
@@ -228,7 +230,7 @@
         return mLastState == StatusBarState.SHADE_LOCKED;
     }
 
-    public void addListener(StateListener listener) {
+    public void addCallback(StateListener listener) {
         synchronized (mListeners) {
             addListenerInternalLocked(listener, Integer.MAX_VALUE);
         }
@@ -244,7 +246,7 @@
      * StatusBarState out of StatusBar.java. Any new listeners should be built not to need ranking
      * (i.e., they are non-dependent on the order of operations of StatusBarState listeners).
      */
-    public void addListener(StateListener listener, @SbStateListenerRank int rank) {
+    public void addCallback(StateListener listener, @SbStateListenerRank int rank) {
         synchronized (mListeners) {
             addListenerInternalLocked(listener, rank);
         }
@@ -264,7 +266,7 @@
         mListeners.sort(mComparator);
     }
 
-    public void removeListener(StateListener listener) {
+    public void removeCallback(StateListener listener) {
         synchronized (mListeners) {
             mListeners.removeIf((it) -> it.listener.equals(listener));
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java
deleted file mode 100644
index bd32856..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java
+++ /dev/null
@@ -1,186 +0,0 @@
-package com.android.systemui.statusbar.car;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.TypedArray;
-import android.os.UserHandle;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import com.android.keyguard.AlphaOptimizedImageButton;
-import com.android.systemui.Dependency;
-import com.android.systemui.R;
-
-/**
- * CarFacetButton is a ui component designed to be used as a shortcut for an app of a defined
- * category. It can also render a indicator impling that there are more options of apps to launch
- * using this component. This is done with a "More icon" currently an arrow as defined in the layout
- * file. The class is to serve as an example.
- * Usage example: A button that allows a user to select a music app and indicate that there are
- * other music apps installed.
- */
-public class CarFacetButton extends LinearLayout {
-    private static final String FACET_FILTER_DELIMITER = ";";
-    /**
-     * Extra information to be sent to a helper to make the decision of what app to launch when
-     * clicked.
-     */
-    private static final String EXTRA_FACET_CATEGORIES = "categories";
-    private static final String EXTRA_FACET_PACKAGES = "packages";
-    private static final String EXTRA_FACET_ID = "filter_id";
-    private static final String EXTRA_FACET_LAUNCH_PICKER = "launch_picker";
-
-    private Context mContext;
-    private AlphaOptimizedImageButton mIcon;
-    private AlphaOptimizedImageButton mMoreIcon;
-    private boolean mSelected = false;
-    private String[] mComponentNames;
-    /** App categories that are to be used with this widget */
-    private String[] mFacetCategories;
-    /** App packages that are allowed to be used with this widget */
-    private String[] mFacetPackages;
-    private int mIconResourceId;
-    /**
-     * If defined in the xml this will be the icon that's rendered when the button is marked as
-     * selected
-     */
-    private int mSelectedIconResourceId;
-    private boolean mUseMoreIcon = true;
-    private float mSelectedAlpha = 1f;
-    private float mUnselectedAlpha = 1f;
-
-
-    public CarFacetButton(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mContext = context;
-        View.inflate(context, R.layout.car_facet_button, this);
-
-        // extract custom attributes
-        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CarFacetButton);
-        setupIntents(typedArray);
-        setupIcons(typedArray);
-        CarFacetButtonController carFacetButtonController = Dependency.get(
-                CarFacetButtonController.class);
-        carFacetButtonController.addFacetButton(this);
-
-    }
-
-    /**
-     * Reads the custom attributes to setup click handlers for this component.
-     */
-    private void setupIntents(TypedArray typedArray) {
-        String intentString = typedArray.getString(R.styleable.CarFacetButton_intent);
-        String longPressIntentString = typedArray.getString(R.styleable.CarFacetButton_longIntent);
-        String categoryString = typedArray.getString(R.styleable.CarFacetButton_categories);
-        String packageString = typedArray.getString(R.styleable.CarFacetButton_packages);
-        String componentNameString =
-                typedArray.getString(R.styleable.CarFacetButton_componentNames);
-        try {
-            final Intent intent = Intent.parseUri(intentString, Intent.URI_INTENT_SCHEME);
-            intent.putExtra(EXTRA_FACET_ID, Integer.toString(getId()));
-
-            if (packageString != null) {
-                mFacetPackages = packageString.split(FACET_FILTER_DELIMITER);
-                intent.putExtra(EXTRA_FACET_PACKAGES, mFacetPackages);
-            }
-            if (categoryString != null) {
-                mFacetCategories = categoryString.split(FACET_FILTER_DELIMITER);
-                intent.putExtra(EXTRA_FACET_CATEGORIES, mFacetCategories);
-            }
-            if (componentNameString != null) {
-                mComponentNames = componentNameString.split(FACET_FILTER_DELIMITER);
-            }
-
-            setOnClickListener(v -> {
-                intent.putExtra(EXTRA_FACET_LAUNCH_PICKER, mSelected);
-                mContext.startActivityAsUser(intent, UserHandle.CURRENT);
-            });
-
-            if (longPressIntentString != null) {
-                final Intent longPressIntent = Intent.parseUri(longPressIntentString,
-                        Intent.URI_INTENT_SCHEME);
-                setOnLongClickListener(v -> {
-                    mContext.startActivityAsUser(longPressIntent, UserHandle.CURRENT);
-                    return true;
-                });
-            }
-        } catch (Exception e) {
-            throw new RuntimeException("Failed to attach intent", e);
-        }
-    }
-
-
-    private void setupIcons(TypedArray styledAttributes) {
-        mSelectedAlpha = styledAttributes.getFloat(
-                R.styleable.CarFacetButton_selectedAlpha, mSelectedAlpha);
-        mUnselectedAlpha = styledAttributes.getFloat(
-                R.styleable.CarFacetButton_unselectedAlpha, mUnselectedAlpha);
-        mIcon = findViewById(R.id.car_nav_button_icon);
-        mIcon.setScaleType(ImageView.ScaleType.CENTER);
-        mIcon.setClickable(false);
-        mIcon.setAlpha(mUnselectedAlpha);
-        mIconResourceId = styledAttributes.getResourceId(R.styleable.CarFacetButton_icon, 0);
-        mIcon.setImageResource(mIconResourceId);
-        mSelectedIconResourceId = styledAttributes.getResourceId(
-                R.styleable.CarFacetButton_selectedIcon, mIconResourceId);
-
-        mMoreIcon = findViewById(R.id.car_nav_button_more_icon);
-        mMoreIcon.setClickable(false);
-        mMoreIcon.setAlpha(mSelectedAlpha);
-        mMoreIcon.setVisibility(GONE);
-        mUseMoreIcon = styledAttributes.getBoolean(R.styleable.CarFacetButton_useMoreIcon, true);
-    }
-
-    /**
-     * @return The app categories the component represents
-     */
-    public String[] getCategories() {
-        if (mFacetCategories == null) {
-            return new String[0];
-        }
-        return mFacetCategories;
-    }
-
-    /**
-     * @return The valid packages that should be considered.
-     */
-    public String[] getFacetPackages() {
-        if (mFacetPackages == null) {
-            return new String[0];
-        }
-        return mFacetPackages;
-    }
-
-    public String[] getComponentName() {
-        if (mComponentNames == null) {
-            return new String[0];
-        }
-        return mComponentNames;
-    }
-
-    /**
-     * Updates the alpha of the icons to "selected" and shows the "More icon"
-     * @param selected true if the view must be selected, false otherwise
-     */
-    public void setSelected(boolean selected) {
-        super.setSelected(selected);
-        setSelected(selected, selected);
-    }
-
-    /**
-     * Updates the visual state to let the user know if it's been selected.
-     * @param selected true if should update the alpha of the icon to selected, false otherwise
-     * @param showMoreIcon true if the "more icon" should be shown, false otherwise. Note this
-     *                     is ignored if the attribute useMoreIcon is set to false
-     */
-    public void setSelected(boolean selected, boolean showMoreIcon) {
-        mSelected = selected;
-        mIcon.setAlpha(mSelected ? mSelectedAlpha : mUnselectedAlpha);
-        mIcon.setImageResource(mSelected ? mSelectedIconResourceId : mIconResourceId);
-        if (mUseMoreIcon) {
-            mMoreIcon.setVisibility(showMoreIcon ? VISIBLE : GONE);
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
index f506753..f899863 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java
@@ -299,6 +299,10 @@
             return top;
         }
 
+        public int getBottom() {
+            return bottom;
+        }
+
         public int getWidth() {
             return right - left;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 1616b6d..70d144e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -952,10 +952,12 @@
 
         // Has a copy of the current UI adjustments.
         ArrayMap<String, NotificationUiAdjustment> oldAdjustments = new ArrayMap<>();
+        ArrayMap<String, Integer> oldImportances = new ArrayMap<>();
         for (NotificationData.Entry entry : entries) {
             NotificationUiAdjustment adjustment =
                     NotificationUiAdjustment.extractFromNotificationEntry(entry);
             oldAdjustments.put(entry.key, adjustment);
+            oldImportances.put(entry.key, entry.importance);
         }
 
         // Populate notification entries from the new rankings.
@@ -978,6 +980,11 @@
                     // Once the RowInflaterTask is done, it will pick up the updated entry, so
                     // no-op here.
                 }
+            } else if (oldImportances.containsKey(entry.key)
+                    && entry.importance != oldImportances.get(entry.key)) {
+                if (entry.rowExists()) {
+                    entry.getRow().onNotificationRankingUpdated();
+                }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
index 1f48c15..09eb8a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
@@ -75,6 +75,6 @@
     /** Returns the value of the new interruption model setting. */
     public static boolean useNewInterruptionModel(Context context) {
         return Settings.Secure.getInt(context.getContentResolver(),
-                NOTIFICATION_NEW_INTERRUPTION_MODEL, 0) != 0;
+                NOTIFICATION_NEW_INTERRUPTION_MODEL, 1) != 0;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index 87313b8..9f02e54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -149,7 +149,7 @@
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
         // Not expected to be destroyed, don't need to unsubscribe
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     public void setUpWithContainer(NotificationListContainer listContainer) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d4d45ea..69e698f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -588,6 +588,13 @@
         updateRippleAllowed();
     }
 
+    /** Called when the notification's ranking was changed (but nothing else changed). */
+    public void onNotificationRankingUpdated() {
+        if (mMenuRow != null) {
+            mMenuRow.onNotificationUpdated(mStatusBarNotification);
+        }
+    }
+
     @VisibleForTesting
     void updateShelfIconColor() {
         StatusBarIconView expandedIcon = mEntry.expandedIcon;
@@ -2001,7 +2008,8 @@
         float interpolation = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(params.getProgress());
         int startClipTopAmount = params.getStartClipTopAmount();
         if (mNotificationParent != null) {
-            top -= mNotificationParent.getTranslationY();
+            float parentY = mNotificationParent.getTranslationY();
+            top -= parentY;
             mNotificationParent.setTranslationZ(translationZ);
             int parentStartClipTopAmount = params.getParentStartClipTopAmount();
             if (startClipTopAmount != 0) {
@@ -2011,8 +2019,12 @@
                 mNotificationParent.setClipTopAmount(clipTopAmount);
             }
             mNotificationParent.setExtraWidthForClipping(extraWidthForClipping);
-            mNotificationParent.setMinimumHeightForClipping(params.getHeight()
-                    + mNotificationParent.getActualHeight());
+            float clipBottom = Math.max(params.getBottom(),
+                    parentY + mNotificationParent.getActualHeight()
+                            - mNotificationParent.getClipBottomAmount());
+            float clipTop = Math.min(params.getTop(), parentY);
+            int minimumHeightForClipping = (int) (clipBottom - clipTop);
+            mNotificationParent.setMinimumHeightForClipping(minimumHeightForClipping);
         } else if (startClipTopAmount != 0) {
             int clipTopAmount = (int) MathUtils.lerp(startClipTopAmount, 0, interpolation);
             setClipTopAmount(clipTopAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
index 70860258..ef343fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
@@ -697,7 +697,7 @@
                         && newView.getPackage() != null
                         && newView.getPackage().equals(oldView.getPackage())
                         && newView.getLayoutId() == oldView.getLayoutId()
-                        && !oldView.isReapplyDisallowed());
+                        && !oldView.hasFlags(RemoteViews.FLAG_REAPPLY_DISALLOWED));
     }
 
     public void setInflationCallback(InflationCallback callback) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index 948d2a5..50564e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -267,7 +267,9 @@
         } else {
             mRightMenuItems.add(mInfoItem);
             mRightMenuItems.add(mAppOpsItem);
-            mRightMenuItems.add(mSnoozeItem);
+            if (!isForeground) {
+                mRightMenuItems.add(mSnoozeItem);
+            }
         }
 
         populateMenuViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 5d640e0..eca1a14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -618,7 +618,7 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         Dependency.get(StatusBarStateController.class)
-                .addListener(mStateListener, StatusBarStateController.RANK_STACK_SCROLLER);
+                .addCallback(mStateListener, StatusBarStateController.RANK_STACK_SCROLLER);
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
@@ -626,7 +626,7 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        Dependency.get(StatusBarStateController.class).removeListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
         Dependency.get(ConfigurationController.class).removeCallback(this);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 3b13fe9..24570ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -120,15 +120,15 @@
     @Override
     public void onResume() {
         super.onResume();
-        mCommandQueue.addCallbacks(this);
-        mStatusBarStateController.addListener(this);
+        mCommandQueue.addCallback(this);
+        mStatusBarStateController.addCallback(this);
     }
 
     @Override
     public void onPause() {
         super.onPause();
-        mCommandQueue.removeCallbacks(this);
-        mStatusBarStateController.removeListener(this);
+        mCommandQueue.removeCallback(this);
+        mStatusBarStateController.removeCallback(this);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 94b2cde..cfa751c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -88,7 +88,7 @@
     public DozeScrimController(DozeParameters dozeParameters) {
         mDozeParameters = dozeParameters;
         //Never expected to be destroyed
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 9faada0..aa0b7b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -129,7 +129,7 @@
                 updateTouchableRegionListener();
             }
         });
-        Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).addCallback(mStateListener);
         mBubbleController.setBubbleStateChangeListener((hasBubbles) -> {
             if (!hasBubbles) {
                 mBubbleGoingAway = true;
@@ -143,7 +143,7 @@
     }
 
     public void destroy() {
-        Dependency.get(StatusBarStateController.class).removeListener(mStateListener);
+        Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
     }
 
     private void initResources() {
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 b29889d..57cc7d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -73,15 +73,15 @@
         mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mStatusBarStateController = Dependency.get(StatusBarStateController.class);
         SysUiServiceProvider.getComponent(context, CommandQueue.class)
-                .addCallbacks(this);
-        mStatusBarStateController.addListener(this);
+                .addCallback(this);
+        mStatusBarStateController.addCallback(this);
         mDozeAmount = mStatusBarStateController.getDozeAmount();
     }
 
     public void destroy(Context context) {
         SysUiServiceProvider.getComponent(context, CommandQueue.class)
-                .removeCallbacks(this);
-        mStatusBarStateController.removeListener(this);
+                .removeCallback(this);
+        mStatusBarStateController.removeCallback(this);
     }
 
     public void saveState(Bundle outState) {
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 8657003..d2bfd12 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -199,7 +199,7 @@
     public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mCommandQueue = SysUiServiceProvider.getComponent(getContext(), CommandQueue.class);
-        mCommandQueue.addCallbacks(this);
+        mCommandQueue.addCallback(this);
         mStatusBar = SysUiServiceProvider.getComponent(getContext(), StatusBar.class);
         mRecents = SysUiServiceProvider.getComponent(getContext(), Recents.class);
         mDivider = SysUiServiceProvider.getComponent(getContext(), Divider.class);
@@ -225,7 +225,7 @@
     @Override
     public void onDestroy() {
         super.onDestroy();
-        mCommandQueue.removeCallbacks(this);
+        mCommandQueue.removeCallback(this);
         Dependency.get(AccessibilityManagerWrapper.class).removeCallback(
                 mAccessibilityListener);
         mContentResolver.unregisterContentObserver(mMagnificationObserver);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index 12a0cc8..3984405 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -24,7 +24,6 @@
 import android.view.Display;
 import android.view.IWallpaperVisibilityListener;
 import android.view.IWindowManager;
-import android.view.MotionEvent;
 import android.view.View;
 
 import com.android.internal.statusbar.IStatusBarService;
@@ -165,23 +164,4 @@
         }
         mView.onDarkIntensityChange(darkIntensity);
     }
-
-    private final View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
-        @Override
-        public boolean onTouch(View v, MotionEvent ev) {
-            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-                // even though setting the systemUI visibility below will turn these views
-                // on, we need them to come up faster so that they can catch this motion
-                // event
-                applyLightsOut(false, false, false);
-
-                try {
-                    mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
-                            "LightsOutListener");
-                } catch (android.os.RemoteException ex) {
-                }
-            }
-            return false;
-        }
-    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
index 83067f6..a8d00c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
@@ -127,6 +127,15 @@
     }
 
     /**
+     * Decide if the controller should not send the current motion event to launcher via
+     * {@link OverviewProxyService}
+     * @return if controller should not proxy
+     */
+    public boolean disableProxyEvents() {
+        return false;
+    }
+
+    /**
      * Tell if action is enabled. Compared to {@link #canPerformAction()} this is based on settings
      * if the action is disabled for a particular gesture. For example a back action can be enabled
      * however if there is nothing to back to then {@link #canPerformAction()} should return false.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
index 3e31fa0..2a68fa5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
@@ -82,7 +82,7 @@
     private boolean mIsDozing;
 
     public NotificationGroupAlertTransferHelper() {
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 448b5c3..8f4369a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -55,7 +55,7 @@
     private boolean mIsUpdatingUnchangedGroup;
 
     public NotificationGroupManager() {
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     /**
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 33d176a..a2a11bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -366,7 +366,7 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         FragmentHostManager.get(this).addTagListener(QS.TAG, mFragmentListener);
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
         Dependency.get(ZenModeController.class).addCallback(this);
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
@@ -375,7 +375,7 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         FragmentHostManager.get(this).removeTagListener(QS.TAG, mFragmentListener);
-        Dependency.get(StatusBarStateController.class).removeListener(this);
+        Dependency.get(StatusBarStateController.class).removeCallback(this);
         Dependency.get(ZenModeController.class).removeCallback(this);
         Dependency.get(ConfigurationController.class).removeCallback(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index c84f3db..ee1eb42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -268,7 +268,7 @@
         mLocationController.addCallback(this);
         mPrivacyItemController.setListening(true);
 
-        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
+        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallback(this);
         ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
 
         // Clear out all old notifications on startup (only present in the case where sysui dies)
@@ -296,7 +296,7 @@
         mKeyguardMonitor.removeCallback(this);
         mLocationController.removeCallback(this);
         mPrivacyItemController.setListening(false);
-        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
+        SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallback(this);
         mContext.unregisterReceiver(mIntentReceiver);
 
         NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
index 74744f1..2b202eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
@@ -212,6 +212,11 @@
     }
 
     @Override
+    public boolean disableProxyEvents() {
+        return true;
+    }
+
+    @Override
     protected void onGestureStart(MotionEvent event) {
         updateHighlight();
         ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 43e86d6..4983618 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -185,6 +185,7 @@
 
         // Requires proxy and an active gesture or able to perform any gesture to continue
         if (mOverviewEventSender.getProxy() == null
+                || !mOverviewEventSender.shouldShowSwipeUpUI()
                 || (mCurrentAction == null && !canPerformAnyAction())) {
             return deadZoneConsumed;
         }
@@ -275,25 +276,21 @@
                         if (mDragVPositive ? (posV < touchDownV) : (posV > touchDownV)) {
                             // Swiping up gesture
                             tryToStartGesture(mGestureActions[ACTION_SWIPE_UP_INDEX],
-                                    false /* alignedWithNavBar */, false /* positiveDirection */,
-                                    event);
+                                    false /* alignedWithNavBar */, event);
                         } else {
                             // Swiping down gesture
                             tryToStartGesture(mGestureActions[ACTION_SWIPE_DOWN_INDEX],
-                                    false /* alignedWithNavBar */, true /* positiveDirection */,
-                                    event);
+                                    false /* alignedWithNavBar */, event);
                         }
                     } else if (exceededSwipeHorizontalTouchSlop) {
                         if (mDragHPositive ? (posH < touchDownH) : (posH > touchDownH)) {
                             // Swiping left (ltr) gesture
                             tryToStartGesture(mGestureActions[ACTION_SWIPE_LEFT_INDEX],
-                                    true /* alignedWithNavBar */, false /* positiveDirection */,
-                                    event);
+                                    true /* alignedWithNavBar */, event);
                         } else {
                             // Swiping right (ltr) gesture
                             tryToStartGesture(mGestureActions[ACTION_SWIPE_RIGHT_INDEX],
-                                    true /* alignedWithNavBar */, true /* positiveDirection */,
-                                    event);
+                                    true /* alignedWithNavBar */, event);
                         }
                     }
                 }
@@ -306,7 +303,6 @@
             case MotionEvent.ACTION_UP:
                 if (mCurrentAction != null) {
                     mCurrentAction.endGesture();
-                    mCurrentAction = null;
                 }
 
                 // Return the hit target back to its original position
@@ -329,6 +325,11 @@
         if (shouldProxyEvents(action)) {
             proxyMotionEvents(event);
         }
+
+        // Clear action when gesture and event proxy finishes
+        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
+            mCurrentAction = null;
+        }
         return mCurrentAction != null || deadZoneConsumed;
     }
 
@@ -354,8 +355,7 @@
 
     private boolean shouldProxyEvents(int action) {
         final boolean actionValid = (mCurrentAction == null
-                || (mGestureActions[ACTION_SWIPE_UP_INDEX] != null
-                        && mGestureActions[ACTION_SWIPE_UP_INDEX].isActive()));
+                || !mCurrentAction.disableProxyEvents());
         if (actionValid && !mIsInScreenPinning) {
             // Allow down, cancel and up events, move and other events are passed if notifications
             // are not showing and disabled gestures (such as long press) are not executed
@@ -455,7 +455,7 @@
     }
 
     private void tryToStartGesture(NavigationGestureAction action, boolean alignedWithNavBar,
-            boolean positiveDirection, MotionEvent event) {
+            MotionEvent event) {
         if (action == null) {
             return;
         }
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 cfd53be..962e214 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -161,7 +161,6 @@
 import com.android.systemui.qs.QSFragment;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.qs.QSTileHost;
-import com.android.systemui.qs.car.CarQSFragment;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.ScreenPinningRequest;
 import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -474,8 +473,10 @@
                 return;
             }
             WallpaperInfo info = wallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
-            final boolean supportsAmbientMode = info != null &&
-                    info.supportsAmbientMode();
+            final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_dozeSupportsAodWallpaper);
+            final boolean supportsAmbientMode = deviceSupportsAodWallpaper
+                    && info != null && info.supportsAmbientMode();
 
             mStatusBarWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
             mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
@@ -578,6 +579,7 @@
     private boolean mVibrateOnOpening;
     private VibratorHelper mVibratorHelper;
     protected NotificationPresenter mPresenter;
+    private boolean mPulsing;
 
     @Override
     public void onActiveStateChanged(int code, int uid, String packageName, boolean active) {
@@ -626,7 +628,7 @@
         mBubbleController.setExpandListener(mBubbleExpandListener);
 
         mColorExtractor.addOnColorsChangedListener(this);
-        mStatusBarStateController.addListener(this, StatusBarStateController.RANK_STATUS_BAR);
+        mStatusBarStateController.addCallback(this, StatusBarStateController.RANK_STATUS_BAR);
 
         mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
         mDreamManager = IDreamManager.Stub.asInterface(
@@ -662,7 +664,7 @@
 
         // Connect in to the status bar manager service
         mCommandQueue = getComponent(CommandQueue.class);
-        mCommandQueue.addCallbacks(this);
+        mCommandQueue.addCallback(this);
 
         int[] switches = new int[9];
         ArrayList<IBinder> binders = new ArrayList<>();
@@ -918,8 +920,7 @@
                     Dependency.get(ExtensionController.class)
                             .newExtension(QS.class)
                             .withPlugin(QS.class)
-                            .withFeature(PackageManager.FEATURE_AUTOMOTIVE, CarQSFragment::new)
-                            .withDefault(QSFragment::new)
+                            .withDefault(this::createDefaultQSFragment)
                             .build());
             final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
                     mIconController);
@@ -1007,6 +1008,10 @@
         ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
     }
 
+    protected QS createDefaultQSFragment() {
+        return new QSFragment();
+    }
+
     protected void setUpPresenter() {
         // Set up the initial notification state.
         mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
@@ -1540,7 +1545,7 @@
     }
 
     public boolean isPulsing() {
-        return mAmbientPulseManager.hasNotifications();
+        return mPulsing;
     }
 
     public boolean isLaunchTransitionFadingAway() {
@@ -2885,7 +2890,7 @@
         mContext.unregisterReceiver(mDemoReceiver);
         mAssistManager.destroy();
         mHeadsUpManager.destroy();
-        mStatusBarStateController.removeListener(this);
+        mStatusBarStateController.removeCallback(this);
 
         if (mQSPanel != null && mQSPanel.getHost() != null) {
             mQSPanel.getHost().destroy();
@@ -3931,6 +3936,10 @@
                 return;
             }
 
+            // Set the state to pulsing, so ScrimController will know what to do once we ask it to
+            // execute the transition. The pulse callback will then be invoked when the scrims
+            // are black, indicating that StatusBar is ready to present the rest of the UI.
+            mPulsing = true;
             mDozeScrimController.pulse(new PulseCallback() {
                 @Override
                 public void onPulseStarted() {
@@ -3944,6 +3953,7 @@
 
                 @Override
                 public void onPulseFinished() {
+                    mPulsing = false;
                     callback.onPulseFinished();
                     setPulsing(false);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 7c17c01..4f25349 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -76,7 +76,7 @@
         loadDimens();
 
         SysUiServiceProvider.getComponent(context, CommandQueue.class)
-                .addCallbacks(this);
+                .addCallback(this);
         Dependency.get(TunerService.class).addTunable(this, ICON_BLACKLIST);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 484fe11..0f8970f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -151,7 +151,7 @@
         mLockPatternUtils = lockPatternUtils;
         mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
         KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitorCallback);
-        Dependency.get(StatusBarStateController.class).addListener(this);
+        Dependency.get(StatusBarStateController.class).addCallback(this);
     }
 
     public void registerStatusBar(StatusBar statusBar,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index a743d41e..e3f6bd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -70,10 +70,10 @@
         mContext = context;
         mContext.registerReceiverAsUser(mChallengeReceiver, UserHandle.ALL,
                 new IntentFilter(ACTION_DEVICE_LOCKED_CHANGED), null, null);
-        mStatusBarStateController.addListener(mStateListener);
+        mStatusBarStateController.addCallback(mStateListener);
         mKeyguardManager = context.getSystemService(KeyguardManager.class);
         mCommandQueue = getComponent(context, CommandQueue.class);
-        mCommandQueue.addCallbacks(this);
+        mCommandQueue.addCallback(this);
     }
 
     private void setStatusBarState(int state) {
@@ -206,7 +206,7 @@
     }
 
     @Override
-    public boolean handleRemoteViewClick(PendingIntent pendingIntent,
+    public boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
             NotificationRemoteInputManager.ClickHandler defaultHandler) {
         final boolean isActivity = pendingIntent.isActivity();
         if (isActivity) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index 158ee8a..986a86d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -92,7 +92,7 @@
         mKeyguardScreenRotation = shouldEnableKeyguardScreenRotation();
         mDozeParameters = dozeParameters;
         mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
-        Dependency.get(StatusBarStateController.class).addListener(
+        Dependency.get(StatusBarStateController.class).addCallback(
                 mStateListener, StatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
         Dependency.get(ConfigurationController.class).addCallback(this);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 978a72d..53e461d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -49,6 +49,7 @@
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.Window;
+import android.view.WindowInsetsController;
 import android.widget.FrameLayout;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -785,6 +786,11 @@
         @Override
         public void reportActivityRelaunched() {
         }
+
+        @Override
+        public WindowInsetsController getInsetsController() {
+            return null;
+        }
     };
 
 }
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 8517d90..aafdcd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -165,7 +165,7 @@
         mClockVisibleByUser = bundle.getBoolean(VISIBLE_BY_USER, true);
         mShowSeconds = bundle.getBoolean(SHOW_SECONDS, false);
         if (bundle.containsKey(VISIBILITY)) {
-            setVisibility(bundle.getInt(VISIBILITY));
+            super.setVisibility(bundle.getInt(VISIBILITY));
         }
     }
 
@@ -187,7 +187,7 @@
                     null, Dependency.get(Dependency.TIME_TICK_HANDLER));
             Dependency.get(TunerService.class).addTunable(this, CLOCK_SECONDS,
                     StatusBarIconController.ICON_BLACKLIST);
-            SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
+            SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallback(this);
             if (mShowDark) {
                 Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);
             }
@@ -203,6 +203,7 @@
 
         // Make sure we update to the current time
         updateClock();
+        updateClockVisibility();
         updateShowSeconds();
     }
 
@@ -214,7 +215,7 @@
             mAttached = false;
             Dependency.get(TunerService.class).removeTunable(this);
             SysUiServiceProvider.getComponent(getContext(), CommandQueue.class)
-                    .removeCallbacks(this);
+                    .removeCallback(this);
             if (mShowDark) {
                 Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(this);
             }
@@ -247,6 +248,15 @@
         }
     };
 
+    @Override
+    public void setVisibility(int visibility) {
+        if (visibility == View.VISIBLE && !shouldBeVisible()) {
+            return;
+        }
+
+        super.setVisibility(visibility);
+    }
+
     public void setClockVisibleByUser(boolean visible) {
         mClockVisibleByUser = visible;
         updateClockVisibility();
@@ -257,11 +267,15 @@
         updateClockVisibility();
     }
 
+    private boolean shouldBeVisible() {
+        return mClockVisibleByPolicy && mClockVisibleByUser;
+    }
+
     private void updateClockVisibility() {
-        boolean visible = mClockVisibleByPolicy && mClockVisibleByUser;
+        boolean visible = shouldBeVisible();
         Dependency.get(IconLogger.class).onIconVisibility("clock", visible);
         int visibility = visible ? View.VISIBLE : View.GONE;
-        setVisibility(visibility);
+        super.setVisibility(visibility);
     }
 
     final void updateClock() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
index 639e50c..9c099f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
-import android.os.SystemProperties;
+import android.sysprop.VoldProperties;
 
 /**
  * Helper for determining whether the phone is decrypted yet.
@@ -26,7 +26,7 @@
     public static final boolean IS_DATA_ENCRYPTED = isDataEncrypted();
 
     private static boolean isDataEncrypted() {
-        String voldState = SystemProperties.get("vold.decrypt");
+        String voldState = VoldProperties.decrypt().orElse("");
         return "1".equals(voldState) || "trigger_restart_min_framework".equals(voldState);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index f36066c..2a4336e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -21,7 +21,6 @@
 import android.text.method.TransformationMethod;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.Size;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -41,6 +40,7 @@
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
 
 import java.text.BreakIterator;
+import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 import java.util.PriorityQueue;
@@ -282,9 +282,9 @@
 
         Drawable iconDrawable = action.getIcon().loadDrawable(context);
         // Add the action icon to the Smart Action button.
-        Size newIconSize = calculateIconSizeFromSingleLineButton(context, root,
-                new Size(iconDrawable.getIntrinsicWidth(), iconDrawable.getIntrinsicHeight()));
-        iconDrawable.setBounds(0, 0, newIconSize.getWidth(), newIconSize.getHeight());
+        int newIconSize = context.getResources().getDimensionPixelSize(
+                R.dimen.smart_action_button_icon_size);
+        iconDrawable.setBounds(0, 0, newIconSize, newIconSize);
         button.setCompoundDrawables(iconDrawable, null, null, null);
 
         button.setOnClickListener(view ->
@@ -295,30 +295,12 @@
 
         // TODO(b/119010281): handle accessibility
 
+        // Mark this as an Action button
+        final LayoutParams lp = (LayoutParams) button.getLayoutParams();
+        lp.buttonType = SmartButtonType.ACTION;
         return button;
     }
 
-    private static Size calculateIconSizeFromSingleLineButton(Context context, ViewGroup root,
-            Size originalIconSize) {
-        Button button = (Button) LayoutInflater.from(context).inflate(
-                R.layout.smart_action_button, root, false);
-        // Add simple text here to ensure the button displays one line of text.
-        button.setText("a");
-        return calculateIconSizeFromButtonHeight(button, originalIconSize);
-    }
-
-    // Given a button with text on a single line - we want to add an icon to that button. This
-    // method calculates the icon height to use to avoid making the button grow in height.
-    private static Size calculateIconSizeFromButtonHeight(Button button, Size originalIconSize) {
-        // A completely permissive measure spec should make the button text single-line.
-        button.measure(MEASURE_SPEC_ANY_LENGTH, MEASURE_SPEC_ANY_LENGTH);
-        int buttonHeight = button.getMeasuredHeight();
-        int newIconHeight = buttonHeight / 2;
-        int newIconWidth = (int) (originalIconSize.getWidth()
-                * ((double) newIconHeight) / originalIconSize.getHeight());
-        return new Size(newIconWidth, newIconHeight);
-    }
-
     @Override
     public LayoutParams generateLayoutParams(AttributeSet attrs) {
         return new LayoutParams(mContext, attrs);
@@ -352,18 +334,26 @@
         int displayedChildCount = 0;
         int buttonPaddingHorizontal = mSingleLineButtonPaddingHorizontal;
 
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
+        // Set up a list of suggestions where actions come before replies. Note that the Buttons
+        // themselves have already been added to the view hierarchy in an order such that Smart
+        // Replies are shown before Smart Actions. The order of the list below determines which
+        // suggestions will be shown at all - only the first X elements are shown (where X depends
+        // on how much space each suggestion button needs).
+        List<View> smartActions = filterActionsOrReplies(SmartButtonType.ACTION);
+        List<View> smartReplies = filterActionsOrReplies(SmartButtonType.REPLY);
+        List<View> smartSuggestions = new ArrayList<>(smartActions);
+        smartSuggestions.addAll(smartReplies);
+        List<View> coveredSuggestions = new ArrayList<>();
+
+        for (View child : smartSuggestions) {
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            if (child.getVisibility() != View.VISIBLE || !(child instanceof Button)) {
-                continue;
-            }
 
             child.setPadding(buttonPaddingHorizontal, child.getPaddingTop(),
                     buttonPaddingHorizontal, child.getPaddingBottom());
             child.measure(MEASURE_SPEC_ANY_LENGTH, heightMeasureSpec);
 
+            coveredSuggestions.add(child);
+
             final int lineCount = ((Button) child).getLineCount();
             if (lineCount < 1 || lineCount > 2) {
                 // If smart reply has no text, or more than two lines, then don't show it.
@@ -417,7 +407,8 @@
 
                     // Mark all buttons from the last squeezing round as "failed to squeeze", so
                     // that they're re-measured without squeezing later.
-                    markButtonsWithPendingSqueezeStatusAs(LayoutParams.SQUEEZE_STATUS_FAILED, i);
+                    markButtonsWithPendingSqueezeStatusAs(
+                            LayoutParams.SQUEEZE_STATUS_FAILED, coveredSuggestions);
 
                     // The current button doesn't fit, so there's no point in measuring further
                     // buttons.
@@ -426,7 +417,8 @@
 
                 // The current button fits, so mark all squeezed buttons as "successfully squeezed"
                 // to prevent them from being un-squeezed in a subsequent squeezing round.
-                markButtonsWithPendingSqueezeStatusAs(LayoutParams.SQUEEZE_STATUS_SUCCESSFUL, i);
+                markButtonsWithPendingSqueezeStatusAs(
+                        LayoutParams.SQUEEZE_STATUS_SUCCESSFUL, coveredSuggestions);
             }
 
             lp.show = true;
@@ -445,6 +437,22 @@
                         mPaddingTop + maxChildHeight + mPaddingBottom), heightMeasureSpec));
     }
 
+    private List<View> filterActionsOrReplies(SmartButtonType buttonType) {
+        List<View> actions = new ArrayList<>();
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (child.getVisibility() != View.VISIBLE || !(child instanceof Button)) {
+                continue;
+            }
+            if (lp.buttonType == buttonType) {
+                actions.add(child);
+            }
+        }
+        return actions;
+    }
+
     private void resetButtonsLayoutParams() {
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
@@ -615,9 +623,9 @@
         }
     }
 
-    private void markButtonsWithPendingSqueezeStatusAs(int squeezeStatus, int maxChildIndex) {
-        for (int i = 0; i <= maxChildIndex; i++) {
-            final View child = getChildAt(i);
+    private void markButtonsWithPendingSqueezeStatusAs(
+            int squeezeStatus, List<View> coveredChildren) {
+        for (View child : coveredChildren) {
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
             if (lp.squeezeStatus == LayoutParams.SQUEEZE_STATUS_PENDING) {
                 lp.squeezeStatus = squeezeStatus;
@@ -712,6 +720,11 @@
         return mActivityStarter;
     }
 
+    private enum SmartButtonType {
+        REPLY,
+        ACTION
+    }
+
     @VisibleForTesting
     static class LayoutParams extends ViewGroup.LayoutParams {
 
@@ -737,6 +750,7 @@
 
         private boolean show = false;
         private int squeezeStatus = SQUEEZE_STATUS_NONE;
+        private SmartButtonType buttonType = SmartButtonType.REPLY;
 
         private LayoutParams(Context c, AttributeSet attrs) {
             super(c, attrs);
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 cd379c5..4a69cd7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -42,7 +42,7 @@
     public void start() {
         putComponent(TvStatusBar.class, this);
         CommandQueue commandQueue = getComponent(CommandQueue.class);
-        commandQueue.addCallbacks(this);
+        commandQueue.addCallback(this);
         int[] switches = new int[9];
         ArrayList<IBinder> binders = new ArrayList<>();
         ArrayList<String> iconSlots = new ArrayList<>();
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index 6812410..490cdd5c 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -57,13 +57,13 @@
         public void onViewAttachedToWindow(View v) {
             mView = v;
             SysUiServiceProvider.getComponent(v.getContext(), CommandQueue.class)
-                    .addCallbacks(this);
+                    .addCallback(this);
         }
 
         @Override
         public void onViewDetachedFromWindow(View v) {
             SysUiServiceProvider.getComponent(mView.getContext(), CommandQueue.class)
-                    .removeCallbacks(this);
+                    .removeCallback(this);
             mView = null;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
deleted file mode 100644
index 9b616e0..0000000
--- a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
- * Copyright (C) 2018 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.volume;
-
-import android.animation.Animator;
-import android.animation.AnimatorInflater;
-import android.animation.AnimatorSet;
-import android.annotation.DrawableRes;
-import android.annotation.Nullable;
-import android.app.Dialog;
-import android.app.KeyguardManager;
-import android.car.Car;
-import android.car.CarNotConnectedException;
-import android.car.media.CarAudioManager;
-import android.car.media.ICarVolumeCallback;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.ServiceConnection;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.os.Debug;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.Xml;
-import android.view.ContextThemeWrapper;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.SeekBar;
-import android.widget.SeekBar.OnSeekBarChangeListener;
-
-import androidx.car.widget.ListItem;
-import androidx.car.widget.ListItemAdapter;
-import androidx.car.widget.ListItemAdapter.BackgroundStyle;
-import androidx.car.widget.ListItemProvider.ListProvider;
-import androidx.car.widget.PagedListView;
-import androidx.car.widget.SeekbarListItem;
-
-import com.android.systemui.R;
-import com.android.systemui.plugins.VolumeDialog;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Car version of the volume dialog.
- *
- * Methods ending in "H" must be called on the (ui) handler.
- */
-public class CarVolumeDialogImpl implements VolumeDialog {
-  private static final String TAG = Util.logTag(CarVolumeDialogImpl.class);
-
-  private static final String XML_TAG_VOLUME_ITEMS = "carVolumeItems";
-  private static final String XML_TAG_VOLUME_ITEM = "item";
-  private static final int HOVERING_TIMEOUT = 16000;
-  private static final int NORMAL_TIMEOUT = 3000;
-  private static final int LISTVIEW_ANIMATION_DURATION_IN_MILLIS = 250;
-  private static final int DISMISS_DELAY_IN_MILLIS = 50;
-  private static final int ARROW_FADE_IN_START_DELAY_IN_MILLIS = 100;
-
-  private final Context mContext;
-  private final H mHandler = new H();
-
-  private Window mWindow;
-  private CustomDialog mDialog;
-  private PagedListView mListView;
-  private ListItemAdapter mPagedListAdapter;
-  // All the volume items.
-  private final SparseArray<VolumeItem> mVolumeItems = new SparseArray<>();
-  // Available volume items in car audio manager.
-  private final List<VolumeItem> mAvailableVolumeItems = new ArrayList<>();
-  // Volume items in the PagedListView.
-  private final List<ListItem> mVolumeLineItems = new ArrayList<>();
-  private final KeyguardManager mKeyguard;
-
-  private Car mCar;
-  private CarAudioManager mCarAudioManager;
-
-  private boolean mHovering;
-  private boolean mShowing;
-  private boolean mExpanded;
-
-  public CarVolumeDialogImpl(Context context) {
-    mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
-    mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-    mCar = Car.createCar(mContext, mServiceConnection);
-  }
-
-  public void init(int windowType, Callback callback) {
-    initDialog();
-
-    mCar.connect();
-  }
-
-  @Override
-  public void destroy() {
-    mHandler.removeCallbacksAndMessages(null);
-
-    cleanupAudioManager();
-    // unregisterVolumeCallback is not being called when disconnect car, so we manually cleanup
-    // audio manager beforehand.
-    mCar.disconnect();
-  }
-
-  private void initDialog() {
-    loadAudioUsageItems();
-    mVolumeLineItems.clear();
-    mDialog = new CustomDialog(mContext);
-
-    mHovering = false;
-    mShowing = false;
-    mExpanded = false;
-    mWindow = mDialog.getWindow();
-    mWindow.requestFeature(Window.FEATURE_NO_TITLE);
-    mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
-    mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND
-        | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
-    mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
-        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
-        | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
-    mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
-    mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast);
-    final WindowManager.LayoutParams lp = mWindow.getAttributes();
-    lp.format = PixelFormat.TRANSLUCENT;
-    lp.setTitle(VolumeDialogImpl.class.getSimpleName());
-    lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
-    lp.windowAnimations = -1;
-    mWindow.setAttributes(lp);
-    mWindow.setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-
-    mDialog.setCanceledOnTouchOutside(true);
-    mDialog.setContentView(R.layout.car_volume_dialog);
-    mDialog.setOnShowListener(dialog -> {
-      mListView.setTranslationY(-mListView.getHeight());
-      mListView.setAlpha(0);
-      mListView.animate()
-          .alpha(1)
-          .translationY(0)
-          .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
-          .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
-          .start();
-    });
-    mListView = (PagedListView) mWindow.findViewById(R.id.volume_list);
-    mListView.setOnHoverListener((v, event) -> {
-      int action = event.getActionMasked();
-      mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
-          || (action == MotionEvent.ACTION_HOVER_MOVE);
-      rescheduleTimeoutH();
-      return true;
-    });
-
-    mPagedListAdapter = new ListItemAdapter(mContext, new ListProvider(mVolumeLineItems),
-        BackgroundStyle.PANEL);
-    mListView.setAdapter(mPagedListAdapter);
-    mListView.setMaxPages(PagedListView.UNLIMITED_PAGES);
-  }
-
-  public void show(int reason) {
-    mHandler.obtainMessage(H.SHOW, reason).sendToTarget();
-  }
-
-  public void dismiss(int reason) {
-    mHandler.obtainMessage(H.DISMISS, reason).sendToTarget();
-  }
-
-  private void showH(int reason) {
-    if (D.BUG) {
-      Log.d(TAG, "showH r=" + Events.DISMISS_REASONS[reason]);
-    }
-
-    mHandler.removeMessages(H.SHOW);
-    mHandler.removeMessages(H.DISMISS);
-    rescheduleTimeoutH();
-    // Refresh the data set before showing.
-    mPagedListAdapter.notifyDataSetChanged();
-    if (mShowing) {
-      return;
-    }
-    mShowing = true;
-
-    mDialog.show();
-    Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
-  }
-
-  protected void rescheduleTimeoutH() {
-    mHandler.removeMessages(H.DISMISS);
-    final int timeout = computeTimeoutH();
-    mHandler.sendMessageDelayed(mHandler
-        .obtainMessage(H.DISMISS, Events.DISMISS_REASON_TIMEOUT), timeout);
-
-    if (D.BUG) {
-      Log.d(TAG, "rescheduleTimeout " + timeout + " " + Debug.getCaller());
-    }
-  }
-
-  private int computeTimeoutH() {
-    return mHovering ? HOVERING_TIMEOUT : NORMAL_TIMEOUT;
-  }
-
-  protected void dismissH(int reason) {
-    if (D.BUG) {
-      Log.d(TAG, "dismissH r=" + Events.DISMISS_REASONS[reason]);
-    }
-
-    mHandler.removeMessages(H.DISMISS);
-    mHandler.removeMessages(H.SHOW);
-    if (!mShowing) {
-      return;
-    }
-
-    mListView.animate().cancel();
-
-    mListView.setTranslationY(0);
-    mListView.setAlpha(1);
-    mListView.animate()
-        .alpha(0)
-        .translationY(-mListView.getHeight())
-        .setDuration(LISTVIEW_ANIMATION_DURATION_IN_MILLIS)
-        .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator())
-        .withEndAction(() -> mHandler.postDelayed(() -> {
-          if (D.BUG) {
-            Log.d(TAG, "mDialog.dismiss()");
-          }
-          mDialog.dismiss();
-          mShowing = false;
-        }, DISMISS_DELAY_IN_MILLIS))
-        .start();
-
-    Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason);
-  }
-
-  public void dump(PrintWriter writer) {
-    writer.println(VolumeDialogImpl.class.getSimpleName() + " state:");
-    writer.print("  mShowing: "); writer.println(mShowing);
-  }
-
-  private void loadAudioUsageItems() {
-    try (XmlResourceParser parser = mContext.getResources().getXml(R.xml.car_volume_items)) {
-      AttributeSet attrs = Xml.asAttributeSet(parser);
-      int type;
-      // Traverse to the first start tag
-      while ((type=parser.next()) != XmlResourceParser.END_DOCUMENT
-          && type != XmlResourceParser.START_TAG) {
-      }
-
-      if (!XML_TAG_VOLUME_ITEMS.equals(parser.getName())) {
-        throw new RuntimeException("Meta-data does not start with carVolumeItems tag");
-      }
-      int outerDepth = parser.getDepth();
-      int rank = 0;
-      while ((type=parser.next()) != XmlResourceParser.END_DOCUMENT
-          && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) {
-        if (type == XmlResourceParser.END_TAG) {
-          continue;
-        }
-        if (XML_TAG_VOLUME_ITEM.equals(parser.getName())) {
-          TypedArray item = mContext.getResources().obtainAttributes(
-              attrs, R.styleable.carVolumeItems_item);
-          int usage = item.getInt(R.styleable.carVolumeItems_item_usage, -1);
-          if (usage >= 0) {
-            VolumeItem volumeItem = new VolumeItem();
-            volumeItem.usage = usage;
-            volumeItem.rank = rank;
-            volumeItem.icon = item.getResourceId(R.styleable.carVolumeItems_item_icon, 0);
-            mVolumeItems.put(usage, volumeItem);
-            rank++;
-          }
-          item.recycle();
-        }
-      }
-    } catch (XmlPullParserException | IOException e) {
-      Log.e(TAG, "Error parsing volume groups configuration", e);
-    }
-  }
-
-  private VolumeItem getVolumeItemForUsages(int[] usages) {
-    int rank = Integer.MAX_VALUE;
-    VolumeItem result = null;
-    for (int usage : usages) {
-      VolumeItem volumeItem = mVolumeItems.get(usage);
-      if (volumeItem.rank < rank) {
-        rank = volumeItem.rank;
-        result = volumeItem;
-      }
-    }
-    return result;
-  }
-
-  private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
-    try {
-      return carAudioManager.getGroupVolume(volumeGroupId);
-    } catch (CarNotConnectedException e) {
-      Log.e(TAG, "Car is not connected!", e);
-    }
-    return 0;
-  }
-
-  private static int getMaxSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
-    try {
-      return carAudioManager.getGroupMaxVolume(volumeGroupId);
-    } catch (CarNotConnectedException e) {
-      Log.e(TAG, "Car is not connected!", e);
-    }
-    return 0;
-  }
-
-  private SeekbarListItem addSeekbarListItem(VolumeItem volumeItem, int volumeGroupId,
-      int supplementalIconId, @Nullable View.OnClickListener supplementalIconOnClickListener) {
-    SeekbarListItem listItem = new SeekbarListItem(mContext);
-    listItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
-    int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint);
-    int progress = getSeekbarValue(mCarAudioManager, volumeGroupId);
-    listItem.setProgress(progress);
-    listItem.setOnSeekBarChangeListener(
-        new CarVolumeDialogImpl.VolumeSeekBarChangeListener(volumeGroupId, mCarAudioManager));
-    Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon);
-    primaryIcon.mutate().setTint(color);
-    listItem.setPrimaryActionIcon(primaryIcon);
-    if (supplementalIconId != 0) {
-      Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId);
-      supplementalIcon.mutate().setTint(color);
-      listItem.setSupplementalIcon(supplementalIcon, true);
-      listItem.setSupplementalIconListener(supplementalIconOnClickListener);
-    } else {
-      listItem.setSupplementalEmptyIcon(true);
-      listItem.setSupplementalIconListener(null);
-    }
-
-    mVolumeLineItems.add(listItem);
-    volumeItem.listItem = listItem;
-    volumeItem.progress = progress;
-    return listItem;
-  }
-
-  private VolumeItem findVolumeItem(SeekbarListItem targetItem) {
-    for (int i = 0; i < mVolumeItems.size(); ++i) {
-      VolumeItem volumeItem = mVolumeItems.valueAt(i);
-      if (volumeItem.listItem == targetItem) {
-        return volumeItem;
-      }
-    }
-    return null;
-  }
-
-  private void cleanupAudioManager() {
-    try {
-      mCarAudioManager.unregisterVolumeCallback(mVolumeChangeCallback.asBinder());
-    } catch (CarNotConnectedException e) {
-      Log.e(TAG, "Car is not connected!", e);
-    }
-    mVolumeLineItems.clear();
-    mCarAudioManager = null;
-  }
-
-  private final class H extends Handler {
-    private static final int SHOW = 1;
-    private static final int DISMISS = 2;
-
-    public H() {
-      super(Looper.getMainLooper());
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-      switch (msg.what) {
-        case SHOW:
-          showH(msg.arg1);
-          break;
-        case DISMISS:
-          dismissH(msg.arg1);
-          break;
-        default:
-      }
-    }
-  }
-
-  private final class CustomDialog extends Dialog implements DialogInterface {
-    public CustomDialog(Context context) {
-      super(context, com.android.systemui.R.style.qs_theme);
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-      rescheduleTimeoutH();
-      return super.dispatchTouchEvent(ev);
-    }
-
-    @Override
-    protected void onStart() {
-      super.setCanceledOnTouchOutside(true);
-      super.onStart();
-    }
-
-    @Override
-    protected void onStop() {
-      super.onStop();
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-      if (isShowing()) {
-        if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
-          mHandler.obtainMessage(
-            H.DISMISS, Events.DISMISS_REASON_TOUCH_OUTSIDE).sendToTarget();
-          return true;
-        }
-      }
-      return false;
-    }
-  }
-
-  private final class ExpandIconListener implements View.OnClickListener {
-    @Override
-    public void onClick(final View v) {
-      mExpanded = !mExpanded;
-      Animator inAnimator;
-      if (mExpanded) {
-        for (int groupId = 0; groupId < mAvailableVolumeItems.size(); ++groupId) {
-          // Adding the items which are not coming from the default item.
-          VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
-          if (volumeItem.defaultItem) {
-            // Set progress here due to the progress of seekbar may not be updated.
-            volumeItem.listItem.setProgress(volumeItem.progress);
-          } else {
-            addSeekbarListItem(volumeItem, groupId, 0, null);
-          }
-        }
-        inAnimator = AnimatorInflater.loadAnimator(
-            mContext, R.anim.car_arrow_fade_in_rotate_up);
-      } else {
-        // Only keeping the default stream if it is not expended.
-        Iterator itr = mVolumeLineItems.iterator();
-        while (itr.hasNext()) {
-          SeekbarListItem seekbarListItem = (SeekbarListItem) itr.next();
-          VolumeItem volumeItem = findVolumeItem(seekbarListItem);
-          if (!volumeItem.defaultItem) {
-            itr.remove();
-          } else {
-            // Set progress here due to the progress of seekbar may not be updated.
-            seekbarListItem.setProgress(volumeItem.progress);
-          }
-        }
-        inAnimator = AnimatorInflater.loadAnimator(
-            mContext, R.anim.car_arrow_fade_in_rotate_down);
-      }
-
-      Animator outAnimator = AnimatorInflater.loadAnimator(
-          mContext, R.anim.car_arrow_fade_out);
-      inAnimator.setStartDelay(ARROW_FADE_IN_START_DELAY_IN_MILLIS);
-      AnimatorSet animators = new AnimatorSet();
-      animators.playTogether(outAnimator, inAnimator);
-      animators.setTarget(v);
-      animators.start();
-      mPagedListAdapter.notifyDataSetChanged();
-    }
-  }
-
-  private final class VolumeSeekBarChangeListener implements OnSeekBarChangeListener {
-    private final int mVolumeGroupId;
-    private final CarAudioManager mCarAudioManager;
-
-    private VolumeSeekBarChangeListener(int volumeGroupId, CarAudioManager carAudioManager) {
-      mVolumeGroupId = volumeGroupId;
-      mCarAudioManager = carAudioManager;
-    }
-
-    @Override
-    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-      if (!fromUser) {
-        // For instance, if this event is originated from AudioService,
-        // we can ignore it as it has already been handled and doesn't need to be
-        // sent back down again.
-        return;
-      }
-      try {
-        if (mCarAudioManager == null) {
-          Log.w(TAG, "Ignoring volume change event because the car isn't connected");
-          return;
-        }
-        mAvailableVolumeItems.get(mVolumeGroupId).progress = progress;
-        mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
-      } catch (CarNotConnectedException e) {
-        Log.e(TAG, "Car is not connected!", e);
-      }
-    }
-
-    @Override
-    public void onStartTrackingTouch(SeekBar seekBar) {}
-
-    @Override
-    public void onStopTrackingTouch(SeekBar seekBar) {}
-  }
-
-  private final ICarVolumeCallback mVolumeChangeCallback = new ICarVolumeCallback.Stub() {
-    @Override
-    public void onGroupVolumeChanged(int groupId, int flags) {
-      VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
-      int value = getSeekbarValue(mCarAudioManager, groupId);
-      // Do not update the progress if it is the same as before. When car audio manager sets its
-      // group volume caused by the seekbar progress changed, it also triggers this callback.
-      // Updating the seekbar at the same time could block the continuous seeking.
-      if (value != volumeItem.progress) {
-        volumeItem.listItem.setProgress(value);
-        volumeItem.progress = value;
-      }
-      if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
-        show(Events.SHOW_REASON_VOLUME_CHANGED);
-      }
-    }
-
-    @Override
-    public void onMasterMuteChanged(int flags) {
-      // ignored
-    }
-  };
-
-  private final ServiceConnection mServiceConnection = new ServiceConnection() {
-    @Override
-    public void onServiceConnected(ComponentName name, IBinder service) {
-      try {
-        mExpanded = false;
-        mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
-        int volumeGroupCount = mCarAudioManager.getVolumeGroupCount();
-        // Populates volume slider items from volume groups to UI.
-        for (int groupId = 0; groupId < volumeGroupCount; groupId++) {
-          VolumeItem volumeItem = getVolumeItemForUsages(
-              mCarAudioManager.getUsagesForVolumeGroupId(groupId));
-          mAvailableVolumeItems.add(volumeItem);
-          // The first one is the default item.
-          if (groupId == 0) {
-            volumeItem.defaultItem = true;
-            addSeekbarListItem(volumeItem, groupId, R.drawable.car_ic_keyboard_arrow_down,
-                new ExpandIconListener());
-          }
-        }
-
-        // If list is already initiated, update its content.
-        if (mPagedListAdapter != null) {
-          mPagedListAdapter.notifyDataSetChanged();
-        }
-        mCarAudioManager.registerVolumeCallback(mVolumeChangeCallback.asBinder());
-      } catch (CarNotConnectedException e) {
-        Log.e(TAG, "Car is not connected!", e);
-      }
-    }
-
-    /**
-     * This does not get called when service is properly disconnected.
-     * So we need to also handle cleanups in destroy().
-     */
-    @Override
-    public void onServiceDisconnected(ComponentName name) {
-      cleanupAudioManager();
-    }
-  };
-
-  /**
-   * Wrapper class which contains information of each volume group.
-   */
-  private static class VolumeItem {
-    private @AudioAttributes.AttributeUsage int usage;
-    private int rank;
-    private boolean defaultItem = false;
-    private @DrawableRes int icon;
-    private SeekbarListItem listItem;
-    private int progress;
-  }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 2861dff..0805677 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -19,12 +19,10 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.media.AudioManager;
 import android.media.VolumePolicy;
 import android.os.Bundle;
-import android.os.Handler;
 import android.view.WindowManager.LayoutParams;
 
 import com.android.settingslib.applications.InterestingConfigChanges;
@@ -57,7 +55,7 @@
     public static final boolean DEFAULT_DO_NOT_DISTURB_WHEN_SILENT = false;
 
     private final SystemUI mSysui;
-    private final Context mContext;
+    protected final Context mContext;
     private final VolumeDialogControllerImpl mController;
     private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
             ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
@@ -70,7 +68,7 @@
             400    // vibrateToSilentDebounce
     );
 
-    public VolumeDialogComponent(SystemUI sysui, Context context, Handler handler) {
+    public VolumeDialogComponent(SystemUI sysui, Context context) {
         mSysui = sysui;
         mContext = context;
         mController = (VolumeDialogControllerImpl) Dependency.get(VolumeDialogController.class);
@@ -81,7 +79,6 @@
         Dependency.get(ExtensionController.class).newExtension(VolumeDialog.class)
                 .withPlugin(VolumeDialog.class)
                 .withDefault(this::createDefault)
-                .withFeature(PackageManager.FEATURE_AUTOMOTIVE, this::createCarDefault)
                 .withCallback(dialog -> {
                     if (mDialog != null) {
                         mDialog.destroy();
@@ -94,7 +91,7 @@
                 VOLUME_SILENT_DO_NOT_DISTURB);
     }
 
-    private VolumeDialog createDefault() {
+    protected VolumeDialog createDefault() {
         VolumeDialogImpl impl = new VolumeDialogImpl(mContext);
         impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
         impl.setAutomute(true);
@@ -102,10 +99,6 @@
         return impl;
     }
 
-    private VolumeDialog createCarDefault() {
-        return new CarVolumeDialogImpl(mContext);
-    }
-
     @Override
     public void onTuningChanged(String key, String newValue) {
         if (VOLUME_DOWN_SILENT.equals(key)) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index e4f37de..f8cf793 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -22,6 +22,7 @@
 
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.qs.tiles.DndTile;
 
 import java.io.FileDescriptor;
@@ -43,7 +44,9 @@
             mContext.getResources().getBoolean(R.bool.enable_safety_warning);
         mEnabled = enableVolumeUi || enableSafetyWarning;
         if (!mEnabled) return;
-        mVolumeComponent = new VolumeDialogComponent(this, mContext, null);
+
+        mVolumeComponent = SystemUIFactory.getInstance()
+                .createVolumeDialogComponent(this, mContext);
         mVolumeComponent.setEnableDialogs(enableVolumeUi, enableSafetyWarning);
         putComponent(VolumeComponent.class, getVolumeComponent());
         setDefaultVolumeController();
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index b32bf99..83ec33c 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -38,8 +38,6 @@
     android.test.runner \
     telephony-common \
     android.test.base \
-    android.car \
-    android.car.userlib
 
 LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
new file mode 100644
index 0000000..78700b8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSTileHostTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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.qs;
+
+
+import static junit.framework.TestCase.assertFalse;
+
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+public class QSTileHostTest extends SysuiTestCase {
+
+    @Test
+    public void testLoadTileSpecs_emptySetting() {
+        List<String> tiles = QSTileHost.loadTileSpecs(mContext, "");
+        assertFalse(tiles.isEmpty());
+    }
+
+    @Test
+    public void testLoadTileSpecs_nullSetting() {
+        List<String> tiles = QSTileHost.loadTileSpecs(mContext, null);
+        assertFalse(tiles.isEmpty());
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/car/CarQsFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/car/CarQsFragmentTest.java
deleted file mode 100644
index f89a932..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/car/CarQsFragmentTest.java
+++ /dev/null
@@ -1,89 +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.systemui.qs.car;
-
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-
-import android.content.Context;
-import android.support.test.filters.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.LayoutInflaterBuilder;
-import android.testing.TestableLooper;
-import android.testing.TestableLooper.RunWithLooper;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.keyguard.CarrierText;
-import com.android.systemui.Dependency;
-import com.android.systemui.SysuiBaseFragmentTest;
-import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.policy.Clock;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for {@link CarQSFragment}.
- */
-@RunWith(AndroidTestingRunner.class)
-@RunWithLooper(setAsMainLooper = true)
-@SmallTest
-@Ignore
-public class CarQsFragmentTest extends SysuiBaseFragmentTest {
-    public CarQsFragmentTest() {
-        super(CarQSFragment.class);
-    }
-
-    @Before
-    public void initDependencies() {
-        mContext.addMockSystemService(Context.LAYOUT_INFLATER_SERVICE,
-                new LayoutInflaterBuilder(mContext)
-                        .replace("com.android.systemui.statusbar.policy.SplitClockView",
-                                FrameLayout.class)
-                        .replace("TextClock", View.class)
-                        .replace(CarrierText.class, View.class)
-                        .replace(Clock.class, View.class)
-                        .build());
-        mSysuiContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
-        mDependency.injectTestDependency(Dependency.BG_LOOPER,
-                TestableLooper.get(this).getLooper());
-    }
-
-    @Test
-    @Ignore("Flaky")
-    public void testLayoutInflation() {
-        CarQSFragment fragment = (CarQSFragment) mFragment;
-        mFragments.dispatchResume();
-
-        assertNotNull(fragment.getHeader());
-        assertNotNull(fragment.getFooter());
-    }
-
-    @Test
-    @Ignore("Flaky")
-    public void testListening() {
-        CarQSFragment qs = (CarQSFragment) mFragment;
-        mFragments.dispatchResume();
-        processAllMessages();
-
-        qs.setListening(true);
-        processAllMessages();
-
-        qs.setListening(false);
-        processAllMessages();
-    }
-}
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 8ae3cd8..a04e57b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -14,6 +14,8 @@
 
 package com.android.systemui.statusbar;
 
+import static android.view.Display.DEFAULT_DISPLAY;
+
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -42,7 +44,7 @@
     public void setup() {
         mCommandQueue = new CommandQueue();
         mCallbacks = mock(Callbacks.class);
-        mCommandQueue.addCallbacks(mCallbacks);
+        mCommandQueue.addCallback(mCallbacks);
         verify(mCallbacks).disable(eq(0), eq(0), eq(false));
     }
 
@@ -64,11 +66,12 @@
         verify(mCallbacks).removeIcon(eq(slot));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testDisable() {
         int state1 = 14;
         int state2 = 42;
-        mCommandQueue.disable(state1, state2);
+        mCommandQueue.disable(DEFAULT_DISPLAY, state1, state2);
         waitForIdleSync();
         verify(mCallbacks).disable(eq(state1), eq(state2), eq(true));
     }
@@ -95,24 +98,27 @@
         verify(mCallbacks).animateExpandSettingsPanel(eq(panel));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testSetSystemUiVisibility() {
         Rect r = new Rect();
-        mCommandQueue.setSystemUiVisibility(1, 2, 3, 4, null, r);
+        mCommandQueue.setSystemUiVisibility(DEFAULT_DISPLAY, 1, 2, 3, 4, null, r);
         waitForIdleSync();
         verify(mCallbacks).setSystemUiVisibility(eq(1), eq(2), eq(3), eq(4), eq(null), eq(r));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testTopAppWindowChanged() {
-        mCommandQueue.topAppWindowChanged(true);
+        mCommandQueue.topAppWindowChanged(DEFAULT_DISPLAY, true);
         waitForIdleSync();
         verify(mCallbacks).topAppWindowChanged(eq(true));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testShowImeButton() {
-        mCommandQueue.setImeWindowStatus(null, 1, 2, true);
+        mCommandQueue.setImeWindowStatus(DEFAULT_DISPLAY, null, 1, 2, true);
         waitForIdleSync();
         verify(mCallbacks).setImeWindowStatus(eq(null), eq(1), eq(2), eq(true));
     }
@@ -166,9 +172,10 @@
         verify(mCallbacks).toggleKeyboardShortcutsMenu(eq(1));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testSetWindowState() {
-        mCommandQueue.setWindowState(1, 2);
+        mCommandQueue.setWindowState(DEFAULT_DISPLAY, 1, 2);
         waitForIdleSync();
         verify(mCallbacks).setWindowState(eq(1), eq(2));
     }
@@ -180,30 +187,34 @@
         verify(mCallbacks).showScreenPinningRequest(eq(1));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testAppTransitionPending() {
-        mCommandQueue.appTransitionPending();
+        mCommandQueue.appTransitionPending(DEFAULT_DISPLAY);
         waitForIdleSync();
         verify(mCallbacks).appTransitionPending(eq(false));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testAppTransitionCancelled() {
-        mCommandQueue.appTransitionCancelled();
+        mCommandQueue.appTransitionCancelled(DEFAULT_DISPLAY);
         waitForIdleSync();
         verify(mCallbacks).appTransitionCancelled();
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testAppTransitionStarting() {
-        mCommandQueue.appTransitionStarting(1, 2);
+        mCommandQueue.appTransitionStarting(DEFAULT_DISPLAY, 1, 2);
         waitForIdleSync();
         verify(mCallbacks).appTransitionStarting(eq(1L), eq(2L), eq(false));
     }
 
+    // TODO(b/117478341): add test case for multi-display
     @Test
     public void testAppTransitionFinished() {
-        mCommandQueue.appTransitionFinished();
+        mCommandQueue.appTransitionFinished(DEFAULT_DISPLAY);
         waitForIdleSync();
         verify(mCallbacks).appTransitionFinished();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index 906e718..bb9911b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -25,7 +25,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.Notification;
+import android.app.NotificationChannel;
 import android.service.notification.StatusBarNotification;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -35,6 +35,7 @@
 import android.view.ViewGroup;
 
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.utils.leaks.LeakCheckedTest;
 
 import org.junit.Before;
@@ -47,15 +48,22 @@
 @SmallTest
 public class NotificationMenuRowTest extends LeakCheckedTest {
 
+    private ExpandableNotificationRow mRow;
+
     @Before
     public void setup() {
         injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+        mRow = mock(ExpandableNotificationRow.class);
+        NotificationData.Entry entry = new NotificationData.Entry(
+                mock(StatusBarNotification.class));
+        entry.channel = mock(NotificationChannel.class);
+        when(mRow.getEntry()).thenReturn(entry);
     }
 
     @Test
     public void testAttachDetach() {
         NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
-        row.createMenu(null, null);
+        row.createMenu(mRow, null);
         ViewUtils.attachView(row.getMenuView());
         TestableLooper.get(this).processAllMessages();
         ViewUtils.detachView(row.getMenuView());
@@ -65,9 +73,9 @@
     @Test
     public void testRecreateMenu() {
         NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
-        row.createMenu(null, null);
+        row.createMenu(mRow, null);
         assertTrue(row.getMenuView() != null);
-        row.createMenu(null, null);
+        row.createMenu(mRow, null);
         assertTrue(row.getMenuView() != null);
     }
 
@@ -81,12 +89,7 @@
     @Test
     public void testNoAppOpsInSlowSwipe() {
         NotificationMenuRow row = new NotificationMenuRow(mContext);
-        Notification n = mock(Notification.class);
-        StatusBarNotification sbn = mock(StatusBarNotification.class);
-        when(sbn.getNotification()).thenReturn(n);
-        ExpandableNotificationRow parent = mock(ExpandableNotificationRow.class);
-        when(parent.getStatusBarNotification()).thenReturn(sbn);
-        row.createMenu(parent, null);
+        row.createMenu(mRow, null);
 
         ViewGroup container = (ViewGroup) row.getMenuView();
         // one for snooze and one for noti blocking
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
index 4177cd1..1783d0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
@@ -38,12 +38,12 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.content.Context;
 import com.android.systemui.R;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.SysuiTestCase;
 
+import android.content.Context;
 import android.content.res.Resources;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -78,6 +78,7 @@
         mProxyService = mock(OverviewProxyService.class);
         mProxy = mock(IOverviewProxy.Stub.class);
         doReturn(mProxy).when(mProxyService).getProxy();
+        doReturn(true).when(mProxyService).shouldShowSwipeUpUI();
         mDependency.injectTestDependency(OverviewProxyService.class, mProxyService);
 
         mStatusBar = mock(StatusBar.class);
@@ -106,6 +107,18 @@
     }
 
     @Test
+    public void testNoGesturesWhenSwipeUpDisabled() throws Exception {
+        doReturn(false).when(mProxyService).shouldShowSwipeUpUI();
+        mController.setGestureActions(mockAction(true), null /* swipeDownAction */,
+                null /* swipeLeftAction */, null /* swipeRightAction */);
+
+        MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
+        assertFalse(mController.onInterceptTouchEvent(ev));
+        verify(mNavigationBarView, never()).requestUnbufferedDispatch(ev);
+        assertNull(mController.getCurrentAction());
+    }
+
+    @Test
     public void testHasActionDetectGesturesTouchdown() throws Exception {
         MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
 
@@ -395,6 +408,7 @@
         verify(mProxy, times(1)).onQuickScrubStart();
         verify(mProxyService, times(1)).notifyQuickScrubStarted();
         verify(mNavigationBarView, times(1)).updateSlippery();
+        verify(mProxy, never()).onMotionEvent(moveEvent1);
 
         // Move again for scrub
         MotionEvent moveEvent2 = event(MotionEvent.ACTION_MOVE, 200, y);
@@ -402,6 +416,7 @@
         assertEquals(action, mController.getCurrentAction());
         verify(action, times(1)).onGestureMove(200, y);
         verify(mProxy, times(1)).onQuickScrubProgress(1f / 2);
+        verify(mProxy, never()).onMotionEvent(moveEvent2);
 
         // Action up
         MotionEvent upEvent = event(MotionEvent.ACTION_UP, 1, y);
@@ -409,6 +424,7 @@
         assertNull(mController.getCurrentAction());
         verify(action, times(1)).onGestureEnd();
         verify(mProxy, times(1)).onQuickScrubEnd();
+        verify(mProxy, never()).onMotionEvent(upEvent);
     }
 
     @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 e9e8eb7..c207fef 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
@@ -72,6 +72,8 @@
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.classifier.FalsingManager;
+import com.android.systemui.doze.DozeHost;
+import com.android.systemui.doze.DozeLog;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
@@ -123,6 +125,7 @@
     @Mock private IStatusBarService mBarService;
     @Mock private IDreamManager mDreamManager;
     @Mock private ScrimController mScrimController;
+    @Mock private DozeScrimController mDozeScrimController;
     @Mock private ArrayList<Entry> mNotificationList;
     @Mock private BiometricUnlockController mBiometricUnlockController;
     @Mock private NotificationData mNotificationData;
@@ -211,7 +214,7 @@
                 mKeyguardViewMediator, mRemoteInputManager, mock(NotificationGroupManager.class),
                 mock(NotificationGroupAlertTransferHelper.class), mock(FalsingManager.class),
                 mock(StatusBarWindowController.class), mock(NotificationIconAreaController.class),
-                mock(DozeScrimController.class), mock(NotificationShelf.class),
+                mDozeScrimController, mock(NotificationShelf.class),
                 mLockscreenUserManager, mCommandQueue, mNotificationPresenter,
                 mock(BubbleController.class));
         mStatusBar.mContext = mContext;
@@ -570,7 +573,28 @@
     }
 
     @Test
+    public void testPulseWhileDozing_updatesScrimController() {
+        mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
+        mStatusBar.showKeyguardImpl();
 
+        // Keep track of callback to be able to stop the pulse
+        DozeHost.PulseCallback[] pulseCallback = new DozeHost.PulseCallback[1];
+        doAnswer(invocation -> {
+            pulseCallback[0] = invocation.getArgument(0);
+            return null;
+        }).when(mDozeScrimController).pulse(any(), anyInt());
+
+        // Starting a pulse should change the scrim controller to the pulsing state
+        mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class),
+                DozeLog.PULSE_REASON_NOTIFICATION);
+        verify(mScrimController).transitionTo(eq(ScrimState.PULSING), any());
+
+        // Ending a pulse should take it back to keyguard state
+        pulseCallback[0].onPulseFinished();
+        verify(mScrimController).transitionTo(eq(ScrimState.KEYGUARD));
+    }
+
+    @Test
     public void testSetState_changesIsFullScreenUserSwitcherState() {
         mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
         assertFalse(mStatusBar.isFullScreenUserSwitcherState());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index df7aeab..506fa97 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -801,4 +801,55 @@
         assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(1), mView.getChildAt(1));
         assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(2), mView.getChildAt(2));
     }
+
+    @Test
+    public void testMeasure_choicesAndActionsPrioritizeActionsOnlyActions() {
+        String[] choices = new String[] {"Reply"};
+        String[] actions = new String[] {"Looooooong actioooon", "second action", "third action"};
+
+        // All actions should be displayed as DOUBLE-line smart action buttons.
+        ViewGroup expectedView = buildExpectedView(new String[0], 2,
+                createActions(new String[] {
+                        "Looooooong \nactioooon", "second \naction", "third \naction"}));
+        expectedView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+
+        setSmartRepliesAndActions(choices, actions);
+        mView.measure(
+                MeasureSpec.makeMeasureSpec(expectedView.getMeasuredWidth(), MeasureSpec.AT_MOST),
+                MeasureSpec.UNSPECIFIED);
+
+        assertEqualMeasures(expectedView, mView);
+        // smart replies
+        assertReplyButtonHidden(mView.getChildAt(0));
+        // smart actions
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(0), mView.getChildAt(1));
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(1), mView.getChildAt(2));
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(2), mView.getChildAt(3));
+    }
+
+    @Test
+    public void testMeasure_choicesAndActionsPrioritizeActions() {
+        String[] choices = new String[] {"Short", "longer reply"};
+        String[] actions = new String[] {"Looooooong actioooon", "second action"};
+
+        // All actions should be displayed as DOUBLE-line smart action buttons.
+        ViewGroup expectedView = buildExpectedView(new String[] {"Short"}, 2,
+                createActions(new String[] {"Looooooong \nactioooon", "second \naction"}));
+        expectedView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+
+        setSmartRepliesAndActions(choices, actions);
+        mView.measure(
+                MeasureSpec.makeMeasureSpec(expectedView.getMeasuredWidth(), MeasureSpec.AT_MOST),
+                MeasureSpec.UNSPECIFIED);
+
+        Button firstAction = ((Button) mView.getChildAt(1));
+
+        assertEqualMeasures(expectedView, mView);
+        // smart replies
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(0), mView.getChildAt(0));
+        assertReplyButtonHidden(mView.getChildAt(1));
+        // smart actions
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(1), mView.getChildAt(2));
+        assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(2), mView.getChildAt(3));
+    }
 }
diff --git a/packages/overlays/AdaptiveIconChangeOverlay/Android.mk b/packages/overlays/AdaptiveIconChangeOverlay/Android.mk
new file mode 100644
index 0000000..6e3b8cb
--- /dev/null
+++ b/packages/overlays/AdaptiveIconChangeOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+#  Copyright 2018, 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_RRO_THEME := SquareIcon
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := SquareIconOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/AdaptiveIconChangeOverlay/AndroidManifest.xml b/packages/overlays/AdaptiveIconChangeOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..33da510
--- /dev/null
+++ b/packages/overlays/AdaptiveIconChangeOverlay/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.theme.icon.square"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <overlay android:targetPackage="android"
+        android:category="android.theme.customization.adaptive_icon_shape"
+        android:priority="1"/>
+
+    <application android:label="@string/square_icon_overlay" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/AdaptiveIconChangeOverlay/res/values/config.xml b/packages/overlays/AdaptiveIconChangeOverlay/res/values/config.xml
new file mode 100644
index 0000000..54623f5
--- /dev/null
+++ b/packages/overlays/AdaptiveIconChangeOverlay/res/values/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2018, 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">
+    <!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. -->
+    <string name="config_icon_mask" translatable="false">"M50,0L100,0 100,100 0,100 0,0z"</string>
+    <!-- Flag indicating whether round icons should be parsed from the application manifest. -->
+    <bool name="config_useRoundIcon">false</bool>
+
+</resources>
+
diff --git a/packages/overlays/AdaptiveIconChangeOverlay/res/values/strings.xml b/packages/overlays/AdaptiveIconChangeOverlay/res/values/strings.xml
new file mode 100644
index 0000000..64b7d0d
--- /dev/null
+++ b/packages/overlays/AdaptiveIconChangeOverlay/res/values/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2018, 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">
+    <!-- Square icon overlay [DO NOT TRANSLATE] -->
+    <string name="square_icon_overlay">Square Icons</string>
+
+</resources>
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index c56f31e..0da07ae 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -175,10 +175,6 @@
         }
     };
 
-    // TODO(b/117779333): move to superclass / create super-class for ShellCommand
-    @GuardedBy("mLock")
-    private boolean mAllowInstantService;
-
     /**
      * Supported modes for Augmented Autofill Smart Suggestions.
      */
@@ -271,6 +267,11 @@
         addCompatibilityModeRequestsLocked(service, userId);
     }
 
+    @Override // from AbstractMasterSystemService
+    protected void enforceCallingPermissionForManagement() {
+        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+    }
+
     @Override // from SystemService
     public void onStart() {
         publishBinderService(AUTOFILL_MANAGER_SERVICE, new AutoFillManagerServiceStub());
@@ -290,7 +291,7 @@
     // Called by Shell command.
     void destroySessions(@UserIdInt int userId, IResultReceiver receiver) {
         Slog.i(TAG, "destroySessions() for userId " + userId);
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (mLock) {
             if (userId != UserHandle.USER_ALL) {
@@ -313,7 +314,7 @@
     // Called by Shell command.
     void listSessions(int userId, IResultReceiver receiver) {
         Slog.i(TAG, "listSessions() for userId " + userId);
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         final Bundle resultData = new Bundle();
         final ArrayList<String> sessions = new ArrayList<>();
@@ -340,7 +341,7 @@
     // Called by Shell command.
     void reset() {
         Slog.i(TAG, "reset()");
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (mLock) {
             visitServicesLocked((s) -> s.destroyLocked());
@@ -351,7 +352,7 @@
     // Called by Shell command.
     void setLogLevel(int level) {
         Slog.i(TAG, "setLogLevel(): " + level);
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         final long token = Binder.clearCallingIdentity();
         try {
@@ -388,7 +389,7 @@
 
     // Called by Shell command.
     int getLogLevel() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (mLock) {
             if (sVerbose) return AutofillManager.FLAG_ADD_CLIENT_VERBOSE;
@@ -399,7 +400,7 @@
 
     // Called by Shell command.
     int getMaxPartitions() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (mLock) {
             return sPartitionMaxCount;
@@ -408,8 +409,8 @@
 
     // Called by Shell command.
     void setMaxPartitions(int max) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
         Slog.i(TAG, "setMaxPartitions(): " + max);
+        enforceCallingPermissionForManagement();
 
         final long token = Binder.clearCallingIdentity();
         try {
@@ -433,7 +434,7 @@
 
     // Called by Shell command.
     int getMaxVisibleDatasets() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         synchronized (sLock) {
             return sVisibleDatasetsMaxCount;
@@ -442,8 +443,8 @@
 
     // Called by Shell command.
     void setMaxVisibleDatasets(int max) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
         Slog.i(TAG, "setMaxVisibleDatasets(): " + max);
+        enforceCallingPermissionForManagement();
 
         final long token = Binder.clearCallingIdentity();
         try {
@@ -480,7 +481,7 @@
     // Called by Shell command.
     void getScore(@Nullable String algorithmName, @NonNull String value1,
             @NonNull String value2, @NonNull RemoteCallback callback) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
 
         final FieldClassificationStrategy strategy =
                 new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT);
@@ -491,33 +492,16 @@
 
     // Called by Shell command.
     Boolean getFullScreenMode() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
         return sFullScreenMode;
     }
 
     // Called by Shell command.
     void setFullScreenMode(@Nullable Boolean mode) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        enforceCallingPermissionForManagement();
         sFullScreenMode = mode;
     }
 
-    // Called by Shell command.
-    boolean getAllowInstantService() {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-        synchronized (mLock) {
-            return mAllowInstantService;
-        }
-    }
-
-    // Called by Shell command.
-    void setAllowInstantService(boolean mode) {
-        getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
-        Slog.i(TAG, "setAllowInstantService(): " + mode);
-        synchronized (mLock) {
-            mAllowInstantService = mode;
-        }
-    }
-
     private void setLoggingLevelsLocked(boolean debug, boolean verbose) {
         com.android.server.autofill.Helper.sDebug = debug;
         android.view.autofill.Helper.sDebug = debug;
@@ -1218,7 +1202,6 @@
                     mAutofillCompatState.dump(prefix, pw);
                     pw.print("from settings: ");
                     pw.println(getWhitelistedCompatModePackagesFromSettings());
-                    pw.print("Allow instant service: "); pw.println(mAllowInstantService);
                     if (mSupportedSmartSuggestionModes != 0) {
                         pw.print("Smart Suggestion modes: ");
                         pw.println(smartSuggestionFlagsToString(mSupportedSmartSuggestionModes));
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 0df99d4..18bc856 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -190,6 +190,11 @@
         return mInfo.getServiceInfo();
     }
 
+    @Override // from PerUserSystemService
+    protected String getDefaultComponentName() {
+        return getComponentNameFromSettings();
+    }
+
     @Nullable
     String[] getUrlBarResourceIdsForCompatMode(@NonNull String packageName) {
         return mAutofillCompatState.getUrlBarResourceIds(packageName, mUserId);
@@ -369,7 +374,7 @@
 
         final long identity = Binder.clearCallingIdentity();
         try {
-            final String autoFillService = getComponentNameFromSettings();
+            final String autoFillService = getComponentNameLocked();
             final ComponentName componentName = serviceInfo.getComponentName();
             if (componentName.equals(ComponentName.unflattenFromString(autoFillService))) {
                 mMetricsLogger.action(MetricsEvent.AUTOFILL_SERVICE_DISABLED_SELF,
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 9aa9d7c..af65759 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -40,9 +40,9 @@
 import android.text.format.DateUtils;
 import android.util.Slog;
 
-import com.android.server.AbstractRemoteService;
+import com.android.server.AbstractSinglePendingRequestRemoteService;
 
-final class RemoteFillService extends AbstractRemoteService {
+final class RemoteFillService extends AbstractSinglePendingRequestRemoteService<RemoteFillService> {
 
     private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
     private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
@@ -69,8 +69,8 @@
         mCallbacks = callbacks;
     }
 
-    @Override
-    protected void onConnectedStateChanged(boolean state) {
+    @Override // from AbstractRemoteService
+    protected void handleOnConnectedStateChanged(boolean state) {
         if (mAutoFillService == null) {
             Slog.w(mTag, "onConnectedStateChanged(): null service");
             return;
@@ -82,18 +82,18 @@
         }
     }
 
-    @Override
+    @Override // from AbstractRemoteService
     protected IInterface getServiceInterface(IBinder service) {
         mAutoFillService = IAutoFillService.Stub.asInterface(service);
         return mAutoFillService;
     }
 
-    @Override
+    @Override // from AbstractRemoteService
     protected long getTimeoutIdleBindMillis() {
         return TIMEOUT_IDLE_BIND_MILLIS;
     }
 
-    @Override
+    @Override // from AbstractRemoteService
     protected long getRemoteRequestMillis() {
         return TIMEOUT_REMOTE_REQUEST_MILLIS;
     }
@@ -136,6 +136,19 @@
         scheduleRequest(new PendingSaveRequest(request, this));
     }
 
+    private boolean handleResponseCallbackCommon(
+            @NonNull PendingRequest<RemoteFillService> pendingRequest) {
+        if (isDestroyed()) return false;
+
+        if (mPendingRequest == pendingRequest) {
+            mPendingRequest = null;
+        }
+        if (mPendingRequest == null) {
+            scheduleUnbind();
+        }
+        return true;
+    }
+
     private void dispatchOnFillRequestSuccess(@NonNull PendingFillRequest pendingRequest,
             @Nullable FillResponse response, int requestFlags) {
         mHandler.post(() -> {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 8676f7f..79565f9 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -902,7 +902,7 @@
 
     // VultureCallback
     @Override
-    public void onServiceDied(AbstractRemoteService service) {
+    public void onServiceDied(AbstractRemoteService<? extends AbstractRemoteService<?>> service) {
         Slog.w(TAG, "removing session because service died");
         forceRemoveSelfLocked();
     }
@@ -2579,11 +2579,13 @@
                     + " when server returned null for session " + this.id);
         }
 
+        final AutofillValue currentValue = mViewStates.get(mCurrentViewId).getCurrentValue();
+
         // TODO(b/111330312): we might need to add a new state in the AutofillManager to optimize
         // furgher AFM -> AFMS calls.
         // TODO(b/119638958): add CTS tests
         return intelligenceManagerInternal.requestAutofill(mService.getUserId(), mClient,
-                mActivityToken, this.id, mCurrentViewId);
+                mActivityToken, this.id, mCurrentViewId, currentValue);
     }
 
     @GuardedBy("mLock")
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java b/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java
new file mode 100644
index 0000000..f356b4f
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKey.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2018 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.backup.encryption.keys;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.IntDef;
+import android.content.Context;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.RecoveryController;
+import android.util.Slog;
+
+import javax.crypto.SecretKey;
+
+/**
+ * Wraps a {@link RecoveryController}'s {@link SecretKey}. These are kept in "AndroidKeyStore" (a
+ * provider for {@link java.security.KeyStore} and {@link javax.crypto.KeyGenerator}. They are also
+ * synced with the recoverable key store, wrapped by the primary key. This allows them to be
+ * recovered on a user's subsequent device through providing their lock screen secret.
+ */
+public class RecoverableKeyStoreSecondaryKey {
+    private static final String TAG = "RecoverableKeyStoreSecondaryKey";
+
+    private final String mAlias;
+    private final SecretKey mSecretKey;
+
+    /**
+     * A new instance.
+     *
+     * @param alias The alias. It is keyed with this in AndroidKeyStore and the recoverable key
+     *     store.
+     * @param secretKey The key.
+     */
+    public RecoverableKeyStoreSecondaryKey(String alias, SecretKey secretKey) {
+        mAlias = checkNotNull(alias);
+        mSecretKey = checkNotNull(secretKey);
+    }
+
+    /**
+     * The ID, as stored in the recoverable {@link java.security.KeyStore}, and as used to identify
+     * wrapped tertiary keys on the backup server.
+     */
+    public String getAlias() {
+        return mAlias;
+    }
+
+    /** The secret key, to be used to wrap tertiary keys. */
+    public SecretKey getSecretKey() {
+        return mSecretKey;
+    }
+
+    /**
+     * The status of the key. i.e., whether it's been synced to remote trusted hardware.
+     *
+     * @param context The application context.
+     * @return One of {@link Status#SYNCED}, {@link Status#NOT_SYNCED} or {@link Status#DESTROYED}.
+     */
+    public @Status int getStatus(Context context) {
+        try {
+            return getStatusInternal(context);
+        } catch (InternalRecoveryServiceException e) {
+            Slog.wtf(TAG, "Internal error getting recovery status", e);
+            // Return NOT_SYNCED by default, as we do not want the backups to fail or to repeatedly
+            // attempt to reinitialize.
+            return Status.NOT_SYNCED;
+        }
+    }
+
+    private @Status int getStatusInternal(Context context) throws InternalRecoveryServiceException {
+        int status = RecoveryController.getInstance(context).getRecoveryStatus(mAlias);
+        switch (status) {
+            case RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE:
+                return Status.DESTROYED;
+            case RecoveryController.RECOVERY_STATUS_SYNCED:
+                return Status.SYNCED;
+            case RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS:
+                return Status.NOT_SYNCED;
+            default:
+                // Throw an exception if we encounter a status that doesn't match any of the above.
+                throw new InternalRecoveryServiceException(
+                        "Unexpected status from getRecoveryStatus: " + status);
+        }
+    }
+
+    /** Status of a key in the recoverable key store. */
+    @IntDef({Status.NOT_SYNCED, Status.SYNCED, Status.DESTROYED})
+    public @interface Status {
+        /**
+         * The key has not yet been synced to remote trusted hardware. This may be because the user
+         * has not yet unlocked their device.
+         */
+        int NOT_SYNCED = 1;
+
+        /**
+         * The key has been synced with remote trusted hardware. It should now be recoverable on
+         * another device.
+         */
+        int SYNCED = 2;
+
+        /** The key has been lost forever. This can occur if the user disables their lock screen. */
+        int DESTROYED = 3;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java b/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java
new file mode 100644
index 0000000..db5fe77
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManager.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2018 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.backup.encryption.keys;
+
+import android.content.Context;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.LockScreenRequiredException;
+import android.security.keystore.recovery.RecoveryController;
+import android.util.ByteStringUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.util.Optional;
+
+import javax.crypto.SecretKey;
+
+/**
+ * Manages generating, deleting, and retrieving secondary keys through {@link RecoveryController}.
+ *
+ * <p>The recoverable key store will be synced remotely via the {@link RecoveryController}, allowing
+ * recovery of keys on other devices owned by the user.
+ */
+public class RecoverableKeyStoreSecondaryKeyManager {
+    private static final String BACKUP_KEY_ALIAS_PREFIX =
+            "com.android.server.backup/recoverablekeystore/";
+    private static final int BACKUP_KEY_SUFFIX_LENGTH_BITS = 128;
+    private static final int BITS_PER_BYTE = 8;
+
+    /** A new instance. */
+    public static RecoverableKeyStoreSecondaryKeyManager getInstance(Context context) {
+        return new RecoverableKeyStoreSecondaryKeyManager(
+                RecoveryController.getInstance(context), new SecureRandom());
+    }
+
+    private final RecoveryController mRecoveryController;
+    private final SecureRandom mSecureRandom;
+
+    @VisibleForTesting
+    public RecoverableKeyStoreSecondaryKeyManager(
+            RecoveryController recoveryController, SecureRandom secureRandom) {
+        mRecoveryController = recoveryController;
+        mSecureRandom = secureRandom;
+    }
+
+    /**
+     * Generates a new recoverable key using the {@link RecoveryController}.
+     *
+     * @throws InternalRecoveryServiceException if an unexpected error occurred generating the key.
+     * @throws LockScreenRequiredException if the user does not have a lock screen. A lock screen is
+     *     required to generate a recoverable key.
+     */
+    public RecoverableKeyStoreSecondaryKey generate()
+            throws InternalRecoveryServiceException, LockScreenRequiredException,
+                    UnrecoverableKeyException {
+        String alias = generateId();
+        mRecoveryController.generateKey(alias);
+        SecretKey key = (SecretKey) mRecoveryController.getKey(alias);
+        if (key == null) {
+            throw new InternalRecoveryServiceException(
+                    String.format(
+                            "Generated key %s but could not get it back immediately afterwards.",
+                            alias));
+        }
+        return new RecoverableKeyStoreSecondaryKey(alias, key);
+    }
+
+    /**
+     * Removes the secondary key. This means the key will no longer be recoverable.
+     *
+     * @param alias The alias of the key.
+     * @throws InternalRecoveryServiceException if there was a {@link RecoveryController} error.
+     */
+    public void remove(String alias) throws InternalRecoveryServiceException {
+        mRecoveryController.removeKey(alias);
+    }
+
+    /**
+     * Returns the {@link RecoverableKeyStoreSecondaryKey} with {@code alias} if it is in the {@link
+     * RecoveryController}. Otherwise, {@link Optional#empty()}.
+     */
+    public Optional<RecoverableKeyStoreSecondaryKey> get(String alias)
+            throws InternalRecoveryServiceException, UnrecoverableKeyException {
+        SecretKey secretKey = (SecretKey) mRecoveryController.getKey(alias);
+        return Optional.ofNullable(secretKey)
+                .map(key -> new RecoverableKeyStoreSecondaryKey(alias, key));
+    }
+
+    /**
+     * Generates a new key alias. This has more entropy than a UUID - it can be considered
+     * universally unique.
+     */
+    private String generateId() {
+        byte[] id = new byte[BACKUP_KEY_SUFFIX_LENGTH_BITS / BITS_PER_BYTE];
+        mSecureRandom.nextBytes(id);
+        return BACKUP_KEY_ALIAS_PREFIX + ByteStringUtils.toHexString(id);
+    }
+
+    /** Constructs a {@link RecoverableKeyStoreSecondaryKeyManager}. */
+    public interface RecoverableKeyStoreSecondaryKeyManagerProvider {
+        /** Returns a newly constructed {@link RecoverableKeyStoreSecondaryKeyManager}. */
+        RecoverableKeyStoreSecondaryKeyManager get();
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
new file mode 100644
index 0000000..ebf09df
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyGenerator.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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.backup.encryption.keys;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+/** 256-bit AES key generator. Each app should have its own separate AES key. */
+public class TertiaryKeyGenerator {
+    private static final int KEY_SIZE_BITS = 256;
+    private static final String KEY_ALGORITHM = "AES";
+
+    private final KeyGenerator mKeyGenerator;
+
+    /** New instance generating keys using {@code secureRandom}. */
+    public TertiaryKeyGenerator(SecureRandom secureRandom) {
+        try {
+            mKeyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
+            mKeyGenerator.init(KEY_SIZE_BITS, secureRandom);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(
+                    "Impossible condition: JCE thinks it does not support AES.", e);
+        }
+    }
+
+    /** Generates a new random AES key. */
+    public SecretKey generate() {
+        return mKeyGenerator.generateKey();
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java
new file mode 100644
index 0000000..ec90f6c
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/keys/TertiaryKeyRotationTracker.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2018 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.backup.encryption.keys;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Locale;
+
+/**
+ * Tracks when a tertiary key rotation is due.
+ *
+ * <p>After a certain number of incremental backups, the device schedules a full backup, which will
+ * generate a new encryption key, effecting a key rotation. We should do this on a regular basis so
+ * that if a key does become compromised it has limited value to the attacker.
+ *
+ * <p>No additional synchronization of this class is provided. Only one instance should be used at
+ * any time. This should be fine as there should be no parallelism in backups.
+ */
+public class TertiaryKeyRotationTracker {
+    private static final int MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION = 31;
+    private static final String SHARED_PREFERENCES_NAME = "tertiary_key_rotation_tracker";
+
+    private static final String TAG = "TertiaryKeyRotationTracker";
+    private static final boolean DEBUG = false;
+
+    /**
+     * A new instance, using {@code context} to commit data to disk via {@link SharedPreferences}.
+     */
+    public static TertiaryKeyRotationTracker getInstance(Context context) {
+        return new TertiaryKeyRotationTracker(
+                context.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE));
+    }
+
+    private final SharedPreferences mSharedPreferences;
+
+    /** New instance, storing data in {@code mSharedPreferences}. */
+    @VisibleForTesting
+    TertiaryKeyRotationTracker(SharedPreferences sharedPreferences) {
+        mSharedPreferences = sharedPreferences;
+    }
+
+    /**
+     * Returns {@code true} if the given app is due having its key rotated.
+     *
+     * @param packageName The package name of the app.
+     */
+    public boolean isKeyRotationDue(String packageName) {
+        return getBackupsSinceRotation(packageName) >= MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION;
+    }
+
+    /**
+     * Records that an incremental backup has occurred. Each incremental backup brings the app
+     * closer to the time when its key should be rotated.
+     *
+     * @param packageName The package name of the app for which the backup occurred.
+     */
+    public void recordBackup(String packageName) {
+        int backupsSinceRotation = getBackupsSinceRotation(packageName) + 1;
+        mSharedPreferences.edit().putInt(packageName, backupsSinceRotation).apply();
+        if (DEBUG) {
+            Slog.d(
+                    TAG,
+                    String.format(
+                            Locale.US,
+                            "Incremental backup for %s. %d backups until key rotation.",
+                            packageName,
+                            Math.max(
+                                    0,
+                                    MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION
+                                            - backupsSinceRotation)));
+        }
+    }
+
+    /**
+     * Resets the rotation delay for the given app. Should be invoked after a key rotation.
+     *
+     * @param packageName Package name of the app whose key has rotated.
+     */
+    public void resetCountdown(String packageName) {
+        mSharedPreferences.edit().putInt(packageName, 0).apply();
+    }
+
+    /** Marks all enrolled packages for key rotation. */
+    public void markAllForRotation() {
+        SharedPreferences.Editor editor = mSharedPreferences.edit();
+        for (String packageName : mSharedPreferences.getAll().keySet()) {
+            editor.putInt(packageName, MAX_BACKUPS_UNTIL_TERTIARY_KEY_ROTATION);
+        }
+        editor.apply();
+    }
+
+    private int getBackupsSinceRotation(String packageName) {
+        return mSharedPreferences.getInt(packageName, 0);
+    }
+}
diff --git a/services/core/java/com/android/server/AbstractMasterSystemService.java b/services/core/java/com/android/server/AbstractMasterSystemService.java
index 9c1e3cd..76010b3 100644
--- a/services/core/java/com/android/server/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/AbstractMasterSystemService.java
@@ -39,6 +39,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.Preconditions;
 
 import java.io.PrintWriter;
 import java.util.List;
@@ -93,6 +94,12 @@
     public boolean debug = false;
 
     /**
+     * Whether the service is allowed to bind to an instant-app.
+     */
+    @GuardedBy("mLock")
+    protected boolean mAllowInstantService;
+
+    /**
      * Users disabled due to {@link UserManager} restrictions, or {@code null} if the service cannot
      * be disabled through {@link UserManager}.
      */
@@ -176,6 +183,107 @@
     }
 
     /**
+     * Gets whether the service is allowed to bind to an instant-app.
+     *
+     * <p>Typically called by {@code ShellCommand} during CTS tests.
+     *
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     */
+    public final boolean getAllowInstantService() {
+        enforceCallingPermissionForManagement();
+        synchronized (mLock) {
+            return mAllowInstantService;
+        }
+    }
+
+    /**
+     * Sets whether the service is allowed to bind to an instant-app.
+     *
+     * <p>Typically called by {@code ShellCommand} during CTS tests.
+     *
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     */
+    public final void setAllowInstantService(boolean mode) {
+        Slog.i(mTag, "setAllowInstantService(): " + mode);
+        enforceCallingPermissionForManagement();
+        synchronized (mLock) {
+            mAllowInstantService = mode;
+        }
+    }
+
+    /**
+     * Temporary sets the service implementation.
+     *
+     * <p>Typically used by Shell command and/or CTS tests.
+     *
+     * @param componentName name of the new component
+     * @param durationMs how long the change will be valid (the service will be automatically reset
+     *            to the default component after this timeout expires).
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     * @throws IllegalArgumentException if value of {@code durationMs} is higher than
+     *             {@link #getMaximumTemporaryServiceDurationMs()}.
+     */
+    public final void setTemporaryService(@UserIdInt int userId, @NonNull String componentName,
+            int durationMs) {
+        Slog.i(mTag, "setTemporaryService(" + userId + ") to " + componentName + " for "
+                + durationMs + "ms");
+        enforceCallingPermissionForManagement();
+
+        Preconditions.checkNotNull(componentName);
+        final int maxDurationMs = getMaximumTemporaryServiceDurationMs();
+        if (durationMs > maxDurationMs) {
+            throw new IllegalArgumentException(
+                    "Max duration is " + maxDurationMs + " (called with " + durationMs + ")");
+        }
+
+        synchronized (mLock) {
+            final S service = getServiceForUserLocked(userId);
+            if (service != null) {
+                service.setTemporaryServiceLocked(componentName, durationMs);
+            }
+        }
+    }
+
+    /**
+     * Gets the maximum time the service implementation can be changed.
+     *
+     * @throws UnsupportedOperationException if subclass doesn't override it.
+     */
+    protected int getMaximumTemporaryServiceDurationMs() {
+        throw new UnsupportedOperationException("Not implemented by " + getClass());
+    }
+
+    /**
+     * Resets the temporary service implementation to the default component.
+     *
+     * <p>Typically used by Shell command and/or CTS tests.
+     *
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     */
+    public final void resetTemporaryService(@UserIdInt int userId) {
+        Slog.i(mTag, "resetTemporaryService(): " + userId);
+        enforceCallingPermissionForManagement();
+        synchronized (mLock) {
+            final S service = getServiceForUserLocked(userId);
+            if (service != null) {
+                service.resetTemporaryServiceLocked();
+            }
+        }
+    }
+
+    /**
+     * Asserts that the caller has permissions to manage this service.
+     *
+     * <p>Typically called by {@code ShellCommand} implementations.
+     *
+     * @throws UnsupportedOperationException if subclass doesn't override it.
+     * @throws SecurityException if caller is not allowed to manage this service's settings.
+     */
+    protected void enforceCallingPermissionForManagement() {
+        throw new UnsupportedOperationException("Not implemented by " + getClass());
+    }
+
+    /**
      * Creates a new service that will be added to the cache.
      *
      * @param resolvedUserId the resolved user id for the service.
@@ -362,6 +470,7 @@
             pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
             pw.print(" Verbose: "); pw.println(realVerbose);
             pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers);
+            pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService);
             pw.print(prefix); pw.print("Settings property: "); pw.println(
                     getServiceSettingsProperty());
             pw.print(prefix); pw.print("Cached services: ");
diff --git a/services/core/java/com/android/server/AbstractMultiplePendingRequestsRemoteService.java b/services/core/java/com/android/server/AbstractMultiplePendingRequestsRemoteService.java
new file mode 100644
index 0000000..f532b22
--- /dev/null
+++ b/services/core/java/com/android/server/AbstractMultiplePendingRequestsRemoteService.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Base class representing a remote service that can queue multiple pending requests while not
+ * bound.
+ *
+ * @param <S> the concrete remote service class
+ *
+ * @hide
+ */
+public abstract class AbstractMultiplePendingRequestsRemoteService<
+        S extends AbstractMultiplePendingRequestsRemoteService<S>>
+        extends AbstractRemoteService<S> {
+
+    private final int mInitialCapacity;
+
+    protected ArrayList<PendingRequest<S>> mPendingRequests;
+
+    public AbstractMultiplePendingRequestsRemoteService(@NonNull Context context,
+            @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
+            @NonNull VultureCallback callback, boolean bindInstantServiceAllowed, boolean verbose,
+            int initialCapacity) {
+        super(context, serviceInterface, componentName, userId, callback, bindInstantServiceAllowed,
+                verbose);
+        mInitialCapacity = initialCapacity;
+    }
+
+    @Override // from AbstractRemoteService
+    void handlePendingRequests() {
+        if (mPendingRequests != null) {
+            final int size = mPendingRequests.size();
+            if (mVerbose) Slog.v(mTag, "Sending " + size + " pending requests");
+            for (int i = 0; i < size; i++) {
+                mPendingRequests.get(i).run();
+            }
+            mPendingRequests = null;
+        }
+    }
+
+    @Override // from AbstractRemoteService
+    protected void handleOnDestroy() {
+        if (mPendingRequests != null) {
+            final int size = mPendingRequests.size();
+            if (mVerbose) Slog.v(mTag, "Canceling " + size + " pending requests");
+            for (int i = 0; i < size; i++) {
+                mPendingRequests.get(i).cancel();
+            }
+            mPendingRequests = null;
+        }
+    }
+
+    @Override // from AbstractRemoteService
+    public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+        super.dump(prefix, pw);
+
+        pw.append(prefix).append("initialCapacity=").append(String.valueOf(mInitialCapacity))
+                .println();
+        final int size = mPendingRequests == null ? 0 : mPendingRequests.size();
+        pw.append(prefix).append("pendingRequests=").append(String.valueOf(size)).println();
+    }
+
+    @Override // from AbstractRemoteService
+    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest) {
+        if (mPendingRequests == null) {
+            mPendingRequests = new ArrayList<>(mInitialCapacity);
+        }
+        mPendingRequests.add(pendingRequest);
+        if (mVerbose) {
+            Slog.v(mTag, "queued " + mPendingRequests.size() + " requests; last=" + pendingRequest);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/AbstractPerUserSystemService.java b/services/core/java/com/android/server/AbstractPerUserSystemService.java
index 001d85f..a26102d 100644
--- a/services/core/java/com/android/server/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/AbstractPerUserSystemService.java
@@ -26,12 +26,17 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ServiceInfo;
 import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Slog;
+import android.util.TimeUtils;
 
 import com.android.internal.annotations.GuardedBy;
 
@@ -49,6 +54,9 @@
 public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSystemService<S, M>,
         M extends AbstractMasterSystemService<M, S>> {
 
+    /** Handler message to {@link #resetTemporaryServiceLocked()} */
+    private static final int MSG_RESET_TEMPORARY_SERVICE = 0;
+
     protected final @UserIdInt int mUserId;
     protected final Object mLock;
     protected final String mTag = getClass().getSimpleName();
@@ -70,6 +78,26 @@
     @GuardedBy("mLock")
     private ServiceInfo mServiceInfo;
 
+    /**
+     * Temporary service name set by {@link #setTemporaryServiceLocked(String, int)}.
+     *
+     * <p>Typically used by Shell command and/or CTS tests.
+     */
+    @GuardedBy("mLock")
+    private String mTemporaryServiceName;
+
+    /**
+     * When the temporary service will expire (and reset back to the default).
+     */
+    @GuardedBy("mLock")
+    private long mTemporaryServiceExpiration;
+
+    /**
+     * Handler used to reset the temporary service name.
+     */
+    @GuardedBy("mLock")
+    private Handler mTemporaryHandler;
+
     protected AbstractPerUserSystemService(@NonNull M master, @NonNull Object lock,
             @UserIdInt int userId) {
         mMaster = master;
@@ -130,7 +158,7 @@
         mDisabled = disabled;
         ComponentName serviceComponent = null;
         ServiceInfo serviceInfo = null;
-        final String componentName = getComponentNameFromSettings();
+        final String componentName = getComponentNameLocked();
         if (!TextUtils.isEmpty(componentName)) {
             try {
                 serviceComponent = ComponentName.unflattenFromString(componentName);
@@ -191,6 +219,29 @@
     }
 
     /**
+     * Gets the current name of the service, which is either the
+     *  {@link #getDefaultComponentName() default service} or the
+     *  {@link #setTemporaryServiceLocked(String, int) temporary one}.
+     */
+    protected final String getComponentNameLocked() {
+        if (mTemporaryServiceName != null) {
+            // Always log it, as it should only be used on CTS or during development
+            Slog.w(mTag, "getComponentName(): using temporary name " + mTemporaryServiceName);
+            return mTemporaryServiceName;
+        }
+        return getDefaultComponentName();
+    }
+
+    /**
+     * Gets the name of the default component for the service.
+     *
+     * <p>Typically implemented by returning {@link #getComponentNameFromSettings()} or by using
+     * a string from the system resources.
+     */
+    @Nullable
+    protected abstract String getDefaultComponentName();
+
+    /**
      * Gets this name of the remote service this service binds to as defined by {@link Settings}.
      */
     @Nullable
@@ -201,6 +252,66 @@
     }
 
     /**
+     * Checks whether the current service for the user was temporarily set.
+     */
+    public final boolean isTemporaryServiceSetLocked() {
+        return mTemporaryServiceName != null;
+    }
+
+    /**
+     * Temporary sets the service implementation.
+     *
+     * @param componentName name of the new component
+     * @param durationMs how long the change will be valid (the service will be automatically reset
+     * to the default component after this timeout expires).
+     */
+    protected final void setTemporaryServiceLocked(@NonNull String componentName, int durationMs) {
+        mTemporaryServiceName = componentName;
+
+        if (mTemporaryHandler == null) {
+            mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
+                @Override
+                public void handleMessage(Message msg) {
+                    if (msg.what == MSG_RESET_TEMPORARY_SERVICE) {
+                        synchronized (mLock) {
+                            resetTemporaryServiceLocked();
+                        }
+                    } else {
+                        Slog.wtf(mTag, "invalid handler msg: " + msg);
+                    }
+                }
+            };
+        } else {
+            removeResetTemporaryServiceMessageLocked();
+        }
+        mTemporaryServiceExpiration = SystemClock.elapsedRealtime() + durationMs;
+        mTemporaryHandler.sendEmptyMessageDelayed(MSG_RESET_TEMPORARY_SERVICE, durationMs);
+
+        updateLocked(mDisabled);
+    }
+
+    private void removeResetTemporaryServiceMessageLocked() {
+        if (mMaster.verbose) {
+            Slog.v(mTag, "setTemporaryServiceLocked(): removing old message");
+        }
+        // NOTE: caller should already have checked it
+        mTemporaryHandler.removeMessages(MSG_RESET_TEMPORARY_SERVICE);
+    }
+
+    /**
+     * Resets the temporary service implementation to the default component.
+     */
+    protected final void resetTemporaryServiceLocked() {
+        Slog.i(mTag, "resetting temporary service from " + mTemporaryServiceName);
+        mTemporaryServiceName = null;
+        if (mTemporaryHandler != null) {
+            removeResetTemporaryServiceMessageLocked();
+            mTemporaryHandler = null;
+        }
+        updateLocked(mDisabled);
+    }
+
+    /**
      * Gets the {@link ComponentName} of the remote service this service binds to, or {@code null}
      * if the service is disabled.
      */
@@ -290,12 +401,14 @@
             pw.print(prefix); pw.print("Service UID: ");
             pw.println(mServiceInfo.applicationInfo.uid);
         }
-        final String componentName = getComponentNameFromSettings();
-        if (componentName != null) {
-            pw.print(prefix); pw.print("Service name: ");
-            pw.println(componentName);
+        if (mTemporaryServiceName != null) {
+            pw.print(prefix); pw.print("Temporary service name: "); pw.print(mTemporaryServiceName);
+            final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime();
+            pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.println(")");
+            pw.print(prefix); pw.print(prefix);
+            pw.print("Default service name: "); pw.println(getDefaultComponentName());
         } else {
-            pw.println("No service package set");
+            pw.print(prefix); pw.print("Service name: "); pw.println(getDefaultComponentName());
         }
     }
 }
diff --git a/services/core/java/com/android/server/AbstractRemoteService.java b/services/core/java/com/android/server/AbstractRemoteService.java
index 0d4cf6b..f636487 100644
--- a/services/core/java/com/android/server/AbstractRemoteService.java
+++ b/services/core/java/com/android/server/AbstractRemoteService.java
@@ -45,13 +45,20 @@
  *
  * <p>All state of this class is modified on a handler thread.
  *
+ * <p><b>NOTE: </b>this class should not be extended directly, you should extend either
+ * {@link AbstractSinglePendingRequestRemoteService} or
+ * {@link AbstractMultiplePendingRequestsRemoteService}.
+ *
  * <p>See {@code com.android.server.autofill.RemoteFillService} for a concrete
  * (no pun intended) example of how to use it.
  *
+ * @param <S> the concrete remote service class
+ *
  * @hide
  */
 //TODO(b/117779333): improve javadoc above instead of using Autofill as an example
-public abstract class AbstractRemoteService implements DeathRecipient {
+public abstract class AbstractRemoteService<S extends AbstractRemoteService<S>>
+        implements DeathRecipient {
 
     private static final int MSG_UNBIND = 1;
 
@@ -64,8 +71,6 @@
     protected final Handler mHandler;
     protected final ComponentName mComponentName;
 
-    protected PendingRequest<? extends AbstractRemoteService> mPendingRequest;
-
     private final Context mContext;
     private final Intent mIntent;
     private final VultureCallback mVultureCallback;
@@ -88,10 +93,11 @@
          *
          * @param service service that died!
          */
-        void onServiceDied(AbstractRemoteService service);
+        void onServiceDied(AbstractRemoteService<? extends AbstractRemoteService<?>> service);
     }
 
-    public AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
+    // NOTE: must be package-protected so this class is not extend outside
+    AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
             @NonNull ComponentName componentName, int userId, @NonNull VultureCallback callback,
             boolean bindInstantServiceAllowed, boolean verbose) {
         mContext = context;
@@ -118,12 +124,25 @@
         return mDestroyed;
     }
 
+    private void handleOnConnectedStateChangedInternal(boolean connected) {
+        if (connected) {
+            handlePendingRequests();
+        }
+        handleOnConnectedStateChanged(connected);
+    }
+
     /**
-     * Callback called when the system connected / disconnected to the service.
+     * Handles the pending requests when the connection it bounds to the remote service.
+     */
+    abstract void handlePendingRequests();
+
+    /**
+     * Callback called when the system connected / disconnected to the service and the pending
+     * requests have been handled.
      *
      * @param state {@code true} when connected, {@code false} when disconnected.
      */
-    protected void onConnectedStateChanged(boolean state) {
+    protected void handleOnConnectedStateChanged(boolean state) {
     }
 
     /**
@@ -144,14 +163,18 @@
 
     private void handleDestroy() {
         if (checkIfDestroyed()) return;
-        if (mPendingRequest != null) {
-            mPendingRequest.cancel();
-            mPendingRequest = null;
-        }
-        ensureUnbound();
+        handleOnDestroy();
+        handleEnsureUnbound();
         mDestroyed = true;
     }
 
+    /**
+     * Clears the state when this object is destroyed.
+     *
+     * <p>Typically used to cancel the pending requests.
+     */
+    protected abstract void handleOnDestroy();
+
     @Override // from DeathRecipient
     public void binderDied() {
         mHandler.sendMessage(obtainMessage(AbstractRemoteService::handleBinderDied, this));
@@ -183,9 +206,7 @@
         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();
+                .append(String.valueOf(handleIsBound())).println();
         pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
         pw.append(prefix).append("idleTimeout=")
             .append(Long.toString(getTimeoutIdleBindMillis() / 1000)).append("s").println();
@@ -194,7 +215,7 @@
         pw.println();
     }
 
-    protected void scheduleRequest(PendingRequest<? extends AbstractRemoteService> pendingRequest) {
+    protected void scheduleRequest(@NonNull PendingRequest<S> pendingRequest) {
         mHandler.sendMessage(obtainMessage(
                 AbstractRemoteService::handlePendingRequest, this, pendingRequest));
     }
@@ -215,19 +236,20 @@
     private void handleUnbind() {
         if (checkIfDestroyed()) return;
 
-        ensureUnbound();
+        handleEnsureUnbound();
     }
 
-    private void handlePendingRequest(
-            PendingRequest<? extends AbstractRemoteService> pendingRequest) {
+    /**
+     * Handles a request, either processing it right now when bound, or saving it to be handled when
+     * bound.
+     */
+    protected final void handlePendingRequest(@NonNull PendingRequest<S> pendingRequest) {
         if (checkIfDestroyed() || mCompleted) return;
 
-        if (!isBound()) {
-            if (mPendingRequest != null) {
-                mPendingRequest.cancel();
-            }
-            mPendingRequest = pendingRequest;
-            ensureBound();
+        if (!handleIsBound()) {
+            if (mVerbose) Slog.v(mTag, "handlePendingRequest(): queuing" + pendingRequest);
+            handlePendingRequestWhileUnBound(pendingRequest);
+            handleEnsureBound();
         } else {
             if (mVerbose) Slog.v(mTag, "handlePendingRequest(): " + pendingRequest);
             pendingRequest.run();
@@ -237,12 +259,17 @@
         }
     }
 
-    private boolean isBound() {
+    /**
+     * Defines what to do with a request that arrives while not bound to the service.
+     */
+    abstract void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest);
+
+    private boolean handleIsBound() {
         return mServiceInterface != null;
     }
 
-    private void ensureBound() {
-        if (isBound() || mBinding) return;
+    private void handleEnsureBound() {
+        if (handleIsBound() || mBinding) return;
 
         if (mVerbose) Slog.v(mTag, "ensureBound()");
         mBinding = true;
@@ -265,13 +292,13 @@
         }
     }
 
-    private void ensureUnbound() {
-        if (!isBound() && !mBinding) return;
+    private void handleEnsureUnbound() {
+        if (!handleIsBound() && !mBinding) return;
 
         if (mVerbose) Slog.v(mTag, "ensureUnbound()");
         mBinding = false;
-        if (isBound()) {
-            onConnectedStateChanged(false);
+        if (handleIsBound()) {
+            handleOnConnectedStateChangedInternal(false);
             if (mServiceInterface != null) {
                 mServiceInterface.asBinder().unlinkToDeath(this, 0);
                 mServiceInterface = null;
@@ -283,6 +310,7 @@
     private class RemoteServiceConnection implements ServiceConnection {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
+            if (mVerbose) Slog.v(mTag, "onServiceConnected()");
             if (mDestroyed || !mBinding) {
                 // This is abnormal. Unbinding the connection has been requested already.
                 Slog.wtf(mTag, "onServiceConnected() was dispatched after unbindService.");
@@ -296,15 +324,7 @@
                 handleBinderDied();
                 return;
             }
-            onConnectedStateChanged(true);
-
-            if (mPendingRequest != null) {
-                final PendingRequest<? extends AbstractRemoteService> pendingRequest =
-                        mPendingRequest;
-                mPendingRequest = null;
-                handlePendingRequest(pendingRequest);
-            }
-
+            handleOnConnectedStateChangedInternal(true);
             mServiceDied = false;
         }
 
@@ -325,25 +345,12 @@
         return mDestroyed;
     }
 
-    protected boolean handleResponseCallbackCommon(
-            PendingRequest<? extends AbstractRemoteService> pendingRequest) {
-        if (isDestroyed()) return false;
-
-        if (mPendingRequest == pendingRequest) {
-            mPendingRequest = null;
-        }
-        if (mPendingRequest == null) {
-            scheduleUnbind();
-        }
-        return true;
-    }
-
     /**
      * Base class for the requests serviced by the remote service.
      *
      * @param <S> the remote service class
      */
-    public abstract static class PendingRequest<S extends AbstractRemoteService>
+    public abstract static class PendingRequest<S extends AbstractRemoteService<S>>
             implements Runnable {
         protected final String mTag = getClass().getSimpleName();
         protected final Object mLock = new Object();
diff --git a/services/core/java/com/android/server/AbstractSinglePendingRequestRemoteService.java b/services/core/java/com/android/server/AbstractSinglePendingRequestRemoteService.java
new file mode 100644
index 0000000..8e1f540
--- /dev/null
+++ b/services/core/java/com/android/server/AbstractSinglePendingRequestRemoteService.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+
+/**
+ * Base class representing a remote service that can have only one pending requests while not bound.
+ *
+ * <p>If another request is received while not bound, the previous one will be canceled.
+ *
+ * @param <S> the concrete remote service class
+ *
+ * @hide
+ */
+public abstract class AbstractSinglePendingRequestRemoteService<
+        S extends AbstractSinglePendingRequestRemoteService<S>> extends AbstractRemoteService<S> {
+
+    protected PendingRequest<S> mPendingRequest;
+
+    public AbstractSinglePendingRequestRemoteService(@NonNull Context context,
+            @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
+            @NonNull VultureCallback callback, boolean bindInstantServiceAllowed,
+            boolean verbose) {
+        super(context, serviceInterface, componentName, userId, callback, bindInstantServiceAllowed,
+                verbose);
+    }
+
+    @Override // from AbstractRemoteService
+    void handlePendingRequests() {
+        if (mPendingRequest != null) {
+            final PendingRequest<S> pendingRequest = mPendingRequest;
+            mPendingRequest = null;
+            handlePendingRequest(pendingRequest);
+        }
+    }
+
+    @Override // from AbstractRemoteService
+    protected void handleOnDestroy() {
+        if (mPendingRequest != null) {
+            mPendingRequest.cancel();
+            mPendingRequest = null;
+        }
+    }
+
+    @Override // from AbstractRemoteService
+    public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+        super.dump(prefix, pw);
+        pw.append(prefix).append("hasPendingRequest=")
+                .append(String.valueOf(mPendingRequest != null)).println();
+    }
+
+    @Override // from AbstractRemoteService
+    void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest) {
+        if (mPendingRequest != null) {
+            if (mVerbose) {
+                Slog.v(mTag, "handlePendingRequestWhileUnBound(): cancelling " + mPendingRequest);
+            }
+            mPendingRequest.cancel();
+        }
+        mPendingRequest = pendingRequest;
+    }
+}
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index 9820321..81f0259 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -98,7 +98,7 @@
             mBinderCallsStats.setSamplingInterval(mParser.getInt(
                     SETTINGS_SAMPLING_INTERVAL_KEY,
                     BinderCallsStats.PERIODIC_SAMPLING_INTERVAL_DEFAULT));
-            mBinderCallsStats.setSamplingInterval(mParser.getInt(
+            mBinderCallsStats.setMaxBinderCallStats(mParser.getInt(
                     SETTINGS_MAX_CALL_STATS_KEY,
                     BinderCallsStats.MAX_BINDER_CALL_STATS_COUNT_DEFAULT));
 
@@ -116,6 +116,7 @@
                 }
                 mEnabled = enabled;
                 mBinderCallsStats.reset();
+                mBinderCallsStats.setAddDebugEntries(enabled);
             }
         }
     }
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 7ee3d3b..126bf65 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -1236,7 +1236,8 @@
                     OsConstants.UDP_ENCAP,
                     OsConstants.UDP_ENCAP_ESPINUDP);
 
-            mSrvConfig.getNetdInstance().ipSecSetEncapSocketOwner(sockFd, callingUid);
+            mSrvConfig.getNetdInstance().ipSecSetEncapSocketOwner(
+                        new ParcelFileDescriptor(sockFd), callingUid);
             if (port != 0) {
                 Log.v(TAG, "Binding to port " + port);
                 Os.bind(sockFd, INADDR_ANY, port);
@@ -1696,7 +1697,7 @@
         mSrvConfig
                 .getNetdInstance()
                 .ipSecApplyTransportModeTransform(
-                        socket.getFileDescriptor(),
+                        socket,
                         callingUid,
                         direction,
                         c.getSourceAddress(),
@@ -1715,7 +1716,7 @@
             throws RemoteException {
         mSrvConfig
                 .getNetdInstance()
-                .ipSecRemoveTransportModeTransform(socket.getFileDescriptor());
+                .ipSecRemoveTransportModeTransform(socket);
     }
 
     /**
diff --git a/services/core/java/com/android/server/LooperStatsService.java b/services/core/java/com/android/server/LooperStatsService.java
index c563ad2..fa3baba 100644
--- a/services/core/java/com/android/server/LooperStatsService.java
+++ b/services/core/java/com/android/server/LooperStatsService.java
@@ -94,6 +94,8 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
         pw.print("Start time: ");
         pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStats.getStartTimeMillis()));
+        pw.print("On battery time (ms): ");
+        pw.println(mStats.getBatteryTimeMillis());
         final List<LooperStats.ExportedEntry> entries = mStats.getEntries();
         entries.sort(Comparator
                 .comparing((LooperStats.ExportedEntry entry) -> entry.workSourceUid)
diff --git a/services/core/java/com/android/server/RuntimeService.java b/services/core/java/com/android/server/RuntimeService.java
new file mode 100644
index 0000000..ccfac80
--- /dev/null
+++ b/services/core/java/com/android/server/RuntimeService.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.Context;
+import android.os.Binder;
+import android.service.runtime.DebugEntryProto;
+import android.service.runtime.RuntimeServiceInfoProto;
+import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+
+import libcore.timezone.TimeZoneDataFiles;
+import libcore.util.CoreLibraryDebug;
+import libcore.util.DebugInfo;
+
+import com.android.internal.util.DumpUtils;
+import com.android.timezone.distro.DistroException;
+import com.android.timezone.distro.DistroVersion;
+import com.android.timezone.distro.FileUtils;
+import com.android.timezone.distro.TimeZoneDistro;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * This service exists only as a "dumpsys" target which reports information about the status of the
+ * runtime and related libraries.
+ */
+public class RuntimeService extends Binder {
+
+    private static final String TAG = "RuntimeService";
+
+    private final Context mContext;
+
+    public RuntimeService(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) {
+            return;
+        }
+
+        boolean protoFormat = hasOption(args, "--proto");
+        ProtoOutputStream proto = null;
+
+        DebugInfo coreLibraryDebugInfo = CoreLibraryDebug.getDebugInfo();
+        addTimeZoneApkDebugInfo(coreLibraryDebugInfo);
+
+        if (protoFormat) {
+            proto = new ProtoOutputStream(fd);
+            reportTimeZoneInfoProto(coreLibraryDebugInfo, proto);
+        } else {
+            reportTimeZoneInfo(coreLibraryDebugInfo, pw);
+        }
+
+        if (protoFormat) {
+            proto.flush();
+        }
+    }
+
+    /** Returns {@code true} if {@code args} contains {@code arg}. */
+    private static boolean hasOption(String[] args, String arg) {
+        for (String opt : args) {
+            if (arg.equals(opt)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Add information to {@link DebugInfo} about the time zone data supplied by the
+     * "Time zone updates via APK" feature.
+     */
+    private static void addTimeZoneApkDebugInfo(DebugInfo coreLibraryDebugInfo) {
+        // Add /data tz data set using the DistroVersion class (which libcore cannot use).
+        // This update mechanism will be removed after the time zone APEX is launched so this
+        // untidiness will disappear with it.
+        String debugKeyPrefix = "core_library.timezone.data_";
+        String versionFileName = TimeZoneDataFiles.getDataTimeZoneFile(
+                TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+        addDistroVersionDebugInfo(versionFileName, debugKeyPrefix, coreLibraryDebugInfo);
+    }
+
+    /**
+     * Prints {@code coreLibraryDebugInfo} to {@code pw}.
+     *
+     * <p>If you change this method, make sure to modify
+     * {@link #reportTimeZoneInfoProto(DebugInfo, ProtoOutputStream)} as well.
+     */
+    private static void reportTimeZoneInfo(DebugInfo coreLibraryDebugInfo,
+            PrintWriter pw) {
+        pw.println("Core Library Debug Info: ");
+        for (DebugInfo.DebugEntry debugEntry : coreLibraryDebugInfo.getDebugEntries()) {
+            pw.print(debugEntry.getKey());
+            pw.print(": \"");
+            pw.print(debugEntry.getStringValue());
+            pw.println("\"");
+        }
+    }
+
+    /**
+     * Adds {@code coreLibraryDebugInfo} to {@code protoStream}.
+     *
+     * <p>If you change this method, make sure to modify
+     * {@link #reportTimeZoneInfo(DebugInfo, PrintWriter)}.
+     */
+    private static void reportTimeZoneInfoProto(
+            DebugInfo coreLibraryDebugInfo, ProtoOutputStream protoStream) {
+        for (DebugInfo.DebugEntry debugEntry : coreLibraryDebugInfo.getDebugEntries()) {
+            long entryToken = protoStream.start(RuntimeServiceInfoProto.DEBUG_ENTRY);
+            protoStream.write(DebugEntryProto.KEY, debugEntry.getKey());
+            protoStream.write(DebugEntryProto.STRING_VALUE, debugEntry.getStringValue());
+            protoStream.end(entryToken);
+        }
+    }
+
+    /**
+     * Adds version information to {@code debugInfo} from the distro_version file that may exist
+     * at {@code distroVersionFileName}. If the file does not exist or cannot be read this is
+     * reported as debug information too.
+     */
+    private static void addDistroVersionDebugInfo(String distroVersionFileName,
+            String debugKeyPrefix, DebugInfo debugInfo) {
+        File file = new File(distroVersionFileName);
+        String statusKey = debugKeyPrefix + "status";
+        if (file.exists()) {
+            try {
+                byte[] versionBytes =
+                        FileUtils.readBytes(file, DistroVersion.DISTRO_VERSION_FILE_LENGTH);
+                DistroVersion distroVersion = DistroVersion.fromBytes(versionBytes);
+                String formatVersionString = distroVersion.formatMajorVersion + "."
+                        + distroVersion.formatMinorVersion;
+                debugInfo.addStringEntry(statusKey, "OK")
+                        .addStringEntry(debugKeyPrefix + "formatVersion", formatVersionString)
+                        .addStringEntry(debugKeyPrefix + "rulesVersion",
+                                distroVersion.rulesVersion)
+                        .addStringEntry(debugKeyPrefix + "revision",
+                                distroVersion.revision);
+            } catch (IOException | DistroException e) {
+                debugInfo.addStringEntry(statusKey, "ERROR");
+                debugInfo.addStringEntry(debugKeyPrefix + "exception_class",
+                        e.getClass().getName());
+                debugInfo.addStringEntry(debugKeyPrefix + "exception_msg", e.getMessage());
+                logMessage("Error reading " + file, e);
+            }
+        } else {
+            debugInfo.addStringEntry(statusKey, "NOT_FOUND");
+        }
+    }
+
+    private static void logMessage(String msg, Throwable t) {
+        Slog.v(TAG, msg, t);
+    }
+}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index e933bd0..390126c 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -99,6 +99,7 @@
 import android.os.storage.VolumeRecord;
 import android.provider.MediaStore;
 import android.provider.Settings;
+import android.sysprop.VoldProperties;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
@@ -1015,7 +1016,7 @@
 
         // On an encrypted device we can't see system properties yet, so pull
         // the system locale out of the mount service.
-        if ("".equals(SystemProperties.get("vold.encrypt_progress"))) {
+        if ("".equals(VoldProperties.encrypt_progress().orElse(""))) {
             copyLocaleFromMountService();
         }
     }
diff --git a/services/core/java/com/android/server/WallpaperUpdateReceiver.java b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
new file mode 100644
index 0000000..629e882
--- /dev/null
+++ b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.app.ActivityThread;
+import android.app.WallpaperManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.AsyncTask;
+import android.util.Slog;
+
+/**
+ * Receiver responsible for updating the wallpaper when the device
+ * configuration has changed.
+ *
+ * @hide
+ */
+public class WallpaperUpdateReceiver extends BroadcastReceiver {
+
+    private static final String TAG = "WallpaperUpdateReceiver";
+    private static final boolean DEBUG = false;
+
+    @Override
+    public void onReceive(final Context context, final Intent intent) {
+        if (DEBUG) Slog.d(TAG, "onReceive: " + intent);
+
+        if (intent != null && Intent.ACTION_DEVICE_CUSTOMIZATION_READY.equals(intent.getAction())) {
+            AsyncTask.execute(this::updateWallpaper);
+        }
+    }
+
+    private void updateWallpaper() {
+        try {
+            ActivityThread currentActivityThread = ActivityThread.currentActivityThread();
+            Context uiContext = currentActivityThread.getSystemUiContext();
+            WallpaperManager wallpaperManager = WallpaperManager.getInstance(uiContext);
+            if (DEBUG) Slog.d(TAG, "Set customized default_wallpaper.");
+            Bitmap blank = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+            // set a blank wallpaper to force a redraw of default_wallpaper
+            wallpaperManager.setBitmap(blank);
+            wallpaperManager.setResource(com.android.internal.R.drawable.default_wallpaper);
+        } catch (Exception e) {
+            Slog.w(TAG, "Failed to customize system wallpaper." + e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0e354d5..8842f41 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -272,6 +272,7 @@
 import android.os.WorkSource;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
+import android.sysprop.VoldProperties;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.text.style.SuggestionSpan;
@@ -666,16 +667,50 @@
     final class PidMap {
         private final SparseArray<ProcessRecord> mPidMap = new SparseArray<>();
 
+        /**
+         * Puts the process record in the map.
+         * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
+         * method.
+         */
         void put(int key, ProcessRecord value) {
-            mPidMap.put(key, value);
+            synchronized (this) {
+                mPidMap.put(key, value);
+            }
             mAtmInternal.onProcessMapped(key, value.getWindowProcessController());
         }
 
+        /**
+         * Removes the process record from the map.
+         * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
+         * method.
+         */
         void remove(int pid) {
-            mPidMap.remove(pid);
+            synchronized (this) {
+                mPidMap.remove(pid);
+            }
             mAtmInternal.onProcessUnMapped(pid);
         }
 
+        /**
+         * Removes the process record from the map if it has a thread.
+         * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
+         * method.
+         */
+        boolean removeIfNoThread(int pid) {
+            boolean removed = false;
+            synchronized (this) {
+                final ProcessRecord app = get(pid);
+                if (app != null && app.thread == null) {
+                    mPidMap.remove(pid);
+                    removed = true;
+                }
+            }
+            if (removed) {
+                mAtmInternal.onProcessUnMapped(pid);
+            }
+            return removed;
+        }
+
         ProcessRecord get(int pid) {
             return mPidMap.get(pid);
         }
@@ -1889,9 +1924,7 @@
                 app.getWindowProcessController().setPid(MY_PID);
                 app.maxAdj = ProcessList.SYSTEM_ADJ;
                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
-                synchronized (mPidsSelfLocked) {
-                    mPidsSelfLocked.put(app.pid, app);
-                }
+                mPidsSelfLocked.put(app.pid, app);
                 mProcessList.updateLruProcessLocked(app, false, null);
                 updateOomAdjLocked();
             }
@@ -4254,14 +4287,7 @@
 
     private final void processStartTimedOutLocked(ProcessRecord app) {
         final int pid = app.pid;
-        boolean gone = false;
-        synchronized (mPidsSelfLocked) {
-            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
-            if (knownApp != null && knownApp.thread == null) {
-                mPidsSelfLocked.remove(pid);
-                gone = true;
-            }
-        }
+        boolean gone = mPidsSelfLocked.removeIfNoThread(pid);
 
         if (gone) {
             Slog.w(TAG, "Process " + app + " failed to attach");
@@ -4782,8 +4808,8 @@
             SystemProperties.set("sys.boot_completed", "1");
 
             // And trigger dev.bootcomplete if we are not showing encryption progress
-            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
-                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
+            if (!"trigger_restart_min_framework".equals(VoldProperties.decrypt().orElse(""))
+                    || "".equals(VoldProperties.encrypt_progress().orElse(""))) {
                 SystemProperties.set("dev.bootcomplete", "1");
             }
             mUserController.sendBootCompleted(
@@ -13113,11 +13139,8 @@
             return true;
         } else if (app.pid > 0 && app.pid != MY_PID) {
             // Goodbye!
-            boolean removed;
-            synchronized (mPidsSelfLocked) {
-                mPidsSelfLocked.remove(app.pid);
-                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
-            }
+            mPidsSelfLocked.remove(app.pid);
+            mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
             if (app.isolated) {
                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 2541352..24543b7 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -25,10 +25,12 @@
 import android.net.wifi.WifiActivityEnergyInfo;
 import android.os.BatteryStats;
 import android.os.Parcelable;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SynchronousResultReceiver;
 import android.os.SystemClock;
+import android.os.ThreadLocalWorkSource;
 import android.telephony.ModemActivityInfo;
 import android.telephony.TelephonyManager;
 import android.util.IntArray;
@@ -43,11 +45,9 @@
 import libcore.util.EmptyArray;
 
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -74,7 +74,12 @@
     private final ScheduledExecutorService mExecutorService =
             Executors.newSingleThreadScheduledExecutor(
                     (ThreadFactory) r -> {
-                        Thread t = new Thread(r, "batterystats-worker");
+                        Thread t = new Thread(
+                                () -> {
+                                    ThreadLocalWorkSource.setUid(Process.myUid());
+                                    r.run();
+                                },
+                                "batterystats-worker");
                         t.setPriority(Thread.NORM_PRIORITY);
                         return t;
                     });
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 7991783..62f1009 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1246,10 +1246,8 @@
         long startTime = SystemClock.elapsedRealtime();
         if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
             checkSlow(startTime, "startProcess: removing from pids map");
-            synchronized (mService.mPidsSelfLocked) {
-                mService.mPidsSelfLocked.remove(app.pid);
-                mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
-            }
+            mService.mPidsSelfLocked.remove(app.pid);
+            mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
             checkSlow(startTime, "startProcess: done removing from pids map");
             app.setPid(0);
         }
@@ -1767,8 +1765,8 @@
             mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
                     true /*replacingPid*/);
         }
+        mService.mPidsSelfLocked.put(pid, app);
         synchronized (mService.mPidsSelfLocked) {
-            mService.mPidsSelfLocked.put(pid, app);
             if (!procAttached) {
                 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
                 msg.obj = app;
@@ -1928,10 +1926,8 @@
                 .pendingStart)) {
             int pid = app.pid;
             if (pid > 0) {
-                synchronized (mService.mPidsSelfLocked) {
-                    mService.mPidsSelfLocked.remove(pid);
-                    mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
-                }
+                mService.mPidsSelfLocked.remove(pid);
+                mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
                 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
                 if (app.isolated) {
                     mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java
index 0b6786c..521fa23 100644
--- a/services/core/java/com/android/server/display/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/ColorDisplayService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.display;
 
+import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.TypeEvaluator;
@@ -29,8 +31,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.database.ContentObserver;
+import android.hardware.display.IColorDisplayManager;
 import android.net.Uri;
 import android.opengl.Matrix;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
@@ -39,6 +43,7 @@
 import android.util.Slog;
 import android.view.animation.AnimationUtils;
 
+import com.android.internal.R;
 import com.android.internal.app.ColorDisplayController;
 import com.android.server.SystemService;
 import com.android.server.twilight.TwilightListener;
@@ -49,12 +54,8 @@
 import java.time.LocalTime;
 import java.time.ZoneId;
 
-import com.android.internal.R;
-
-import static com.android.server.display.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
-
 /**
- * Tints the display at night.
+ * Controls the display's color transforms.
  */
 public final class ColorDisplayService extends SystemService
         implements ColorDisplayController.Callback {
@@ -101,7 +102,7 @@
 
     @Override
     public void onStart() {
-        // Nothing to publish.
+        publishBinderService(Context.COLOR_DISPLAY_SERVICE, new BinderService());
     }
 
     @Override
@@ -171,7 +172,7 @@
                     }
                 };
                 cr.registerContentObserver(Secure.getUriFor(Secure.USER_SETUP_COMPLETE),
-                        false /* notifyForDescendents */, mUserSetupObserver, mCurrentUser);
+                        false /* notifyForDescendants */, mUserSetupObserver, mCurrentUser);
             } else if (mBootCompleted) {
                 setUp();
             }
@@ -405,8 +406,8 @@
     }
 
     /**
-     * Returns the first date time corresponding to the local time that occurs before the
-     * provided date time.
+     * Returns the first date time corresponding to the local time that occurs before the provided
+     * date time.
      *
      * @param compareTime the LocalDateTime to compare against
      * @return the prior LocalDateTime corresponding to this local time
@@ -420,8 +421,8 @@
     }
 
     /**
-     * Returns the first date time corresponding to this local time that occurs after the
-     * provided date time.
+     * Returns the first date time corresponding to this local time that occurs after the provided
+     * date time.
      *
      * @param compareTime the LocalDateTime to compare against
      * @return the next LocalDateTime corresponding to this local time
@@ -434,6 +435,11 @@
         return ldt.isBefore(compareTime) ? ldt.plusDays(1) : ldt;
     }
 
+    private boolean isDeviceColorManagedInternal() {
+        final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
+        return dtm.isDeviceColorManaged();
+    }
+
     private abstract class AutoMode implements ColorDisplayController.Callback {
         public abstract void onStart();
 
@@ -616,4 +622,16 @@
             return mResultMatrix;
         }
     }
+
+    private final class BinderService extends IColorDisplayManager.Stub {
+        @Override
+        public boolean isDeviceColorManaged() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return isDeviceColorManagedInternal();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index d6931e0..5ca1755 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -16,7 +16,6 @@
 
 package com.android.server.display;
 
-import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.opengl.Matrix;
 import android.os.IBinder;
@@ -27,8 +26,10 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.ColorDisplayController;
+
 import java.util.Arrays;
 
 /**
@@ -59,10 +60,6 @@
 
     private static final int SURFACE_FLINGER_TRANSACTION_COLOR_MATRIX = 1015;
     private static final int SURFACE_FLINGER_TRANSACTION_DALTONIZER = 1014;
-
-    private static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
-    private static final String PERSISTENT_PROPERTY_DISPLAY_COLOR = "persist.sys.sf.native_mode";
-
     /**
      * SurfaceFlinger global saturation factor.
      */
@@ -71,6 +68,10 @@
      * SurfaceFlinger display color (managed, unmanaged, etc.).
      */
     private static final int SURFACE_FLINGER_TRANSACTION_DISPLAY_COLOR = 1023;
+    private static final int SURFACE_FLINGER_TRANSACTION_QUERY_WIDE_COLOR = 1030;
+
+    private static final String PERSISTENT_PROPERTY_SATURATION = "persist.sys.sf.color_saturation";
+    private static final String PERSISTENT_PROPERTY_DISPLAY_COLOR = "persist.sys.sf.native_mode";
 
     private static final float COLOR_SATURATION_NATURAL = 1.0f;
     private static final float COLOR_SATURATION_BOOSTED = 1.1f;
@@ -269,6 +270,29 @@
     }
 
     /**
+     * Returns whether the screen is wide color gamut via SurfaceFlinger's
+     * {@link #SURFACE_FLINGER_TRANSACTION_QUERY_WIDE_COLOR}.
+     */
+    public boolean isDeviceColorManaged() {
+        final IBinder flinger = ServiceManager.getService(SURFACE_FLINGER);
+        if (flinger != null) {
+            final Parcel data = Parcel.obtain();
+            final Parcel reply = Parcel.obtain();
+            data.writeInterfaceToken("android.ui.ISurfaceComposer");
+            try {
+                flinger.transact(SURFACE_FLINGER_TRANSACTION_QUERY_WIDE_COLOR, data, reply, 0);
+                return reply.readBoolean();
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Failed to query wide color support", ex);
+            } finally {
+                data.recycle();
+                reply.recycle();
+            }
+        }
+        return false;
+    }
+
+    /**
      * Propagates the provided saturation to the SurfaceFlinger.
      */
     private void applySaturation(float saturation) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index b148a2f..c0d3fdf 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -980,7 +980,7 @@
      * @param sourceAddress a logical address of source device where sends polling message
      * @param pickStrategy strategy how to pick polling candidates
      * @param retryCount the number of retry used to send polling message to remote devices
-     * @throw IllegalArgumentException if {@code pickStrategy} is invalid value
+     * @throws IllegalArgumentException if {@code pickStrategy} is invalid value
      */
     @ServiceThreadOnly
     void pollDevices(DevicePollingCallback callback, int sourceAddress, int pickStrategy,
diff --git a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java
index d5be26a..f424869 100644
--- a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java
+++ b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java
@@ -16,10 +16,12 @@
 package com.android.server.intelligence;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 
 /**
@@ -53,6 +55,7 @@
      * @param activityToken activity that originated this request.
      * @param autofillSessionId autofill session id (must be used on {@code client} calls.
      * @param focusedId id of the the field that triggered this request.
+     * @param focusedValue current value of the field that triggered this request.
      *
      * @return {@code false} if the service cannot handle this request, {@code true} otherwise.
      * <b>NOTE: </b> it must return right away; typically it will return {@code false} if the
@@ -60,7 +63,8 @@
      */
     public abstract AugmentedAutofillCallback requestAutofill(@UserIdInt int userId,
             @NonNull IAutoFillManagerClient client, @NonNull IBinder activityToken,
-            int autofillSessionId, @NonNull AutofillId focusedId);
+            int autofillSessionId, @NonNull AutofillId focusedId,
+            @Nullable AutofillValue focusedValue);
 
     /**
      * Callback used by the Autofill Session to communicate with the Augmented Autofill service.
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index 2584187..9b9f4de 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -15,12 +15,15 @@
  */
 package com.android.server.notification;
 
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.provider.Settings;
 import android.telecom.TelecomManager;
 
 import com.android.internal.util.NotificationMessagingUtil;
@@ -47,6 +50,21 @@
 
     @Override
     public int compare(NotificationRecord left, NotificationRecord right) {
+        final int leftImportance = left.getImportance();
+        final int rightImportance = right.getImportance();
+        final boolean isLeftHighImportance = leftImportance >= IMPORTANCE_DEFAULT;
+        final boolean isRightHighImportance = rightImportance >= IMPORTANCE_DEFAULT;
+
+        // With new interruption model, prefer importance bucket above all other criteria
+        // (to ensure buckets are contiguous)
+        if (Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL, 1) == 1) {
+            if (isLeftHighImportance != isRightHighImportance) {
+                // by importance bucket, high importance higher than low importance
+                return -1 * Boolean.compare(isLeftHighImportance, isRightHighImportance);
+            }
+        }
+
         // first all colorized notifications
         boolean leftImportantColorized = isImportantColorized(left);
         boolean rightImportantColorized = isImportantColorized(right);
@@ -86,8 +104,6 @@
             return -1 * Boolean.compare(leftPeople, rightPeople);
         }
 
-        final int leftImportance = left.getImportance();
-        final int rightImportance = right.getImportance();
         if (leftImportance != rightImportance) {
             // by importance, high to low
             return -1 * Integer.compare(leftImportance, rightImportance);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6c2549e..95e1962 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -207,7 +207,6 @@
 import com.android.internal.util.XmlUtils;
 import com.android.server.DeviceIdleController;
 import com.android.server.EventLogTags;
-import com.android.server.IoThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.lights.Light;
@@ -266,7 +265,7 @@
 
     // message codes
     static final int MESSAGE_DURATION_REACHED = 2;
-    // 3: removed to a different handler
+    static final int MESSAGE_SAVE_POLICY_FILE = 3;
     static final int MESSAGE_SEND_RANKING_UPDATE = 4;
     static final int MESSAGE_LISTENER_HINTS_CHANGED = 5;
     static final int MESSAGE_LISTENER_NOTIFICATION_FILTER_CHANGED = 6;
@@ -428,6 +427,7 @@
     private GroupHelper mGroupHelper;
     private int mAutoGroupAtCount;
     private boolean mIsTelevision;
+    private boolean mIsAutomotive;
 
     private MetricsLogger mMetricsLogger;
     private Predicate<String> mAllowedManagedServicePackages;
@@ -573,7 +573,7 @@
             mListeners.migrateToXml();
             mAssistants.migrateToXml();
             mConditionProviders.migrateToXml();
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         mAssistants.ensureAssistant();
@@ -603,28 +603,34 @@
         }
     }
 
-    private void handleSavePolicyFile() {
-        IoThread.getHandler().post(() -> {
-            if (DBG) Slog.d(TAG, "handleSavePolicyFile");
-            synchronized (mPolicyFile) {
-                final FileOutputStream stream;
-                try {
-                    stream = mPolicyFile.startWrite();
-                } catch (IOException e) {
-                    Slog.w(TAG, "Failed to save policy file", e);
-                    return;
-                }
+    /**
+     * Saves notification policy
+     */
+    public void savePolicyFile() {
+        mHandler.removeMessages(MESSAGE_SAVE_POLICY_FILE);
+        mHandler.sendEmptyMessage(MESSAGE_SAVE_POLICY_FILE);
+    }
 
-                try {
-                    writePolicyXml(stream, false /*forBackup*/);
-                    mPolicyFile.finishWrite(stream);
-                } catch (IOException e) {
-                    Slog.w(TAG, "Failed to save policy file, restoring backup", e);
-                    mPolicyFile.failWrite(stream);
-                }
+    private void handleSavePolicyFile() {
+        if (DBG) Slog.d(TAG, "handleSavePolicyFile");
+        synchronized (mPolicyFile) {
+            final FileOutputStream stream;
+            try {
+                stream = mPolicyFile.startWrite();
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to save policy file", e);
+                return;
             }
-            BackupManager.dataChanged(getContext().getPackageName());
-        });
+
+            try {
+                writePolicyXml(stream, false /*forBackup*/);
+                mPolicyFile.finishWrite(stream);
+            } catch (IOException e) {
+                Slog.w(TAG, "Failed to save policy file, restoring backup", e);
+                mPolicyFile.failWrite(stream);
+            }
+        }
+        BackupManager.dataChanged(getContext().getPackageName());
     }
 
     private void writePolicyXml(OutputStream stream, boolean forBackup) throws IOException {
@@ -1132,8 +1138,8 @@
 
                     }
                 }
-
                 mHandler.scheduleOnPackageChanged(removingPackage, changeUserId, pkgList, uidList);
+                savePolicyFile();
             }
         }
     };
@@ -1200,7 +1206,7 @@
                 mListeners.onUserRemoved(userId);
                 mConditionProviders.onUserRemoved(userId);
                 mAssistants.onUserRemoved(userId);
-                handleSavePolicyFile();
+                savePolicyFile();
             } else if (action.equals(Intent.ACTION_USER_UNLOCKED)) {
                 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                 mUserProfiles.updateCache(context);
@@ -1388,6 +1394,11 @@
     }
 
     @VisibleForTesting
+    void setIsAutomotive(boolean isAutomotive) {
+        mIsAutomotive = isAutomotive;
+    }
+
+    @VisibleForTesting
     void setIsTelevision(boolean isTelevision) {
         mIsTelevision = isTelevision;
     }
@@ -1451,7 +1462,7 @@
         mZenModeHelper.addCallback(new ZenModeHelper.Callback() {
             @Override
             public void onConfigChanged() {
-                handleSavePolicyFile();
+                savePolicyFile();
             }
 
             @Override
@@ -1543,6 +1554,9 @@
 
         mIsTelevision = mPackageManagerClient.hasSystemFeature(FEATURE_LEANBACK)
                 || mPackageManagerClient.hasSystemFeature(FEATURE_TELEVISION);
+
+        mIsAutomotive =
+                mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0);
     }
 
     @Override
@@ -1750,7 +1764,7 @@
                     modifiedChannel, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED);
         }
 
-        handleSavePolicyFile();
+        savePolicyFile();
     }
 
     private void maybeNotifyChannelOwner(String pkg, int uid, NotificationChannel preUpdate,
@@ -2218,7 +2232,7 @@
                 Slog.w(TAG, "Can't notify app about app block change", e);
             }
 
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         /**
@@ -2275,7 +2289,7 @@
         public void setShowBadge(String pkg, int uid, boolean showBadge) {
             checkCallerIsSystem();
             mPreferencesHelper.setShowBadge(pkg, uid, showBadge);
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2291,7 +2305,7 @@
                 if (info != null) {
                     mPreferencesHelper.setNotificationDelegate(
                             callingPkg, callingUid, delegate, info.uid);
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 }
             } catch (RemoteException e) {
                 // :(
@@ -2302,7 +2316,7 @@
         public void revokeNotificationDelegate(String callingPkg) {
             checkCallerIsSameApp(callingPkg);
             mPreferencesHelper.revokeNotificationDelegate(callingPkg, Binder.getCallingUid());
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2337,7 +2351,7 @@
                 NotificationChannelGroup group) throws RemoteException {
             enforceSystemOrSystemUI("Caller not system or systemui");
             createNotificationChannelGroup(pkg, uid, group, false, false);
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2350,7 +2364,7 @@
                 final NotificationChannelGroup group = groups.get(i);
                 createNotificationChannelGroup(pkg, Binder.getCallingUid(), group, true, false);
             }
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         private void createNotificationChannelsImpl(String pkg, int uid,
@@ -2368,7 +2382,7 @@
                         mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), false),
                         NOTIFICATION_CHANNEL_OR_GROUP_ADDED);
             }
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2413,7 +2427,7 @@
                     UserHandle.getUserHandleForUid(callingUid),
                     mPreferencesHelper.getNotificationChannel(pkg, callingUid, channelId, true),
                     NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -2455,7 +2469,7 @@
                 mListeners.notifyNotificationChannelGroupChanged(
                         pkg, UserHandle.getUserHandleForUid(callingUid), groupToDelete,
                         NOTIFICATION_CHANNEL_OR_GROUP_DELETED);
-                handleSavePolicyFile();
+                savePolicyFile();
             }
         }
 
@@ -2588,7 +2602,7 @@
                         true, UserHandle.getCallingUserId(), packages, uids);
             }
 
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
 
@@ -3376,7 +3390,7 @@
                 final ByteArrayInputStream bais = new ByteArrayInputStream(payload);
                 try {
                     readPolicyXml(bais, true /*forRestore*/);
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 } catch (NumberFormatException | XmlPullParserException | IOException e) {
                     Slog.w(TAG, "applyRestore: error reading payload", e);
                 }
@@ -3417,7 +3431,7 @@
                                     .setPackage(pkg)
                                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
                             UserHandle.of(userId), null);
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3561,7 +3575,7 @@
                                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
                             UserHandle.of(userId), null);
 
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3587,7 +3601,7 @@
                                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
                             UserHandle.of(userId), null);
 
-                    handleSavePolicyFile();
+                    savePolicyFile();
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -3670,7 +3684,7 @@
             verifyPrivilegedListener(token, user, false);
             createNotificationChannelGroup(
                     pkg, getUidForPackageAndUser(pkg, user), group, false, true);
-            handleSavePolicyFile();
+            savePolicyFile();
         }
 
         @Override
@@ -3719,7 +3733,7 @@
             }
             if (allow != mLockScreenAllowSecureNotifications) {
                 mLockScreenAllowSecureNotifications = allow;
-                handleSavePolicyFile();
+                savePolicyFile();
             }
         }
 
@@ -4478,7 +4492,7 @@
                 Slog.d(TAG, "Ignored enqueue for snoozed notification " + r.getKey());
             }
             mSnoozeHelper.update(userId, r);
-            handleSavePolicyFile();
+            savePolicyFile();
             return false;
         }
 
@@ -4609,7 +4623,7 @@
                 mSnoozeHelper.snooze(r, mDuration);
             }
             r.recordSnoozed();
-            handleSavePolicyFile();
+            savePolicyFile();
         }
     }
 
@@ -4687,7 +4701,7 @@
                     if (mReason != REASON_SNOOZED) {
                         final boolean wasSnoozed = mSnoozeHelper.cancel(mUserId, mPkg, mTag, mId);
                         if (wasSnoozed) {
-                            handleSavePolicyFile();
+                            savePolicyFile();
                         }
                     }
                 }
@@ -5131,7 +5145,9 @@
 
         // Should this notification make noise, vibe, or use the LED?
         final boolean aboveThreshold =
-                record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT;
+                mIsAutomotive
+                        ? record.getImportance() > NotificationManager.IMPORTANCE_DEFAULT
+                        : record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT;
 
         // Remember if this notification already owns the notification channels.
         boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
@@ -5729,6 +5745,9 @@
                 case MESSAGE_FINISH_TOKEN_TIMEOUT:
                     handleKillTokenTimeout((ToastRecord) msg.obj);
                     break;
+                case MESSAGE_SAVE_POLICY_FILE:
+                    handleSavePolicyFile();
+                    break;
                 case MESSAGE_SEND_RANKING_UPDATE:
                     handleSendRankingUpdate();
                     break;
@@ -6246,7 +6265,7 @@
             Slog.d(TAG, String.format("unsnooze event(%s, %s)", key, listenerName));
         }
         mSnoozeHelper.repost(key);
-        handleSavePolicyFile();
+        savePolicyFile();
     }
 
     @GuardedBy("mNotificationLock")
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8abb500..dab4e79 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -58,6 +58,7 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
 import static android.content.pm.PackageManager.INSTALL_INTERNAL;
+import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
@@ -10299,12 +10300,21 @@
                         compareSignatures(
                             signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures,
                             pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
-                        // Treat mismatched signatures on system packages using a shared UID as
-                        // fatal for the system overall, rather than just failing to install
-                        // whichever package happened to be scanned later.
-                        throw new IllegalStateException(
-                                "Signature mismatch on system package " + pkg.packageName
-                                + " for shared user " + pkgSetting.sharedUser);
+                        if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 28) {
+                            // Mismatched signatures is an error and silently skipping system
+                            // packages will likely break the device in unforeseen ways. However,
+                            // we allow the device to boot anyway because, prior to P, vendors were
+                            // not expecting the platform to crash in this situation.
+                            throw new PackageManagerException(
+                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
+                                    "Signature mismatch for shared user: " + pkgSetting.sharedUser);
+                        } else {
+                            // Treat mismatched signatures on system packages using a shared UID as
+                            // fatal for the system overall, rather than just failing to install
+                            // whichever package happened to be scanned later.
+                            throw new IllegalStateException("Signature mismatch on system package "
+                                + pkg.packageName + " for shared user " + pkgSetting.sharedUser);
+                        }
                     }
 
                     signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 68fe1d8..51619cf 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -46,7 +46,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.permission.PermissionManager;
@@ -1059,6 +1058,17 @@
             return;
         }
 
+        // Intersect the requestedPermissions for a factory image with that of its current update
+        // in case the latter one removed a <uses-permission>
+        String[] requestedByNonSystemPackage = getPackageInfo(pkg.packageName).requestedPermissions;
+        int size = requestedPermissions.length;
+        for (int i = 0; i < size; i++) {
+            if (!ArrayUtils.contains(requestedByNonSystemPackage, requestedPermissions[i])) {
+                requestedPermissions[i] = null;
+            }
+        }
+        requestedPermissions = ArrayUtils.filterNotNull(requestedPermissions, String[]::new);
+
         PackageManager pm = mContext.getPackageManager();
         final ArraySet<String> permissions = new ArraySet<>(permissionsWithoutSplits);
         ApplicationInfo applicationInfo = pkg.applicationInfo;
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 79e2688..07bebad 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -29,8 +29,12 @@
 import android.os.IThermalService;
 import android.os.IThermalStatusListener;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
 import android.os.Temperature;
 import android.util.ArrayMap;
 import android.util.Slog;
@@ -77,6 +81,10 @@
     @GuardedBy("mLock")
     private int mStatus;
 
+    /** If override status takes effect*/
+    @GuardedBy("mLock")
+    private boolean mIsStatusOverride;
+
     /** Current thermal map, key as name */
     @GuardedBy("mLock")
     private ArrayMap<String, Temperature> mTemperatureMap = new ArrayMap<>();
@@ -184,13 +192,19 @@
                 newStatus = t.getStatus();
             }
         }
+        // Do not update if override from shell
+        if (!mIsStatusOverride) {
+            setStatusLocked(newStatus);
+        }
+    }
+
+    private void setStatusLocked(int newStatus) {
         if (newStatus != mStatus) {
             mStatus = newStatus;
             notifyStatusListenersLocked();
         }
     }
 
-
     private void postEventListenerCurrentTemperatures(IThermalEventListener listener,
             @Nullable Integer type) {
         synchronized (mLock) {
@@ -241,12 +255,7 @@
             // Thermal Shutdown for Skin temperature
             if (temperature.getStatus() == Temperature.THROTTLING_SHUTDOWN
                     && temperature.getType() == Temperature.TYPE_SKIN) {
-                final long token = Binder.clearCallingIdentity();
-                try {
-                    mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
-                } finally {
-                    Binder.restoreCallingIdentity(token);
-                }
+                mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
             }
 
             Temperature old = mTemperatureMap.put(temperature.getName(), temperature);
@@ -263,8 +272,14 @@
         }
     }
 
+    /* HwBinder callback **/
     private void onTemperatureChangedCallback(Temperature temperature) {
-        onTemperatureChanged(temperature, true);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            onTemperatureChanged(temperature, true);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     private void dumpTemperaturesLocked(PrintWriter pw, String prefix,
@@ -393,7 +408,7 @@
         }
 
         @Override
-        public int getCurrentStatus() {
+        public int getCurrentThermalStatus() {
             synchronized (mLock) {
                 final long token = Binder.clearCallingIdentity();
                 try {
@@ -434,8 +449,93 @@
                 Binder.restoreCallingIdentity(token);
             }
         }
+
+        private boolean isCallerShell() {
+            final int callingUid = Binder.getCallingUid();
+            return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
+        }
+
+        @Override
+        public void onShellCommand(FileDescriptor in, FileDescriptor out,
+                FileDescriptor err, String[] args, ShellCallback callback,
+                ResultReceiver resultReceiver) {
+            if (!isCallerShell()) {
+                Slog.w(TAG, "Only shell is allowed to call thermalservice shell commands");
+                return;
+            }
+            (new ThermalShellCommand()).exec(
+                    this, in, out, err, args, callback, resultReceiver);
+        }
+
     };
 
+    class ThermalShellCommand extends ShellCommand {
+        @Override
+        public int onCommand(String cmd) {
+            switch(cmd != null ? cmd : "") {
+                case "override-status":
+                    return runOverrideStatus();
+                case "reset":
+                    return runReset();
+                default:
+                    return handleDefaultCommands(cmd);
+            }
+        }
+
+        private int runReset() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    mIsStatusOverride = false;
+                    onTemperatureMapChangedLocked();
+                    return 0;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        private int runOverrideStatus() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                final PrintWriter pw = getOutPrintWriter();
+                int status;
+                try {
+                    status = Integer.parseInt(getNextArgRequired());
+                } catch (RuntimeException ex) {
+                    pw.println("Error: " + ex.toString());
+                    return -1;
+                }
+                if (!Temperature.isValidStatus(status)) {
+                    pw.println("Invalid status: " + Integer.toString(status));
+                    return -1;
+                }
+                synchronized (mLock) {
+                    mIsStatusOverride = true;
+                    setStatusLocked(status);
+                }
+                return 0;
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void onHelp() {
+            final PrintWriter pw = getOutPrintWriter();
+            pw.println("Thermal service (thermalservice) commands:");
+            pw.println("  help");
+            pw.println("    Print this help text.");
+            pw.println("");
+            pw.println("  override-status STATUS");
+            pw.println("    sets and locks the thermal status of the device to STATUS.");
+            pw.println("    status code is defined in android.os.Temperature.");
+            pw.println("  reset");
+            pw.println("    unlocks the thermal status of the device.");
+            pw.println();
+        }
+    }
+
     abstract static class ThermalHalWrapper {
         protected static final String TAG = ThermalHalWrapper.class.getSimpleName();
 
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index b065470..b5ad235 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -55,6 +55,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
@@ -106,7 +107,7 @@
         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
         getContext().registerReceiverAsUser(new BroadcastReceiver() {
             @Override
-            public void onReceive(Context context, Intent intent) {
+            public void onReceive(@NonNull Context context, @NonNull Intent intent) {
                 if (TextUtils.equals(intent.getAction(), Intent.ACTION_USER_REMOVED)) {
                     int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                     onRemoveUser(userId);
@@ -129,10 +130,11 @@
             userState = getUserStateLocked(userId);
         }
         String packagesHash = computeComponentStateHash(userId);
-        boolean needGrant;
+        String lastGrantPackagesHash;
         synchronized (mLock) {
-            needGrant = !packagesHash.equals(userState.getLastGrantPackagesHashLocked());
+            lastGrantPackagesHash = userState.getLastGrantPackagesHashLocked();
         }
+        boolean needGrant = !Objects.equals(packagesHash, lastGrantPackagesHash);
         if (needGrant) {
             // Some vital packages state has changed since last role grant
             // Run grants again
@@ -144,7 +146,6 @@
                         public void onSuccess() {
                             result.complete(null);
                         }
-
                         @Override
                         public void onFailure() {
                             result.completeExceptionally(new RuntimeException());
@@ -163,7 +164,8 @@
         }
     }
 
-    private String computeComponentStateHash(int userId) {
+    @Nullable
+    private String computeComponentStateHash(@UserIdInt int userId) {
         PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
 
@@ -198,8 +200,7 @@
     private RoleUserState getUserStateLocked(@UserIdInt int userId) {
         RoleUserState userState = mUserStates.get(userId);
         if (userState == null) {
-            userState = new RoleUserState(userId);
-            userState.readSyncLocked();
+            userState = RoleUserState.newInstanceLocked(userId);
             mUserStates.put(userId, userState);
         }
         return userState;
@@ -386,11 +387,11 @@
         }
 
         @Override
-        public void onShellCommand(FileDescriptor in, FileDescriptor out,
-                FileDescriptor err, String[] args, ShellCallback callback,
-                ResultReceiver resultReceiver) {
-            (new RoleManagerShellCommand(this)).exec(
-                    this, in, out, err, args, callback, resultReceiver);
+        public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+                @Nullable FileDescriptor err, @NonNull String[] args,
+                @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) {
+            new RoleManagerShellCommand(this).exec(this, in, out, err, args, callback,
+                    resultReceiver);
         }
     }
 }
diff --git a/services/core/java/com/android/server/role/RoleManagerShellCommand.java b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
index e1977ef..336b311 100644
--- a/services/core/java/com/android/server/role/RoleManagerShellCommand.java
+++ b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
@@ -16,6 +16,8 @@
 
 package com.android.server.role;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.role.IRoleManager;
 import android.app.role.IRoleManagerCallback;
 import android.os.RemoteException;
@@ -27,13 +29,17 @@
 import java.util.concurrent.TimeUnit;
 
 class RoleManagerShellCommand extends ShellCommand {
+
+    @NonNull
     private final IRoleManager mRoleManager;
 
-    RoleManagerShellCommand(IRoleManager roleManager) {
+    RoleManagerShellCommand(@NonNull IRoleManager roleManager) {
         mRoleManager = roleManager;
     }
 
     private class Callback extends IRoleManagerCallback.Stub {
+
+        @NonNull
         private final CompletableFuture<Void> mResult = new CompletableFuture<>();
 
         public int waitForResult() {
@@ -58,7 +64,7 @@
     }
 
     @Override
-    public int onCommand(String cmd) {
+    public int onCommand(@Nullable String cmd) {
         if (cmd == null) {
             return handleDefaultCommands(cmd);
         }
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index f218d3a..3e3e156 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -47,6 +47,7 @@
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Stores the state of roles for a user.
@@ -70,25 +71,41 @@
     private final int mUserId;
 
     @GuardedBy("RoleManagerService.mLock")
-    private int mVersion;
+    private int mVersion = VERSION_UNDEFINED;
 
     @GuardedBy("RoleManagerService.mLock")
-    private String mLastGrantPackagesHash = null;
+    @Nullable
+    private String mLastGrantPackagesHash;
 
     /**
      * Maps role names to its holders' package names. The values should never be null.
      */
     @GuardedBy("RoleManagerService.mLock")
-    @Nullable
-    private ArrayMap<String, ArraySet<String>> mRoles = null;
+    @NonNull
+    private ArrayMap<String, ArraySet<String>> mRoles = new ArrayMap<>();
 
     @GuardedBy("RoleManagerService.mLock")
     private boolean mDestroyed;
 
+    @NonNull
     private final Handler mWriteHandler = new Handler(BackgroundThread.getHandler().getLooper());
 
-    public RoleUserState(@UserIdInt int userId) {
+    private RoleUserState(@UserIdInt int userId) {
         mUserId = userId;
+
+        readSyncLocked();
+    }
+
+    /**
+     * Create a new instance of user state, and read its state from disk if previously persisted.
+     *
+     * @param userId the user id for the new user state
+     *
+     * @return the new user state
+     */
+    @GuardedBy("RoleManagerService.mLock")
+    public static RoleUserState newInstanceLocked(@UserIdInt int userId) {
+        return new RoleUserState(userId);
     }
 
     /**
@@ -116,7 +133,9 @@
     }
 
     /**
-     * Get the hash representing the state of packages during the last time initial grants was run
+     * Get the hash representing the state of packages during the last time initial grants was run.
+     *
+     * @return the hash representing the state of packages
      */
     @GuardedBy("RoleManagerService.mLock")
     public String getLastGrantPackagesHashLocked() {
@@ -124,10 +143,16 @@
     }
 
     /**
-     * Set the hash representing the state of packages during the last time initial grants was run
+     * Set the hash representing the state of packages during the last time initial grants was run.
+     *
+     * @param lastGrantPackagesHash the hash representing the state of packages
      */
     @GuardedBy("RoleManagerService.mLock")
-    public void setLastGrantPackagesHashLocked(String lastGrantPackagesHash) {
+    public void setLastGrantPackagesHashLocked(@Nullable String lastGrantPackagesHash) {
+        throwIfDestroyedLocked();
+        if (Objects.equals(mLastGrantPackagesHash, lastGrantPackagesHash)) {
+            return;
+        }
         mLastGrantPackagesHash = lastGrantPackagesHash;
         writeAsyncLocked();
     }
@@ -250,9 +275,9 @@
      * Schedule writing the state to file.
      */
     @GuardedBy("RoleManagerService.mLock")
-    void writeAsyncLocked() {
+    private void writeAsyncLocked() {
         throwIfDestroyedLocked();
-        int version = mVersion;
+
         ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
         for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
             String roleName = mRoles.keyAt(i);
@@ -260,15 +285,16 @@
             roleHolders = new ArraySet<>(roleHolders);
             roles.put(roleName, roleHolders);
         }
+
         mWriteHandler.removeCallbacksAndMessages(null);
         // TODO: Throttle writes.
-        mWriteHandler.sendMessage(PooledLambda.obtainMessage(
-                RoleUserState::writeSync, this, version, roles, mLastGrantPackagesHash));
+        mWriteHandler.sendMessage(PooledLambda.obtainMessage(RoleUserState::writeSync, this,
+                mVersion, mLastGrantPackagesHash, roles));
     }
 
     @WorkerThread
-    private void writeSync(int version, @NonNull ArrayMap<String, ArraySet<String>> roles,
-            String packagesHash) {
+    private void writeSync(int version, @Nullable String packagesHash,
+            @NonNull ArrayMap<String, ArraySet<String>> roles) {
         AtomicFile atomicFile = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
         FileOutputStream out = null;
         try {
@@ -280,7 +306,7 @@
                     "http://xmlpull.org/v1/doc/features.html#indent-output", true);
             serializer.startDocument(null, true);
 
-            serializeRoles(serializer, version, roles, packagesHash);
+            serializeRoles(serializer, version, packagesHash, roles);
 
             serializer.endDocument();
             atomicFile.finishWrite(out);
@@ -296,19 +322,26 @@
 
     @WorkerThread
     private void serializeRoles(@NonNull XmlSerializer serializer, int version,
-            @NonNull ArrayMap<String, ArraySet<String>> roles, String packagesHash)
+            @Nullable String packagesHash, @NonNull ArrayMap<String, ArraySet<String>> roles)
             throws IOException {
         serializer.startTag(null, TAG_ROLES);
+
         serializer.attribute(null, ATTRIBUTE_VERSION, Integer.toString(version));
-        serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
+
+        if (packagesHash != null) {
+            serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
+        }
+
         for (int i = 0, size = roles.size(); i < size; ++i) {
             String roleName = roles.keyAt(i);
             ArraySet<String> roleHolders = roles.valueAt(i);
+
             serializer.startTag(null, TAG_ROLE);
             serializer.attribute(null, ATTRIBUTE_NAME, roleName);
             serializeRoleHolders(serializer, roleHolders);
             serializer.endTag(null, TAG_ROLE);
         }
+
         serializer.endTag(null, TAG_ROLES);
     }
 
@@ -317,6 +350,7 @@
             @NonNull ArraySet<String> roleHolders) throws IOException {
         for (int i = 0, size = roleHolders.size(); i < size; ++i) {
             String roleHolder = roleHolders.valueAt(i);
+
             serializer.startTag(null, TAG_HOLDER);
             serializer.attribute(null, ATTRIBUTE_NAME, roleHolder);
             serializer.endTag(null, TAG_HOLDER);
@@ -327,11 +361,7 @@
      * Read the state from file.
      */
     @GuardedBy("RoleManagerService.mLock")
-    public void readSyncLocked() {
-        if (mRoles != null) {
-            throw new IllegalStateException("This RoleUserState has already read the roles.xml");
-        }
-
+    private void readSyncLocked() {
         File file = getFile(mUserId);
         try (FileInputStream in = new AtomicFile(file).openRead()) {
             XmlPullParser parser = Xml.newPullParser();
@@ -339,8 +369,6 @@
             parseXmlLocked(parser);
         } catch (FileNotFoundException e) {
             Slog.i(LOG_TAG, "roles.xml not found");
-            mRoles = new ArrayMap<>();
-            mVersion = VERSION_UNDEFINED;
         } catch (XmlPullParserException | IOException e) {
             throw new IllegalStateException("Failed to parse roles.xml: " + file, e);
         }
@@ -362,13 +390,14 @@
                 return;
             }
         }
+        Slog.w(LOG_TAG, "Missing <" + TAG_ROLES + "> in roles.xml");
     }
 
     private void parseRolesLocked(@NonNull XmlPullParser parser) throws IOException,
             XmlPullParserException {
         mVersion = Integer.parseInt(parser.getAttributeValue(null, ATTRIBUTE_VERSION));
         mLastGrantPackagesHash = parser.getAttributeValue(null, ATTRIBUTE_PACKAGES_HASH);
-        mRoles = new ArrayMap<>();
+        mRoles.clear();
 
         int type;
         int depth;
diff --git a/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java b/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java
new file mode 100644
index 0000000..7ce071f
--- /dev/null
+++ b/services/core/java/com/android/server/signedconfig/SignedConfigApplicator.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 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.signedconfig;
+
+import android.content.Context;
+
+class SignedConfigApplicator {
+
+    static void applyConfig(Context context, String config, String signature) {
+        //TODO verify signature
+        //TODO parse & apply config
+    }
+
+}
diff --git a/services/core/java/com/android/server/signedconfig/SignedConfigService.java b/services/core/java/com/android/server/signedconfig/SignedConfigService.java
new file mode 100644
index 0000000..1485686
--- /dev/null
+++ b/services/core/java/com/android/server/signedconfig/SignedConfigService.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 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.signedconfig;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Slog;
+
+import com.android.server.LocalServices;
+
+/**
+ * Signed config service. This is not an Android Service, but just owns a broadcast receiver for
+ * receiving package install and update notifications from the package manager.
+ */
+public class SignedConfigService {
+
+    private static final boolean DBG = false;
+    private static final String TAG = "SignedConfig";
+
+    // TODO should these be elsewhere? In a public API?
+    private static final String KEY_CONFIG = "android.signedconfig";
+    private static final String KEY_CONFIG_SIGNATURE = "android.signedconfig.signature";
+
+    private static class UpdateReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            new SignedConfigService(context).handlePackageBroadcast(intent);
+        }
+    }
+
+    private final Context mContext;
+    private final PackageManagerInternal mPacMan;
+
+    public SignedConfigService(Context context) {
+        mContext = context;
+        mPacMan = LocalServices.getService(PackageManagerInternal.class);
+    }
+
+    void handlePackageBroadcast(Intent intent) {
+        if (DBG) Slog.d(TAG, "handlePackageBroadcast " + intent);
+        Uri packageData = intent.getData();
+        String packageName = packageData == null ? null : packageData.getSchemeSpecificPart();
+        if (DBG) Slog.d(TAG, "handlePackageBroadcast package=" + packageName);
+        if (packageName == null) {
+            return;
+        }
+        int userId = mContext.getUser().getIdentifier();
+        PackageInfo pi = mPacMan.getPackageInfo(packageName, PackageManager.GET_META_DATA,
+                android.os.Process.SYSTEM_UID, userId);
+        if (pi == null) {
+            Slog.w(TAG, "Got null PackageInfo for " + packageName + "; user " + userId);
+            return;
+        }
+        Bundle metaData = pi.applicationInfo.metaData;
+        if (metaData == null) {
+            if (DBG) Slog.d(TAG, "handlePackageBroadcast: no metadata");
+            return;
+        }
+        if (metaData.containsKey(KEY_CONFIG)
+                && metaData.containsKey(KEY_CONFIG_SIGNATURE)) {
+            String config = metaData.getString(KEY_CONFIG);
+            String signature = metaData.getString(KEY_CONFIG_SIGNATURE);
+            if (DBG) {
+                Slog.d(TAG, "Got signed config: " + config);
+                Slog.d(TAG, "Got config signature: " + signature);
+            }
+            SignedConfigApplicator.applyConfig(mContext, config, signature);
+        } else {
+            if (DBG) Slog.d(TAG, "Package has no config/signature.");
+        }
+    }
+
+    /**
+     * Register to receive broadcasts from the package manager.
+     */
+    public static void registerUpdateReceiver(Context context) {
+        if (DBG) Slog.d(TAG, "Registering receiver");
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+        filter.addDataScheme("package");
+        context.registerReceiver(new UpdateReceiver(), filter);
+    }
+}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index e645b84..6e4c00e 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -17,6 +17,7 @@
 package com.android.server.statusbar;
 
 import static android.app.StatusBarManager.DISABLE2_GLOBAL_ACTIONS;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 import android.app.ActivityThread;
 import android.app.Notification;
@@ -25,6 +26,8 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.hardware.biometrics.IBiometricServiceReceiverInternal;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
@@ -40,7 +43,7 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
-import android.view.Display;
+import android.util.SparseArray;
 
 import com.android.internal.R;
 import com.android.internal.statusbar.IStatusBar;
@@ -63,7 +66,7 @@
  * A note on locking:  We rely on the fact that calls onto mBar are oneway or
  * if they are local, that they just enqueue messages to not deadlock.
  */
-public class StatusBarManagerService extends IStatusBarService.Stub {
+public class StatusBarManagerService extends IStatusBarService.Stub implements DisplayListener {
     private static final String TAG = "StatusBarManagerService";
     private static final boolean SPEW = false;
 
@@ -79,24 +82,13 @@
     private final ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
     private GlobalActionsProvider.GlobalActionsListener mGlobalActionListener;
     private IBinder mSysUiVisToken = new Binder();
-    private int mDisabled1 = 0;
-    private int mDisabled2 = 0;
 
     private final Object mLock = new Object();
     private final DeathRecipient mDeathRecipient = new DeathRecipient();
-    // encompasses lights-out mode and other flags defined on View
-    private int mSystemUiVisibility = 0;
-    private int mFullscreenStackSysUiVisibility;
-    private int mDockedStackSysUiVisibility;
-    private final Rect mFullscreenStackBounds = new Rect();
-    private final Rect mDockedStackBounds = new Rect();
-    private boolean mMenuVisible = false;
-    private int mImeWindowVis = 0;
-    private int mImeBackDisposition;
-    private boolean mShowImeSwitcher;
-    private IBinder mImeToken = null;
     private int mCurrentUserId;
 
+    private SparseArray<UiState> mDisplayUiState = new SparseArray<>();
+
     private class DeathRecipient implements IBinder.DeathRecipient {
         public void binderDied() {
             mBar.asBinder().unlinkToDeath(this,0);
@@ -185,8 +177,29 @@
 
         LocalServices.addService(StatusBarManagerInternal.class, mInternalService);
         LocalServices.addService(GlobalActionsProvider.class, mGlobalActionsProvider);
+
+        // We always have a default display.
+        final UiState state = new UiState();
+        mDisplayUiState.put(DEFAULT_DISPLAY, state);
+
+        final DisplayManager displayManager =
+                (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+        displayManager.registerDisplayListener(this, mHandler);
     }
 
+    @Override
+    public void onDisplayAdded(int displayId) {}
+
+    @Override
+    public void onDisplayRemoved(int displayId) {
+        synchronized (mLock) {
+            mDisplayUiState.remove(displayId);
+        }
+    }
+
+    @Override
+    public void onDisplayChanged(int displayId) {}
+
     /**
      * Private API used by NotificationManagerService.
      */
@@ -240,22 +253,14 @@
 
         @Override
         public void topAppWindowChanged(int displayId, boolean menuVisible) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
-            StatusBarManagerService.this.topAppWindowChanged(menuVisible);
+            StatusBarManagerService.this.topAppWindowChanged(displayId, menuVisible);
         }
 
         @Override
         public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
                 int dockedStackVis, int mask, Rect fullscreenBounds, Rect dockedBounds,
                 String cause) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
-            StatusBarManagerService.this.setSystemUiVisibility(vis, fullscreenStackVis,
+            StatusBarManagerService.this.setSystemUiVisibility(displayId, vis, fullscreenStackVis,
                     dockedStackVis, mask, fullscreenBounds, dockedBounds, cause);
         }
 
@@ -272,13 +277,9 @@
         @Override
         public void appTransitionFinished(int displayId) {
             enforceStatusBarService();
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
-                    mBar.appTransitionFinished();
+                    mBar.appTransitionFinished(displayId);
                 } catch (RemoteException ex) {}
             }
         }
@@ -374,39 +375,27 @@
 
         @Override
         public void setWindowState(int displayId, int window, int state) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
-                    mBar.setWindowState(window, state);
+                    mBar.setWindowState(displayId, window, state);
                 } catch (RemoteException ex) {}
             }
         }
 
         @Override
         public void appTransitionPending(int displayId) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
-                    mBar.appTransitionPending();
+                    mBar.appTransitionPending(displayId);
                 } catch (RemoteException ex) {}
             }
         }
 
         @Override
         public void appTransitionCancelled(int displayId) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
-                    mBar.appTransitionCancelled();
+                    mBar.appTransitionCancelled(displayId);
                 } catch (RemoteException ex) {}
             }
         }
@@ -414,14 +403,10 @@
         @Override
         public void appTransitionStarting(int displayId, long statusBarAnimationsStartTime,
                 long statusBarAnimationsDuration) {
-            if (displayId != Display.DEFAULT_DISPLAY) {
-                // TODO (b/117478341): Resolve one status bar/ navigation bar assumption
-                return;
-            }
             if (mBar != null) {
                 try {
                     mBar.appTransitionStarting(
-                            statusBarAnimationsStartTime, statusBarAnimationsDuration);
+                            displayId, statusBarAnimationsStartTime, statusBarAnimationsDuration);
                 } catch (RemoteException ex) {}
             }
         }
@@ -449,6 +434,7 @@
             return false;
         }
 
+        // TODO(b/118592525): support it per display if necessary.
         @Override
         public void onProposedRotationChanged(int rotation, boolean isValid) {
             if (mBar != null){
@@ -462,7 +448,9 @@
     private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {
         @Override
         public boolean isGlobalActionsDisabled() {
-            return (mDisabled2 & DISABLE2_GLOBAL_ACTIONS) != 0;
+            // TODO(b/118592525): support global actions for multi-display.
+            final int disabled2 = mDisplayUiState.get(DEFAULT_DISPLAY).getDisabled2();
+            return (disabled2 & DISABLE2_GLOBAL_ACTIONS) != 0;
         }
 
         @Override
@@ -664,20 +652,23 @@
         }
     }
 
+    // TODO(b/117478341): make it aware of multi-display if needed.
     @Override
     public void disable(int what, IBinder token, String pkg) {
         disableForUser(what, token, pkg, mCurrentUserId);
     }
 
+    // TODO(b/117478341): make it aware of multi-display if needed.
     @Override
     public void disableForUser(int what, IBinder token, String pkg, int userId) {
         enforceStatusBar();
 
         synchronized (mLock) {
-            disableLocked(userId, what, token, pkg, 1);
+            disableLocked(DEFAULT_DISPLAY, userId, what, token, pkg, 1);
         }
     }
 
+    // TODO(b/117478341): make it aware of multi-display if needed.
     /**
      * Disable additional status bar features. Pass the bitwise-or of the DISABLE2_* flags.
      * To re-enable everything, pass {@link #DISABLE_NONE}.
@@ -689,6 +680,7 @@
         disable2ForUser(what, token, pkg, mCurrentUserId);
     }
 
+    // TODO(b/117478341): make it aware of multi-display if needed.
     /**
      * Disable additional status bar features for a given user. Pass the bitwise-or of the
      * DISABLE2_* flags. To re-enable everything, pass {@link #DISABLE_NONE}.
@@ -700,11 +692,12 @@
         enforceStatusBar();
 
         synchronized (mLock) {
-            disableLocked(userId, what, token, pkg, 2);
+            disableLocked(DEFAULT_DISPLAY, userId, what, token, pkg, 2);
         }
     }
 
-    private void disableLocked(int userId, int what, IBinder token, String pkg, int whichFlag) {
+    private void disableLocked(int displayId, int userId, int what, IBinder token, String pkg,
+            int whichFlag) {
         // It's important that the the callback and the call to mBar get done
         // in the same order when multiple threads are calling this function
         // so they are paired correctly.  The messages on the handler will be
@@ -723,22 +716,19 @@
                 disabledData += "    ([" + i + "] " + tok + "), ";
             }
             disabledData += " }";
-            Log.d(TAG, "disabledlocked (b/113914868): net1=" + net1 + ", mDisabled1=" + mDisabled1
-                    + ", token=" + token + ", mDisableRecords=" + mDisableRecords.size() + " => "
-                    + disabledData);
-        }
+            final UiState state = getUiState(displayId);
 
-        if (net1 != mDisabled1 || net2 != mDisabled2) {
-            mDisabled1 = net1;
-            mDisabled2 = net2;
-            mHandler.post(new Runnable() {
-                    public void run() {
-                        mNotificationDelegate.onSetDisabled(net1);
-                    }
-                });
+            Log.d(TAG, "disabledlocked (b/113914868): displayId=" + displayId + "net1=" + net1
+                    + ", mDisabled1=" + state.mDisabled1 + ", token=" + token
+                    + ", mDisableRecords=" + mDisableRecords.size() + " => " + disabledData);
+        }
+        final UiState state = getUiState(displayId);
+        if (state.disableEquals(net1, net2)) {
+            state.setDisabled(net1, net2);
+            mHandler.post(() -> mNotificationDelegate.onSetDisabled(net1));
             if (mBar != null) {
                 try {
-                    mBar.disable(net1, net2);
+                    mBar.disable(displayId, net1, net2);
                 } catch (RemoteException ex) {
                 }
             }
@@ -808,26 +798,27 @@
      * response to a window with {@link android.view.WindowManager.LayoutParams#needsMenuKey} set
      * to {@link android.view.WindowManager.LayoutParams#NEEDS_MENU_SET_TRUE}.
      */
-    private void topAppWindowChanged(final boolean menuVisible) {
+    private void topAppWindowChanged(int displayId, final boolean menuVisible) {
         enforceStatusBar();
 
-        if (SPEW) Slog.d(TAG, (menuVisible?"showing":"hiding") + " MENU key");
-
+        if (SPEW) {
+            Slog.d(TAG, "display#" + displayId + ": "
+                    + (menuVisible ? "showing" : "hiding") + " MENU key");
+        }
         synchronized(mLock) {
-            mMenuVisible = menuVisible;
-            mHandler.post(new Runnable() {
-                public void run() {
-                    if (mBar != null) {
-                        try {
-                            mBar.topAppWindowChanged(menuVisible);
-                        } catch (RemoteException ex) {
-                        }
+            getUiState(displayId).setMenuVisible(menuVisible);
+            mHandler.post(() -> {
+                if (mBar != null) {
+                    try {
+                        mBar.topAppWindowChanged(displayId, menuVisible);
+                    } catch (RemoteException ex) {
                     }
                 }
             });
         }
     }
 
+    // TODO(b/117478341): support back button change when IME is showing on a external display.
     @Override
     public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition,
             final boolean showImeSwitcher) {
@@ -841,39 +832,42 @@
             // In case of IME change, we need to call up setImeWindowStatus() regardless of
             // mImeWindowVis because mImeWindowVis may not have been set to false when the
             // previous IME was destroyed.
-            mImeWindowVis = vis;
-            mImeBackDisposition = backDisposition;
-            mImeToken = token;
-            mShowImeSwitcher = showImeSwitcher;
-            mHandler.post(new Runnable() {
-                public void run() {
-                    if (mBar != null) {
-                        try {
-                            mBar.setImeWindowStatus(token, vis, backDisposition, showImeSwitcher);
-                        } catch (RemoteException ex) {
-                        }
-                    }
-                }
+            // TODO(b/117478341): support back button change when IME is showing on a external
+            // display.
+            getUiState(DEFAULT_DISPLAY)
+                    .setImeWindowState(vis, backDisposition, showImeSwitcher, token);
+
+            mHandler.post(() -> {
+                if (mBar == null) return;
+                try {
+                    // TODO(b/117478341): support back button change when IME is showing on a
+                    // external display.
+                    mBar.setImeWindowStatus(
+                            DEFAULT_DISPLAY, token, vis, backDisposition, showImeSwitcher);
+                } catch (RemoteException ex) { }
             });
         }
     }
 
     @Override
-    public void setSystemUiVisibility(int vis, int mask, String cause) {
-        setSystemUiVisibility(vis, 0, 0, mask, mFullscreenStackBounds, mDockedStackBounds, cause);
+    public void setSystemUiVisibility(int displayId, int vis, int mask, String cause) {
+        final UiState state = getUiState(displayId);
+        setSystemUiVisibility(displayId, vis, 0, 0, mask,
+                state.mFullscreenStackBounds, state.mDockedStackBounds, cause);
     }
 
-    private void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis, int mask,
-            Rect fullscreenBounds, Rect dockedBounds, String cause) {
+    private void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
+            int dockedStackVis, int mask, Rect fullscreenBounds, Rect dockedBounds, String cause) {
         // also allows calls from window manager which is in this process.
         enforceStatusBarService();
 
         if (SPEW) Slog.d(TAG, "setSystemUiVisibility(0x" + Integer.toHexString(vis) + ")");
 
         synchronized (mLock) {
-            updateUiVisibilityLocked(vis, fullscreenStackVis, dockedStackVis, mask,
+            updateUiVisibilityLocked(displayId, vis, fullscreenStackVis, dockedStackVis, mask,
                     fullscreenBounds, dockedBounds);
             disableLocked(
+                    displayId,
                     mCurrentUserId,
                     vis & StatusBarManager.DISABLE_MASK,
                     mSysUiVisToken,
@@ -881,30 +875,107 @@
         }
     }
 
-    private void updateUiVisibilityLocked(final int vis,
+    private void updateUiVisibilityLocked(final int displayId, final int vis,
             final int fullscreenStackVis, final int dockedStackVis, final int mask,
             final Rect fullscreenBounds, final Rect dockedBounds) {
-        if (mSystemUiVisibility != vis
-                || mFullscreenStackSysUiVisibility != fullscreenStackVis
-                || mDockedStackSysUiVisibility != dockedStackVis
-                || !mFullscreenStackBounds.equals(fullscreenBounds)
-                || !mDockedStackBounds.equals(dockedBounds)) {
+        final UiState state = getUiState(displayId);
+        if (!state.systemUiStateEquals(vis, fullscreenStackVis, dockedStackVis,
+                fullscreenBounds, dockedBounds)) {
+            state.setSystemUiState(vis, fullscreenStackVis, dockedStackVis, fullscreenBounds,
+                    dockedBounds);
+            mHandler.post(() -> {
+                if (mBar != null) {
+                    try {
+                        mBar.setSystemUiVisibility(displayId, vis, fullscreenStackVis,
+                                dockedStackVis, mask, fullscreenBounds, dockedBounds);
+                    } catch (RemoteException ex) {
+                        Log.w(TAG, "Can not get StatusBar!");
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * @return {@link UiState} specified by {@code displayId}.
+     *
+     * <p>
+     *   Note: If {@link UiState} specified by {@code displayId} does not exist, {@link UiState}
+     *   will be allocated and {@code mDisplayUiState} will be updated accordingly.
+     * <p/>
+     */
+    private UiState getUiState(int displayId) {
+        UiState state = mDisplayUiState.get(displayId);
+        if (state == null) {
+            state = new UiState();
+            mDisplayUiState.put(displayId, state);
+        }
+        return state;
+    }
+
+    private class UiState {
+        private int mSystemUiVisibility = 0;
+        private int mFullscreenStackSysUiVisibility = 0;
+        private int mDockedStackSysUiVisibility = 0;
+        private final Rect mFullscreenStackBounds = new Rect();
+        private final Rect mDockedStackBounds = new Rect();
+        private boolean mMenuVisible = false;
+        private int mDisabled1 = 0;
+        private int mDisabled2 = 0;
+        private int mImeWindowVis = 0;
+        private int mImeBackDisposition = 0;
+        private boolean mShowImeSwitcher = false;
+        private IBinder mImeToken = null;
+
+        private int getDisabled1() {
+            return mDisabled1;
+        }
+
+        private int getDisabled2() {
+            return mDisabled2;
+        }
+
+        private void setDisabled(int disabled1, int disabled2) {
+            mDisabled1 = disabled1;
+            mDisabled2 = disabled2;
+        }
+
+        private boolean isMenuVisible() {
+            return mMenuVisible;
+        }
+
+        private void setMenuVisible(boolean menuVisible) {
+            mMenuVisible = menuVisible;
+        }
+
+        private boolean disableEquals(int disabled1, int disabled2) {
+            return mDisabled1 == disabled1 && mDisabled2 == disabled2;
+        }
+
+        private void setSystemUiState(final int vis, final int fullscreenStackVis,
+                final int dockedStackVis, final Rect fullscreenBounds, final Rect dockedBounds) {
             mSystemUiVisibility = vis;
             mFullscreenStackSysUiVisibility = fullscreenStackVis;
             mDockedStackSysUiVisibility = dockedStackVis;
             mFullscreenStackBounds.set(fullscreenBounds);
             mDockedStackBounds.set(dockedBounds);
-            mHandler.post(new Runnable() {
-                    public void run() {
-                        if (mBar != null) {
-                            try {
-                                mBar.setSystemUiVisibility(vis, fullscreenStackVis, dockedStackVis,
-                                        mask, fullscreenBounds, dockedBounds);
-                            } catch (RemoteException ex) {
-                            }
-                        }
-                    }
-                });
+        }
+
+        private boolean systemUiStateEquals(final int vis, final int fullscreenStackVis,
+                final int dockedStackVis, final Rect fullscreenBounds, final Rect dockedBounds) {
+            return mSystemUiVisibility == vis
+                && mFullscreenStackSysUiVisibility == fullscreenStackVis
+                && mDockedStackSysUiVisibility == dockedStackVis
+                && mFullscreenStackBounds.equals(fullscreenBounds)
+                && mDockedStackBounds.equals(dockedBounds);
+        }
+
+        private void setImeWindowState(final int vis, final int backDisposition,
+                final boolean showImeSwitcher, final IBinder token) {
+            mImeWindowVis = vis;
+            mImeBackDisposition = backDisposition;
+            mShowImeSwitcher = showImeSwitcher;
+            mImeToken = token;
         }
     }
 
@@ -939,6 +1010,7 @@
     // ================================================================================
     // Callbacks from the status bar service.
     // ================================================================================
+    // TODO(b/118592525): refactor it as an IStatusBar API.
     @Override
     public void registerStatusBar(IStatusBar bar, List<String> iconSlots,
             List<StatusBarIcon> iconList, int switches[], List<IBinder> binders,
@@ -956,18 +1028,21 @@
             }
         }
         synchronized (mLock) {
+            // TODO(b/118592525): Currently, status bar only works on the default display.
+            // Make it aware of multi-display if needed.
+            final UiState state = mDisplayUiState.get(DEFAULT_DISPLAY);
             switches[0] = gatherDisableActionsLocked(mCurrentUserId, 1);
-            switches[1] = mSystemUiVisibility;
-            switches[2] = mMenuVisible ? 1 : 0;
-            switches[3] = mImeWindowVis;
-            switches[4] = mImeBackDisposition;
-            switches[5] = mShowImeSwitcher ? 1 : 0;
+            switches[1] = state.mSystemUiVisibility;
+            switches[2] = state.mMenuVisible ? 1 : 0;
+            switches[3] = state.mImeWindowVis;
+            switches[4] = state.mImeBackDisposition;
+            switches[5] = state.mShowImeSwitcher ? 1 : 0;
             switches[6] = gatherDisableActionsLocked(mCurrentUserId, 2);
-            switches[7] = mFullscreenStackSysUiVisibility;
-            switches[8] = mDockedStackSysUiVisibility;
-            binders.add(mImeToken);
-            fullscreenStackBounds.set(mFullscreenStackBounds);
-            dockedStackBounds.set(mDockedStackBounds);
+            switches[7] = state.mFullscreenStackSysUiVisibility;
+            switches[8] = state.mDockedStackSysUiVisibility;
+            binders.add(state.mImeToken);
+            fullscreenStackBounds.set(state.mFullscreenStackBounds);
+            dockedStackBounds.set(state.mDockedStackBounds);
         }
     }
 
@@ -1309,8 +1384,13 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
         synchronized (mLock) {
-            pw.println("  mDisabled1=0x" + Integer.toHexString(mDisabled1));
-            pw.println("  mDisabled2=0x" + Integer.toHexString(mDisabled2));
+            for (int i = 0; i < mDisplayUiState.size(); i++) {
+                final int key = mDisplayUiState.keyAt(i);
+                final UiState state = mDisplayUiState.get(key);
+                pw.println("  displayId=" + key);
+                pw.println("    mDisabled1=0x" + Integer.toHexString(state.getDisabled1()));
+                pw.println("    mDisabled2=0x" + Integer.toHexString(state.getDisabled2()));
+            }
             final int N = mDisableRecords.size();
             pw.println("  mDisableRecords.size=" + N);
             for (int i=0; i<N; i++) {
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index cfec8ef..64ff9cf 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2822,8 +2822,6 @@
         IoUtils.closeQuietly(stream);
 
         if (!success) {
-            wpdData.mWidth = -1;
-            wpdData.mHeight = -1;
             wallpaper.cropHint.set(0, 0, 0, 0);
             wpdData.mPadding.set(0, 0, 0, 0);
             wallpaper.name = "";
@@ -2839,6 +2837,7 @@
             }
         }
 
+        ensureSaneWallpaperDisplaySize(wpdData, DEFAULT_DISPLAY);
         ensureSaneWallpaperData(wallpaper, DEFAULT_DISPLAY);
         WallpaperData lockWallpaper = mLockWallpaperMap.get(userId);
         if (lockWallpaper != null) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 25399ef..255a003 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2543,7 +2543,7 @@
 
         // Bounds changed...update configuration to match.
         if (!matchParentBounds()) {
-            task.computeOverrideConfiguration(mTmpConfig, updatedBounds, null /* insetBounds */,
+            task.computeOverrideConfiguration(mTmpConfig, updatedBounds,
                     false /* overrideWidth */, false /* overrideHeight */);
         }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index d40a4fa..3ccede0 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -4944,9 +4944,12 @@
                 }
             }
 
-            mTmpBounds.put(task.taskId, task.getOverrideBounds());
-            if (tempTaskInsetBounds != null) {
-                mTmpInsetBounds.put(task.taskId, tempTaskInsetBounds);
+            if (task.hasDisplayedBounds()) {
+                mTmpBounds.put(task.taskId, task.getDisplayedBounds());
+                mTmpInsetBounds.put(task.taskId, task.getOverrideBounds());
+            } else {
+                mTmpBounds.put(task.taskId, task.getOverrideBounds());
+                mTmpInsetBounds.put(task.taskId, null);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 0967afd..37db671 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -863,6 +863,13 @@
      */
     Configuration getGlobalConfigurationForCallingPid() {
         final int pid = Binder.getCallingPid();
+        return getGlobalConfigurationForPid(pid);
+    }
+
+    /**
+     * Return the global configuration used by the process corresponding to the given pid.
+     */
+    Configuration getGlobalConfigurationForPid(int pid) {
         if (pid == MY_PID || pid < 0) {
             return getGlobalConfiguration();
         }
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index fb93d39..c458c94 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2178,9 +2178,9 @@
         final TaskStack stack = getStack();
         final Task task = getTask();
         if (task != null && task.inFreeformWindowingMode()) {
-            task.getRelativePosition(outPosition);
+            task.getRelativeDisplayedPosition(outPosition);
         } else if (stack != null) {
-            stack.getRelativePosition(outPosition);
+            stack.getRelativeDisplayedPosition(outPosition);
         }
 
         // Always use stack bounds in order to have the ability to animate outside the task region.
@@ -2193,6 +2193,18 @@
         outBounds.offsetTo(0, 0);
     }
 
+    @Override
+    Rect getDisplayedBounds() {
+        final Task task = getTask();
+        if (task != null) {
+            final Rect overrideDisplayedBounds = task.getOverrideDisplayedBounds();
+            if (!overrideDisplayedBounds.isEmpty()) {
+                return overrideDisplayedBounds;
+            }
+        }
+        return getBounds();
+    }
+
     boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
             boolean isVoiceInteraction) {
 
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 64553a8..e779d1b 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -319,6 +319,13 @@
         onOverrideConfigurationChanged(mTmpConfig);
     }
 
+    /** Sets the windowing mode for the configuration container. */
+    void setDisplayWindowingMode(int windowingMode) {
+        mTmpConfig.setTo(getOverrideConfiguration());
+        mTmpConfig.windowConfiguration.setDisplayWindowingMode(windowingMode);
+        onOverrideConfigurationChanged(mTmpConfig);
+    }
+
     /**
      * Returns true if this container is currently in multi-window mode. I.e. sharing the screen
      * with another activity.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 05e8267..aba2eb3 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1546,6 +1546,7 @@
         final int dh = displayInfo.logicalHeight;
         config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
         config.windowConfiguration.setWindowingMode(getWindowingMode());
+        config.windowConfiguration.setDisplayWindowingMode(getWindowingMode());
         config.windowConfiguration.setRotation(displayInfo.rotation);
 
         final float density = mDisplayMetrics.density;
@@ -1953,6 +1954,17 @@
         mWmService.mWindowsChanged = true;
     }
 
+    @Override
+    public void setWindowingMode(int windowingMode) {
+        super.setWindowingMode(windowingMode);
+        super.setDisplayWindowingMode(windowingMode);
+    }
+
+    @Override
+    void setDisplayWindowingMode(int windowingMode) {
+        setWindowingMode(windowingMode);
+    }
+
     /**
      * In split-screen mode we process the IME containers above the docked divider
      * rather than directly above their target.
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index f1d77b9..581cec9 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2834,6 +2834,9 @@
             return 0;
         }
 
+        mDisplayContent.getInsetsStateController().onBarControllingWindowChanged(
+                mTopFullscreenOpaqueWindowState);
+
         int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null)
                 & ~mResettingSystemUiFlags
                 & ~mForceClearedSystemUiFlags;
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index e96f0b1..282838f 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -18,11 +18,18 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.graphics.Point;
 import android.graphics.Rect;
+import android.util.proto.ProtoOutputStream;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
 import android.view.InsetsSource;
+import android.view.InsetsSourceControl;
 
 import com.android.internal.util.function.TriConsumer;
-import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
+import java.io.PrintWriter;
 
 /**
  * Controller for a specific inset source on the server. It's called provider as it provides the
@@ -32,11 +39,19 @@
 
     private final Rect mTmpRect = new Rect();
     private final @NonNull InsetsSource mSource;
+    private final DisplayContent mDisplayContent;
+    private final InsetsStateController mStateController;
+    private @Nullable InsetsSourceControl mControl;
+    private @Nullable WindowState mControllingWin;
+    private @Nullable ControlAdapter mAdapter;
     private WindowState mWin;
     private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider;
 
-    InsetsSourceProvider(InsetsSource source) {
+    InsetsSourceProvider(InsetsSource source, InsetsStateController stateController,
+            DisplayContent displayContent) {
         mSource = source;
+        mDisplayContent = displayContent;
+        mStateController = stateController;
     }
 
     InsetsSource getSource() {
@@ -84,4 +99,81 @@
         mSource.setVisible(mWin.isVisible() && !mWin.mGivenInsetsPending);
 
     }
+
+    void updateControlForTarget(@Nullable WindowState target) {
+        if (target == mControllingWin) {
+            return;
+        }
+        if (target == null) {
+            revokeControl();
+            return;
+        }
+        mAdapter = new ControlAdapter();
+        mWin.startAnimation(mDisplayContent.getPendingTransaction(), mAdapter,
+                false /* TODO hidden */);
+        mControllingWin = target;
+        mControl = new InsetsSourceControl(mSource.getType(), mAdapter.mCapturedLeash);
+    }
+
+    InsetsSourceControl getControl() {
+        return mControl;
+    }
+
+    void revokeControl() {
+        if (mControllingWin != null) {
+
+            // Cancelling the animation will invoke onAnimationCancelled, resetting all the fields.
+            mWin.cancelAnimation();
+        }
+    }
+
+    private class ControlAdapter implements AnimationAdapter {
+
+        private SurfaceControl mCapturedLeash;
+
+        @Override
+        public boolean getShowWallpaper() {
+            return false;
+        }
+
+        @Override
+        public int getBackgroundColor() {
+            return 0;
+        }
+
+        @Override
+        public void startAnimation(SurfaceControl animationLeash, Transaction t,
+                OnAnimationFinishedCallback finishCallback) {
+            mCapturedLeash = animationLeash;
+            t.setPosition(mCapturedLeash, mSource.getFrame().left, mSource.getFrame().top);
+        }
+
+        @Override
+        public void onAnimationCancelled(SurfaceControl animationLeash) {
+            if (mAdapter == this) {
+                mStateController.notifyControlRevoked(mControllingWin, InsetsSourceProvider.this);
+                mControl = null;
+                mControllingWin = null;
+                mAdapter = null;
+            }
+        }
+
+        @Override
+        public long getDurationHint() {
+            return 0;
+        }
+
+        @Override
+        public long getStatusBarTransitionsStartTime() {
+            return 0;
+        }
+
+        @Override
+        public void dump(PrintWriter pw, String prefix) {
+        }
+
+        @Override
+        public void writeToProto(ProtoOutputStream proto) {
+        }
+    };
 }
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 1189ee6..592b7fb 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -20,10 +20,17 @@
 import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.TYPE_TOP_BAR;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.SparseArray;
+import android.view.InsetsSourceControl;
 import android.view.InsetsState;
+import android.view.ViewRootImpl;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.function.Consumer;
 
 /**
@@ -34,7 +41,11 @@
     private final InsetsState mLastState = new InsetsState();
     private final InsetsState mState = new InsetsState();
     private final DisplayContent mDisplayContent;
-    private ArrayMap<Integer, InsetsSourceProvider> mControllers = new ArrayMap<>();
+
+    private final ArrayMap<Integer, InsetsSourceProvider> mControllers = new ArrayMap<>();
+    private final ArrayMap<WindowState, ArrayList<Integer>> mWinControlTypeMap = new ArrayMap<>();
+    private final SparseArray<WindowState> mTypeWinControlMap = new SparseArray<>();
+    private final ArraySet<WindowState> mPendingControlChanged = new ArraySet<>();
 
     private final Consumer<WindowState> mDispatchInsetsChanged = w -> {
         if (w.isVisible()) {
@@ -72,12 +83,25 @@
         return state;
     }
 
+    @Nullable InsetsSourceControl[] getControlsForDispatch(WindowState target) {
+        ArrayList<Integer> controlled = mWinControlTypeMap.get(target);
+        if (controlled == null) {
+            return null;
+        }
+        final int size = controlled.size();
+        final InsetsSourceControl[] result = new InsetsSourceControl[size];
+        for (int i = 0; i < size; i++) {
+            result[i] = mControllers.get(controlled.get(i)).getControl();
+        }
+        return result;
+    }
+
     /**
      * @return The provider of a specific type.
      */
     InsetsSourceProvider getSourceProvider(int type) {
         return mControllers.computeIfAbsent(type,
-                key -> new InsetsSourceProvider(mState.getSource(key)));
+                key -> new InsetsSourceProvider(mState.getSource(key), this, mDisplayContent));
     }
 
     /**
@@ -93,6 +117,84 @@
         }
     }
 
+    void onImeTargetChanged(@Nullable WindowState imeTarget) {
+        onControlChanged(TYPE_IME, imeTarget);
+        notifyPendingInsetsControlChanged();
+    }
+
+    /**
+     * Called when the top opaque fullscreen window that is able to control the system bars changes.
+     *
+     * @param controllingWindow The window that is now able to control the system bars appearance
+     *                          and visibility.
+     */
+    void onBarControllingWindowChanged(@Nullable WindowState controllingWindow) {
+        // TODO: Apply policy that determines whether controllingWindow is able to control system
+        // bars
+
+        // TODO: Depending on the form factor, mapping is different
+        onControlChanged(TYPE_TOP_BAR, controllingWindow);
+        onControlChanged(TYPE_NAVIGATION_BAR, controllingWindow);
+        notifyPendingInsetsControlChanged();
+    }
+
+    void notifyControlRevoked(@NonNull WindowState previousControllingWin,
+            InsetsSourceProvider provider) {
+        removeFromControlMaps(previousControllingWin, provider.getSource().getType());
+    }
+
+    private void onControlChanged(int type, @Nullable WindowState win) {
+        if (!ViewRootImpl.USE_NEW_INSETS) {
+            return;
+        }
+        final WindowState previous = mTypeWinControlMap.get(type);
+        if (win == previous) {
+            return;
+        }
+        final InsetsSourceProvider controller = mControllers.get(type);
+        if (controller == null) {
+            return;
+        }
+        controller.updateControlForTarget(win);
+        if (previous != null) {
+            removeFromControlMaps(previous, type);
+            mPendingControlChanged.add(previous);
+        }
+        if (win != null) {
+            addToControlMaps(win, type);
+            mPendingControlChanged.add(win);
+        }
+    }
+
+    private void removeFromControlMaps(@NonNull WindowState win, int type) {
+        final ArrayList<Integer> array = mWinControlTypeMap.get(win);
+        if (array == null) {
+            return;
+        }
+        array.remove((Integer) type);
+        if (array.isEmpty()) {
+            mWinControlTypeMap.remove(win);
+        }
+        mTypeWinControlMap.remove(type);
+    }
+
+    private void addToControlMaps(@NonNull WindowState win, int type) {
+        final ArrayList<Integer> array = mWinControlTypeMap.computeIfAbsent(win,
+                key -> new ArrayList<>());
+        array.add(type);
+        mTypeWinControlMap.put(type, win);
+    }
+
+    private void notifyPendingInsetsControlChanged() {
+        mDisplayContent.mWmService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
+            for (int i = mPendingControlChanged.size() - 1; i >= 0; i--) {
+                final WindowState controllingWin = mPendingControlChanged.valueAt(i);
+                controllingWin.notifyInsetsControlChanged();
+            }
+            mPendingControlChanged.clear();
+        });
+    }
+
     private void notifyInsetsChanged() {
         mDisplayContent.forAllWindows(mDispatchInsetsChanged, true /* traverseTopToBottom */);
     }
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index b6609e4..83ba384 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -504,10 +504,12 @@
     public void binderDied() {
         cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
 
-        // Clear associated input consumers on runner death
-        final InputMonitor inputMonitor =
-                mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
-        inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
+        synchronized (mService.getWindowManagerLock()) {
+            // Clear associated input consumers on runner death
+            final InputMonitor inputMonitor =
+                    mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
+            inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
+        }
     }
 
     void checkAnimationReady(WallpaperController wallpaperController) {
@@ -603,8 +605,8 @@
             mTask = task;
             mIsRecentTaskInvisible = isRecentTaskInvisible;
             final WindowContainer container = mTask.getParent();
-            container.getRelativePosition(mPosition);
-            container.getBounds(mBounds);
+            container.getRelativeDisplayedPosition(mPosition);
+            mBounds.set(container.getDisplayedBounds());
         }
 
         RemoteAnimationTarget createRemoteAnimationApp() {
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index 35264a2..8f18aa5 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -252,7 +252,7 @@
      * before mContainer has been updated, any relevant properties (like {@param windowingMode})
      * need to be passed in.
      */
-    public void adjustConfigurationForBounds(Rect bounds, Rect insetBounds,
+    public void adjustConfigurationForBounds(Rect bounds,
             Rect nonDecorBounds, Rect stableBounds, boolean overrideWidth,
             boolean overrideHeight, float density, Configuration config,
             Configuration parentConfig, int windowingMode) {
@@ -303,11 +303,9 @@
                 // Additionally task dimensions should not be bigger than its parents dimensions.
                 // The non decor inset are areas that could never be removed in Honeycomb. See
                 // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
-                intersectDisplayBoundsExcludeInsets(nonDecorBounds,
-                        insetBounds != null ? insetBounds : bounds, mTmpNonDecorInsets,
+                intersectDisplayBoundsExcludeInsets(nonDecorBounds, bounds, mTmpNonDecorInsets,
                         mTmpDisplayBounds, overrideWidth, overrideHeight);
-                intersectDisplayBoundsExcludeInsets(stableBounds,
-                        insetBounds != null ? insetBounds : bounds, mTmpStableInsets,
+                intersectDisplayBoundsExcludeInsets(stableBounds, bounds, mTmpStableInsets,
                         mTmpDisplayBounds, overrideWidth, overrideHeight);
                 width = Math.min((int) (stableBounds.width() / density),
                         parentConfig.screenWidthDp);
@@ -323,7 +321,7 @@
             config.screenWidthDp = width;
             config.screenHeightDp = height;
             config.smallestScreenWidthDp = getSmallestWidthForTaskBounds(
-                    insetBounds != null ? insetBounds : bounds, density, windowingMode);
+                    bounds, density, windowingMode);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index d3db5df..c70f075 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -27,11 +27,11 @@
 import static com.android.server.wm.TaskProto.APP_WINDOW_TOKENS;
 import static com.android.server.wm.TaskProto.BOUNDS;
 import static com.android.server.wm.TaskProto.DEFER_REMOVAL;
+import static com.android.server.wm.TaskProto.DISPLAYED_BOUNDS;
 import static com.android.server.wm.TaskProto.FILLS_PARENT;
 import static com.android.server.wm.TaskProto.ID;
 import static com.android.server.wm.TaskProto.SURFACE_HEIGHT;
 import static com.android.server.wm.TaskProto.SURFACE_WIDTH;
-import static com.android.server.wm.TaskProto.TEMP_INSET_BOUNDS;
 import static com.android.server.wm.TaskProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -66,8 +66,8 @@
     final Rect mPreparedFrozenBounds = new Rect();
     final Configuration mPreparedFrozenMergedConfig = new Configuration();
 
-    // Bounds used to calculate the insets.
-    private final Rect mTempInsetBounds = new Rect();
+    // If non-empty, bounds used to display the task during animations/interactions.
+    private final Rect mOverrideDisplayedBounds = new Rect();
 
     /** ID of the display which rotation {@link #mRotation} has. */
     private int mLastRotationDisplayId = Display.INVALID_DISPLAY;
@@ -307,23 +307,23 @@
     }
 
     /**
-     * Sets the bounds used to calculate the insets. See
-     * {@link android.app.IActivityTaskManager#resizeDockedStack} why this is needed.
+     * Sets bounds that override where the task is displayed. Used during transient operations
+     * like animation / interaction.
      */
-    void setTempInsetBounds(Rect tempInsetBounds) {
-        if (tempInsetBounds != null) {
-            mTempInsetBounds.set(tempInsetBounds);
+    void setOverrideDisplayedBounds(Rect overrideDisplayedBounds) {
+        if (overrideDisplayedBounds != null) {
+            mOverrideDisplayedBounds.set(overrideDisplayedBounds);
         } else {
-            mTempInsetBounds.setEmpty();
+            mOverrideDisplayedBounds.setEmpty();
         }
     }
 
     /**
-     * Gets the bounds used to calculate the insets. See
+     * Gets the bounds that override where the task is displayed. See
      * {@link android.app.IActivityTaskManager#resizeDockedStack} why this is needed.
      */
-    void getTempInsetBounds(Rect out) {
-        out.set(mTempInsetBounds);
+    Rect getOverrideDisplayedBounds() {
+        return mOverrideDisplayedBounds;
     }
 
     void setResizeable(int resizeMode) {
@@ -380,8 +380,13 @@
         } else {
             mTmpRect2.offsetTo(adjustedBounds.left, adjustedBounds.top);
         }
-        setTempInsetBounds(tempInsetBounds);
-        setBounds(mTmpRect2, false /* forced */);
+        if (tempInsetBounds == null || tempInsetBounds.isEmpty()) {
+            setOverrideDisplayedBounds(null);
+            setBounds(mTmpRect2);
+        } else {
+            setOverrideDisplayedBounds(mTmpRect2);
+            setBounds(tempInsetBounds);
+        }
     }
 
     /** Return true if the current bound can get outputted to the rest of the system as-is. */
@@ -407,6 +412,15 @@
         mStack.getDisplayContent().getBounds(out);
     }
 
+    @Override
+    public Rect getDisplayedBounds() {
+        if (mOverrideDisplayedBounds.isEmpty()) {
+            return super.getDisplayedBounds();
+        } else {
+            return mOverrideDisplayedBounds;
+        }
+    }
+
     /**
      * Calculate the maximum visible area of this task. If the task has only one app,
      * the result will be visible frame of that app. If the task has more than one apps,
@@ -723,7 +737,7 @@
         }
         proto.write(FILLS_PARENT, matchParentBounds());
         getBounds().writeToProto(proto, BOUNDS);
-        mTempInsetBounds.writeToProto(proto, TEMP_INSET_BOUNDS);
+        mOverrideDisplayedBounds.writeToProto(proto, DISPLAYED_BOUNDS);
         proto.write(DEFER_REMOVAL, mDeferRemoval);
         proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth());
         proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight());
@@ -739,7 +753,7 @@
         pw.println(doublePrefix + "mBounds=" + getBounds().toShortString());
         pw.println(doublePrefix + "mdr=" + mDeferRemoval);
         pw.println(doublePrefix + "appTokens=" + mChildren);
-        pw.println(doublePrefix + "mTempInsetBounds=" + mTempInsetBounds.toShortString());
+        pw.println(doublePrefix + "mDisplayedBounds=" + mOverrideDisplayedBounds.toShortString());
 
         final String triplePrefix = doublePrefix + "  ";
         final String quadruplePrefix = triplePrefix + "  ";
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 30751bc..3cf0bd7 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -310,6 +310,11 @@
     // This number will be assigned when we evaluate OOM scores for all visible tasks.
     int mLayerRank = -1;
 
+    // When non-empty, this represents the bounds this task will be drawn at. This gets set during
+    // transient operations such as split-divider dragging and animations.
+    // TODO(b/119687367): This member is temporary.
+    final Rect mDisplayedBounds = new Rect();
+
     /** Helper object used for updating override configuration. */
     private Configuration mTmpConfig = new Configuration();
 
@@ -447,6 +452,9 @@
         }
 
         mWindowContainerController = controller;
+        if (!mDisplayedBounds.isEmpty() && controller.mContainer != null) {
+            controller.mContainer.setOverrideDisplayedBounds(mDisplayedBounds);
+        }
     }
 
     void removeWindowContainer() {
@@ -1732,9 +1740,15 @@
         final Configuration newOverrideConfig = new Configuration();
         if (bounds != null) {
             newOverrideConfig.setTo(getOverrideConfiguration());
-            mTmpRect.set(bounds);
+            if (insetBounds != null && !insetBounds.isEmpty()) {
+                mTmpRect.set(insetBounds);
+                setDisplayedBounds(bounds);
+            } else {
+                mTmpRect.set(bounds);
+                setDisplayedBounds(null);
+            }
             adjustForMinimalTaskDimensions(mTmpRect);
-            computeOverrideConfiguration(newOverrideConfig, mTmpRect, insetBounds,
+            computeOverrideConfiguration(newOverrideConfig, mTmpRect,
                     mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
         }
 
@@ -1782,16 +1796,23 @@
                 setLastNonFullscreenBounds(currentBounds);
             }
             setBounds(null);
+            setDisplayedBounds(null);
             newConfig.unset();
         } else {
-            mTmpRect.set(bounds);
+            if (insetBounds != null && !insetBounds.isEmpty()) {
+                mTmpRect.set(insetBounds);
+                setDisplayedBounds(bounds);
+            } else {
+                mTmpRect.set(bounds);
+                setDisplayedBounds(null);
+            }
             adjustForMinimalTaskDimensions(mTmpRect);
             setBounds(mTmpRect);
 
             if (mStack == null || persistBounds) {
                 setLastNonFullscreenBounds(getOverrideBounds());
             }
-            computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
+            computeOverrideConfiguration(newConfig, mTmpRect,
                     mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
         }
         onOverrideConfigurationChanged(newConfig);
@@ -1847,11 +1868,44 @@
         mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
     }
 
+    /**
+     * Displayed bounds are used to set where the task is drawn at any given time. This is
+     * separate from its actual bounds so that the app doesn't see any meaningful configuration
+     * changes during transitionary periods.
+     */
+    void setDisplayedBounds(Rect bounds) {
+        if (bounds == null) {
+            mDisplayedBounds.setEmpty();
+        } else {
+            mDisplayedBounds.set(bounds);
+        }
+        final TaskWindowContainerController controller = getWindowContainerController();
+        if (controller != null && controller.mContainer != null) {
+            controller.mContainer.setOverrideDisplayedBounds(
+                    mDisplayedBounds.isEmpty() ? null : mDisplayedBounds);
+        }
+    }
+
+    /**
+     * Gets the current overridden displayed bounds. These will be empty if the task is not
+     * currently overriding where it is displayed.
+     */
+    Rect getDisplayedBounds() {
+        return mDisplayedBounds;
+    }
+
+    /**
+     * @return {@code true} if this has overridden displayed bounds.
+     */
+    boolean hasDisplayedBounds() {
+        return !mDisplayedBounds.isEmpty();
+    }
+
     /** Clears passed config and fills it with new override values. */
     // TODO(b/36505427): TaskRecord.computeOverrideConfiguration() is a utility method that doesn't
     // depend on task or stacks, but uses those object to get the display to base the calculation
     // on. Probably best to centralize calculations like this in ConfigurationContainer.
-    void computeOverrideConfiguration(Configuration config, Rect bounds, Rect insetBounds,
+    void computeOverrideConfiguration(Configuration config, Rect bounds,
             boolean overrideWidth, boolean overrideHeight) {
         mTmpNonDecorBounds.set(bounds);
         mTmpStableBounds.set(bounds);
@@ -1863,7 +1917,7 @@
 
         if (mStack != null) {
             final StackWindowController stackController = mStack.getWindowContainerController();
-            stackController.adjustConfigurationForBounds(bounds, insetBounds,
+            stackController.adjustConfigurationForBounds(bounds,
                     mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
                     config, parentConfig, getWindowingMode());
         } else {
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index b1f95f8..b16e184c 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -184,9 +184,15 @@
         // Update bounds of containing tasks.
         for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
             final Task task = mChildren.get(taskNdx);
-            task.setBounds(taskBounds.get(task.mTaskId), false /* forced */);
-            task.setTempInsetBounds(taskTempInsetBounds != null ?
-                    taskTempInsetBounds.get(task.mTaskId) : null);
+            final Rect insetBounds =
+                    taskTempInsetBounds != null ? taskTempInsetBounds.get(task.mTaskId) : null;
+            if (insetBounds != null) {
+                task.setBounds(insetBounds);
+                task.setOverrideDisplayedBounds(taskBounds.get(task.mTaskId));
+            } else {
+                task.setBounds(taskBounds.get(task.mTaskId));
+                task.setOverrideDisplayedBounds(null);
+            }
         }
         return true;
     }
@@ -739,7 +745,7 @@
             return;
         }
 
-        final Rect stackBounds = getBounds();
+        final Rect stackBounds = getDisplayedBounds();
         int width = stackBounds.width();
         int height = stackBounds.height();
 
@@ -1754,14 +1760,6 @@
         scheduleAnimation();
     }
 
-    @Override
-    void getRelativePosition(Point outPos) {
-        super.getRelativePosition(outPos);
-        final int outset = getStackOutset();
-        outPos.x -= outset;
-        outPos.y -= outset;
-    }
-
     AnimatingAppWindowTokenRegistry getAnimatingAppWindowTokenRegistry() {
         return mAnimatingAppWindowTokenRegistry;
     }
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 1275ca0..c30cc17 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1266,7 +1266,7 @@
             return;
         }
 
-        getRelativePosition(mTmpPos);
+        getRelativeDisplayedPosition(mTmpPos);
         if (mTmpPos.equals(mLastSurfacePosition)) {
             return;
         }
@@ -1275,12 +1275,22 @@
         mLastSurfacePosition.set(mTmpPos.x, mTmpPos.y);
     }
 
-    void getRelativePosition(Point outPos) {
-        final Rect bounds = getBounds();
-        outPos.set(bounds.left, bounds.top);
+    /**
+     * Displayed bounds specify where to display this container at. It differs from bounds during
+     * certain operations (like animation or interactive dragging).
+     *
+     * @return the bounds to display this container at.
+     */
+    Rect getDisplayedBounds() {
+        return getBounds();
+    }
+
+    void getRelativeDisplayedPosition(Point outPos) {
+        final Rect dispBounds = getDisplayedBounds();
+        outPos.set(dispBounds.left, dispBounds.top);
         final WindowContainer parent = getParent();
         if (parent != null) {
-            final Rect parentBounds = parent.getBounds();
+            final Rect parentBounds = parent.getDisplayedBounds();
             outPos.offset(-parentBounds.left, -parentBounds.top);
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index e83b863..9f1a587 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ClipData;
-import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.display.DisplayManagerInternal;
@@ -449,11 +448,4 @@
      * Return the display Id for given window.
      */
     public abstract int getDisplayIdForWindow(IBinder windowToken);
-
-    // TODO: use WindowProcessController once go/wm-unified is done.
-    /**
-     * Notifies the window manager that configuration of the process associated with the input pid
-     * changed.
-     */
-    public abstract void onProcessConfigurationChanged(int pid, Configuration newConfig);
 }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 52b24b3..002d6d4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -735,6 +735,7 @@
     final InputManagerService mInputManager;
     final DisplayManagerInternal mDisplayManagerInternal;
     final DisplayManager mDisplayManager;
+    final ActivityTaskManagerService mAtmService;
 
     // Indicates whether this device supports wide color gamut / HDR rendering
     private boolean mHasWideColorGamutSupport;
@@ -897,11 +898,10 @@
 
     public static WindowManagerService main(final Context context, final InputManagerService im,
             final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
-            final WindowManagerGlobalLock globalLock) {
+            ActivityTaskManagerService atm) {
         DisplayThread.getHandler().runWithScissors(() ->
                 sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
-                        globalLock),
-                0);
+                        atm), 0);
         return sInstance;
     }
 
@@ -923,9 +923,10 @@
 
     private WindowManagerService(Context context, InputManagerService inputManager,
             boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
-            WindowManagerGlobalLock globalLock) {
+            ActivityTaskManagerService atm) {
         installLock(this, INDEX_WINDOW);
-        mGlobalLock = globalLock;
+        mGlobalLock = atm.getGlobalLock();
+        mAtmService = atm;
         mContext = context;
         mAllowBootMessages = showBootMsgs;
         mOnlyCore = onlyCore;
@@ -7281,19 +7282,6 @@
                 return Display.INVALID_DISPLAY;
             }
         }
-
-        @Override
-        public void onProcessConfigurationChanged(int pid, Configuration newConfig) {
-            synchronized (mGlobalLock) {
-                Configuration currentConfig = mProcessConfigurations.get(pid);
-                if (currentConfig == null) {
-                    currentConfig = new Configuration(newConfig);
-                } else {
-                    currentConfig.setTo(newConfig);
-                }
-                mProcessConfigurations.put(pid, currentConfig);
-            }
-        }
     }
 
     void registerAppFreezeListener(AppFreezeListener listener) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 2d47e54..e115fed 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -790,6 +790,18 @@
     }
 
     @Override
+    public Rect getDisplayedBounds() {
+        final Task task = getTask();
+        if (task != null) {
+            Rect bounds = task.getOverrideDisplayedBounds();
+            if (!bounds.isEmpty()) {
+                return bounds;
+            }
+        }
+        return super.getDisplayedBounds();
+    }
+
+    @Override
     public void computeFrameLw() {
         if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
             // This window is being replaced and either already got information that it's being
@@ -805,16 +817,7 @@
         final boolean windowsAreFloating = task != null && task.isFloating();
         final DisplayContent dc = getDisplayContent();
 
-        // If the task has temp inset bounds set, we have to make sure all its windows uses
-        // the temp inset frame. Otherwise different display frames get applied to the main
-        // window and the child window, making them misaligned.
-        // Otherwise we need to clear the inset frame, to avoid using a stale frame after leaving
-        // multi window mode.
-        if (task != null && isInMultiWindowMode()) {
-            task.getTempInsetBounds(mInsetFrame);
-        } else {
-            mInsetFrame.setEmpty();
-        }
+        mInsetFrame.set(getBounds());
 
         // Denotes the actual frame used to calculate the insets and to perform the layout. When
         // resizing in docked mode, we'd like to freeze the layout, so we also need to freeze the
@@ -834,7 +837,7 @@
             layoutXDiff = 0;
             layoutYDiff = 0;
         } else {
-            getBounds(mWindowFrames.mContainingFrame);
+            mWindowFrames.mContainingFrame.set(getDisplayedBounds());
             if (mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) {
 
                 // If the bounds are frozen, we still want to translate the window freely and only
@@ -884,14 +887,9 @@
 
             layoutDisplayFrame = new Rect(mWindowFrames.mDisplayFrame);
             mWindowFrames.mDisplayFrame.set(mWindowFrames.mContainingFrame);
-            layoutXDiff =
-                    !mInsetFrame.isEmpty() ? mInsetFrame.left - mWindowFrames.mContainingFrame.left
-                            : 0;
-            layoutYDiff =
-                    !mInsetFrame.isEmpty() ? mInsetFrame.top - mWindowFrames.mContainingFrame.top
-                            : 0;
-            layoutContainingFrame =
-                    !mInsetFrame.isEmpty() ? mInsetFrame : mWindowFrames.mContainingFrame;
+            layoutXDiff = mInsetFrame.left - mWindowFrames.mContainingFrame.left;
+            layoutYDiff = mInsetFrame.top - mWindowFrames.mContainingFrame.top;
+            layoutContainingFrame = mInsetFrame;
             mTmpRect.set(0, 0, dc.getDisplayInfo().logicalWidth, dc.getDisplayInfo().logicalHeight);
             subtractInsets(mWindowFrames.mDisplayFrame, layoutContainingFrame, layoutDisplayFrame,
                     mTmpRect);
@@ -2176,9 +2174,6 @@
             getTouchableRegion(region, true /* forSurface */);
         }
 
-        // The area containing the shadows is not touchable.
-        region.translate(mAttrs.surfaceInsets.left, mAttrs.surfaceInsets.top);
-
         return flags;
     }
 
@@ -2268,8 +2263,10 @@
         // For child windows we want to use the pid for the parent window in case the the child
         // window was added from another process.
         final int pid = getParentWindow() != null ? getParentWindow().mSession.mPid : mSession.mPid;
-        mTempConfiguration.setTo(mWmService.mProcessConfigurations.get(
-                pid, mWmService.mRoot.getConfiguration()));
+        final Configuration processConfig =
+                mWmService.mAtmService.getGlobalConfigurationForPid(pid);
+        mTempConfiguration.setTo(processConfig == null
+                ? mWmService.mRoot.getConfiguration() : processConfig);
         return mTempConfiguration;
     }
 
@@ -2982,6 +2979,17 @@
         }
     }
 
+    void notifyInsetsControlChanged() {
+        final InsetsStateController stateController =
+                getDisplayContent().getInsetsStateController();
+        try {
+            mClient.insetsControlChanged(stateController.getInsetsForDispatch(this),
+                    stateController.getControlsForDispatch(this));
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed to deliver inset state change", e);
+        }
+    }
+
     Rect getBackdropFrame(Rect frame) {
         // When the task is docked, we send fullscreen sized backDropFrame as soon as resizing
         // start even if we haven't received the relayout window, so that the client requests
@@ -4613,7 +4621,7 @@
             outPoint.offset(-parent.mWindowFrames.mFrame.left + parent.mAttrs.surfaceInsets.left,
                     -parent.mWindowFrames.mFrame.top + parent.mAttrs.surfaceInsets.top);
         } else if (parentWindowContainer != null) {
-            final Rect parentBounds = parentWindowContainer.getBounds();
+            final Rect parentBounds = parentWindowContainer.getDisplayedBounds();
             outPoint.offset(-parentBounds.left, -parentBounds.top);
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 8bc6db7..fb5c556 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1020,7 +1020,7 @@
                         mTmpPos.x = 0;
                         mTmpPos.y = 0;
                         if (stack != null) {
-                            stack.getRelativePosition(mTmpPos);
+                            stack.getRelativeDisplayedPosition(mTmpPos);
                         }
 
                         xOffset = -mTmpPos.x;
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 8b873e3..b85489a 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -2,8 +2,6 @@
     name: "libservices.core",
     defaults: ["libservices.core-libs"],
 
-    cpp_std: "c++17",
-
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index b9dabb9..65d3245 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -120,4 +120,9 @@
             int userHandle) {
         return false;
     }
+
+    @Override
+    public List<String> getCrossProfileCalendarPackagesForUser(int userHandle) {
+        return Collections.emptyList();
+    }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 6fbb850..f68f4d7 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -13426,10 +13426,25 @@
         enforceCrossUsersPermission(userHandle);
         synchronized (getLockObject()) {
             final ActiveAdmin admin = getProfileOwnerAdminLocked(userHandle);
-            if (admin != null && admin.mCrossProfileCalendarPackages != null) {
+            if (admin != null) {
                 return admin.mCrossProfileCalendarPackages.contains(packageName);
             }
         }
         return false;
     }
+
+    @Override
+    public List<String> getCrossProfileCalendarPackagesForUser(int userHandle) {
+        if (!mHasFeature) {
+            return Collections.emptyList();
+        }
+        enforceCrossUsersPermission(userHandle);
+        synchronized (getLockObject()) {
+            final ActiveAdmin admin = getProfileOwnerAdminLocked(userHandle);
+            if (admin != null) {
+                return new ArrayList<String>(admin.mCrossProfileCalendarPackages);
+            }
+        }
+        return Collections.emptyList();
+    }
 }
diff --git a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
index 108f91c..8aab7a9 100644
--- a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
+++ b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
@@ -16,6 +16,7 @@
 package com.android.server.intelligence;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.IBinder;
@@ -25,6 +26,7 @@
 import android.service.intelligence.SnapshotData;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 import android.view.intelligence.ContentCaptureEvent;
 
@@ -98,8 +100,10 @@
      * Requests the service to autofill the given field.
      */
     public AugmentedAutofillCallback requestAutofillLocked(@NonNull IAutoFillManagerClient client,
-            int autofillSessionId, @NonNull AutofillId focusedId) {
-        mRemoteService.onRequestAutofillLocked(mId, client, autofillSessionId, focusedId);
+            int autofillSessionId, @NonNull AutofillId focusedId,
+            @Nullable AutofillValue focusedValue) {
+        mRemoteService.onRequestAutofillLocked(mId, client, autofillSessionId, focusedId,
+                focusedValue);
         if (mAutofillCallback == null) {
             mAutofillCallback = () -> mRemoteService.onDestroyAutofillWindowsRequest(mId);
         }
@@ -146,7 +150,7 @@
     }
 
     @Override // from RemoteScreenObservationServiceCallbacks
-    public void onServiceDied(AbstractRemoteService service) {
+    public void onServiceDied(AbstractRemoteService<?> service) {
         // TODO(b/111276913): implement (remove session from PerUserSession?)
         if (mService.isDebug()) {
             Slog.d(TAG, "onServiceDied() for " + mId);
@@ -176,6 +180,10 @@
         pw.println(mAutofillCallback != null);
     }
 
+    String toShortString() {
+        return mId.getValue() + ":" + mActivityToken;
+    }
+
     @Override
     public String toString() {
         return "ContentCaptureSession[id=" + mId.getValue() + ", act=" + mActivityToken + "]";
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
index e0d47d2..e621fef 100644
--- a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.intelligence;
 
+import static android.Manifest.permission.MANAGE_SMART_SUGGESTIONS;
 import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
 
 import android.annotation.NonNull;
@@ -26,9 +27,15 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.UserHandle;
 import android.os.UserManager;
 import android.service.intelligence.InteractionSessionId;
+import android.util.Slog;
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 import android.view.intelligence.ContentCaptureEvent;
 import android.view.intelligence.IIntelligenceManager;
@@ -42,6 +49,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -56,6 +64,10 @@
 
     private static final String TAG = "IntelligenceManagerService";
 
+    static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions";
+
+    private static final int MAX_TEMP_SERVICE_DURATION_MS = 1_000 * 60 * 2; // 2 minutes
+
     @GuardedBy("mLock")
     private ActivityManagerInternal mAm;
 
@@ -66,12 +78,6 @@
     }
 
     @Override // from AbstractMasterSystemService
-    protected String getServiceSettingsProperty() {
-        // TODO(b/111276913): STOPSHIP temporary settings, until it's set by resourcs + cmd
-        return "smart_suggestions_service";
-    }
-
-    @Override // from AbstractMasterSystemService
     protected IntelligencePerUserService newServiceLocked(@UserIdInt int resolvedUserId,
             boolean disabled) {
         return new IntelligencePerUserService(this, mLock, resolvedUserId);
@@ -90,6 +96,66 @@
         service.destroyLocked();
     }
 
+    @Override // from AbstractMasterSystemService
+    protected void enforceCallingPermissionForManagement() {
+        getContext().enforceCallingPermission(MANAGE_SMART_SUGGESTIONS, TAG);
+    }
+
+    @Override // from AbstractMasterSystemService
+    protected int getMaximumTemporaryServiceDurationMs() {
+        return MAX_TEMP_SERVICE_DURATION_MS;
+    }
+
+    // Called by Shell command.
+    void destroySessions(@UserIdInt int userId, @NonNull IResultReceiver receiver) {
+        Slog.i(TAG, "destroySessions() for userId " + userId);
+        enforceCallingPermissionForManagement();
+
+        synchronized (mLock) {
+            if (userId != UserHandle.USER_ALL) {
+                final IntelligencePerUserService service = peekServiceForUserLocked(userId);
+                if (service != null) {
+                    service.destroySessionsLocked();
+                }
+            } else {
+                visitServicesLocked((s) -> s.destroySessionsLocked());
+            }
+        }
+
+        try {
+            receiver.send(0, new Bundle());
+        } catch (RemoteException e) {
+            // Just ignore it...
+        }
+    }
+
+    // Called by Shell command.
+    void listSessions(int userId, IResultReceiver receiver) {
+        Slog.i(TAG, "listSessions() for userId " + userId);
+        enforceCallingPermissionForManagement();
+
+        final Bundle resultData = new Bundle();
+        final ArrayList<String> sessions = new ArrayList<>();
+
+        synchronized (mLock) {
+            if (userId != UserHandle.USER_ALL) {
+                final IntelligencePerUserService service = peekServiceForUserLocked(userId);
+                if (service != null) {
+                    service.listSessionsLocked(sessions);
+                }
+            } else {
+                visitServicesLocked((s) -> s.listSessionsLocked(sessions));
+            }
+        }
+
+        resultData.putStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS, sessions);
+        try {
+            receiver.send(0, resultData);
+        } catch (RemoteException e) {
+            // Just ignore it...
+        }
+    }
+
     private ActivityManagerInternal getAmInternal() {
         synchronized (mLock) {
             if (mAm == null) {
@@ -119,7 +185,7 @@
             synchronized (mLock) {
                 final IntelligencePerUserService service = getServiceForUserLocked(userId);
                 service.startSessionLocked(activityToken, componentName, taskId, displayId,
-                        sessionId, flags, result);
+                        sessionId, flags, mAllowInstantService, result);
             }
         }
 
@@ -154,6 +220,14 @@
                 dumpLocked("", pw);
             }
         }
+
+        @Override
+        public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+                String[] args, ShellCallback callback, ResultReceiver resultReceiver)
+                throws RemoteException {
+            new IntelligenceServiceShellCommand(IntelligenceManagerService.this).exec(
+                    this, in, out, err, args, callback, resultReceiver);
+        }
     }
 
     private final class LocalService extends IntelligenceManagerInternal {
@@ -184,12 +258,13 @@
         @Override
         public AugmentedAutofillCallback requestAutofill(@UserIdInt int userId,
                 @NonNull IAutoFillManagerClient client, @NonNull IBinder activityToken,
-                int autofillSessionId, @NonNull AutofillId focusedId) {
+                int autofillSessionId, @NonNull AutofillId focusedId,
+                @Nullable AutofillValue focusedValue) {
             synchronized (mLock) {
                 final IntelligencePerUserService service = peekServiceForUserLocked(userId);
                 if (service != null) {
                     return service.requestAutofill(client, activityToken, autofillSessionId,
-                            focusedId);
+                            focusedId, focusedValue);
                 }
             }
             return null;
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
index 84e06b0..ffcce9f 100644
--- a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
@@ -36,9 +36,11 @@
 import android.os.RemoteException;
 import android.service.intelligence.InteractionSessionId;
 import android.service.intelligence.SnapshotData;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 import android.view.intelligence.ContentCaptureEvent;
 import android.view.intelligence.ContentCaptureManager;
@@ -49,6 +51,7 @@
 import com.android.server.intelligence.IntelligenceManagerInternal.AugmentedAutofillCallback;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -76,17 +79,24 @@
     protected ServiceInfo newServiceInfo(@NonNull ComponentName serviceComponent)
             throws NameNotFoundException {
 
+        int flags = PackageManager.GET_META_DATA;
+        final boolean isTemp = isTemporaryServiceSetLocked();
+        if (!isTemp) {
+            flags |= PackageManager.MATCH_SYSTEM_ONLY;
+        }
+
         ServiceInfo si;
         try {
-            // TODO(b/111276913): must check that either the service is from a system component,
-            // or it matches a service set by shell cmd (so it can be used on CTS tests and when
-            // OEMs are implementing the real service
-            si = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
-                    PackageManager.GET_META_DATA, mUserId);
+            si = AppGlobals.getPackageManager().getServiceInfo(serviceComponent, flags, mUserId);
         } catch (RemoteException e) {
             Slog.w(TAG, "Could not get service for " + serviceComponent + ": " + e);
             return null;
         }
+        if (si == null) {
+            Slog.w(TAG, "Could not get serviceInfo for " + (isTemp ? " (temp)" : "(default system)")
+                    + " " + serviceComponent.flattenToShortString());
+            return null;
+        }
         if (!Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE.equals(si.permission)) {
             Slog.w(TAG, "SmartSuggestionsService from '" + si.packageName
                     + "' does not require permission "
@@ -104,11 +114,18 @@
         return super.updateLocked(disabled);
     }
 
+    @Override // from PerUserSystemService
+    protected String getDefaultComponentName() {
+        final String name = getContext()
+                .getString(com.android.internal.R.string.config_defaultSmartSuggestionsService);
+        return TextUtils.isEmpty(name) ? null : name;
+    }
+
     // TODO(b/111276913): log metrics
     @GuardedBy("mLock")
     public void startSessionLocked(@NonNull IBinder activityToken,
             @NonNull ComponentName componentName, int taskId, int displayId,
-            @NonNull InteractionSessionId sessionId, int flags,
+            @NonNull InteractionSessionId sessionId, int flags, boolean bindInstantServiceAllowed,
             @NonNull IResultReceiver resultReceiver) {
         if (!isEnabledLocked()) {
             sendToClient(resultReceiver, ContentCaptureManager.STATE_DISABLED);
@@ -138,9 +155,6 @@
             return;
         }
 
-        // TODO(b/117779333): get from mMaster once it's moved to superclass
-        final boolean bindInstantServiceAllowed = false;
-
         session = new ContentCaptureSession(getContext(), mUserId, mLock, activityToken,
                 this, serviceComponentName, componentName, taskId, displayId, sessionId, flags,
                 bindInstantServiceAllowed, mMaster.verbose);
@@ -200,7 +214,7 @@
             return;
         }
         if (mMaster.verbose) {
-            Slog.v(TAG, "sendEvents(): id=" + sessionId + "; events =" + events.size());
+            Slog.v(TAG, "sendEvents(): id=" + sessionId + ", events=" + events.size());
         }
         session.sendEventsLocked(events);
     }
@@ -253,6 +267,11 @@
     @GuardedBy("mLock")
     public void destroyLocked() {
         if (mMaster.debug) Slog.d(TAG, "destroyLocked()");
+        destroySessionsLocked();
+    }
+
+    @GuardedBy("mLock")
+    void destroySessionsLocked() {
         final int numSessions = mSessions.size();
         for (int i = 0; i < numSessions; i++) {
             final ContentCaptureSession session = mSessions.valueAt(i);
@@ -261,14 +280,25 @@
         mSessions.clear();
     }
 
+    @GuardedBy("mLock")
+    void listSessionsLocked(ArrayList<String> output) {
+        final int numSessions = mSessions.size();
+        for (int i = 0; i < numSessions; i++) {
+            final ContentCaptureSession session = mSessions.valueAt(i);
+            output.add(session.toShortString());
+        }
+    }
+
     public AugmentedAutofillCallback requestAutofill(@NonNull IAutoFillManagerClient client,
-            @NonNull IBinder activityToken, int autofillSessionId, @NonNull AutofillId focusedId) {
+            @NonNull IBinder activityToken, int autofillSessionId, @NonNull AutofillId focusedId,
+            @Nullable AutofillValue focusedValue) {
         synchronized (mLock) {
             final ContentCaptureSession session = getSession(activityToken);
             if (session != null) {
                 // TODO(b/111330312): log metrics
                 if (mMaster.verbose) Slog.v(TAG, "requestAugmentedAutofill()");
-                return session.requestAutofillLocked(client, autofillSessionId, focusedId);
+                return session.requestAutofillLocked(client, autofillSessionId, focusedId,
+                        focusedValue);
             }
             if (mMaster.debug) {
                 Slog.d(TAG, "requestAutofill(): no session for " + activityToken);
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligenceServiceShellCommand.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceServiceShellCommand.java
new file mode 100644
index 0000000..0d92a97
--- /dev/null
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceServiceShellCommand.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2018 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.intelligence;
+
+import static com.android.server.intelligence.IntelligenceManagerService.RECEIVER_BUNDLE_EXTRA_SESSIONS;
+
+import android.annotation.NonNull;
+import android.os.Bundle;
+import android.os.ShellCommand;
+import android.os.UserHandle;
+
+import com.android.internal.os.IResultReceiver;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Shell Command implementation for {@link IntelligenceManagerService}.
+ */
+//TODO(b/111276913): rename once the final name is defined
+public final class IntelligenceServiceShellCommand extends ShellCommand {
+
+    private final IntelligenceManagerService mService;
+
+    public IntelligenceServiceShellCommand(@NonNull IntelligenceManagerService service) {
+        mService = service;
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        if (cmd == null) {
+            return handleDefaultCommands(cmd);
+        }
+        final PrintWriter pw = getOutPrintWriter();
+        switch (cmd) {
+            case "list":
+                return requestList(pw);
+            case "destroy":
+                return requestDestroy(pw);
+            case "get":
+                return requestGet(pw);
+            case "set":
+                return requestSet(pw);
+            default:
+                return handleDefaultCommands(cmd);
+        }
+    }
+
+    @Override
+    public void onHelp() {
+        try (PrintWriter pw = getOutPrintWriter();) {
+            // TODO(b/111276913): rename "intelligence" once SELinux rule changed
+            pw.println("Intelligence Service (intelligence) commands:");
+            pw.println("  help");
+            pw.println("    Prints this help text.");
+            pw.println("");
+            pw.println("  get bind-instant-service-allowed");
+            pw.println("    Gets whether binding to services provided by instant apps is allowed");
+            pw.println("");
+            pw.println("  set bind-instant-service-allowed [true | false]");
+            pw.println("    Sets whether binding to services provided by instant apps is allowed");
+            pw.println("");
+            pw.println("  set temporary-service USER_ID [COMPONENT_NAME DURATION]");
+            pw.println("    Temporarily (for DURATION ms) changes the service implemtation.");
+            pw.println("    To reset, call with just the USER_ID argument.");
+            pw.println("");
+            pw.println("  list sessions [--user USER_ID]");
+            pw.println("    Lists all pending sessions.");
+            pw.println("");
+            pw.println("  destroy sessions [--user USER_ID]");
+            pw.println("    Destroys all pending sessions.");
+            pw.println("");
+        }
+    }
+
+    private int requestGet(PrintWriter pw) {
+        final String what = getNextArgRequired();
+        switch(what) {
+            case "bind-instant-service-allowed":
+                return getBindInstantService(pw);
+            default:
+                pw.println("Invalid set: " + what);
+                return -1;
+        }
+    }
+
+    private int requestSet(PrintWriter pw) {
+        final String what = getNextArgRequired();
+
+        switch(what) {
+            case "bind-instant-service-allowed":
+                return setBindInstantService(pw);
+            case "temporary-service":
+                return setTemporaryService();
+            default:
+                pw.println("Invalid set: " + what);
+                return -1;
+        }
+    }
+
+    private int getBindInstantService(PrintWriter pw) {
+        if (mService.getAllowInstantService()) {
+            pw.println("true");
+        } else {
+            pw.println("false");
+        }
+        return 0;
+    }
+
+    private int setBindInstantService(PrintWriter pw) {
+        final String mode = getNextArgRequired();
+        switch (mode.toLowerCase()) {
+            case "true":
+                mService.setAllowInstantService(true);
+                return 0;
+            case "false":
+                mService.setAllowInstantService(false);
+                return 0;
+            default:
+                pw.println("Invalid mode: " + mode);
+                return -1;
+        }
+    }
+
+    private int setTemporaryService() {
+        final int userId = getNextIntArgRequired();
+        final String serviceName = getNextArg();
+        if (serviceName == null) {
+            mService.resetTemporaryService(userId);
+            return 0;
+        }
+        final int duration = getNextIntArgRequired();
+        mService.setTemporaryService(userId, serviceName, duration);
+        return 0;
+    }
+
+    private int requestDestroy(PrintWriter pw) {
+        if (!isNextArgSessions(pw)) {
+            return -1;
+        }
+
+        final int userId = getUserIdFromArgsOrAllUsers();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final IResultReceiver receiver = new IResultReceiver.Stub() {
+            @Override
+            public void send(int resultCode, Bundle resultData) {
+                latch.countDown();
+            }
+        };
+        return requestSessionCommon(pw, latch, () -> mService.destroySessions(userId, receiver));
+    }
+
+    private int requestList(PrintWriter pw) {
+        if (!isNextArgSessions(pw)) {
+            return -1;
+        }
+
+        final int userId = getUserIdFromArgsOrAllUsers();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final IResultReceiver receiver = new IResultReceiver.Stub() {
+            @Override
+            public void send(int resultCode, Bundle resultData) {
+                final ArrayList<String> sessions = resultData
+                        .getStringArrayList(RECEIVER_BUNDLE_EXTRA_SESSIONS);
+                for (String session : sessions) {
+                    pw.println(session);
+                }
+                latch.countDown();
+            }
+        };
+        return requestSessionCommon(pw, latch, () -> mService.listSessions(userId, receiver));
+    }
+
+    private boolean isNextArgSessions(PrintWriter pw) {
+        final String type = getNextArgRequired();
+        if (!type.equals("sessions")) {
+            pw.println("Error: invalid list type");
+            return false;
+        }
+        return true;
+    }
+
+    private int requestSessionCommon(PrintWriter pw, CountDownLatch latch,
+            Runnable command) {
+        command.run();
+        return waitForLatch(pw, latch);
+    }
+
+    private int waitForLatch(PrintWriter pw, CountDownLatch latch) {
+        try {
+            final boolean received = latch.await(5, TimeUnit.SECONDS);
+            if (!received) {
+                pw.println("Timed out after 5 seconds");
+                return -1;
+            }
+        } catch (InterruptedException e) {
+            pw.println("System call interrupted");
+            Thread.currentThread().interrupt();
+            return -1;
+        }
+        return 0;
+    }
+
+    private int getUserIdFromArgsOrAllUsers() {
+        if ("--user".equals(getNextArg())) {
+            return UserHandle.parseUserArg(getNextArgRequired());
+        }
+        return UserHandle.USER_ALL;
+    }
+
+    private int getNextIntArgRequired() {
+        return Integer.parseInt(getNextArgRequired());
+    }
+}
diff --git a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java
index 5ebb99e..d259369 100644
--- a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java
+++ b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java
@@ -23,6 +23,7 @@
 import android.os.IBinder;
 import android.os.IInterface;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.service.intelligence.ContentCaptureEventsRequest;
 import android.service.intelligence.IIntelligenceService;
 import android.service.intelligence.InteractionContext;
@@ -32,16 +33,18 @@
 import android.util.Slog;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
+import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 import android.view.intelligence.ContentCaptureEvent;
 
 import com.android.internal.os.IResultReceiver;
-import com.android.server.AbstractRemoteService;
+import com.android.server.AbstractMultiplePendingRequestsRemoteService;
 
 import java.util.List;
 
 //TODO(b/111276913): rename once the final name is defined
-final class RemoteIntelligenceService extends AbstractRemoteService {
+final class RemoteIntelligenceService
+        extends AbstractMultiplePendingRequestsRemoteService<RemoteIntelligenceService> {
 
     private static final String TAG = "RemoteIntelligenceService";
 
@@ -56,7 +59,7 @@
             RemoteIntelligenceServiceCallbacks callbacks, boolean bindInstantServiceAllowed,
             boolean verbose) {
         super(context, serviceInterface, componentName, userId, callbacks,
-                bindInstantServiceAllowed, verbose);
+                bindInstantServiceAllowed, verbose, /* initialCapacity= */ 2);
         mCallbacks = callbacks;
     }
 
@@ -113,10 +116,10 @@
      */
     public void onRequestAutofillLocked(@NonNull InteractionSessionId sessionId,
             @NonNull IAutoFillManagerClient client, int autofillSessionId,
-            @NonNull AutofillId focusedId) {
+            @NonNull AutofillId focusedId, @Nullable AutofillValue focusedValue) {
         cancelScheduledUnbind();
         scheduleRequest(new PendingAutofillRequest(this, sessionId, client, autofillSessionId,
-                focusedId));
+                focusedId, focusedValue));
     }
 
     /**
@@ -221,16 +224,20 @@
 
     private static final class PendingAutofillRequest extends MyPendingRequest {
         private final @NonNull AutofillId mFocusedId;
+        private final @Nullable AutofillValue mFocusedValue;
         private final @NonNull IAutoFillManagerClient mClient;
         private final int mAutofillSessionId;
+        private final long mRequestTime = SystemClock.elapsedRealtime();
 
         protected PendingAutofillRequest(@NonNull RemoteIntelligenceService service,
                 @NonNull InteractionSessionId sessionId, @NonNull IAutoFillManagerClient client,
-                int autofillSessionId, @NonNull AutofillId focusedId) {
+                int autofillSessionId, @NonNull AutofillId focusedId,
+                @Nullable AutofillValue focusedValue) {
             super(service, sessionId);
             mClient = client;
             mAutofillSessionId = autofillSessionId;
             mFocusedId = focusedId;
+            mFocusedValue = focusedValue;
         }
 
         @Override // from MyPendingRequest
@@ -242,7 +249,7 @@
                     final IBinder realClient = resultData
                             .getBinder(AutofillManager.EXTRA_AUGMENTED_AUTOFILL_CLIENT);
                     remoteService.mService.onAutofillRequest(mSessionId, realClient,
-                            mAutofillSessionId, mFocusedId);
+                            mAutofillSessionId, mFocusedId, mFocusedValue, mRequestTime);
                 }
             };
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 56f7cff..c4d2a91 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -22,6 +22,7 @@
 import static android.os.IServiceManager.DUMP_FLAG_PROTO;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import android.annotation.NonNull;
 import android.app.ActivityThread;
 import android.app.INotificationManager;
 import android.app.usage.UsageStatsManagerInternal;
@@ -55,6 +56,9 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.IStorageManager;
+import android.provider.Settings;
+import android.sysprop.VoldProperties;
+import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Slog;
@@ -120,6 +124,7 @@
 import com.android.server.role.RoleManagerService;
 import com.android.server.security.KeyAttestationApplicationIdProviderService;
 import com.android.server.security.KeyChainSystemService;
+import com.android.server.signedconfig.SignedConfigService;
 import com.android.server.soundtrigger.SoundTriggerService;
 import com.android.server.stats.StatsCompanionService;
 import com.android.server.statusbar.StatusBarManagerService;
@@ -654,7 +659,7 @@
         traceEnd();
 
         // Only run "core" apps if we're encrypting the device.
-        String cryptState = SystemProperties.get("vold.decrypt");
+        String cryptState = VoldProperties.decrypt().orElse("");
         if (ENCRYPTING_STATE.equals(cryptState)) {
             Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
             mOnlyCore = true;
@@ -796,10 +801,6 @@
         boolean disableSystemTextClassifier = SystemProperties.getBoolean(
                 "config.disable_systemtextclassifier", false);
 
-        //TODO(b/111276913): temporarily disabled until the manager is properly implemented to
-        // ignore events when disabled and buffer when enabled
-        boolean disableIntelligence = SystemProperties.getBoolean(
-                "config.disable_intelligence", true);
         boolean disableNetworkTime = SystemProperties.getBoolean("config.disable_networktime",
                 false);
         boolean disableCameraService = SystemProperties.getBoolean("config.disable_cameraservice",
@@ -925,7 +926,7 @@
             ConcurrentUtils.waitForFutureNoInterrupt(mSensorServiceStart, START_SENSOR_SERVICE);
             mSensorServiceStart = null;
             wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
-                    new PhoneWindowManager(), mWindowManagerGlobalLock);
+                    new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
             ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
                     DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
             ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
@@ -994,6 +995,11 @@
             traceBeginAndSlog("PinnerService");
             mSystemServiceManager.startService(PinnerService.class);
             traceEnd();
+
+            traceBeginAndSlog("SignedConfigService");
+            SignedConfigService.registerUpdateReceiver(mSystemContext);
+            traceEnd();
+
         } catch (RuntimeException e) {
             Slog.e("System", "******************************************");
             Slog.e("System", "************ Failure starting core service", e);
@@ -1130,13 +1136,7 @@
                 traceEnd();
             }
 
-            if (!disableIntelligence) {
-                traceBeginAndSlog("StartIntelligenceService");
-                mSystemServiceManager.startService(INTELLIGENCE_MANAGER_SERVICE_CLASS);
-                traceEnd();
-            } else {
-                Slog.d(TAG, "IntelligenceService disabled");
-            }
+            startIntelligenceService(context);
 
             // NOTE: ClipboardService indirectly depends on IntelligenceService
             traceBeginAndSlog("StartClipboardService");
@@ -1503,6 +1503,14 @@
             }
             traceEnd();
 
+            traceBeginAndSlog("RuntimeService");
+            try {
+                ServiceManager.addService("runtime", new RuntimeService(context));
+            } catch (Throwable e) {
+                reportWtf("starting RuntimeService", e);
+            }
+            traceEnd();
+
             // timezone.RulesManagerService will prevent a device starting up if the chain of trust
             // required for safe time zone updates might be broken. RuleManagerService cannot do
             // this check when mOnlyCore == true, so we don't enable the service in this case.
@@ -2092,6 +2100,37 @@
         }, BOOT_TIMINGS_TRACE_LOG);
     }
 
+    private void startIntelligenceService(@NonNull Context context) {
+
+        // First check if it was explicitly enabled by Settings
+        boolean explicitlySupported = false;
+        final String settings = Settings.Global.getString(context.getContentResolver(),
+                Settings.Global.SMART_SUGGESTIONS_SERVICE_EXPLICITLY_ENABLED);
+        if (settings != null) {
+            explicitlySupported = Boolean.parseBoolean(settings);
+            if (explicitlySupported) {
+                Slog.d(TAG, "IntelligenceService explicitly enabled by Settings");
+            } else {
+                Slog.d(TAG, "IntelligenceService explicitly disabled by Settings");
+                return;
+            }
+        }
+
+        // Then check if OEM overlaid the resource that defines the service.
+        if (!explicitlySupported) {
+            final String serviceName = context
+                    .getString(com.android.internal.R.string.config_defaultSmartSuggestionsService);
+            if (TextUtils.isEmpty(serviceName)) {
+                Slog.d(TAG, "IntelligenceService disabled because config resource is not overlaid");
+                return;
+            }
+        }
+
+        traceBeginAndSlog("StartIntelligenceService");
+        mSystemServiceManager.startService(INTELLIGENCE_MANAGER_SERVICE_CLASS);
+        traceEnd();
+    }
+
     static final void startSystemUi(Context context, WindowManagerService windowManager) {
         Intent intent = new Intent();
         intent.setComponent(new ComponentName("com.android.systemui",
diff --git a/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java b/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java
new file mode 100644
index 0000000..5342efa
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyManagerTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2018 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.backup.encryption.keys;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.RecoveryController;
+
+import com.android.server.testing.shadows.ShadowInternalRecoveryServiceException;
+import com.android.server.testing.shadows.ShadowRecoveryController;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.security.SecureRandom;
+import java.util.Optional;
+
+/** Tests for {@link RecoverableKeyStoreSecondaryKeyManager}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+@Config(shadows = {ShadowRecoveryController.class, ShadowInternalRecoveryServiceException.class})
+public class RecoverableKeyStoreSecondaryKeyManagerTest {
+    private static final String BACKUP_KEY_ALIAS_PREFIX =
+            "com.android.server.backup/recoverablekeystore/";
+    private static final int BITS_PER_BYTE = 8;
+    private static final int BACKUP_KEY_SUFFIX_LENGTH_BYTES = 128 / BITS_PER_BYTE;
+    private static final int HEX_PER_BYTE = 2;
+    private static final int BACKUP_KEY_ALIAS_LENGTH =
+            BACKUP_KEY_ALIAS_PREFIX.length() + BACKUP_KEY_SUFFIX_LENGTH_BYTES * HEX_PER_BYTE;
+    private static final String NONEXISTENT_KEY_ALIAS = "NONEXISTENT_KEY_ALIAS";
+
+    private RecoverableKeyStoreSecondaryKeyManager mRecoverableKeyStoreSecondaryKeyManager;
+    private Context mContext;
+
+    /** Create a new {@link RecoverableKeyStoreSecondaryKeyManager} to use in tests. */
+    @Before
+    public void setUp() throws Exception {
+        mContext = RuntimeEnvironment.application;
+
+        mRecoverableKeyStoreSecondaryKeyManager =
+                new RecoverableKeyStoreSecondaryKeyManager(
+                        RecoveryController.getInstance(mContext), new SecureRandom());
+    }
+
+    /** Reset the {@link ShadowRecoveryController}. */
+    @After
+    public void tearDown() throws Exception {
+        ShadowRecoveryController.reset();
+    }
+
+    /** The generated key should always have the prefix {@code BACKUP_KEY_ALIAS_PREFIX}. */
+    @Test
+    public void generate_generatesKeyWithExpectedPrefix() throws Exception {
+        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
+
+        assertThat(key.getAlias()).startsWith(BACKUP_KEY_ALIAS_PREFIX);
+    }
+
+    /** The generated key should always have length {@code BACKUP_KEY_ALIAS_LENGTH}. */
+    @Test
+    public void generate_generatesKeyWithExpectedLength() throws Exception {
+        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
+
+        assertThat(key.getAlias()).hasLength(BACKUP_KEY_ALIAS_LENGTH);
+    }
+
+    /** Ensure that hidden API exceptions are rethrown when generating keys. */
+    @Test
+    public void generate_encounteringHiddenApiException_rethrowsException() {
+        ShadowRecoveryController.setThrowsInternalError(true);
+
+        assertThrows(
+                InternalRecoveryServiceException.class,
+                mRecoverableKeyStoreSecondaryKeyManager::generate);
+    }
+
+    /** Ensure that retrieved keys correspond to those generated earlier. */
+    @Test
+    public void get_getsKeyGeneratedByController() throws Exception {
+        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
+
+        Optional<RecoverableKeyStoreSecondaryKey> retrievedKey =
+                mRecoverableKeyStoreSecondaryKeyManager.get(key.getAlias());
+
+        assertThat(retrievedKey.isPresent()).isTrue();
+        assertThat(retrievedKey.get().getAlias()).isEqualTo(key.getAlias());
+        assertThat(retrievedKey.get().getSecretKey()).isEqualTo(key.getSecretKey());
+    }
+
+    /**
+     * Ensure that a call to {@link RecoverableKeyStoreSecondaryKeyManager#get(java.lang.String)}
+     * for nonexistent aliases returns an emtpy {@link Optional}.
+     */
+    @Test
+    public void get_forNonExistentKey_returnsEmptyOptional() throws Exception {
+        Optional<RecoverableKeyStoreSecondaryKey> retrievedKey =
+                mRecoverableKeyStoreSecondaryKeyManager.get(NONEXISTENT_KEY_ALIAS);
+
+        assertThat(retrievedKey.isPresent()).isFalse();
+    }
+
+    /**
+     * Ensure that exceptions occurring during {@link
+     * RecoverableKeyStoreSecondaryKeyManager#get(java.lang.String)} are not rethrown.
+     */
+    @Test
+    public void get_encounteringInternalException_doesNotPropagateException() throws Exception {
+        ShadowRecoveryController.setThrowsInternalError(true);
+
+        // Should not throw exception
+        mRecoverableKeyStoreSecondaryKeyManager.get(NONEXISTENT_KEY_ALIAS);
+    }
+
+    /** Ensure that keys are correctly removed from the store. */
+    @Test
+    public void remove_removesKeyFromRecoverableStore() throws Exception {
+        RecoverableKeyStoreSecondaryKey key = mRecoverableKeyStoreSecondaryKeyManager.generate();
+
+        mRecoverableKeyStoreSecondaryKeyManager.remove(key.getAlias());
+
+        assertThat(RecoveryController.getInstance(mContext).getAliases())
+                .doesNotContain(key.getAlias());
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java b/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java
new file mode 100644
index 0000000..89977f8
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/keys/RecoverableKeyStoreSecondaryKeyTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2018 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.backup.encryption.keys;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+import android.security.keystore.recovery.RecoveryController;
+
+import com.android.server.backup.encryption.keys.RecoverableKeyStoreSecondaryKey.Status;
+import com.android.server.backup.testing.CryptoTestUtils;
+import com.android.server.testing.shadows.ShadowInternalRecoveryServiceException;
+import com.android.server.testing.shadows.ShadowRecoveryController;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import javax.crypto.SecretKey;
+
+/** Tests for {@link RecoverableKeyStoreSecondaryKey}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+@Config(shadows = {ShadowRecoveryController.class, ShadowInternalRecoveryServiceException.class})
+public class RecoverableKeyStoreSecondaryKeyTest {
+    private static final String TEST_ALIAS = "test";
+    private static final int NONEXISTENT_STATUS_CODE = 42;
+
+    private RecoverableKeyStoreSecondaryKey mSecondaryKey;
+    private SecretKey mGeneratedSecretKey;
+    private Context mContext;
+
+    /** Instantiate a {@link RecoverableKeyStoreSecondaryKey} to use in tests. */
+    @Before
+    public void setUp() throws Exception {
+        mContext = RuntimeEnvironment.application;
+        mGeneratedSecretKey = CryptoTestUtils.generateAesKey();
+        mSecondaryKey = new RecoverableKeyStoreSecondaryKey(TEST_ALIAS, mGeneratedSecretKey);
+    }
+
+    /** Reset the {@link ShadowRecoveryController}. */
+    @After
+    public void tearDown() throws Exception {
+        ShadowRecoveryController.reset();
+    }
+
+    /**
+     * Checks that {@link RecoverableKeyStoreSecondaryKey#getAlias()} returns the value supplied in
+     * the constructor.
+     */
+    @Test
+    public void getAlias() {
+        String alias = mSecondaryKey.getAlias();
+
+        assertThat(alias).isEqualTo(TEST_ALIAS);
+    }
+
+    /**
+     * Checks that {@link RecoverableKeyStoreSecondaryKey#getSecretKey()} returns the value supplied
+     * in the constructor.
+     */
+    @Test
+    public void getSecretKey() {
+        SecretKey secretKey = mSecondaryKey.getSecretKey();
+
+        assertThat(secretKey).isEqualTo(mGeneratedSecretKey);
+    }
+
+    /**
+     * Checks that passing a secret key that is null to the constructor throws an exception.
+     */
+    @Test
+    public void constructor_withNullSecretKey_throwsNullPointerException() {
+        assertThrows(
+                NullPointerException.class,
+                () -> new RecoverableKeyStoreSecondaryKey(TEST_ALIAS, null));
+    }
+
+    /**
+     * Checks that passing an alias that is null to the constructor throws an exception.
+     */
+    @Test
+    public void constructor_withNullAlias_throwsNullPointerException() {
+        assertThrows(
+                NullPointerException.class,
+                () -> new RecoverableKeyStoreSecondaryKey(null, mGeneratedSecretKey));
+    }
+
+    /** Checks that the synced status is returned correctly. */
+    @Test
+    public void getStatus_whenSynced_returnsSynced() throws Exception {
+        setStatus(RecoveryController.RECOVERY_STATUS_SYNCED);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.SYNCED);
+    }
+
+    /** Checks that the in progress sync status is returned correctly. */
+    @Test
+    public void getStatus_whenNotSynced_returnsNotSynced() throws Exception {
+        setStatus(RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.NOT_SYNCED);
+    }
+
+    /** Checks that the failure status is returned correctly. */
+    @Test
+    public void getStatus_onPermanentFailure_returnsDestroyed() throws Exception {
+        setStatus(RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.DESTROYED);
+    }
+
+    /** Checks that an unknown status results in {@code NOT_SYNCED} being returned. */
+    @Test
+    public void getStatus_forUnknownStatusCode_returnsNotSynced() throws Exception {
+        setStatus(NONEXISTENT_STATUS_CODE);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.NOT_SYNCED);
+    }
+
+    /** Checks that an internal error results in {@code NOT_SYNCED} being returned. */
+    @Test
+    public void getStatus_onInternalError_returnsNotSynced() throws Exception {
+        ShadowRecoveryController.setThrowsInternalError(true);
+
+        int status = mSecondaryKey.getStatus(mContext);
+
+        assertThat(status).isEqualTo(Status.NOT_SYNCED);
+    }
+
+    private void setStatus(int status) throws Exception {
+        ShadowRecoveryController.setRecoveryStatus(TEST_ALIAS, status);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java b/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java
new file mode 100644
index 0000000..48216f8
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyGeneratorTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 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.backup.encryption.keys;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import java.security.SecureRandom;
+
+import javax.crypto.SecretKey;
+
+/** Tests for {@link TertiaryKeyGenerator}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class TertiaryKeyGeneratorTest {
+    private static final String KEY_ALGORITHM = "AES";
+    private static final int KEY_SIZE_BITS = 256;
+
+    private TertiaryKeyGenerator mTertiaryKeyGenerator;
+
+    /** Instantiate a new {@link TertiaryKeyGenerator} for use in tests. */
+    @Before
+    public void setUp() {
+        mTertiaryKeyGenerator = new TertiaryKeyGenerator(new SecureRandom());
+    }
+
+    /** Generated keys should be AES keys. */
+    @Test
+    public void generate_generatesAESKeys() {
+        SecretKey secretKey = mTertiaryKeyGenerator.generate();
+
+        assertThat(secretKey.getAlgorithm()).isEqualTo(KEY_ALGORITHM);
+    }
+
+    /** Generated keys should be 256 bits in size. */
+    @Test
+    public void generate_generates256BitKeys() {
+        SecretKey secretKey = mTertiaryKeyGenerator.generate();
+
+        assertThat(secretKey.getEncoded()).hasLength(KEY_SIZE_BITS / 8);
+    }
+
+    /**
+     * Subsequent calls to {@link TertiaryKeyGenerator#generate()} should generate different keys.
+     */
+    @Test
+    public void generate_generatesNewKeys() {
+        SecretKey key1 = mTertiaryKeyGenerator.generate();
+        SecretKey key2 = mTertiaryKeyGenerator.generate();
+
+        assertThat(key1).isNotEqualTo(key2);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java b/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java
new file mode 100644
index 0000000..49bb410
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/keys/TertiaryKeyRotationTrackerTest.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2018 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.backup.encryption.keys;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+
+/** Tests for {@link TertiaryKeyRotationTracker}. */
+@RunWith(RobolectricTestRunner.class)
+@Presubmit
+public class TertiaryKeyRotationTrackerTest {
+    private static final String PACKAGE_1 = "com.package.one";
+    private static final int NUMBER_OF_BACKUPS_BEFORE_ROTATION = 31;
+
+    private TertiaryKeyRotationTracker mTertiaryKeyRotationTracker;
+
+    /** Instantiate a {@link TertiaryKeyRotationTracker} for use in tests. */
+    @Before
+    public void setUp() {
+        mTertiaryKeyRotationTracker = newInstance();
+    }
+
+    /** New packages should not be due for key rotation. */
+    @Test
+    public void isKeyRotationDue_forNewPackage_isFalse() {
+        // Simulate a new package by not calling simulateBackups(). As a result, PACKAGE_1 hasn't
+        // been seen by mTertiaryKeyRotationTracker before.
+        boolean keyRotationDue = mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1);
+
+        assertThat(keyRotationDue).isFalse();
+    }
+
+    /**
+     * Key rotation should not be due after less than {@code NUMBER_OF_BACKUPS_BEFORE_ROTATION}
+     * backups.
+     */
+    @Test
+    public void isKeyRotationDue_afterLessThanRotationAmountBackups_isFalse() {
+        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION - 1);
+
+        boolean keyRotationDue = mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1);
+
+        assertThat(keyRotationDue).isFalse();
+    }
+
+    /** Key rotation should be due after {@code NUMBER_OF_BACKUPS_BEFORE_ROTATION} backups. */
+    @Test
+    public void isKeyRotationDue_afterRotationAmountBackups_isTrue() {
+        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION);
+
+        boolean keyRotationDue = mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1);
+
+        assertThat(keyRotationDue).isTrue();
+    }
+
+    /**
+     * A call to {@link TertiaryKeyRotationTracker#resetCountdown(String)} should make sure no key
+     * rotation is due.
+     */
+    @Test
+    public void resetCountdown_makesKeyRotationNotDue() {
+        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION);
+
+        mTertiaryKeyRotationTracker.resetCountdown(PACKAGE_1);
+
+        assertThat(mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1)).isFalse();
+    }
+
+    /**
+     * New instances of {@link TertiaryKeyRotationTracker} should read state about the number of
+     * backups from disk.
+     */
+    @Test
+    public void isKeyRotationDue_forNewInstance_readsStateFromDisk() {
+        simulateBackups(PACKAGE_1, NUMBER_OF_BACKUPS_BEFORE_ROTATION);
+
+        boolean keyRotationDueForNewInstance = newInstance().isKeyRotationDue(PACKAGE_1);
+
+        assertThat(keyRotationDueForNewInstance).isTrue();
+    }
+
+    /**
+     * A call to {@link TertiaryKeyRotationTracker#markAllForRotation()} should mark all previously
+     * seen packages for rotation.
+     */
+    @Test
+    public void markAllForRotation_marksSeenPackagesForKeyRotation() {
+        simulateBackups(PACKAGE_1, /*numberOfBackups=*/ 1);
+
+        mTertiaryKeyRotationTracker.markAllForRotation();
+
+        assertThat(mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1)).isTrue();
+    }
+
+    /**
+     * A call to {@link TertiaryKeyRotationTracker#markAllForRotation()} should not mark any new
+     * packages for rotation.
+     */
+    @Test
+    public void markAllForRotation_doesNotMarkUnseenPackages() {
+        mTertiaryKeyRotationTracker.markAllForRotation();
+
+        assertThat(mTertiaryKeyRotationTracker.isKeyRotationDue(PACKAGE_1)).isFalse();
+    }
+
+    private void simulateBackups(String packageName, int numberOfBackups) {
+        while (numberOfBackups > 0) {
+            mTertiaryKeyRotationTracker.recordBackup(packageName);
+            numberOfBackups--;
+        }
+    }
+
+    private static TertiaryKeyRotationTracker newInstance() {
+        return TertiaryKeyRotationTracker.getInstance(RuntimeEnvironment.application);
+    }
+}
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java b/services/robotests/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java
new file mode 100644
index 0000000..9c06d81
--- /dev/null
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowInternalRecoveryServiceException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 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.testing.shadows;
+
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/** Shadow {@link InternalRecoveryServiceException}. */
+@Implements(InternalRecoveryServiceException.class)
+public class ShadowInternalRecoveryServiceException {
+    private String mMessage;
+
+    @Implementation
+    public void __constructor__(String message) {
+        mMessage = message;
+    }
+
+    @Implementation
+    public void __constructor__(String message, Throwable cause) {
+        mMessage = message;
+    }
+
+    @Implementation
+    public String getMessage() {
+        return mMessage;
+    }
+}
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowRecoveryController.java b/services/robotests/src/com/android/server/testing/shadows/ShadowRecoveryController.java
new file mode 100644
index 0000000..7dad8a4
--- /dev/null
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowRecoveryController.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2018 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.testing.shadows;
+
+import android.content.Context;
+import android.security.keystore.recovery.InternalRecoveryServiceException;
+import android.security.keystore.recovery.LockScreenRequiredException;
+import android.security.keystore.recovery.RecoveryController;
+
+import com.google.common.collect.ImmutableList;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+import java.lang.reflect.Constructor;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.crypto.KeyGenerator;
+
+/**
+ * Shadow of {@link RecoveryController}.
+ *
+ * <p>Instead of generating keys via the {@link RecoveryController}, this shadow generates them in
+ * memory.
+ */
+@Implements(RecoveryController.class)
+public class ShadowRecoveryController {
+    private static final String KEY_GENERATOR_ALGORITHM = "AES";
+    private static final int KEY_SIZE_BITS = 256;
+
+    private static boolean sIsSupported = true;
+    private static boolean sThrowsInternalError = false;
+    private static HashMap<String, Key> sKeysByAlias = new HashMap<>();
+    private static HashMap<String, Integer> sKeyStatusesByAlias = new HashMap<>();
+
+    @Implementation
+    public void __constructor__() {
+        // do not throw
+    }
+
+    @Implementation
+    public static RecoveryController getInstance(Context context) {
+        // Call non-public constructor.
+        try {
+            Constructor<RecoveryController> constructor = RecoveryController.class.getConstructor();
+            return constructor.newInstance();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Implementation
+    public static boolean isRecoverableKeyStoreEnabled(Context context) {
+        return sIsSupported;
+    }
+
+    @Implementation
+    public Key generateKey(String alias)
+            throws InternalRecoveryServiceException, LockScreenRequiredException {
+        maybeThrowError();
+        KeyGenerator keyGenerator;
+        try {
+            keyGenerator = KeyGenerator.getInstance(KEY_GENERATOR_ALGORITHM);
+        } catch (NoSuchAlgorithmException e) {
+            // Should never happen
+            throw new RuntimeException(e);
+        }
+
+        keyGenerator.init(KEY_SIZE_BITS);
+        Key key = keyGenerator.generateKey();
+        sKeysByAlias.put(alias, key);
+        sKeyStatusesByAlias.put(alias, RecoveryController.RECOVERY_STATUS_SYNC_IN_PROGRESS);
+        return key;
+    }
+
+    @Implementation
+    public Key getKey(String alias)
+            throws InternalRecoveryServiceException, UnrecoverableKeyException {
+        return sKeysByAlias.get(alias);
+    }
+
+    @Implementation
+    public void removeKey(String alias) throws InternalRecoveryServiceException {
+        sKeyStatusesByAlias.remove(alias);
+        sKeysByAlias.remove(alias);
+    }
+
+    @Implementation
+    public int getRecoveryStatus(String alias) throws InternalRecoveryServiceException {
+        maybeThrowError();
+        return sKeyStatusesByAlias.getOrDefault(
+                alias, RecoveryController.RECOVERY_STATUS_PERMANENT_FAILURE);
+    }
+
+    @Implementation
+    public List<String> getAliases() throws InternalRecoveryServiceException {
+        return ImmutableList.copyOf(sKeyStatusesByAlias.keySet());
+    }
+
+    private static void maybeThrowError() throws InternalRecoveryServiceException {
+        if (sThrowsInternalError) {
+            throw new InternalRecoveryServiceException("test error");
+        }
+    }
+
+    /** Sets the recovery status of the key with {@code alias} to {@code status}. */
+    public static void setRecoveryStatus(String alias, int status) {
+        sKeyStatusesByAlias.put(alias, status);
+    }
+
+    /** Sets all existing keys to being synced. */
+    public static void syncAllKeys() {
+        for (String alias : sKeysByAlias.keySet()) {
+            sKeyStatusesByAlias.put(alias, RecoveryController.RECOVERY_STATUS_SYNCED);
+        }
+    }
+
+    public static void setThrowsInternalError(boolean throwsInternalError) {
+        ShadowRecoveryController.sThrowsInternalError = throwsInternalError;
+    }
+
+    public static void setIsSupported(boolean isSupported) {
+        ShadowRecoveryController.sIsSupported = isSupported;
+    }
+
+    @Resetter
+    public static void reset() {
+        sIsSupported = true;
+        sThrowsInternalError = false;
+        sKeysByAlias.clear();
+        sKeyStatusesByAlias.clear();
+    }
+}
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 746c453..cf4d3a8 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -66,6 +66,7 @@
     <uses-permission android:name="android.permission.SUSPEND_APPS"/>
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
     <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
+    <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
 
     <!-- Uses API introduced in O (26) -->
     <uses-sdk android:minSdkVersion="1"
diff --git a/services/tests/servicestests/src/com/android/server/CachedDeviceStateServiceTest.java b/services/tests/servicestests/src/com/android/server/CachedDeviceStateServiceTest.java
index 81107cf..2a78b6f 100644
--- a/services/tests/servicestests/src/com/android/server/CachedDeviceStateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/CachedDeviceStateServiceTest.java
@@ -17,9 +17,10 @@
 package com.android.server;
 
 
-import static org.mockito.Mockito.when;
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.when;
+
 import android.content.Context;
 import android.content.Intent;
 import android.os.BatteryManager;
@@ -134,4 +135,44 @@
         mContext.sendBroadcast(intentUnplugged);
         assertThat(deviceState.isCharging()).isFalse();
     }
+
+    @Test
+    public void correctlyTracksTimeOnBattery() throws Exception {
+        CachedDeviceStateService service = new CachedDeviceStateService(mContext);
+        when(mBatteryManager.getPlugType()).thenReturn(OsProtoEnums.BATTERY_PLUGGED_NONE);
+
+        service.onStart();
+        CachedDeviceState.Readonly deviceState =
+                LocalServices.getService(CachedDeviceState.Readonly.class);
+
+        CachedDeviceState.TimeInStateStopwatch stopwatch =
+                deviceState.createTimeOnBatteryStopwatch();
+
+        // State can be initialized correctly only after PHASE_SYSTEM_SERVICES_READY.
+        assertThat(stopwatch.isRunning()).isFalse();
+        service.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+
+        assertThat(stopwatch.isRunning()).isTrue();
+        stopwatch.reset();
+
+        Thread.sleep(100);
+        assertThat(stopwatch.isRunning()).isTrue();
+        assertThat(stopwatch.getMillis()).isAtLeast(100L);
+
+        long timeOnBatteryBeforePluggedIn = stopwatch.getMillis();
+        Intent intentPluggedIn = new Intent(Intent.ACTION_BATTERY_CHANGED);
+        intentPluggedIn.putExtra(BatteryManager.EXTRA_PLUGGED, OsProtoEnums.BATTERY_PLUGGED_AC);
+        mContext.sendBroadcast(intentPluggedIn);
+
+        assertThat(stopwatch.getMillis()).isAtLeast(timeOnBatteryBeforePluggedIn);
+        assertThat(stopwatch.isRunning()).isFalse();
+
+        long timeOnBatteryAfterPluggedIn = stopwatch.getMillis();
+        Thread.sleep(20);
+        assertThat(stopwatch.getMillis()).isEqualTo(timeOnBatteryAfterPluggedIn);
+
+        stopwatch.reset();
+        assertThat(stopwatch.getMillis()).isEqualTo(0L);
+        assertThat(stopwatch.isRunning()).isFalse();
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
index 53711a6..e0ecd3e 100644
--- a/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
@@ -35,6 +35,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.R;
 import com.android.internal.app.ColorDisplayController;
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
@@ -911,7 +912,11 @@
         startService();
         assertAccessibilityTransformActivated(true /* activated */ );
         assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
-        assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        if (isColorModeValid(ColorDisplayController.COLOR_MODE_SATURATED)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        } else if (isColorModeValid(ColorDisplayController.COLOR_MODE_AUTOMATIC)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_AUTOMATIC);
+        }
     }
 
     @Test
@@ -926,7 +931,11 @@
         startService();
         assertAccessibilityTransformActivated(true /* activated */ );
         assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
-        assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        if (isColorModeValid(ColorDisplayController.COLOR_MODE_SATURATED)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        } else if (isColorModeValid(ColorDisplayController.COLOR_MODE_AUTOMATIC)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_AUTOMATIC);
+        }
     }
 
     @Test
@@ -942,7 +951,11 @@
         startService();
         assertAccessibilityTransformActivated(true /* activated */ );
         assertUserColorMode(ColorDisplayController.COLOR_MODE_NATURAL);
-        assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        if (isColorModeValid(ColorDisplayController.COLOR_MODE_SATURATED)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_SATURATED);
+        } else if (isColorModeValid(ColorDisplayController.COLOR_MODE_AUTOMATIC)) {
+            assertActiveColorMode(ColorDisplayController.COLOR_MODE_AUTOMATIC);
+        }
     }
 
     @Test
@@ -1030,6 +1043,24 @@
     }
 
     /**
+     * Returns whether the color mode is valid on the device the tests are running on.
+     *
+     * @param mode the mode to check
+     */
+    private boolean isColorModeValid(int mode) {
+        final int[] availableColorModes = mContext.getResources().getIntArray(
+            R.array.config_availableColorModes);
+        if (availableColorModes != null) {
+            for (int availableMode : availableColorModes) {
+                if (mode == availableMode) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
      * Convenience method to start {@link #mColorDisplayService}.
      */
     private void startService() {
@@ -1038,7 +1069,6 @@
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                mColorDisplayService.onStart();
                 mColorDisplayService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
                 mColorDisplayService.onStartUser(mUserId);
             }
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index 7cf7df13..c1963da 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -268,10 +268,10 @@
 
     @Test
     public void testGetCurrentStatus() throws RemoteException {
-        int status = Temperature.THROTTLING_WARNING;
+        int status = Temperature.THROTTLING_EMERGENCY;
         Temperature newSkin = new Temperature(100, Temperature.TYPE_SKIN, "skin1", status);
         mFakeHal.mCallback.onValues(newSkin);
-        assertEquals(status, mService.mService.getCurrentStatus());
+        assertEquals(status, mService.mService.getCurrentThermalStatus());
     }
 
     @Test
@@ -294,6 +294,6 @@
         assertEquals(0, mService.mService.getCurrentTemperatures().size());
         assertEquals(0,
                 mService.mService.getCurrentTemperaturesWithType(Temperature.TYPE_SKIN).size());
-        assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentStatus());
+        assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentThermalStatus());
     }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
index 9da204f..41d5a1c 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -456,6 +456,31 @@
     }
 
     @Test
+    public void testNoBeepForImportanceDefaultInAutomotive() throws Exception {
+        mService.setIsAutomotive(true);
+
+        NotificationRecord r = getBeepyNotification();
+        r.setSystemImportance(NotificationManager.IMPORTANCE_DEFAULT);
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyNeverBeep();
+        assertFalse(r.isInterruptive());
+    }
+
+    @Test
+    public void testBeepForImportanceHighInAutomotive() throws Exception {
+        mService.setIsAutomotive(true);
+
+        NotificationRecord r = getBeepyNotification();
+
+        mService.buzzBeepBlinkLocked(r);
+
+        verifyBeepLooped();
+        assertTrue(r.isInterruptive());
+    }
+
+    @Test
     public void testNoInterruptionForMin() throws Exception {
         NotificationRecord r = getBeepyNotification();
         r.setSystemImportance(NotificationManager.IMPORTANCE_MIN);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
index b30bb4b..0681295 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
@@ -15,8 +15,9 @@
  */
 package com.android.server.notification;
 
-import static org.junit.Assert.assertEquals;
+import static org.hamcrest.Matchers.contains;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
@@ -34,8 +35,8 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
-import android.telecom.TelecomManager;
 import android.support.test.runner.AndroidJUnit4;
+import android.telecom.TelecomManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.server.UiServiceTestCase;
@@ -211,7 +212,7 @@
         mRecordColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "colorized", uid2, uid2, n13,
                 new UserHandle(userId), "", 1999), getDefaultChannel());
-        mRecordHighCall.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
+        mRecordColorized.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
 
         Notification n14 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setCategory(Notification.CATEGORY_CALL)
@@ -225,11 +226,11 @@
     }
 
     @Test
-    public void testOrdering() throws Exception {
+    public void testOrdering() {
         final List<NotificationRecord> expected = new ArrayList<>();
         expected.add(mRecordColorizedCall);
-        expected.add(mRecordDefaultMedia);
         expected.add(mRecordColorized);
+        expected.add(mRecordDefaultMedia);
         expected.add(mRecordHighCall);
         expected.add(mRecordInlineReply);
         if (mRecordSms != null) {
@@ -250,11 +251,11 @@
 
         Collections.sort(actual, new NotificationComparator(mContext));
 
-        assertEquals(expected, actual);
+        assertThat(actual, contains(expected.toArray()));
     }
 
     @Test
-    public void testMessaging() throws Exception {
+    public void testMessaging() {
         NotificationComparator comp = new NotificationComparator(mContext);
         assertTrue(comp.isImportantMessaging(mRecordInlineReply));
         if (mRecordSms != null) {
@@ -265,7 +266,7 @@
     }
 
     @Test
-    public void testPeople() throws Exception {
+    public void testPeople() {
         NotificationComparator comp = new NotificationComparator(mContext);
         assertTrue(comp.isImportantPeople(mRecordStarredContact));
         assertTrue(comp.isImportantPeople(mRecordContact));
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index b94f472..845a09f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -95,52 +95,6 @@
     }
 
     @Test
-    public void layoutWindowLw_appDrawsBars() {
-        mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-        addWindow(mWindow);
-
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
-    }
-
-    @Test
-    public void layoutWindowLw_appWontDrawBars() {
-        mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-        addWindow(mWindow);
-
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
-    }
-
-    @Test
-    public void layoutWindowLw_appWontDrawBars_forceStatus() throws Exception {
-        mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-        mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
-        addWindow(mWindow);
-
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
-    }
-
-    @Test
     public void addingWindow_doesNotTamperWithSysuiFlags() {
         mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
         addWindow(mWindow);
@@ -150,253 +104,331 @@
     }
 
     @Test
+    public void layoutWindowLw_appDrawsBars() {
+        synchronized (mWm.mGlobalLock) {
+            mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+            addWindow(mWindow);
+
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+        }
+    }
+
+    @Test
+    public void layoutWindowLw_appWontDrawBars() {
+        synchronized (mWm.mGlobalLock) {
+            mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+            addWindow(mWindow);
+
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
+        }
+    }
+
+    @Test
+    public void layoutWindowLw_appWontDrawBars_forceStatus() throws Exception {
+        synchronized (mWm.mGlobalLock) {
+            mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+            mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+            addWindow(mWindow);
+
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
+        }
+    }
+
+    @Test
     public void layoutWindowLw_withDisplayCutout() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        addWindow(mWindow);
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_never() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
-        addWindow(mWindow);
+            mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_layoutFullscreen() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_fullscreen() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_fullscreenInCutout() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
-        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+            mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+        }
     }
 
 
     @Test
     public void layoutWindowLw_withDisplayCutout_landscape() {
-        addDisplayCutout();
-        setRotation(ROTATION_90);
-        addWindow(mWindow);
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
+            setRotation(ROTATION_90);
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
-        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getContentFrameLw(),
-                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
-        assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+            assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+            assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getContentFrameLw(),
+                    DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_seascape() {
-        addDisplayCutout();
-        setRotation(ROTATION_270);
-        addWindow(mWindow);
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
+            setRotation(ROTATION_270);
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
-        assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
-        assertInsetBy(mWindow.getContentFrameLw(),
-                NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
-        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
-        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+            assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+            assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
+            assertInsetBy(mWindow.getContentFrameLw(),
+                    NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
+            assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_fullscreen_landscape() {
-        addDisplayCutout();
-        setRotation(ROTATION_90);
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
+            setRotation(ROTATION_90);
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
-        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getContentFrameLw(),
-                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+            assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getContentFrameLw(),
+                    DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_floatingInScreen() {
-        addDisplayCutout();
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
 
-        mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN;
-        mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY;
-        mWindow.mAttrs.width = DISPLAY_WIDTH;
-        mWindow.mAttrs.height = DISPLAY_HEIGHT;
-        addWindow(mWindow);
+            mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN;
+            mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY;
+            mWindow.mAttrs.width = DISPLAY_WIDTH;
+            mWindow.mAttrs.height = DISPLAY_HEIGHT;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+        }
     }
 
     @Test
     public void layoutWindowLw_withDisplayCutout_fullscreenInCutout_landscape() {
-        addDisplayCutout();
-        setRotation(ROTATION_90);
+        synchronized (mWm.mGlobalLock) {
+            addDisplayCutout();
+            setRotation(ROTATION_90);
 
-        mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-        mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-        addWindow(mWindow);
+            mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+            mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+            addWindow(mWindow);
 
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
 
-        assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
-        assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getContentFrameLw(),
-                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
-        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
+            assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getContentFrameLw(),
+                    DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+            assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+        }
     }
 
     @Test
     public void layoutHint_appWindow() {
-        // Initialize DisplayFrames
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        synchronized (mWm.mGlobalLock) {
+            // Initialize DisplayFrames
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
 
-        final Rect outFrame = new Rect();
-        final Rect outContentInsets = new Rect();
-        final Rect outStableInsets = new Rect();
-        final Rect outOutsets = new Rect();
-        final DisplayCutout.ParcelableWrapper outDisplayCutout =
-                new DisplayCutout.ParcelableWrapper();
+            final Rect outFrame = new Rect();
+            final Rect outContentInsets = new Rect();
+            final Rect outStableInsets = new Rect();
+            final Rect outOutsets = new Rect();
+            final DisplayCutout.ParcelableWrapper outDisplayCutout =
+                    new DisplayCutout.ParcelableWrapper();
 
-        mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames,
-                false /* floatingStack */, outFrame, outContentInsets, outStableInsets, outOutsets,
-                outDisplayCutout);
+            mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames,
+                    false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+                    outOutsets, outDisplayCutout);
 
-        assertThat(outFrame, is(mFrames.mUnrestricted));
-        assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
-        assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
-        assertThat(outOutsets, is(new Rect()));
-        assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+            assertThat(outFrame, is(mFrames.mUnrestricted));
+            assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+            assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+            assertThat(outOutsets, is(new Rect()));
+            assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+        }
     }
 
     @Test
     public void layoutHint_appWindowInTask() {
-        // Initialize DisplayFrames
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        synchronized (mWm.mGlobalLock) {
+            // Initialize DisplayFrames
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
 
-        final Rect taskBounds = new Rect(100, 100, 200, 200);
+            final Rect taskBounds = new Rect(100, 100, 200, 200);
 
-        final Rect outFrame = new Rect();
-        final Rect outContentInsets = new Rect();
-        final Rect outStableInsets = new Rect();
-        final Rect outOutsets = new Rect();
-        final DisplayCutout.ParcelableWrapper outDisplayCutout =
-                new DisplayCutout.ParcelableWrapper();
+            final Rect outFrame = new Rect();
+            final Rect outContentInsets = new Rect();
+            final Rect outStableInsets = new Rect();
+            final Rect outOutsets = new Rect();
+            final DisplayCutout.ParcelableWrapper outDisplayCutout =
+                    new DisplayCutout.ParcelableWrapper();
 
-        mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
-                false /* floatingStack */, outFrame, outContentInsets, outStableInsets, outOutsets,
-                outDisplayCutout);
+            mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
+                    false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+                    outOutsets, outDisplayCutout);
 
-        assertThat(outFrame, is(taskBounds));
-        assertThat(outContentInsets, is(new Rect()));
-        assertThat(outStableInsets, is(new Rect()));
-        assertThat(outOutsets, is(new Rect()));
-        assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+            assertThat(outFrame, is(taskBounds));
+            assertThat(outContentInsets, is(new Rect()));
+            assertThat(outStableInsets, is(new Rect()));
+            assertThat(outOutsets, is(new Rect()));
+            assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+        }
     }
 
     @Test
     public void layoutHint_appWindowInTask_outsideContentFrame() {
-        // Initialize DisplayFrames
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+        synchronized (mWm.mGlobalLock) {
+            // Initialize DisplayFrames
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
 
-        // Task is in the nav bar area (usually does not happen, but this is similar enough to the
-        // possible overlap with the IME)
-        final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1,
-                200, mFrames.mContent.bottom + 10);
+            // Task is in the nav bar area (usually does not happen, but this is similar enough to
+            // the possible overlap with the IME)
+            final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1,
+                    200, mFrames.mContent.bottom + 10);
 
-        final Rect outFrame = new Rect();
-        final Rect outContentInsets = new Rect();
-        final Rect outStableInsets = new Rect();
-        final Rect outOutsets = new Rect();
-        final DisplayCutout.ParcelableWrapper outDisplayCutout =
-                new DisplayCutout.ParcelableWrapper();
+            final Rect outFrame = new Rect();
+            final Rect outContentInsets = new Rect();
+            final Rect outStableInsets = new Rect();
+            final Rect outOutsets = new Rect();
+            final DisplayCutout.ParcelableWrapper outDisplayCutout =
+                    new DisplayCutout.ParcelableWrapper();
 
-        mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
-                true /* floatingStack */, outFrame, outContentInsets, outStableInsets, outOutsets,
-                outDisplayCutout);
+            mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
+                    true /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+                    outOutsets, outDisplayCutout);
 
-        assertThat(outFrame, is(taskBounds));
-        assertThat(outContentInsets, is(new Rect()));
-        assertThat(outStableInsets, is(new Rect()));
-        assertThat(outOutsets, is(new Rect()));
-        assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+            assertThat(outFrame, is(taskBounds));
+            assertThat(outContentInsets, is(new Rect()));
+            assertThat(outStableInsets, is(new Rect()));
+            assertThat(outOutsets, is(new Rect()));
+            assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+        }
     }
 
     /**
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index c11e606..88215449 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -29,6 +29,7 @@
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
+import org.junit.Before;
 import org.junit.Test;
 
 @SmallTest
@@ -36,8 +37,15 @@
 @Presubmit
 public class InsetsSourceProviderTest extends WindowTestsBase {
 
-    private InsetsSourceProvider mProvider = new InsetsSourceProvider(
-            new InsetsSource(TYPE_TOP_BAR));
+    private InsetsSource mSource = new InsetsSource(TYPE_TOP_BAR);
+    private InsetsSourceProvider mProvider;
+
+    @Before
+    public void setUp() throws Exception {
+        mSource.setVisible(true);
+        mProvider = new InsetsSourceProvider(mSource,
+                mDisplayContent.getInsetsStateController(), mDisplayContent);
+    }
 
     @Test
     public void testPostLayout() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 331622c..11526a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -23,8 +23,10 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
 import android.platform.test.annotations.Presubmit;
+import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 
 import androidx.test.filters.FlakyTest;
@@ -41,12 +43,9 @@
     public void testStripForDispatch_notOwn() {
         final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
         final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
-                .setWindow(topBar, null);
-        topBar.setInsetProvider(
-                mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR));
-        assertNotNull(mDisplayContent.getInsetsStateController().getInsetsForDispatch(app)
-                .getSource(TYPE_TOP_BAR));
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        topBar.setInsetProvider(getController().getSourceProvider(TYPE_TOP_BAR));
+        assertNotNull(getController().getInsetsForDispatch(app).getSource(TYPE_TOP_BAR));
     }
 
     @Test
@@ -54,10 +53,8 @@
         final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
         mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
                 .setWindow(topBar, null);
-        topBar.setInsetProvider(
-                mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR));
-        assertEquals(new InsetsState(),
-                mDisplayContent.getInsetsStateController().getInsetsForDispatch(topBar));
+        topBar.setInsetProvider(getController().getSourceProvider(TYPE_TOP_BAR));
+        assertEquals(new InsetsState(), getController().getInsetsForDispatch(topBar));
     }
 
     @Test
@@ -65,13 +62,47 @@
         final WindowState navBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
         final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
         final WindowState ime = createWindow(null, TYPE_APPLICATION, "parentWindow");
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
-                .setWindow(topBar, null);
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_NAVIGATION_BAR)
-                .setWindow(navBar, null);
-        mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_IME)
-                .setWindow(ime, null);
-        assertEquals(new InsetsState(),
-                mDisplayContent.getInsetsStateController().getInsetsForDispatch(navBar));
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().getSourceProvider(TYPE_NAVIGATION_BAR).setWindow(navBar, null);
+        getController().getSourceProvider(TYPE_IME).setWindow(ime, null);
+        assertEquals(new InsetsState(), getController().getInsetsForDispatch(navBar));
+    }
+
+    @Test
+    public void testBarControllingWinChanged() {
+        final WindowState navBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().getSourceProvider(TYPE_NAVIGATION_BAR).setWindow(navBar, null);
+        getController().onBarControllingWindowChanged(app);
+        InsetsSourceControl[] controls = getController().getControlsForDispatch(app);
+        assertEquals(2, controls.length);
+    }
+
+    @Test
+    public void testControlRevoked() {
+        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().onBarControllingWindowChanged(app);
+        assertNotNull(getController().getControlsForDispatch(app));
+        getController().onBarControllingWindowChanged(null);
+        assertNull(getController().getControlsForDispatch(app));
+    }
+
+    @Test
+    public void testControlRevoked_animation() {
+        final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
+        getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+        getController().onBarControllingWindowChanged(app);
+        assertNotNull(getController().getControlsForDispatch(app));
+        topBar.cancelAnimation();
+        assertNull(getController().getControlsForDispatch(app));
+    }
+
+    private InsetsStateController getController() {
+        return mDisplayContent.getInsetsStateController();
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
index 432af0d..29738ff 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
@@ -24,6 +24,7 @@
 import android.view.DisplayCutout;
 import android.view.DragEvent;
 import android.view.IWindow;
+import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 
 import com.android.internal.os.IResultReceiver;
@@ -40,11 +41,17 @@
             Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId,
             DisplayCutout.ParcelableWrapper displayCutout) throws RemoteException {
     }
+
     @Override
     public void insetsChanged(InsetsState insetsState) throws RemoteException {
     }
 
     @Override
+    public void insetsControlChanged(InsetsState insetsState, InsetsSourceControl[] activeControls)
+            throws RemoteException {
+    }
+
+    @Override
     public void moved(int newX, int newY) throws RemoteException {
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
index 3643457..885a7e0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -231,7 +231,7 @@
 
         final Configuration config = new Configuration();
         final WindowConfiguration winConfig = config.windowConfiguration;
-        stackController.adjustConfigurationForBounds(bounds, null /*insetBounds*/,
+        stackController.adjustConfigurationForBounds(bounds,
                 new Rect() /*nonDecorBounds*/, new Rect() /*stableBounds*/, false /*overrideWidth*/,
                 false /*overrideHeight*/, mDisplayInfo.logicalDensityDpi, config, parentConfig,
                 windowingMode);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
index b3e90de..60a8aeb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java
@@ -76,7 +76,7 @@
 
     private static class TaskWithBounds extends Task {
         final Rect mBounds;
-        final Rect mInsetBounds = new Rect();
+        final Rect mOverrideDisplayedBounds = new Rect();
         boolean mFullscreenForTest = true;
 
         TaskWithBounds(TaskStack stack, WindowManagerService wm, Rect bounds) {
@@ -100,8 +100,8 @@
             outBounds.set(mBounds);
         }
         @Override
-        void getTempInsetBounds(Rect outBounds) {
-            outBounds.set(mInsetBounds);
+        Rect getOverrideDisplayedBounds() {
+            return mOverrideDisplayedBounds;
         }
         @Override
         boolean isFullscreen() {
@@ -343,14 +343,14 @@
                 taskBottom - contentInsetBottom));
 
         pf.set(0, 0, logicalWidth, logicalHeight);
-        // However if we set temp inset bounds, the insets will be computed
-        // as if our window was laid out there,  but it will be laid out according to
-        // the task bounds.
+        // If we set displayed bounds, the insets will be computed with the main task bounds
+        // but the frame will be positioned according to the displayed bounds.
         final int insetLeft = logicalWidth / 5;
         final int insetTop = logicalHeight / 5;
         final int insetRight = insetLeft + (taskRight - taskLeft);
         final int insetBottom = insetTop + (taskBottom - taskTop);
-        task.mInsetBounds.set(insetLeft, insetTop, insetRight, insetBottom);
+        task.mOverrideDisplayedBounds.set(taskBounds);
+        task.mBounds.set(insetLeft, insetTop, insetRight, insetBottom);
         windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
         w.computeFrameLw();
         assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
@@ -430,7 +430,6 @@
         final int taskBottom = logicalHeight / 4 * 3;
         final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
         final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm, taskBounds);
-        task.mInsetBounds.set(taskLeft, taskTop, taskRight, taskBottom);
         task.mFullscreenForTest = false;
         WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
@@ -486,12 +485,12 @@
     }
 
     @Test
-    public void testDisplayCutout_tempInsetBounds() {
+    public void testDisplayCutout_tempDisplayedBounds() {
         // Regular fullscreen task and window
         final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm,
-                new Rect(0, -500, 1000, 1500));
+                new Rect(0, 0, 1000, 2000));
         task.mFullscreenForTest = false;
-        task.mInsetBounds.set(0, 0, 1000, 2000);
+        task.setOverrideDisplayedBounds(new Rect(0, -500, 1000, 1500));
         WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
         w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java
index 4a99172..50fd188 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceRule.java
@@ -30,6 +30,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
 
 import android.app.ActivityManagerInternal;
 import android.content.Context;
@@ -125,11 +126,12 @@
                 if (input != null && input.length > 1) {
                     doReturn(input[1]).when(ims).monitorInput(anyString(), anyInt());
                 }
+                ActivityTaskManagerService atms = mock(ActivityTaskManagerService.class);
+                when(atms.getGlobalLock()).thenReturn(new WindowManagerGlobalLock());
 
                 mService = WindowManagerService.main(context, ims, false, false,
                         mPolicy = new TestWindowManagerPolicy(
-                                WindowManagerServiceRule.this::getWindowManagerService),
-                        new WindowManagerGlobalLock());
+                                WindowManagerServiceRule.this::getWindowManagerService), atms);
                 mService.mTransactionFactory = () -> {
                     final SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
                     mSurfaceTransactions.add(new WeakReference<>(transaction));
@@ -173,21 +175,21 @@
         };
     }
 
-    public WindowManagerService getWindowManagerService() {
+    WindowManagerService getWindowManagerService() {
         return mService;
     }
 
-    public TestWindowManagerPolicy getWindowManagerPolicy() {
-        return mPolicy;
-    }
-
-    public void waitUntilWindowManagerHandlersIdle() {
+    void waitUntilWindowManagerHandlersIdle() {
         final WindowManagerService wm = getWindowManagerService();
-        if (wm != null) {
-            wm.mH.runWithScissors(() -> { }, 0);
-            wm.mAnimationHandler.runWithScissors(() -> { }, 0);
-            SurfaceAnimationThread.getHandler().runWithScissors(() -> { }, 0);
+        if (wm == null) {
+            return;
         }
+        wm.mH.removeCallbacksAndMessages(null);
+        wm.mAnimationHandler.removeCallbacksAndMessages(null);
+        SurfaceAnimationThread.getHandler().removeCallbacksAndMessages(null);
+        wm.mH.runWithScissors(() -> { }, 0);
+        wm.mAnimationHandler.runWithScissors(() -> { }, 0);
+        SurfaceAnimationThread.getHandler().runWithScissors(() -> { }, 0);
     }
 
     private void destroyAllSurfaceTransactions() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
index a1b0411..aa0ecf8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestUtils.java
@@ -28,6 +28,9 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -117,11 +120,11 @@
         // many components rely on the {@link StackWindowController#adjustConfigurationForBounds}
         // to properly set bounds values in the configuration. We must mimick those actions here.
         doAnswer((InvocationOnMock invocationOnMock) -> {
-            final Configuration config = invocationOnMock.<Configuration>getArgument(7);
+            final Configuration config = invocationOnMock.<Configuration>getArgument(6);
             final Rect bounds = invocationOnMock.<Rect>getArgument(0);
             config.windowConfiguration.setBounds(bounds);
             return null;
-        }).when(controller).adjustConfigurationForBounds(any(), any(), any(), any(),
+        }).when(controller).adjustConfigurationForBounds(any(), any(), any(),
                 anyBoolean(), anyBoolean(), anyFloat(), any(), any(), anyInt());
 
         return controller;
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index cef99865..d617de0 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -29,7 +29,6 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.lang.String;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.nio.charset.StandardCharsets;
@@ -908,10 +907,16 @@
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder();
-            sb.append("[pa: ");
+            sb.append("[id: ");
+            sb.append(mTelecomCallId);
+            sb.append(", pa: ");
             sb.append(mAccountHandle);
             sb.append(", hdl: ");
-            sb.append(Log.pii(mHandle));
+            sb.append(Log.piiHandle(mHandle));
+            sb.append(", hdlPres: ");
+            sb.append(mHandlePresentation);
+            sb.append(", videoState: ");
+            sb.append(VideoProfile.videoStateToString(mVideoState));
             sb.append(", caps: ");
             sb.append(capabilitiesToString(mCallCapabilities));
             sb.append(", props: ");
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 7db6940..6628743 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -27,8 +27,8 @@
 import android.os.RemoteException;
 
 import com.android.internal.os.SomeArgs;
-import com.android.internal.telecom.ICallScreeningService;
 import com.android.internal.telecom.ICallScreeningAdapter;
+import com.android.internal.telecom.ICallScreeningService;
 
 /**
  * This service can be implemented by the default dialer (see
@@ -147,7 +147,7 @@
             private boolean mShouldSkipCallLog;
             private boolean mShouldSkipNotification;
 
-            /*
+            /**
              * Sets whether the incoming call should be blocked.
              */
             public Builder setDisallowCall(boolean shouldDisallowCall) {
@@ -155,7 +155,7 @@
                 return this;
             }
 
-            /*
+            /**
              * Sets whether the incoming call should be disconnected as if the user had manually
              * rejected it. This property should only be set to true if the call is disallowed.
              */
@@ -164,16 +164,20 @@
                 return this;
             }
 
-            /*
+            /**
              * Sets whether the incoming call should not be displayed in the call log. This property
              * should only be set to true if the call is disallowed.
+             * <p>
+             * Note: Calls will still be logged with type
+             * {@link android.provider.CallLog.Calls#BLOCKED_TYPE}, regardless of how this property
+             * is set.
              */
             public Builder setSkipCallLog(boolean shouldSkipCallLog) {
                 mShouldSkipCallLog = shouldSkipCallLog;
                 return this;
             }
 
-            /*
+            /**
              * Sets whether a missed call notification should not be shown for the incoming call.
              * This property should only be set to true if the call is disallowed.
              */
@@ -211,6 +215,17 @@
      * Called when a new incoming call is added.
      * {@link CallScreeningService#respondToCall(Call.Details, CallScreeningService.CallResponse)}
      * should be called to allow or disallow the call.
+     * <p>
+     * Note: The {@link Call.Details} instance provided to a call screening service will only have
+     * the following properties set.  The rest of the {@link Call.Details} properties will be set to
+     * their default value or {@code null}.
+     * <ul>
+     *     <li>{@link Call.Details#getState()}</li>
+     *     <li>{@link Call.Details#getConnectTimeMillis()}</li>
+     *     <li>{@link Call.Details#getCreationTimeMillis()}</li>
+     *     <li>{@link Call.Details#getHandle()}</li>
+     *     <li>{@link Call.Details#getHandlePresentation()}</li>
+     * </ul>
      *
      * @param callDetails Information about a new incoming call, see {@link Call.Details}.
      */
diff --git a/telephony/OWNERS b/telephony/OWNERS
index 054288b..2236cba 100644
--- a/telephony/OWNERS
+++ b/telephony/OWNERS
@@ -13,3 +13,4 @@
 shuoq@google.com
 refuhoo@google.com
 paulye@google.com
+nazaninb@google.com
\ No newline at end of file
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.aidl b/telephony/java/android/telephony/AvailableNetworkInfo.aidl
new file mode 100644
index 0000000..1d4378c
--- /dev/null
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018, 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.telephony;
+
+parcelable AvailableNetworkInfo;
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java
new file mode 100644
index 0000000..fe07370
--- /dev/null
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2018 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.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Defines available network information which includes corresponding subscription id,
+ * network plmns and corresponding priority to be used for network selection by Alternative Network
+ * Service.
+ */
+public final class AvailableNetworkInfo implements Parcelable {
+
+    /*
+     * Defines number of priority level high.
+     */
+    public static final int PRIORITY_HIGH = 1;
+
+    /*
+     * Defines number of priority level medium.
+     */
+    public static final int PRIORITY_MED = 2;
+
+    /*
+     * Defines number of priority level low.
+     */
+    public static final int PRIORITY_LOW = 3;
+
+    /**
+     * subscription Id of the available network. This value must be one of the entry retrieved from
+     * {@link SubscriptionManager#getOpportunisticSubscriptions}
+     */
+    private int mSubId;
+
+    /**
+     * Priority for the subscription id.
+     * Priorities are in the range of 1 to 3 where 1
+     * has the highest priority.
+     */
+    private int mPriority;
+
+    /**
+     * Describes the List of PLMN ids (MCC-MNC) associated with mSubId.
+     * If this entry is left empty, then the platform software will not scan the network
+     * to revalidate the input.
+     */
+    private ArrayList<String> mMccMncs;
+
+    /**
+     * Return subscription Id of the available network.
+     * This value must be one of the entry retrieved from
+     * {@link SubscriptionManager#getOpportunisticSubscriptions}
+     * @return subscription id
+     */
+    public int getSubId() {
+        return mSubId;
+    }
+
+    /**
+     * Return priority for the subscription id. Valid value will be within
+     * [{@link AvailableNetworkInfo#PRIORITY_HIGH}, {@link AvailableNetworkInfo#PRIORITY_LOW}]
+     * @return priority level
+     */
+    public int getPriority() {
+        return mPriority;
+    }
+
+    /**
+     * Return List of PLMN ids (MCC-MNC) associated with the sub ID.
+     * If this entry is left empty, then the platform software will not scan the network
+     * to revalidate the input.
+     * @return list of PLMN ids
+     */
+    public List<String> getMccMncs() {
+        return (List<String>) mMccMncs.clone();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mSubId);
+        dest.writeInt(mPriority);
+        dest.writeStringList(mMccMncs);
+    }
+
+    private AvailableNetworkInfo(Parcel in) {
+        mSubId = in.readInt();
+        mPriority = in.readInt();
+        in.readStringList(mMccMncs);
+    }
+
+    public AvailableNetworkInfo(int subId, int priority, ArrayList<String> mccMncs) {
+        mSubId = subId;
+        mPriority = priority;
+        mMccMncs = new ArrayList<String>(mccMncs);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        AvailableNetworkInfo ani;
+
+        try {
+            ani = (AvailableNetworkInfo) o;
+        } catch (ClassCastException ex) {
+            return false;
+        }
+
+        if (o == null) {
+            return false;
+        }
+
+        return (mSubId == ani.mSubId
+                && mPriority == ani.mPriority
+                && (((mMccMncs != null)
+                && mMccMncs.equals(ani.mMccMncs))));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mSubId, mPriority, mMccMncs);
+    }
+
+    public static final Parcelable.Creator<AvailableNetworkInfo> CREATOR =
+            new Creator<AvailableNetworkInfo>() {
+                @Override
+                public AvailableNetworkInfo createFromParcel(Parcel in) {
+                    return new AvailableNetworkInfo(in);
+                }
+
+                @Override
+                public AvailableNetworkInfo[] newArray(int size) {
+                    return new AvailableNetworkInfo[size];
+                }
+            };
+
+    @Override
+    public String toString() {
+        return ("AvailableNetworkInfo:"
+                + " mSubId: " + mSubId
+                + " mPriority: " + mPriority
+                + " mMccMncs: " + Arrays.toString(mMccMncs.toArray()));
+    }
+}
+
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 185c886..62cead1 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1154,20 +1154,33 @@
      */
     public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string";
 
- /**
-  * The Component Name of a carrier-provided CallScreeningService implementation. Telecom will
-  * bind to {@link android.telecom.CallScreeningService} for ALL incoming calls and provide
-  * the carrier
-  * CallScreeningService with the opportunity to allow or block calls.
-  * <p>
-  * The String includes the package name/the class name.
-  * Example:
-  * <item>com.android.carrier/com.android.carrier.callscreeningserviceimpl</item>
-  * <p>
-  * Using {@link ComponentName#flattenToString()} to convert a ComponentName object to String.
-  * Using {@link ComponentName#unflattenFromString(String)} to convert a String object to a
-  * ComponentName.
-  */
+    /**
+     * String to override sim country iso.
+     * Sim country iso is based on sim MCC which is coarse and doesn't work with dual IMSI SIM where
+     * a SIM can have multiple MCC from different countries.
+     * Instead, each sim carrier should have a single country code, apply per carrier based iso
+     * code as an override. The overridden value can be read from
+     * {@link TelephonyManager#getSimCountryIso()} and {@link SubscriptionInfo#getCountryIso()}
+     *
+     * @hide
+     */
+    public static final String KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING =
+            "sim_country_iso_override_string";
+
+   /**
+    * The Component Name of a carrier-provided CallScreeningService implementation. Telecom will
+    * bind to {@link android.telecom.CallScreeningService} for ALL incoming calls and provide
+    * the carrier
+    * CallScreeningService with the opportunity to allow or block calls.
+    * <p>
+    * The String includes the package name/the class name.
+    * Example:
+    * <item>com.android.carrier/com.android.carrier.callscreeningserviceimpl</item>
+    * <p>
+    * Using {@link ComponentName#flattenToString()} to convert a ComponentName object to String.
+    * Using {@link ComponentName#unflattenFromString(String)} to convert a String object to a
+    * ComponentName.
+    */
     public static final String KEY_CARRIER_CALL_SCREENING_APP_STRING = "call_screening_app";
 
     /**
@@ -2533,6 +2546,7 @@
         sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false);
         sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
         sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
+        sDefaults.putString(KEY_SIM_COUNTRY_ISO_OVERRIDE_STRING, "");
         sDefaults.putString(KEY_CARRIER_CALL_SCREENING_APP_STRING, "");
         sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
         sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, "");
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationStates.java
index b6e6cba..5d809d0 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationStates.java
@@ -33,17 +33,31 @@
      */
     public final boolean isNrAvailable;
 
+    /**
+     * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving
+     * cell.
+     *
+     * True the primary serving cell is LTE cell and the plmn-InfoList-r15 is present in SIB2 and
+     * at least one bit in this list is true, otherwise this value should be false.
+     *
+     * Reference: 3GPP TS 36.331 v15.2.2 6.3.1 System information blocks.
+     */
+    public final boolean isEnDcAvailable;
+
     DataSpecificRegistrationStates(
-            int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable) {
+            int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
+            boolean isEnDcAvailable) {
         this.maxDataCalls = maxDataCalls;
         this.isDcNrRestricted = isDcNrRestricted;
         this.isNrAvailable = isNrAvailable;
+        this.isEnDcAvailable = isEnDcAvailable;
     }
 
     private DataSpecificRegistrationStates(Parcel source) {
         maxDataCalls = source.readInt();
         isDcNrRestricted = source.readBoolean();
         isNrAvailable = source.readBoolean();
+        isEnDcAvailable = source.readBoolean();
     }
 
     @Override
@@ -51,6 +65,7 @@
         dest.writeInt(maxDataCalls);
         dest.writeBoolean(isDcNrRestricted);
         dest.writeBoolean(isNrAvailable);
+        dest.writeBoolean(isEnDcAvailable);
     }
 
     @Override
@@ -65,13 +80,14 @@
                 .append(" maxDataCalls = " + maxDataCalls)
                 .append(" isDcNrRestricted = " + isDcNrRestricted)
                 .append(" isNrAvailable = " + isNrAvailable)
+                .append(" isEnDcAvailable = " + isEnDcAvailable)
                 .append(" }")
                 .toString();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable);
+        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable);
     }
 
     @Override
@@ -83,7 +99,8 @@
         DataSpecificRegistrationStates other = (DataSpecificRegistrationStates) o;
         return this.maxDataCalls == other.maxDataCalls
                 && this.isDcNrRestricted == other.isDcNrRestricted
-                && this.isNrAvailable == other.isNrAvailable;
+                && this.isNrAvailable == other.isNrAvailable
+                && this.isEnDcAvailable == other.isEnDcAvailable;
     }
 
     public static final Parcelable.Creator<DataSpecificRegistrationStates> CREATOR =
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index aee744f..b00665e 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -219,12 +219,13 @@
     public NetworkRegistrationState(int domain, int transportType, int regState,
             int accessNetworkTechnology, int rejectCause, boolean emergencyOnly,
             int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls,
-            boolean isDcNrRestricted, boolean isNrAvailable) {
+            boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable) {
         this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly,
                 availableServices, cellIdentity);
 
         mDataSpecificStates = new DataSpecificRegistrationStates(
-                maxDataCalls, isDcNrRestricted, isNrAvailable);
+                maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable);
+        updateNrStatus(mDataSpecificStates);
     }
 
     protected NetworkRegistrationState(Parcel source) {
@@ -448,6 +449,34 @@
         dest.writeInt(mNrStatus);
     }
 
+    /**
+     * Use the 5G NR Non-Standalone indicators from the network registration state to update the
+     * NR status. There are 3 indicators in the network registration state:
+     *
+     * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell.
+     * 2. if NR is supported by the selected PLMN.
+     * 3. if the use of dual connectivity with NR is restricted.
+     *
+     * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary
+     * serving cell.
+     *
+     * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of
+     * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G
+     * NR is restricted.
+     *
+     * @param state data specific registration state contains the 5G NR indicators.
+     */
+    private void updateNrStatus(DataSpecificRegistrationStates state) {
+        mNrStatus = NR_STATUS_NONE;
+        if (state.isEnDcAvailable) {
+            if (!state.isDcNrRestricted && state.isNrAvailable) {
+                mNrStatus = NR_STATUS_NOT_RESTRICTED;
+            } else {
+                mNrStatus = NR_STATUS_RESTRICTED;
+            }
+        }
+    }
+
     public static final Parcelable.Creator<NetworkRegistrationState> CREATOR =
             new Parcelable.Creator<NetworkRegistrationState>() {
         @Override
diff --git a/telephony/java/android/telephony/NumberVerificationCallback.java b/telephony/java/android/telephony/NumberVerificationCallback.java
new file mode 100644
index 0000000..b00c573
--- /dev/null
+++ b/telephony/java/android/telephony/NumberVerificationCallback.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 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.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * A callback for number verification. After a request for number verification is received,
+ * the system will call {@link #onCallReceived(String)} if a phone call was received from a number
+ * matching the provided {@link PhoneNumberRange} or it will call {@link #onVerificationFailed(int)}
+ * if an error occurs.
+ * @hide
+ */
+@SystemApi
+public interface NumberVerificationCallback {
+    /** @hide */
+    @IntDef(value = {REASON_UNSPECIFIED, REASON_TIMED_OUT, REASON_NETWORK_NOT_AVAILABLE,
+            REASON_TOO_MANY_CALLS, REASON_CONCURRENT_REQUESTS, REASON_IN_ECBM,
+            REASON_IN_EMERGENCY_CALL},
+            prefix = {"REASON_"})
+    @interface NumberVerificationFailureReason {}
+
+    /**
+     * Verification failed for an unspecified reason.
+     */
+    int REASON_UNSPECIFIED = 0;
+
+    /**
+     * Verification failed because no phone call was received from a matching number within the
+     * provided timeout.
+     */
+    int REASON_TIMED_OUT = 1;
+
+    /**
+     * Verification failed because no cellular voice network is available.
+     */
+    int REASON_NETWORK_NOT_AVAILABLE = 2;
+
+    /**
+     * Verification failed because there are currently too many ongoing phone calls for a new
+     * incoming phone call to be received.
+     */
+    int REASON_TOO_MANY_CALLS = 3;
+
+    /**
+     * Verification failed because a previous request for verification has not yet completed.
+     */
+    int REASON_CONCURRENT_REQUESTS = 4;
+
+    /**
+     * Verification failed because the phone is in emergency callback mode.
+     */
+    int REASON_IN_ECBM = 5;
+
+    /**
+     * Verification failed because the phone is currently in an emergency call.
+     */
+    int REASON_IN_EMERGENCY_CALL = 6;
+
+    /**
+     * Called when the device receives a phone call from the provided {@link PhoneNumberRange}.
+     * @param phoneNumber The phone number within the range that called. May or may not contain the
+     *                    country code, but will be entirely numeric.
+     */
+    default void onCallReceived(@NonNull String phoneNumber) { }
+
+    /**
+     * Called when verification fails for some reason.
+     * @param reason The reason for failure.
+     */
+    default void onVerificationFailed(@NumberVerificationFailureReason int reason) { }
+}
diff --git a/telephony/java/android/telephony/PhoneNumberRange.aidl b/telephony/java/android/telephony/PhoneNumberRange.aidl
new file mode 100644
index 0000000..b0727be
--- /dev/null
+++ b/telephony/java/android/telephony/PhoneNumberRange.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2018 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.telephony;
+
+parcelable PhoneNumberRange;
diff --git a/telephony/java/android/telephony/PhoneNumberRange.java b/telephony/java/android/telephony/PhoneNumberRange.java
new file mode 100644
index 0000000..d65156f
--- /dev/null
+++ b/telephony/java/android/telephony/PhoneNumberRange.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2018 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.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+/**
+ * This class is used to represent a range of phone numbers. Each range corresponds to a contiguous
+ * block of phone numbers.
+ *
+ * Example:
+ * {@code
+ * {
+ *     mCountryCode = "1"
+ *     mPrefix = "650555"
+ *     mLowerBound = "0055"
+ *     mUpperBound = "0899"
+ * }
+ * }
+ * would match 16505550089 and 6505550472, but not 63827593759 or 16505550900
+ * @hide
+ */
+@SystemApi
+public final class PhoneNumberRange implements Parcelable {
+    public static final Creator<PhoneNumberRange> CREATOR = new Creator<PhoneNumberRange>() {
+        @Override
+        public PhoneNumberRange createFromParcel(Parcel in) {
+            return new PhoneNumberRange(in);
+        }
+
+        @Override
+        public PhoneNumberRange[] newArray(int size) {
+            return new PhoneNumberRange[size];
+        }
+    };
+
+    private final String mCountryCode;
+    private final String mPrefix;
+    private final String mLowerBound;
+    private final String mUpperBound;
+
+    /**
+     * @param countryCode The country code, omitting the leading "+"
+     * @param prefix A prefix that all numbers matching the range must have.
+     * @param lowerBound When concatenated with the prefix, represents the lower bound of phone
+     *                   numbers that match this range.
+     * @param upperBound When concatenated with the prefix, represents the upper bound of phone
+     *                   numbers that match this range.
+     */
+    public PhoneNumberRange(@NonNull String countryCode, @NonNull String prefix,
+            @NonNull String lowerBound, @NonNull String upperBound) {
+        validateLowerAndUpperBounds(lowerBound, upperBound);
+        if (!Pattern.matches("[0-9]+", countryCode)) {
+            throw new IllegalArgumentException("Country code must be all numeric");
+        }
+        if (!Pattern.matches("[0-9]+", prefix)) {
+            throw new IllegalArgumentException("Prefix must be all numeric");
+        }
+        mCountryCode = countryCode;
+        mPrefix = prefix;
+        mLowerBound = lowerBound;
+        mUpperBound = upperBound;
+    }
+
+    private PhoneNumberRange(Parcel in) {
+        mCountryCode = in.readStringNoHelper();
+        mPrefix = in.readStringNoHelper();
+        mLowerBound = in.readStringNoHelper();
+        mUpperBound = in.readStringNoHelper();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeStringNoHelper(mCountryCode);
+        dest.writeStringNoHelper(mPrefix);
+        dest.writeStringNoHelper(mLowerBound);
+        dest.writeStringNoHelper(mUpperBound);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PhoneNumberRange that = (PhoneNumberRange) o;
+        return Objects.equals(mCountryCode, that.mCountryCode)
+                && Objects.equals(mPrefix, that.mPrefix)
+                && Objects.equals(mLowerBound, that.mLowerBound)
+                && Objects.equals(mUpperBound, that.mUpperBound);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mCountryCode, mPrefix, mLowerBound, mUpperBound);
+    }
+
+    @Override
+    public String toString() {
+        return "PhoneNumberRange{"
+                + "mCountryCode='" + mCountryCode + '\''
+                + ", mPrefix='" + mPrefix + '\''
+                + ", mLowerBound='" + mLowerBound + '\''
+                + ", mUpperBound='" + mUpperBound + '\''
+                + '}';
+    }
+
+    private void validateLowerAndUpperBounds(String lowerBound, String upperBound) {
+        if (lowerBound.length() != upperBound.length()) {
+            throw new IllegalArgumentException("Lower and upper bounds must have the same length");
+        }
+        if (!Pattern.matches("[0-9]+", lowerBound)) {
+            throw new IllegalArgumentException("Lower bound must be all numeric");
+        }
+        if (!Pattern.matches("[0-9]+", upperBound)) {
+            throw new IllegalArgumentException("Upper bound must be all numeric");
+        }
+        if (Integer.parseInt(lowerBound) > Integer.parseInt(upperBound)) {
+            throw new IllegalArgumentException("Lower bound must be lower than upper bound");
+        }
+    }
+
+    /**
+     * Checks to see if the provided phone number matches this range.
+     * @param number A phone number, with or without separators or a country code.
+     * @return {@code true} if the number matches, {@code false} otherwise.
+     */
+    public boolean matches(String number) {
+        // Check the prefix, make sure it matches either with or without the country code.
+        String normalizedNumber = number.replaceAll("[^0-9]", "");
+        String prefixWithCountryCode = mCountryCode + mPrefix;
+        String numberPostfix;
+        if (normalizedNumber.startsWith(prefixWithCountryCode)) {
+            numberPostfix = normalizedNumber.substring(prefixWithCountryCode.length());
+        } else if (normalizedNumber.startsWith(mPrefix)) {
+            numberPostfix = normalizedNumber.substring(mPrefix.length());
+        } else {
+            return false;
+        }
+
+        // Next check the postfix to make sure it lies within the bounds.
+        try {
+            int lower = Integer.parseInt(mLowerBound);
+            int upper = Integer.parseInt(mUpperBound);
+            int numberToCheck = Integer.parseInt(numberPostfix);
+            return numberToCheck <= upper && numberToCheck >= lower;
+        } catch (NumberFormatException e) {
+            Log.e(PhoneNumberRange.class.getSimpleName(), "Invalid bounds or number.", e);
+            return false;
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 13fbeaa..ca0c854 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -118,6 +118,13 @@
      */
     public static final int FREQUENCY_RANGE_MMWAVE = 4;
 
+    private static final List<Integer> FREQUENCY_RANGE_ORDER = Arrays.asList(
+            FREQUENCY_RANGE_UNKNOWN,
+            FREQUENCY_RANGE_LOW,
+            FREQUENCY_RANGE_MID,
+            FREQUENCY_RANGE_HIGH,
+            FREQUENCY_RANGE_MMWAVE);
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = "DUPLEX_MODE_",
@@ -1835,4 +1842,13 @@
             mNetworkRegistrationStates.add(regState);
         }
     }
+
+    /**
+     * @hide
+     */
+    public static final int getBetterNRFrequencyRange(int range1, int range2) {
+        return FREQUENCY_RANGE_ORDER.indexOf(range1) > FREQUENCY_RANGE_ORDER.indexOf(range2)
+                ? range1
+                : range2;
+    }
 }
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index b41e14e..bacfe61a 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -150,6 +150,11 @@
     private String mGroupUUID;
 
     /**
+     *  A property in opportunistic subscription to indicate whether it is metered or not.
+     */
+    private boolean mIsMetered;
+
+    /**
      * @hide
      */
     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
@@ -158,7 +163,7 @@
             @Nullable UiccAccessRule[] accessRules, String cardId) {
         this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
                 roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardId,
-                false, null);
+                false, null, true);
     }
 
     /**
@@ -168,7 +173,7 @@
             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
             Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
             @Nullable UiccAccessRule[] accessRules, String cardId, boolean isOpportunistic,
-            @Nullable String groupUUID) {
+            @Nullable String groupUUID, boolean isMetered) {
         this.mId = id;
         this.mIccId = iccId;
         this.mSimSlotIndex = simSlotIndex;
@@ -187,8 +192,10 @@
         this.mCardId = cardId;
         this.mIsOpportunistic = isOpportunistic;
         this.mGroupUUID = groupUUID;
+        this.mIsMetered = isMetered;
     }
 
+
     /**
      * @return the subscription ID.
      */
@@ -403,6 +410,18 @@
     }
 
     /**
+     * Used in opportunistic subscription ({@link #isOpportunistic()}) to indicate whether it's
+     * metered or not.This is one of the factors when deciding to switch to the subscription.
+     * (a non-metered subscription, for example, would likely be preferred over a metered one).
+     *
+     * @return whether subscription is metered.
+     * @hide
+     */
+    public boolean isMetered() {
+        return mIsMetered;
+    }
+
+    /**
      * Checks whether the app with the given context is authorized to manage this subscription
      * according to its metadata. Only supported for embedded subscriptions (if {@link #isEmbedded}
      * returns true).
@@ -496,10 +515,11 @@
             String cardId = source.readString();
             boolean isOpportunistic = source.readBoolean();
             String groupUUID = source.readString();
+            boolean isMetered = source.readBoolean();
 
             return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
                     nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
-                    isEmbedded, accessRules, cardId, isOpportunistic, groupUUID);
+                    isEmbedded, accessRules, cardId, isOpportunistic, groupUUID, isMetered);
         }
 
         @Override
@@ -528,6 +548,7 @@
         dest.writeString(mCardId);
         dest.writeBoolean(mIsOpportunistic);
         dest.writeString(mGroupUUID);
+        dest.writeBoolean(mIsMetered);
     }
 
     @Override
@@ -561,14 +582,14 @@
                 + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded
                 + " accessRules " + Arrays.toString(mAccessRules)
                 + " cardId=" + cardIdToPrint + " isOpportunistic " + mIsOpportunistic
-                + " mGroupUUID=" + mGroupUUID + "}";
+                + " mGroupUUID=" + mGroupUUID + " isMetered=" + mIsMetered + "}";
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded,
-                mIsOpportunistic, mGroupUUID, mIccId, mNumber, mMcc, mMnc, mCountryIso,
-                mCardId, mDisplayName, mCarrierName, mAccessRules);
+                mIsOpportunistic, mGroupUUID, mIsMetered, mIccId, mNumber, mMcc, mMnc,
+                mCountryIso, mCardId, mDisplayName, mCarrierName, mAccessRules);
     }
 
     @Override
@@ -591,6 +612,7 @@
                 && mIsEmbedded == toCompare.mIsEmbedded
                 && mIsOpportunistic == toCompare.mIsOpportunistic
                 && Objects.equals(mGroupUUID, toCompare.mGroupUUID)
+                && mIsMetered == toCompare.mIsMetered
                 && Objects.equals(mIccId, toCompare.mIccId)
                 && Objects.equals(mNumber, toCompare.mNumber)
                 && Objects.equals(mMcc, toCompare.mMcc)
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 45cfe1e..2c06c47 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -407,6 +407,13 @@
     public static final String MNC = "mnc";
 
     /**
+     * TelephonyProvider column name for the iso country code associated with a SIM.
+     * <P>Type: TEXT (String)</P>
+     * @hide
+     */
+    public static final String ISO_COUNTRY_CODE = "iso_country_code";
+
+    /**
      * TelephonyProvider column name for the sim provisioning status associated with a SIM.
      * <P>Type: INTEGER (int)</P>
      * @hide
@@ -576,7 +583,12 @@
      * @hide
      */
     public static final String GROUP_UUID = "group_uuid";
-
+    /**
+     * TelephonyProvider column name for whether a subscription is metered or not, that is, whether
+     * the network it connects to charges for subscription or not. For example, paid CBRS or unpaid.
+     * @hide
+     */
+    public static final String IS_METERED = "is_metered";
     /**
      * Broadcast Action: The user has changed one of the default subs related to
      * data, phone calls, or sms</p>
@@ -1578,14 +1590,23 @@
         return subId;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setDefaultSmsSubId(int subId) {
-        if (VDBG) logd("setDefaultSmsSubId sub id = " + subId);
+    /**
+     * Set the subscription which will be used by default for SMS, with the subscription which
+     * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
+     * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
+     *
+     * @param subscriptionId the supplied subscription ID
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDefaultSmsSubId(int subscriptionId) {
+        if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId);
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                iSub.setDefaultSmsSubId(subId);
+                iSub.setDefaultSmsSubId(subscriptionId);
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -1633,14 +1654,23 @@
         return subId;
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public void setDefaultDataSubId(int subId) {
-        if (VDBG) logd("setDataSubscription sub id = " + subId);
+    /**
+     * Set the subscription which will be used by default for data, with the subscription which
+     * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied
+     * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}).
+     *
+     * @param subscriptionId the supplied subscription ID
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setDefaultDataSubId(int subscriptionId) {
+        if (VDBG) logd("setDataSubscription sub id = " + subscriptionId);
         try {
             ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
             if (iSub != null) {
-                iSub.setDefaultDataSubId(subId);
+                iSub.setDefaultDataSubId(subscriptionId);
             }
         } catch (RemoteException ex) {
             // ignore it
@@ -2403,6 +2433,21 @@
         return groupUUID;
     }
 
+    /**
+     * Set metered by simInfo index
+     *
+     * @param isMetered whether it’s a metered subscription.
+     * @param subId the unique SubscriptionInfo index in database
+     * @return the number of records updated
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public int setMetered(boolean isMetered, int subId) {
+        if (VDBG) logd("[setIsMetered]+ isMetered:" + isMetered + " subId:" + subId);
+        return setSubscriptionPropertyHelper(subId, "setIsMetered",
+                (iSub)-> iSub.setMetered(isMetered, subId));
+    }
+
     private interface CallISubMethodHelper {
         int callMethod(ISub iSub) throws RemoteException;
     }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 7a6647c..fa9b76d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -77,6 +77,7 @@
 import com.android.internal.telecom.ITelecomService;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.IAns;
+import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.IPhoneSubInfo;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.ITelephonyRegistry;
@@ -1341,6 +1342,13 @@
      */
     public static final String EXTRA_RECOVERY_ACTION = "recoveryAction";
 
+    /**
+     * The max value for the timeout passed in {@link #requestNumberVerification}.
+     * @hide
+     */
+    @SystemApi
+    public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000;
+
     //
     //
     // Device Info
@@ -5503,6 +5511,73 @@
     }
 
     /**
+     * Request that the next incoming call from a number matching {@code range} be intercepted.
+     *
+     * This API is intended for OEMs to provide a service for apps to verify the device's phone
+     * number. When called, the Telephony stack will store the provided {@link PhoneNumberRange} and
+     * intercept the next incoming call from a number that lies within the range, within a timeout
+     * specified by {@code timeoutMillis}.
+     *
+     * If such a phone call is received, the caller will be notified via
+     * {@link NumberVerificationCallback#onCallReceived(String)} on the provided {@link Executor}.
+     * If verification fails for any reason, the caller will be notified via
+     * {@link NumberVerificationCallback#onVerificationFailed(int)}
+     * on the provided {@link Executor}.
+     *
+     * In addition to the {@link Manifest.permission#MODIFY_PHONE_STATE} permission, callers of this
+     * API must also be listed in the device configuration as an authorized app in
+     * {@code packages/services/Telephony/res/values/config.xml} under the
+     * {@code config_number_verification_package_name} key.
+     *
+     * @hide
+     * @param range The range of phone numbers the caller expects a phone call from.
+     * @param timeoutMillis The amount of time to wait for such a call, or
+     *                      {@link #MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS}, whichever is lesser.
+     * @param executor The {@link Executor} that callbacks should be executed on.
+     * @param callback The callback to use for delivering results.
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void requestNumberVerification(@NonNull PhoneNumberRange range, long timeoutMillis,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull NumberVerificationCallback callback) {
+        if (executor == null) {
+            throw new NullPointerException("Executor must be non-null");
+        }
+        if (callback == null) {
+            throw new NullPointerException("Callback must be non-null");
+        }
+
+        INumberVerificationCallback internalCallback = new INumberVerificationCallback.Stub() {
+            @Override
+            public void onCallReceived(String phoneNumber) {
+                Binder.withCleanCallingIdentity(() ->
+                        executor.execute(() ->
+                                callback.onCallReceived(phoneNumber)));
+            }
+
+            @Override
+            public void onVerificationFailed(int reason) {
+                Binder.withCleanCallingIdentity(() ->
+                        executor.execute(() ->
+                                callback.onVerificationFailed(reason)));
+            }
+        };
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                telephony.requestNumberVerification(range, timeoutMillis, internalCallback,
+                        getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "requestNumberVerification RemoteException", ex);
+            executor.execute(() ->
+                    callback.onVerificationFailed(NumberVerificationCallback.REASON_UNSPECIFIED));
+        }
+    }
+
+    /**
      * Sets a per-phone telephony property with the value specified.
      *
      * @hide
@@ -9533,4 +9608,34 @@
         }
         return subId;
     }
+
+    /**
+     * Update availability of a list of networks in the current location.
+     *
+     * This api should be called to inform AlternativeNetwork Service about the availability
+     * of a network at the current location. This information will be used by AlternativeNetwork
+     * service to decide to attach to the network opportunistically. If an empty list is passed,
+     * it is assumed that no network is available.
+     * Requires that the calling app has carrier privileges on both primary and
+     * secondary subscriptions (see {@link #hasCarrierPrivileges}), or has permission
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     * @param availableNetworks is a list of available network information.
+     * @return true if request is accepted
+     *
+     */
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    public boolean updateAvailableNetworks(List<AvailableNetworkInfo> availableNetworks) {
+        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        boolean ret = false;
+        try {
+            IAns iAlternativeNetworkService = getIAns();
+            if (iAlternativeNetworkService != null) {
+                ret = iAlternativeNetworkService.updateAvailableNetworks(availableNetworks,
+                        pkgForDebug);
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "updateAvailableNetworks RemoteException", ex);
+        }
+        return ret;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/IAns.aidl b/telephony/java/com/android/internal/telephony/IAns.aidl
index e9a4649..98bcd41 100755
--- a/telephony/java/com/android/internal/telephony/IAns.aidl
+++ b/telephony/java/com/android/internal/telephony/IAns.aidl
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.telephony.AvailableNetworkInfo;
 
 interface IAns {
 
@@ -78,4 +79,23 @@
      *
      */
     int getPreferredData(String callingPackage);
+
+    /**
+     * Update availability of a list of networks in the current location.
+     *
+     * This api should be called if the caller is aware of the availability of a network
+     * at the current location. This information will be used by AlternativeNetwork service
+     * to decide to attach to the network. If an empty list is passed,
+     * it is assumed that no network is available.
+     * Requires that the calling app has carrier privileges on both primary and
+     * secondary subscriptions (see
+     * {@link #hasCarrierPrivileges}), or has permission
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     *  @param availableNetworks is a list of available network information.
+     *  @param callingPackage caller's package name
+     *  @return true if request is accepted
+     *
+     */
+    boolean updateAvailableNetworks(in List<AvailableNetworkInfo> availableNetworks,
+            String callingPackage);
 }
diff --git a/telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl b/telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl
new file mode 100644
index 0000000..76918af
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2018 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.telephony;
+
+oneway interface INumberVerificationCallback {
+    void onCallReceived(String phoneNumber);
+    void onVerificationFailed(int reason);
+}
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index bc44519..f9db4b0 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -184,6 +184,15 @@
     String setSubscriptionGroup(in int[] subIdList, String callingPackage);
 
     /**
+     * Set whether a subscription is metered
+     *
+     * @param isMetered whether it’s a metered subscription.
+     * @param subId the unique SubscriptionInfo index in database
+     * @return the number of records updated
+     */
+    int setMetered(boolean isMetered, int subId);
+
+    /**
      * Set which subscription is preferred for cellular data. It's
      * designed to overwrite default data subscription temporarily.
      *
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 32e939a0..399dc52 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -35,6 +35,7 @@
 import android.telephony.ModemActivityInfo;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.NetworkScanRequest;
+import android.telephony.PhoneNumberRange;
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
@@ -49,6 +50,7 @@
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.telephony.CellNetworkScanResult;
+import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.OperatorInfo;
 
 import java.util.List;
@@ -871,6 +873,17 @@
     String getCdmaMin(int subId);
 
     /**
+     * Request that the next incoming call from a number matching {@code range} be intercepted.
+     * @param range The range of phone numbers the caller expects a phone call from.
+     * @param timeoutMillis The amount of time to wait for such a call, or
+     *                      {@link #MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS}, whichever is lesser.
+     * @param callback the callback aidl
+     * @param callingPackage the calling package name.
+     */
+    void requestNumberVerification(in PhoneNumberRange range, long timeoutMillis,
+            in INumberVerificationCallback callback, String callingPackage);
+
+    /**
      * Has the calling application been granted special privileges by the carrier.
      *
      * If any of the packages in the calling UID has carrier privileges, the
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 4dc0341..d8f9618 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -542,7 +542,7 @@
 
         verify(mMockNetd)
                 .ipSecApplyTransportModeTransform(
-                        eq(pfd.getFileDescriptor()),
+                        eq(pfd),
                         eq(mUid),
                         eq(IpSecManager.DIRECTION_OUT),
                         anyString(),
@@ -555,7 +555,7 @@
         ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
         mIpSecService.removeTransportModeTransforms(pfd);
 
-        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
+        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd);
     }
 
     private IpSecTunnelInterfaceResponse createAndValidateTunnel(
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 2c94a60..724446e 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -425,7 +425,7 @@
         ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(new Socket());
         mIpSecService.removeTransportModeTransforms(pfd);
 
-        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd.getFileDescriptor());
+        verify(mMockNetd).ipSecRemoveTransportModeTransform(pfd);
     }
 
     @Test
@@ -620,10 +620,10 @@
                 mIpSecService.openUdpEncapsulationSocket(0, new Binder());
 
         FileDescriptor sockFd = udpEncapResp.fileDescriptor.getFileDescriptor();
-        ArgumentMatcher<FileDescriptor> fdMatcher = (arg) -> {
+        ArgumentMatcher<ParcelFileDescriptor> fdMatcher = (arg) -> {
                     try {
                         StructStat sockStat = Os.fstat(sockFd);
-                        StructStat argStat = Os.fstat(arg);
+                        StructStat argStat = Os.fstat(arg.getFileDescriptor());
 
                         return sockStat.st_ino == argStat.st_ino
                                 && sockStat.st_dev == argStat.st_dev;
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index ed70fb3..df0daeb 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -240,6 +240,12 @@
         }
         break;
 
+      case android::RES_TABLE_OVERLAYABLE_TYPE:
+        if (!ParseOverlayable(parser.chunk())) {
+          return false;
+        }
+        break;
+
       default:
         diag_->Warn(DiagMessage(source_)
                     << "unexpected chunk type "
@@ -383,24 +389,12 @@
       return false;
     }
 
-    const uint32_t type_spec_flags = entry_type_spec_flags_[res_id];
-    if ((entry->flags & ResTable_entry::FLAG_PUBLIC) != 0 ||
-        (type_spec_flags & ResTable_typeSpec::SPEC_OVERLAYABLE) != 0) {
-      if (entry->flags & ResTable_entry::FLAG_PUBLIC) {
-        Visibility visibility;
-        visibility.level = Visibility::Level::kPublic;
-        visibility.source = source_.WithLine(0);
-        if (!table_->SetVisibilityWithIdMangled(name, visibility, res_id, diag_)) {
-          return false;
-        }
-      }
-
-      if (type_spec_flags & ResTable_typeSpec::SPEC_OVERLAYABLE) {
-        Overlayable overlayable;
-        overlayable.source = source_.WithLine(0);
-        if (!table_->AddOverlayableMangled(name, overlayable, diag_)) {
-          return false;
-        }
+    if (entry->flags & ResTable_entry::FLAG_PUBLIC) {
+      Visibility visibility;
+      visibility.level = Visibility::Level::kPublic;
+      visibility.source = source_.WithLine(0);
+      if (!table_->SetVisibilityWithIdMangled(name, visibility, res_id, diag_)) {
+        return false;
       }
 
       // Erase the ID from the map once processed, so that we don't mark the same symbol more than
@@ -433,6 +427,72 @@
   return true;
 }
 
+bool BinaryResourceParser::ParseOverlayable(const ResChunk_header* chunk) {
+  const ResTable_overlayable_header* header = ConvertTo<ResTable_overlayable_header>(chunk);
+  if (!header) {
+    diag_->Error(DiagMessage(source_) << "corrupt ResTable_category_header chunk");
+    return false;
+  }
+
+  ResChunkPullParser parser(GetChunkData(chunk),
+                            GetChunkDataLen(chunk));
+  while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
+    if (util::DeviceToHost16(parser.chunk()->type) == android::RES_TABLE_OVERLAYABLE_POLICY_TYPE) {
+      const ResTable_overlayable_policy_header* policy_header =
+          ConvertTo<ResTable_overlayable_policy_header>(parser.chunk());
+
+      std::vector<Overlayable::Policy> policies;
+      if (policy_header->policy_flags & ResTable_overlayable_policy_header::POLICY_PUBLIC) {
+        policies.push_back(Overlayable::Policy::kPublic);
+      }
+      if (policy_header->policy_flags
+          & ResTable_overlayable_policy_header::POLICY_SYSTEM_PARTITION) {
+        policies.push_back(Overlayable::Policy::kSystem);
+      }
+      if (policy_header->policy_flags
+          & ResTable_overlayable_policy_header::POLICY_VENDOR_PARTITION) {
+        policies.push_back(Overlayable::Policy::kVendor);
+      }
+      if (policy_header->policy_flags
+          & ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION) {
+        policies.push_back(Overlayable::Policy::kProduct);
+      }
+      if (policy_header->policy_flags
+          & ResTable_overlayable_policy_header::POLICY_PRODUCT_SERVICES_PARTITION) {
+        policies.push_back(Overlayable::Policy::kProductServices);
+      }
+
+      const ResTable_ref* const ref_begin = reinterpret_cast<const ResTable_ref*>(
+          ((uint8_t *)policy_header) + util::DeviceToHost32(policy_header->header.headerSize));
+      const ResTable_ref* const ref_end = ref_begin
+          + util::DeviceToHost32(policy_header->entry_count);
+      for (auto ref_iter = ref_begin; ref_iter != ref_end; ++ref_iter) {
+        ResourceId res_id(util::DeviceToHost32(ref_iter->ident));
+        const auto iter = id_index_.find(res_id);
+
+        // If the overlayable chunk comes before the type chunks, the resource ids and resource name
+        // pairing will not exist at this point.
+        if (iter == id_index_.cend()) {
+          diag_->Error(DiagMessage(source_) << "failed to find resource name for overlayable"
+                                            << " resource " << res_id);
+          return false;
+        }
+
+        for (Overlayable::Policy policy : policies) {
+          Overlayable overlayable;
+          overlayable.source = source_.WithLine(0);
+          overlayable.policy = policy;
+          if (!table_->AddOverlayable(iter->second, overlayable, diag_)) {
+            return false;
+          }
+        }
+      }
+    }
+  }
+
+  return true;
+}
+
 std::unique_ptr<Item> BinaryResourceParser::ParseValue(const ResourceNameRef& name,
                                                        const ConfigDescription& config,
                                                        const android::Res_value& value) {
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.h b/tools/aapt2/format/binary/BinaryResourceParser.h
index 2bdc051..a2eee50 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.h
+++ b/tools/aapt2/format/binary/BinaryResourceParser.h
@@ -54,6 +54,7 @@
   bool ParseTypeSpec(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
   bool ParseType(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
   bool ParseLibrary(const android::ResChunk_header* chunk);
+  bool ParseOverlayable(const android::ResChunk_header* chunk);
 
   std::unique_ptr<Item> ParseValue(const ResourceNameRef& name,
                                    const android::ConfigDescription& config,
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index 6c1a9ba..976c328 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -24,6 +24,7 @@
 #include "android-base/logging.h"
 #include "android-base/macros.h"
 #include "android-base/stringprintf.h"
+#include "androidfw/ResourceUtils.h"
 
 #include "ResourceTable.h"
 #include "ResourceValues.h"
@@ -216,6 +217,11 @@
   size_t entry_count_ = 0;
 };
 
+struct PolicyChunk {
+  uint32_t policy_flags;
+  std::set<ResourceId> ids;
+};
+
 class PackageFlattener {
  public:
   PackageFlattener(IAaptContext* context, ResourceTablePackage* package,
@@ -267,6 +273,8 @@
       FlattenLibrarySpec(buffer);
     }
 
+    FlattenOverlayable(buffer);
+
     pkg_writer.Finish();
     return true;
   }
@@ -413,6 +421,97 @@
     return sorted_entries;
   }
 
+  void FlattenOverlayable(BigBuffer* buffer) {
+    std::vector<PolicyChunk> policies;
+
+    CHECK(bool(package_->id)) << "package must have an ID set when flattening <overlayable>";
+    for (auto& type : package_->types) {
+      CHECK(bool(type->id)) << "type must have an ID set when flattening <overlayable>";
+      for (auto& entry : type->entries) {
+        CHECK(bool(type->id)) << "entry must have an ID set when flattening <overlayable>";
+
+        // TODO(b/120298168): Convert the policies vector to a policy set or bitmask
+        if (!entry->overlayable_declarations.empty()) {
+          uint16_t policy_flags = 0;
+          for (Overlayable overlayable : entry->overlayable_declarations) {
+            if (overlayable.policy) {
+              switch (overlayable.policy.value()) {
+                case Overlayable::Policy::kPublic:
+                  policy_flags |= ResTable_overlayable_policy_header::POLICY_PUBLIC;
+                  break;
+                case Overlayable::Policy::kSystem:
+                  policy_flags |= ResTable_overlayable_policy_header::POLICY_SYSTEM_PARTITION;
+                  break;
+                case Overlayable::Policy::kVendor:
+                  policy_flags |= ResTable_overlayable_policy_header::POLICY_VENDOR_PARTITION;
+                  break;
+                case Overlayable::Policy::kProduct:
+                  policy_flags |= ResTable_overlayable_policy_header::POLICY_PRODUCT_PARTITION;
+                  break;
+                case Overlayable::Policy::kProductServices:
+                  policy_flags |=
+                      ResTable_overlayable_policy_header::POLICY_PRODUCT_SERVICES_PARTITION;
+                  break;
+              }
+            } else {
+              // Encode overlayable entries defined without a policy as publicly overlayable
+              policy_flags |= ResTable_overlayable_policy_header::POLICY_PUBLIC;
+            }
+          }
+
+          // Find the overlayable policy chunk with the same policies as the entry
+          PolicyChunk* policy_chunk = nullptr;
+          for (PolicyChunk& policy : policies) {
+            if (policy.policy_flags == policy_flags) {
+              policy_chunk = &policy;
+              break;
+            }
+          }
+
+          // Create a new policy chunk if an existing one with the same policy cannot be found
+          if (policy_chunk == nullptr) {
+            PolicyChunk p;
+            p.policy_flags = policy_flags;
+            policies.push_back(p);
+            policy_chunk = &policies.back();
+          }
+
+          policy_chunk->ids.insert(android::make_resid(package_->id.value(), type->id.value(),
+                                                       entry->id.value()));
+        }
+      }
+    }
+
+    if (policies.empty()) {
+      // Only write the overlayable chunk if the APK has overlayable entries
+      return;
+    }
+
+    ChunkWriter writer(buffer);
+    writer.StartChunk<ResTable_overlayable_header>(RES_TABLE_OVERLAYABLE_TYPE);
+
+    // Write each policy block for the overlayable
+    for (PolicyChunk& policy : policies) {
+      ChunkWriter policy_writer(buffer);
+      ResTable_overlayable_policy_header* policy_type =
+          policy_writer.StartChunk<ResTable_overlayable_policy_header>(
+              RES_TABLE_OVERLAYABLE_POLICY_TYPE);
+      policy_type->policy_flags = util::HostToDevice32(policy.policy_flags);
+      policy_type->entry_count = util::HostToDevice32(static_cast<uint32_t>(policy.ids.size()));
+
+      // Write the ids after the policy header
+      ResTable_ref* id_block = policy_writer.NextBlock<ResTable_ref>(policy.ids.size());
+      for (const ResourceId& id : policy.ids) {
+        id_block->ident = util::HostToDevice32(id.id);
+        id_block++;
+      }
+
+      policy_writer.Finish();
+    }
+
+    writer.Finish();
+  }
+
   bool FlattenTypeSpec(ResourceTableType* type, std::vector<ResourceEntry*>* sorted_entries,
                        BigBuffer* buffer) {
     ChunkWriter type_spec_writer(buffer);
@@ -446,11 +545,6 @@
         config_masks[entry->id.value()] |= util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
       }
 
-      if (!entry->overlayable_declarations.empty()) {
-        config_masks[entry->id.value()] |=
-            util::HostToDevice32(ResTable_typeSpec::SPEC_OVERLAYABLE);
-      }
-
       const size_t config_count = entry->values.size();
       for (size_t i = 0; i < config_count; i++) {
         const ConfigDescription& config = entry->values[i]->config;
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index cd1414c..410efbe 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -628,24 +628,108 @@
 }
 
 TEST_F(TableFlattenerTest, FlattenOverlayable) {
+  std::string name = "com.app.test:integer/overlayable";
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
           .SetPackageId("com.app.test", 0x7f)
-          .AddSimple("com.app.test:integer/overlayable", ResourceId(0x7f020000))
+          .AddSimple(name, ResourceId(0x7f020000))
+          .AddOverlayable(name, Overlayable::Policy::kProduct)
+          .AddOverlayable(name, Overlayable::Policy::kSystem)
+          .AddOverlayable(name, Overlayable::Policy::kVendor)
           .Build();
 
-  ASSERT_TRUE(table->AddOverlayable(test::ParseNameOrDie("com.app.test:integer/overlayable"),
-                                    Overlayable{}, test::GetDiagnostics()));
+  ResourceTable output_table;
+  ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &output_table));
 
-  ResTable res_table;
-  ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &res_table));
-
-  const StringPiece16 overlayable_name(u"com.app.test:integer/overlayable");
-  uint32_t spec_flags = 0u;
-  ASSERT_THAT(res_table.identifierForName(overlayable_name.data(), overlayable_name.size(), nullptr,
-                                          0u, nullptr, 0u, &spec_flags),
-              Gt(0u));
-  EXPECT_TRUE(spec_flags & android::ResTable_typeSpec::SPEC_OVERLAYABLE);
+  auto search_result = output_table.FindResource(test::ParseNameOrDie(name));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 3);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kSystem);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[1].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[1].policy,
+            Overlayable::Policy::kVendor);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[2].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[2].policy,
+            Overlayable::Policy::kProduct);
 }
 
+TEST_F(TableFlattenerTest, FlattenMultipleOverlayablePolicies) {
+  std::string name_zero = "com.app.test:integer/overlayable_zero";
+  std::string name_one = "com.app.test:integer/overlayable_one";
+  std::string name_two = "com.app.test:integer/overlayable_two";
+  std::string name_three = "com.app.test:integer/overlayable_three";
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .SetPackageId("com.app.test", 0x7f)
+          .AddSimple(name_zero, ResourceId(0x7f020000))
+          .AddOverlayable(name_zero, Overlayable::Policy::kProduct)
+          .AddOverlayable(name_zero, Overlayable::Policy::kSystem)
+          .AddOverlayable(name_zero, Overlayable::Policy::kProductServices)
+          .AddSimple(name_one, ResourceId(0x7f020001))
+          .AddOverlayable(name_one, Overlayable::Policy::kPublic)
+          .AddOverlayable(name_one, Overlayable::Policy::kSystem)
+          .AddSimple(name_two, ResourceId(0x7f020002))
+          .AddOverlayable(name_two, Overlayable::Policy::kProduct)
+          .AddOverlayable(name_two, Overlayable::Policy::kSystem)
+          .AddOverlayable(name_two, Overlayable::Policy::kProductServices)
+          .AddSimple(name_three, ResourceId(0x7f020003))
+          .AddOverlayable(name_three, {})
+          .Build();
+
+  ResourceTable output_table;
+  ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &output_table));
+
+  auto search_result = output_table.FindResource(test::ParseNameOrDie(name_zero));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 3);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kSystem);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[1].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[1].policy,
+            Overlayable::Policy::kProduct);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[2].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[2].policy,
+            Overlayable::Policy::kProductServices);
+
+  search_result = output_table.FindResource(test::ParseNameOrDie(name_one));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 2);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kPublic);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[1].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[1].policy,
+            Overlayable::Policy::kSystem);
+
+  search_result = output_table.FindResource(test::ParseNameOrDie(name_two));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 3);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kSystem);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[1].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[1].policy,
+            Overlayable::Policy::kProduct);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[2].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[2].policy,
+            Overlayable::Policy::kProductServices);
+
+  search_result = output_table.FindResource(test::ParseNameOrDie(name_three));
+  ASSERT_TRUE(search_result);
+  ASSERT_THAT(search_result.value().entry, NotNull());
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations.size(), 1);
+  EXPECT_TRUE(search_result.value().entry->overlayable_declarations[0].policy);
+  EXPECT_EQ(search_result.value().entry->overlayable_declarations[0].policy,
+            Overlayable::Policy::kPublic);
+
+}
+
+
 }  // namespace aapt
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 3a5d585..1b6626a 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -368,7 +368,16 @@
         // Symbol state information may be lost if there is no value for the resource.
         if (entry->visibility.level != Visibility::Level::kUndefined && entry->values.empty()) {
           context->GetDiagnostics()->Error(DiagMessage(entry->visibility.source)
-                                           << "no definition for declared symbol '" << name << "'");
+                                               << "no definition for declared symbol '" << name
+                                               << "'");
+          error = true;
+        }
+
+        // Ensure that definitions for values declared as overlayable exist
+        if (!entry->overlayable_declarations.empty() && entry->values.empty()) {
+          context->GetDiagnostics()->Error(DiagMessage(entry->overlayable_declarations[0].source)
+                                           << "no definition for overlayable symbol '"
+                                           << name << "'");
           error = true;
         }
 
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index 2f1e53c..01728fa1 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -26,6 +26,7 @@
 FLAG_GREYLIST = "greylist"
 FLAG_BLACKLIST = "blacklist"
 FLAG_GREYLIST_MAX_O = "greylist-max-o"
+FLAG_GREYLIST_MAX_P = "greylist-max-p"
 
 # List of all known flags.
 FLAGS = [
@@ -33,6 +34,7 @@
     FLAG_GREYLIST,
     FLAG_BLACKLIST,
     FLAG_GREYLIST_MAX_O,
+    FLAG_GREYLIST_MAX_P,
 ]
 FLAGS_SET = set(FLAGS)
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 8e0d4ac..89b6703 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1982,6 +1982,8 @@
     public static final int WIFI_FEATURE_WPA3_SUITE_B     = 0x10000000; // WPA3-Enterprise Suite-B
     /** @hide */
     public static final int WIFI_FEATURE_OWE              = 0x20000000; // Enhanced Open
+    /** @hide */
+    public static final int WIFI_FEATURE_LOW_LATENCY      = 0x40000000; // Low Latency modes
 
     private int getSupportedFeatures() {
         try {
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index b0ed110..e0442f2 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -22,7 +22,6 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -1695,7 +1694,6 @@
      * @param listener for callback on success or failure. Can be null.
      * @hide
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
     public void factoryReset(@NonNull Channel c, @Nullable ActionListener listener) {
         checkChannel(c);