Merge "Helper methods for constructing MediaStore Uris."
diff --git a/Android.bp b/Android.bp
index 56547b2..4c07fcf 100644
--- a/Android.bp
+++ b/Android.bp
@@ -248,7 +248,6 @@
         "core/java/android/os/ICancellationSignal.aidl",
         "core/java/android/os/IDeviceIdentifiersPolicyService.aidl",
         "core/java/android/os/IDeviceIdleController.aidl",
-        "core/java/android/os/IDynamicAndroidService.aidl",
         "core/java/android/os/IHardwarePropertiesManager.aidl",
         ":libincident_aidl",
         "core/java/android/os/IMaintenanceActivityListener.aidl",
@@ -272,6 +271,7 @@
         "core/java/android/os/IUserManager.aidl",
         ":libvibrator_aidl",
         "core/java/android/os/IVibratorService.aidl",
+        "core/java/android/os/image/IDynamicSystemService.aidl",
         "core/java/android/os/storage/IStorageManager.aidl",
         "core/java/android/os/storage/IStorageEventListener.aidl",
         "core/java/android/os/storage/IStorageShutdownObserver.aidl",
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 30c2c69..6160acb 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -253,6 +253,7 @@
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/overlay/ExperimentNavigationBarSlim)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/SystemUI)
 $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/DynamicAndroidInstallationService)
 # ******************************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
 # ******************************************************************
diff --git a/api/current.txt b/api/current.txt
index a961295..a15daa2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5481,10 +5481,10 @@
     method public boolean getAutoExpandBubble();
     method @Nullable public android.app.PendingIntent getDeleteIntent();
     method public int getDesiredHeight();
+    method @DimenRes public int getDesiredHeightResId();
     method @NonNull public android.graphics.drawable.Icon getIcon();
     method @NonNull public android.app.PendingIntent getIntent();
     method public boolean getSuppressInitialNotification();
-    method @Deprecated public CharSequence getTitle();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.Notification.BubbleMetadata> CREATOR;
   }
@@ -5495,10 +5495,10 @@
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean);
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(@Nullable android.app.PendingIntent);
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int);
+    method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setIcon(@NonNull android.graphics.drawable.Icon);
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setIntent(@NonNull android.app.PendingIntent);
     method @NonNull public android.app.Notification.BubbleMetadata.Builder setSuppressInitialNotification(boolean);
-    method @Deprecated public android.app.Notification.BubbleMetadata.Builder setTitle(CharSequence);
   }
 
   public static class Notification.Builder {
@@ -9794,6 +9794,7 @@
     field public static final int BIND_DEBUG_UNBIND = 2; // 0x2
     field public static final int BIND_EXTERNAL_SERVICE = -2147483648; // 0x80000000
     field public static final int BIND_IMPORTANT = 64; // 0x40
+    field public static final int BIND_INCLUDE_CAPABILITIES = 4096; // 0x1000
     field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
     field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
     field public static final String BIOMETRIC_SERVICE = "biometric";
@@ -12356,6 +12357,7 @@
     method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[]);
     method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@StyleRes int, @NonNull @StyleableRes int[]) throws android.content.res.Resources.NotFoundException;
     method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@Nullable android.util.AttributeSet, @NonNull @StyleableRes int[], @AttrRes int, @StyleRes int);
+    method public void rebase();
     method public boolean resolveAttribute(int, android.util.TypedValue, boolean);
     method public void setTo(android.content.res.Resources.Theme);
   }
@@ -22664,18 +22666,22 @@
   public final class GnssClock implements android.os.Parcelable {
     method public int describeContents();
     method public double getBiasNanos();
-    method public double getBiasUncertaintyNanos();
+    method @FloatRange(from=0.0f) public double getBiasUncertaintyNanos();
     method public double getDriftNanosPerSecond();
-    method public double getDriftUncertaintyNanosPerSecond();
+    method @FloatRange(from=0.0f) public double getDriftUncertaintyNanosPerSecond();
+    method public long getElapsedRealtimeNanos();
+    method @IntRange(from=0) public long getElapsedRealtimeUncertaintyNanos();
     method public long getFullBiasNanos();
     method public int getHardwareClockDiscontinuityCount();
     method public int getLeapSecond();
     method public long getTimeNanos();
-    method public double getTimeUncertaintyNanos();
+    method @FloatRange(from=0.0f) public double getTimeUncertaintyNanos();
     method public boolean hasBiasNanos();
     method public boolean hasBiasUncertaintyNanos();
     method public boolean hasDriftNanosPerSecond();
     method public boolean hasDriftUncertaintyNanosPerSecond();
+    method public boolean hasElapsedRealtimeNanos();
+    method public boolean hasElapsedRealtimeUncertaintyNanos();
     method public boolean hasFullBiasNanos();
     method public boolean hasLeapSecond();
     method public boolean hasTimeUncertaintyNanos();
@@ -24846,6 +24852,7 @@
     field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
     field public static final int STATUS_PENDING = 3; // 0x3
     field public static final int STATUS_USABLE = 0; // 0x0
+    field public static final int STATUS_USABLE_IN_FUTURE = 5; // 0x5
   }
 
   public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
@@ -26389,15 +26396,15 @@
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final int COMMAND_CODE_CUSTOM = 0; // 0x0
     field @NonNull public static final android.os.Parcelable.Creator<android.media.Session2Command> CREATOR;
-    field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff
-    field public static final int RESULT_INFO_SKIPPED = 1; // 0x1
-    field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
   public static final class Session2Command.Result {
     ctor public Session2Command.Result(int, @Nullable android.os.Bundle);
     method public int getResultCode();
     method @Nullable public android.os.Bundle getResultData();
+    field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff
+    field public static final int RESULT_INFO_SKIPPED = 1; // 0x1
+    field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
   public final class Session2CommandGroup implements android.os.Parcelable {
@@ -30752,7 +30759,6 @@
     method public double getAltitudeUncertainty();
     method public java.util.List<android.net.MacAddress> getColocatedBssids();
     method public int getDatum();
-    method public boolean getDependentStationIndication();
     method public int getExpectedToMove();
     method public double getFloorNumber();
     method public double getHeightAboveFloorMeters();
@@ -30765,7 +30771,6 @@
     method @Nullable public String getMapImageMimeType();
     method @Nullable public android.net.Uri getMapImageUri();
     method public boolean getRegisteredLocationAgreementIndication();
-    method public boolean getRegisteredLocationDseIndication();
     method public boolean isLciSubelementValid();
     method public boolean isZaxisSubelementValid();
     method @Nullable public android.location.Address toCivicLocationAddress();
@@ -41723,7 +41728,7 @@
     method public void onNotificationRemoved(android.service.notification.StatusBarNotification);
     method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
     method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap, int);
-    method public void onStatusBarIconsBehaviorChanged(boolean);
+    method public void onSilentStatusBarIconsVisibilityChanged(boolean);
     method public final void requestInterruptionFilter(int);
     method public final void requestListenerHints(int);
     method public static void requestRebind(android.content.ComponentName);
diff --git a/api/system-current.txt b/api/system-current.txt
index 2ae3a77..876c2b2 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1361,7 +1361,6 @@
     field public static final String BACKUP_SERVICE = "backup";
     field public static final String CONTENT_SUGGESTIONS_SERVICE = "content_suggestions";
     field public static final String CONTEXTHUB_SERVICE = "contexthub";
-    field public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android";
     field public static final String EUICC_CARD_SERVICE = "euicc_card";
     field public static final String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final String NETD_SERVICE = "netd";
@@ -1388,32 +1387,6 @@
     method public void sendOrderedBroadcast(android.content.Intent, String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle);
   }
 
-  public class DynamicAndroidClient {
-    ctor public DynamicAndroidClient(@NonNull android.content.Context);
-    method public void bind();
-    method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener, @NonNull java.util.concurrent.Executor);
-    method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener);
-    method public void start(String, long);
-    method public void start(String, long, long);
-    method public void unbind();
-    field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6
-    field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4
-    field public static final int CAUSE_ERROR_IO = 3; // 0x3
-    field public static final int CAUSE_ERROR_IPC = 5; // 0x5
-    field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2
-    field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1
-    field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0
-    field public static final int STATUS_IN_PROGRESS = 2; // 0x2
-    field public static final int STATUS_IN_USE = 4; // 0x4
-    field public static final int STATUS_NOT_STARTED = 1; // 0x1
-    field public static final int STATUS_READY = 3; // 0x3
-    field public static final int STATUS_UNKNOWN = 0; // 0x0
-  }
-
-  public static interface DynamicAndroidClient.OnStatusChangedListener {
-    method public void onStatusChanged(int, int, long);
-  }
-
   public class Intent implements java.lang.Cloneable android.os.Parcelable {
     field public static final String ACTION_BATTERY_LEVEL_CHANGED = "android.intent.action.BATTERY_LEVEL_CHANGED";
     field public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY";
@@ -1488,6 +1461,7 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.content.om.OverlayInfo> CREATOR;
     field public final String category;
     field public final String packageName;
+    field public final String targetOverlayableName;
     field public final String targetPackageName;
     field public final int userId;
   }
@@ -4938,7 +4912,6 @@
     method public int getCellularDataNetworkType();
     method public int getCellularSignalStrengthDb();
     method public int getCellularSignalStrengthDbm();
-    method public boolean getIsSameRegisteredCell();
     method public int getLinkSpeedMbps();
     method public int getProbeElapsedTimeSinceLastUpdateMillis();
     method public int getProbeMcsRateSinceLastUpdate();
@@ -4962,6 +4935,7 @@
     method public long getTotalTxBad();
     method public long getTotalTxRetries();
     method public long getTotalTxSuccess();
+    method public boolean isSameRegisteredCell();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiUsabilityStatsEntry> CREATOR;
     field public static final int PROBE_STATUS_FAILURE = 3; // 0x3
@@ -5451,14 +5425,14 @@
   public final class PowerManager {
     method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long);
     method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend();
-    method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveMode();
+    method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveModeTrigger();
     method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSaveEnabled(boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSavePolicy(@NonNull android.os.BatterySaverPolicyConfig);
-    method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSavings(boolean, int);
+    method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSaveHint(boolean, int);
     method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setPowerSaveModeEnabled(boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY}) public void userActivity(long, int, int);
-    field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1
-    field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0
+    field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
+    field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
     field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3
     field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1
     field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0
@@ -5665,6 +5639,36 @@
 
 }
 
+package android.os.image {
+
+  public class DynamicSystemClient {
+    ctor public DynamicSystemClient(@NonNull android.content.Context);
+    method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void bind();
+    method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
+    method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
+    method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long);
+    method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long, long);
+    method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void unbind();
+    field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6
+    field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4
+    field public static final int CAUSE_ERROR_IO = 3; // 0x3
+    field public static final int CAUSE_ERROR_IPC = 5; // 0x5
+    field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2
+    field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1
+    field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0
+    field public static final int STATUS_IN_PROGRESS = 2; // 0x2
+    field public static final int STATUS_IN_USE = 4; // 0x4
+    field public static final int STATUS_NOT_STARTED = 1; // 0x1
+    field public static final int STATUS_READY = 3; // 0x3
+    field public static final int STATUS_UNKNOWN = 0; // 0x0
+  }
+
+  public static interface DynamicSystemClient.OnStatusChangedListener {
+    method public void onStatusChanged(int, int, long);
+  }
+
+}
+
 package android.os.storage {
 
   public class StorageManager {
@@ -6431,7 +6435,7 @@
 
   public abstract class ContentCaptureService extends android.app.Service {
     ctor public ContentCaptureService();
-    method public final void disableContentCaptureServices();
+    method public final void disableSelf();
     method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent);
     method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData);
     method public void onConnected();
@@ -7571,11 +7575,11 @@
     field public static final int VSNCP_TIMEOUT = 2236; // 0x8bc
   }
 
-  public final class DataSpecificRegistrationStates implements android.os.Parcelable {
+  public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
     method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationStates> CREATOR;
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
   }
 
   public final class DisconnectCause {
@@ -7684,7 +7688,7 @@
     method public int getAccessNetworkTechnology();
     method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
     method @Nullable public android.telephony.CellIdentity getCellIdentity();
-    method @Nullable public android.telephony.DataSpecificRegistrationStates getDataSpecificStates();
+    method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
     method public int getDomain();
     method public int getRegistrationState();
     method public int getRejectCause();
@@ -9491,6 +9495,10 @@
     method public int getUid();
   }
 
+  public final class StatsLog {
+    method public static void writeRaw(@NonNull byte[], int);
+  }
+
   public class StatsLogAtoms {
     field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170; // 0xaa
     field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED = 8; // 0x8
diff --git a/api/test-current.txt b/api/test-current.txt
index 07944fa..6532cf8 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -352,6 +352,10 @@
     method public boolean isUiModeLocked();
   }
 
+  public class WallpaperManager {
+    method @RequiresPermission("android.permission.SET_WALLPAPER_COMPONENT") public boolean setWallpaperComponent(android.content.ComponentName);
+  }
+
   public class WindowConfiguration implements java.lang.Comparable<android.app.WindowConfiguration> android.os.Parcelable {
     ctor public WindowConfiguration();
     method public int compareTo(android.app.WindowConfiguration);
@@ -584,12 +588,14 @@
   }
 
   public final class ContentCaptureOptions implements android.os.Parcelable {
+    ctor public ContentCaptureOptions(int);
     ctor public ContentCaptureOptions(int, int, int, int, int, @Nullable android.util.ArraySet<android.content.ComponentName>);
     method public int describeContents();
     method public static android.content.ContentCaptureOptions forWhitelistingItself();
     method public void writeToParcel(android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.content.ContentCaptureOptions> CREATOR;
     field public final int idleFlushingFrequencyMs;
+    field public final boolean lite;
     field public final int logHistorySize;
     field public final int loggingLevel;
     field public final int maxBufferSize;
@@ -608,6 +614,7 @@
   public abstract class Context {
     method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract android.view.Display getDisplay();
+    method public abstract int getDisplayId();
     method public android.os.UserHandle getUser();
     method public int getUserId();
     method public void setAutofillOptions(@Nullable android.content.AutofillOptions);
@@ -618,6 +625,7 @@
 
   public class ContextWrapper extends android.content.Context {
     method public android.view.Display getDisplay();
+    method public int getDisplayId();
   }
 
   public class Intent implements java.lang.Cloneable android.os.Parcelable {
@@ -927,19 +935,23 @@
     method public void resetBiasUncertaintyNanos();
     method public void resetDriftNanosPerSecond();
     method public void resetDriftUncertaintyNanosPerSecond();
+    method public void resetElapsedRealtimeNanos();
+    method public void resetElapsedRealtimeUncertaintyNanos();
     method public void resetFullBiasNanos();
     method public void resetLeapSecond();
     method public void resetTimeUncertaintyNanos();
     method public void set(android.location.GnssClock);
     method public void setBiasNanos(double);
-    method public void setBiasUncertaintyNanos(double);
+    method public void setBiasUncertaintyNanos(@FloatRange(from=0.0f) double);
     method public void setDriftNanosPerSecond(double);
-    method public void setDriftUncertaintyNanosPerSecond(double);
+    method public void setDriftUncertaintyNanosPerSecond(@FloatRange(from=0.0f) double);
+    method public void setElapsedRealtimeNanos(long);
+    method public void setElapsedRealtimeUncertaintyNanos(@IntRange(from=0) long);
     method public void setFullBiasNanos(long);
     method public void setHardwareClockDiscontinuityCount(int);
     method public void setLeapSecond(int);
     method public void setTimeNanos(long);
-    method public void setTimeUncertaintyNanos(double);
+    method public void setTimeUncertaintyNanos(@FloatRange(from=0.0f) double);
   }
 
   public final class GnssMeasurement implements android.os.Parcelable {
@@ -1799,11 +1811,11 @@
   }
 
   public final class PowerManager {
-    method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveMode();
-    method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSavings(boolean, int);
+    method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveModeTrigger();
+    method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSaveHint(boolean, int);
     method @RequiresPermission(anyOf={"android.permission.DEVICE_POWER", "android.permission.POWER_SAVER"}) public boolean setPowerSaveModeEnabled(boolean);
-    field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1
-    field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0
+    field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
+    field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
   }
 
   public class Process {
@@ -2151,7 +2163,7 @@
 
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
-    field public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode";
+    field public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
     field public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
     field public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS = "captive_portal_fallback_probe_specs";
     field public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
@@ -2436,7 +2448,7 @@
 
   public abstract class ContentCaptureService extends android.app.Service {
     ctor public ContentCaptureService();
-    method public final void disableContentCaptureServices();
+    method public final void disableSelf();
     method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent);
     method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData);
     method public void onConnected();
@@ -2555,10 +2567,34 @@
 
 package android.telephony {
 
+  public final class AccessNetworkConstants {
+    field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
+    field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
+  }
+
   public class CarrierConfigManager {
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
   }
 
+  public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
+  }
+
+  public final class LteVopsSupportInfo implements android.os.Parcelable {
+    ctor public LteVopsSupportInfo(int, int);
+    method public int describeContents();
+    method public int getEmcBearerSupport();
+    method public int getVopsSupport();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR;
+    field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
+    field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3
+    field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2
+  }
+
   public class MbmsDownloadSession implements java.lang.AutoCloseable {
     field public static final String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override";
   }
@@ -2571,12 +2607,59 @@
     field public static final String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override";
   }
 
+  public final class NetworkRegistrationInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getAccessNetworkTechnology();
+    method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
+    method @Nullable public android.telephony.CellIdentity getCellIdentity();
+    method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
+    method public int getDomain();
+    method public int getRegistrationState();
+    method public int getRejectCause();
+    method public int getRoamingType();
+    method public int getTransportType();
+    method public boolean isEmergencyEnabled();
+    method public boolean isRoaming();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
+    field public static final int DOMAIN_CS = 1; // 0x1
+    field public static final int DOMAIN_PS = 2; // 0x2
+    field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
+    field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
+    field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
+    field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
+    field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
+    field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
+    field public static final int SERVICE_TYPE_DATA = 2; // 0x2
+    field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
+    field public static final int SERVICE_TYPE_SMS = 3; // 0x3
+    field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
+    field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
+  }
+
+  public static final class NetworkRegistrationInfo.Builder {
+    ctor public NetworkRegistrationInfo.Builder();
+    method @NonNull public android.telephony.NetworkRegistrationInfo build();
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List<java.lang.Integer>);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
+    method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
+  }
+
   public class ServiceState implements android.os.Parcelable {
+    method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo);
     method public void setCdmaSystemAndNetworkId(int, int);
     method public void setCellBandwidths(int[]);
     method public void setChannelNumber(int);
+    method public void setDataRoamingType(int);
     method public void setRilDataRadioTechnology(int);
     method public void setRilVoiceRadioTechnology(int);
+    method public void setVoiceRoamingType(int);
   }
 
   public class TelephonyManager {
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index 24331af..55b1003 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -196,13 +196,7 @@
 
   std::stringstream stream;
   for (const auto& overlay : interesting_apks) {
-    std::vector<std::string> verify_args = {"--idmap-path", overlay.idmap_path};
-    for (const std::string& policy : overlay.policies) {
-      verify_args.emplace_back("--policy");
-      verify_args.emplace_back(policy);
-    }
-
-    if (!Verify(std::vector<std::string>(verify_args))) {
+    if (!Verify(std::vector<std::string>({"--idmap-path", overlay.idmap_path}))) {
       std::vector<std::string> create_args = {"--target-apk-path",  target_apk_path,
                                               "--overlay-apk-path", overlay.apk_path,
                                               "--idmap-path",       overlay.idmap_path};
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index 2a3eee2..16c936c 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -84,4 +84,6 @@
     optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
 
     optional bool allow_from_any_uid = 50003 [default = false];
+
+    optional string log_from_module = 50004;
 }
\ No newline at end of file
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index d740961..a3776c4 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -4759,7 +4759,6 @@
 HPLandroid/os/IDeviceIdleController$Stub$Proxy;->addPowerSaveTempWhitelistAppForSms(Ljava/lang/String;ILjava/lang/String;)J
 HPLandroid/os/IDeviceIdleController$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HPLandroid/os/IDeviceIdleController$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
-HPLandroid/os/IDynamicAndroidService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HPLandroid/os/IHardwarePropertiesManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
 HPLandroid/os/IHardwarePropertiesManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HPLandroid/os/IInstalld$Stub$Proxy;->clearAppData(Ljava/lang/String;Ljava/lang/String;IIJ)V
@@ -5081,6 +5080,7 @@
 HPLandroid/os/health/HealthStatsWriter;->writeParcelableMap(Landroid/os/Parcel;Landroid/util/ArrayMap;)V
 HPLandroid/os/health/TimerStat;-><init>(IJ)V
 HPLandroid/os/health/TimerStat;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/os/image/IDynamicSystemService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
 HPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->onStorageStateChanged(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 HPLandroid/os/storage/IStorageManager$Stub$Proxy;->allocateBytes(Ljava/lang/String;JILjava/lang/String;)V
 HPLandroid/os/storage/IStorageManager$Stub$Proxy;->changeEncryptionPassword(ILjava/lang/String;)I
@@ -24027,7 +24027,6 @@
 HSPLandroid/os/IDeviceIdleController$Stub;-><init>()V
 HSPLandroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController;
 HSPLandroid/os/IDumpstate$Stub;-><init>()V
-HSPLandroid/os/IDynamicAndroidService$Stub;-><init>()V
 HSPLandroid/os/IExternalVibratorService$Stub;-><init>()V
 HSPLandroid/os/IHardwarePropertiesManager$Stub;-><init>()V
 HSPLandroid/os/IIncidentCompanion$Stub;-><init>()V
@@ -24837,6 +24836,7 @@
 HSPLandroid/os/ZygoteProcess;->zygoteSendArgsAndGetResult(Landroid/os/ZygoteProcess$ZygoteState;ZLjava/util/ArrayList;)Landroid/os/Process$ProcessStartResult;
 HSPLandroid/os/health/HealthStatsParceler$1;-><init>()V
 HSPLandroid/os/health/TimerStat$1;-><init>()V
+HSPLandroid/os/image/IDynamicSystemService$Stub;-><init>()V
 HSPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
 HSPLandroid/os/storage/IStorageEventListener$Stub;->asBinder()Landroid/os/IBinder;
 HSPLandroid/os/storage/IStorageManager$Stub$Proxy;->getVolumeList(ILjava/lang/String;I)[Landroid/os/storage/StorageVolume;
@@ -47386,7 +47386,6 @@
 Landroid/os/DropBoxManager$Entry$1;
 Landroid/os/DropBoxManager$Entry;
 Landroid/os/DropBoxManager;
-Landroid/os/DynamicAndroidManager;
 Landroid/os/Environment$UserEnvironment;
 Landroid/os/Environment;
 Landroid/os/EventLogTags;
@@ -47428,8 +47427,6 @@
 Landroid/os/IDeviceIdleController;
 Landroid/os/IDumpstate$Stub;
 Landroid/os/IDumpstate;
-Landroid/os/IDynamicAndroidService$Stub;
-Landroid/os/IDynamicAndroidService;
 Landroid/os/IExternalVibratorService$Stub;
 Landroid/os/IExternalVibratorService;
 Landroid/os/IHardwarePropertiesManager$Stub;
@@ -47689,6 +47686,10 @@
 Landroid/os/health/SystemHealthManager;
 Landroid/os/health/TimerStat$1;
 Landroid/os/health/TimerStat;
+Landroid/os/image/DynamicSystemClient;
+Landroid/os/image/DynamicSystemManager;
+Landroid/os/image/IDynamicSystemService$Stub;
+Landroid/os/image/IDynamicSystemService;
 Landroid/os/storage/DiskInfo;
 Landroid/os/storage/IObbActionListener$Stub;
 Landroid/os/storage/IObbActionListener;
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 76d69cd..79cdb77 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -1680,7 +1680,6 @@
 Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String;
 Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V
 Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V
-Lcom/android/internal/widget/LockPatternUtils;->saveLockPassword(Ljava/lang/String;Ljava/lang/String;II)V
 Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J
 Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V
 Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V
diff --git a/config/preloaded-classes b/config/preloaded-classes
index fda028d..abdbab2 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -2724,7 +2724,6 @@
 android.os.DropBoxManager$Entry$1
 android.os.DropBoxManager$Entry
 android.os.DropBoxManager
-android.os.DynamicAndroidManager
 android.os.Environment$UserEnvironment
 android.os.Environment
 android.os.EventLogTags
@@ -2909,6 +2908,8 @@
 android.os.health.SystemHealthManager
 android.os.health.TimerStat$1
 android.os.health.TimerStat
+android.os.image.DynamicSystemClient
+android.os.image.DynamicSystemManager
 android.os.storage.IObbActionListener$Stub
 android.os.storage.IObbActionListener
 android.os.storage.IStorageManager$Stub$Proxy
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 7ba6146..d634aa5 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -21,6 +21,7 @@
 import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast;
 
 import android.annotation.ColorInt;
+import android.annotation.DimenRes;
 import android.annotation.DrawableRes;
 import android.annotation.IdRes;
 import android.annotation.IntDef;
@@ -8521,6 +8522,7 @@
         private PendingIntent mDeleteIntent;
         private Icon mIcon;
         private int mDesiredHeight;
+        @DimenRes private int mDesiredHeightResId;
         private int mFlags;
 
         /**
@@ -8547,10 +8549,11 @@
         private static final int FLAG_SUPPRESS_INITIAL_NOTIFICATION = 0x00000002;
 
         private BubbleMetadata(PendingIntent expandIntent, PendingIntent deleteIntent,
-                Icon icon, int height) {
+                Icon icon, int height, @DimenRes int heightResId) {
             mPendingIntent = expandIntent;
             mIcon = icon;
             mDesiredHeight = height;
+            mDesiredHeightResId = heightResId;
             mDeleteIntent = deleteIntent;
         }
 
@@ -8562,6 +8565,7 @@
             if (in.readInt() != 0) {
                 mDeleteIntent = PendingIntent.CREATOR.createFromParcel(in);
             }
+            mDesiredHeightResId = in.readInt();
         }
 
         /**
@@ -8581,17 +8585,6 @@
         }
 
         /**
-         * @return the title that will appear along with the app content defined by
-         * {@link #getIntent()} for this bubble.
-         *
-         * @deprecated titles are no longer required or shown.
-         */
-        @Deprecated
-        public CharSequence getTitle() {
-            return "";
-        }
-
-        /**
          * @return the icon that will be displayed for this bubble when it is collapsed.
          */
         @NonNull
@@ -8600,7 +8593,7 @@
         }
 
         /**
-         * @return the ideal height for the floating window that app content defined by
+         * @return the ideal height, in DPs, for the floating window that app content defined by
          * {@link #getIntent()} for this bubble.
          */
         public int getDesiredHeight() {
@@ -8608,6 +8601,15 @@
         }
 
         /**
+         * @return the resId of ideal height for the floating window that app content defined by
+         * {@link #getIntent()} for this bubble.
+         */
+        @DimenRes
+        public int getDesiredHeightResId() {
+            return mDesiredHeightResId;
+        }
+
+        /**
          * @return whether this bubble should auto expand when it is posted.
          *
          * @see BubbleMetadata.Builder#setAutoExpandBubble(boolean)
@@ -8654,6 +8656,7 @@
             if (mDeleteIntent != null) {
                 mDeleteIntent.writeToParcel(out, 0);
             }
+            out.writeInt(mDesiredHeightResId);
         }
 
         private void setFlags(int flags) {
@@ -8668,6 +8671,7 @@
             private PendingIntent mPendingIntent;
             private Icon mIcon;
             private int mDesiredHeight;
+            @DimenRes private int mDesiredHeightResId;
             private int mFlags;
             private PendingIntent mDeleteIntent;
 
@@ -8691,19 +8695,6 @@
             }
 
             /**
-             * Sets the title that will appear along with the app content for this bubble.
-             *
-             * <p>A title is required and should expect to fit on a single line and make sense when
-             * shown with the content defined by {@link #setIntent(PendingIntent)}.</p>
-             *
-             * @deprecated titles are no longer required or shown.
-             */
-            @Deprecated
-            public BubbleMetadata.Builder setTitle(CharSequence title) {
-                return this;
-            }
-
-            /**
              * Sets the icon that will represent the bubble when it is collapsed.
              *
              * <p>An icon is required and should be representative of the content within the bubble.
@@ -8733,13 +8724,35 @@
             }
 
             /**
-             * Sets the desired height for the app content defined by
+             * Sets the desired height in DPs for the app content defined by
              * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not
              * enough space on the screen or if the provided height is too small to be useful.
+             * <p>
+             * If {@link #setDesiredHeightResId(int)} was previously called on this builder, the
+             * previous value set will be cleared after calling this method, and this value will
+             * be used instead.
              */
             @NonNull
             public BubbleMetadata.Builder setDesiredHeight(int height) {
                 mDesiredHeight = Math.max(height, 0);
+                mDesiredHeightResId = 0;
+                return this;
+            }
+
+
+            /**
+             * Sets the desired height via resId for the app content defined by
+             * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not
+             * enough space on the screen or if the provided height is too small to be useful.
+             * <p>
+             * If {@link #setDesiredHeight(int)} was previously called on this builder, the
+             * previous value set will be cleared after calling this method, and this value will
+             * be used instead.
+             */
+            @NonNull
+            public BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int heightResId) {
+                mDesiredHeightResId = heightResId;
+                mDesiredHeight = 0;
                 return this;
             }
 
@@ -8801,7 +8814,7 @@
                     throw new IllegalStateException("Must supply an icon for the bubble");
                 }
                 BubbleMetadata data = new BubbleMetadata(mPendingIntent, mDeleteIntent,
-                        mIcon, mDesiredHeight);
+                        mIcon, mDesiredHeight, mDesiredHeightResId);
                 data.setFlags(mFlags);
                 return data;
             }
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 4d280b7..d67bfb6 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -131,13 +131,11 @@
 import android.os.Build;
 import android.os.DeviceIdleManager;
 import android.os.DropBoxManager;
-import android.os.DynamicAndroidManager;
 import android.os.HardwarePropertiesManager;
 import android.os.IBatteryPropertiesRegistrar;
 import android.os.IBinder;
 import android.os.IDeviceIdleController;
 import android.os.IDumpstate;
-import android.os.IDynamicAndroidService;
 import android.os.IHardwarePropertiesManager;
 import android.os.IPowerManager;
 import android.os.IRecoverySystem;
@@ -155,6 +153,8 @@
 import android.os.UserManager;
 import android.os.Vibrator;
 import android.os.health.SystemHealthManager;
+import android.os.image.DynamicSystemManager;
+import android.os.image.IDynamicSystemService;
 import android.os.storage.StorageManager;
 import android.permission.PermissionControllerManager;
 import android.permission.PermissionManager;
@@ -1275,15 +1275,15 @@
                                 IRollbackManager.Stub.asInterface(b));
                     }});
 
-        registerService(Context.DYNAMIC_ANDROID_SERVICE, DynamicAndroidManager.class,
-                new CachedServiceFetcher<DynamicAndroidManager>() {
+        registerService(Context.DYNAMIC_SYSTEM_SERVICE, DynamicSystemManager.class,
+                new CachedServiceFetcher<DynamicSystemManager>() {
                     @Override
-                    public DynamicAndroidManager createService(ContextImpl ctx)
+                    public DynamicSystemManager createService(ContextImpl ctx)
                             throws ServiceNotFoundException {
                         IBinder b = ServiceManager.getServiceOrThrow(
-                                Context.DYNAMIC_ANDROID_SERVICE);
-                        return new DynamicAndroidManager(
-                                IDynamicAndroidService.Stub.asInterface(b));
+                                Context.DYNAMIC_SYSTEM_SERVICE);
+                        return new DynamicSystemManager(
+                                IDynamicSystemService.Stub.asInterface(b));
                     }});
         //CHECKSTYLE:ON IndentationCheck
     }
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index a929fe0..325a54b 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -25,6 +25,7 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -1666,6 +1667,7 @@
      *
      * @hide
      */
+    @TestApi
     @SystemApi
     @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT)
     public boolean setWallpaperComponent(ComponentName name) {
diff --git a/core/java/android/content/ContentCaptureOptions.java b/core/java/android/content/ContentCaptureOptions.java
index 6be0bea..1727d34 100644
--- a/core/java/android/content/ContentCaptureOptions.java
+++ b/core/java/android/content/ContentCaptureOptions.java
@@ -72,9 +72,29 @@
     @Nullable
     public final ArraySet<ComponentName> whitelistedComponents;
 
+    /**
+     * Used to enable just a small set of APIs so it can used by activities belonging to the
+     * content capture service APK.
+     */
+    public final boolean lite;
+
+    public ContentCaptureOptions(int loggingLevel) {
+        this(/* lite= */ true, loggingLevel, /* maxBufferSize= */ 0,
+                /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0,
+                /* logHistorySize= */ 0, /* whitelistedComponents= */ null);
+    }
+
     public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs,
             int textChangeFlushingFrequencyMs, int logHistorySize,
             @Nullable ArraySet<ComponentName> whitelistedComponents) {
+        this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs,
+                textChangeFlushingFrequencyMs, logHistorySize, whitelistedComponents);
+    }
+
+    private ContentCaptureOptions(boolean lite, int loggingLevel, int maxBufferSize,
+            int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize,
+            @Nullable ArraySet<ComponentName> whitelistedComponents) {
+        this.lite = lite;
         this.loggingLevel = loggingLevel;
         this.maxBufferSize = maxBufferSize;
         this.idleFlushingFrequencyMs = idleFlushingFrequencyMs;
@@ -115,6 +135,9 @@
 
     @Override
     public String toString() {
+        if (lite) {
+            return "ContentCaptureOptions [(lite) loggingLevel=" + loggingLevel + "]";
+        }
         return "ContentCaptureOptions [loggingLevel=" + loggingLevel + ", maxBufferSize="
                 + maxBufferSize + ", idleFlushingFrequencyMs=" + idleFlushingFrequencyMs
                 + ", textChangeFlushingFrequencyMs=" + textChangeFlushingFrequencyMs
@@ -125,6 +148,10 @@
     /** @hide */
     public void dumpShort(@NonNull PrintWriter pw) {
         pw.print("logLvl="); pw.print(loggingLevel);
+        if (lite) {
+            pw.print(", lite");
+            return;
+        }
         pw.print(", bufferSize="); pw.print(maxBufferSize);
         pw.print(", idle="); pw.print(idleFlushingFrequencyMs);
         pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs);
@@ -141,7 +168,10 @@
 
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeBoolean(lite);
         parcel.writeInt(loggingLevel);
+        if (lite) return;
+
         parcel.writeInt(maxBufferSize);
         parcel.writeInt(idleFlushingFrequencyMs);
         parcel.writeInt(textChangeFlushingFrequencyMs);
@@ -154,7 +184,11 @@
 
                 @Override
                 public ContentCaptureOptions createFromParcel(Parcel parcel) {
+                    final boolean lite = parcel.readBoolean();
                     final int loggingLevel = parcel.readInt();
+                    if (lite) {
+                        return new ContentCaptureOptions(loggingLevel);
+                    }
                     final int maxBufferSize = parcel.readInt();
                     final int idleFlushingFrequencyMs = parcel.readInt();
                     final int textChangeFlushingFrequencyMs = parcel.readInt();
@@ -171,6 +205,5 @@
                 public ContentCaptureOptions[] newArray(int size) {
                     return new ContentCaptureOptions[size];
                 }
-
     };
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index fb933b1..d7a2e1b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -338,6 +338,14 @@
     public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100;
 
     /**
+     * Flag for {@link #bindService}: If binding from an app that has specific capabilities
+     * due to its foreground state such as an activity or foreground service, then this flag will
+     * allow the bound app to get the same capabilities, as long as it has the required permissions
+     * as well.
+     */
+    public static final int BIND_INCLUDE_CAPABILITIES = 0x00001000;
+
+    /**
      * Flag for {@link #bindService}: This flag is intended to be used only by the system to adjust
      * the scheduling policy for IMEs (and any other out-of-process user-visible components that
      * work closely with the top app) so that UI hosted in such services can have the same
@@ -4644,11 +4652,10 @@
 
      /**
      * Use with {@link #getSystemService(String)} to retrieve an
-     * {@link android.os.DynamicAndroidManager}.
+     * {@link android.os.image.DynamicSystemManager}.
      * @hide
      */
-    @SystemApi
-    public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android";
+    public static final String DYNAMIC_SYSTEM_SERVICE = "dynamic_system";
 
     /**
      * Determine whether the given permission is allowed for a particular
@@ -5322,6 +5329,7 @@
      * @return display ID associated with this {@link Context}.
      * @hide
      */
+    @TestApi
     public abstract int getDisplayId();
 
     /**
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
index 999d986..aabe59d 100644
--- a/core/java/android/content/om/OverlayInfo.java
+++ b/core/java/android/content/om/OverlayInfo.java
@@ -18,12 +18,14 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
 
 /**
  * Immutable overlay information about a package. All PackageInfos that
@@ -138,6 +140,14 @@
     public final String targetPackageName;
 
     /**
+     * Name of the target overlayable declaration.
+     *
+     * @hide
+     */
+    @SystemApi
+    public final String targetOverlayableName;
+
+    /**
      * Category of the overlay package
      *
      * @hide
@@ -190,16 +200,19 @@
      * @hide
      */
     public OverlayInfo(@NonNull OverlayInfo source, @State int state) {
-        this(source.packageName, source.targetPackageName, source.category, source.baseCodePath,
-                state, source.userId, source.priority, source.isStatic);
+        this(source.packageName, source.targetPackageName, source.targetOverlayableName,
+                source.category, source.baseCodePath, state, source.userId, source.priority,
+                source.isStatic);
     }
 
     /** @hide */
     public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
-            @NonNull String category, @NonNull String baseCodePath, int state, int userId,
+            @Nullable String targetOverlayableName, @Nullable String category,
+            @NonNull String baseCodePath, int state, int userId,
             int priority, boolean isStatic) {
         this.packageName = packageName;
         this.targetPackageName = targetPackageName;
+        this.targetOverlayableName = targetOverlayableName;
         this.category = category;
         this.baseCodePath = baseCodePath;
         this.state = state;
@@ -213,6 +226,7 @@
     public OverlayInfo(Parcel source) {
         packageName = source.readString();
         targetPackageName = source.readString();
+        targetOverlayableName = source.readString();
         category = source.readString();
         baseCodePath = source.readString();
         state = source.readInt();
@@ -256,6 +270,7 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeString(packageName);
         dest.writeString(targetPackageName);
+        dest.writeString(targetOverlayableName);
         dest.writeString(category);
         dest.writeString(baseCodePath);
         dest.writeInt(state);
@@ -335,6 +350,8 @@
         result = prime * result + state;
         result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
         result = prime * result + ((targetPackageName == null) ? 0 : targetPackageName.hashCode());
+        result = prime * result + ((targetOverlayableName == null) ? 0
+                : targetOverlayableName.hashCode());
         result = prime * result + ((category == null) ? 0 : category.hashCode());
         result = prime * result + ((baseCodePath == null) ? 0 : baseCodePath.hashCode());
         return result;
@@ -364,7 +381,10 @@
         if (!targetPackageName.equals(other.targetPackageName)) {
             return false;
         }
-        if (!category.equals(other.category)) {
+        if (!Objects.equals(targetOverlayableName, other.targetOverlayableName)) {
+            return false;
+        }
+        if (!Objects.equals(category, other.category)) {
             return false;
         }
         if (!baseCodePath.equals(other.baseCodePath)) {
@@ -375,7 +395,9 @@
 
     @Override
     public String toString() {
-        return "OverlayInfo { overlay=" + packageName + ", target=" + targetPackageName + ", state="
-                + state + " (" + stateToString(state) + "), userId=" + userId + " }";
+        return "OverlayInfo { overlay=" + packageName + ", targetPackage=" + targetPackageName
+                + ((targetOverlayableName == null) ? ""
+                : ", targetOverlyabale=" + targetOverlayableName)
+                + ", state=" + state + " (" + stateToString(state) + "), userId=" + userId + " }";
     }
 }
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 725d601..d6fb28f 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -354,12 +354,12 @@
     public String overlayTarget;
 
     /**
-     * What overlayable set of elements package, if any, this package will overlay.
+     * The name of the overlayable set of elements package, if any, this package will overlay.
      *
      * Overlayable name defined within the target package, or null.
      * @hide
      */
-    public String overlayTargetName;
+    public String targetOverlayableName;
 
     /**
      * The overlay category, if any, of this package
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 743a302..b480939 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -689,7 +689,7 @@
         pi.restrictedAccountType = p.mRestrictedAccountType;
         pi.requiredAccountType = p.mRequiredAccountType;
         pi.overlayTarget = p.mOverlayTarget;
-        pi.overlayTargetName = p.mOverlayTargetName;
+        pi.targetOverlayableName = p.mOverlayTargetName;
         pi.overlayCategory = p.mOverlayCategory;
         pi.overlayPriority = p.mOverlayPriority;
         pi.mOverlayIsStatic = p.mOverlayIsStatic;
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 6b8416d..d7e4e14 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1721,8 +1721,6 @@
          * Rebases the theme against the parent Resource object's current
          * configuration by re-applying the styles passed to
          * {@link #applyStyle(int, boolean)}.
-         *
-         * @hide
          */
         public void rebase() {
             mThemeImpl.rebase();
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index b5c6604..e1d605e 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -53,10 +53,10 @@
     boolean isPowerSaveMode();
     PowerSaveState getPowerSaveState(int serviceType);
     boolean setPowerSaveModeEnabled(boolean mode);
-    boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, int disableThreshold);
+    boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold);
     boolean setAdaptivePowerSavePolicy(in BatterySaverPolicyConfig config);
     boolean setAdaptivePowerSaveEnabled(boolean enabled);
-    int getPowerSaveMode();
+    int getPowerSaveModeTrigger();
     boolean isDeviceIdleMode();
     boolean isLightDeviceIdleMode();
 
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 36bae2d..64e2f89 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -1460,7 +1460,7 @@
      * an on/off switch for a subset of features.
      * @hide
      *
-     * @param dynamicPowerSavingsEnabled A signal indicating to the system if it believes the
+     * @param powerSaveHint A signal indicating to the system if it believes the
      * dynamic power savings behaviors should be activated.
      * @param disableThreshold When the suggesting app believes it would be safe to disable dynamic
      * power savings behaviors.
@@ -1471,10 +1471,9 @@
     @SystemApi
     @TestApi
     @RequiresPermission(permission.POWER_SAVER)
-    public boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled,
-            int disableThreshold) {
+    public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) {
         try {
-            return mService.setDynamicPowerSavings(dynamicPowerSavingsEnabled, disableThreshold);
+            return mService.setDynamicPowerSaveHint(powerSaveHint, disableThreshold);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -1525,54 +1524,54 @@
     /**
      * Indicates automatic battery saver toggling by the system will be based on percentage.
      *
-     * @see PowerManager#getPowerSaveMode()
+     * @see PowerManager#getPowerSaveModeTrigger()
      *
      *  @hide
      */
     @SystemApi
     @TestApi
-    public static final int POWER_SAVER_MODE_PERCENTAGE = 0;
+    public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0;
 
     /**
      * Indicates automatic battery saver toggling by the system will be based on the state
      * of the dynamic power savings signal.
      *
-     * @see PowerManager#setDynamicPowerSavings(boolean, int)
-     * @see PowerManager#getPowerSaveMode()
+     * @see PowerManager#setDynamicPowerSaveHint(boolean, int)
+     * @see PowerManager#getPowerSaveModeTrigger()
      *
      *  @hide
      */
     @SystemApi
     @TestApi
-    public static final int POWER_SAVER_MODE_DYNAMIC = 1;
+    public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(value = {
-        POWER_SAVER_MODE_PERCENTAGE,
-        POWER_SAVER_MODE_DYNAMIC
+        POWER_SAVE_MODE_TRIGGER_PERCENTAGE,
+        POWER_SAVE_MODE_TRIGGER_DYNAMIC
 
     })
-    public @interface AutoPowerSaverMode{}
+    public @interface AutoPowerSaveModeTriggers {}
 
 
     /**
      * Returns the current battery saver control mode. Values it may return are defined in
-     * AutoPowerSaverMode. Note that this is a global device state, not a per user setting.
+     * AutoPowerSaveModeTriggers. Note that this is a global device state, not a per user setting.
      *
      * @return The current value power saver mode for the system.
      *
-     * @see AutoPowerSaverMode
-     * @see PowerManager#getPowerSaveMode()
+     * @see AutoPowerSaveModeTriggers
+     * @see PowerManager#getPowerSaveModeTrigger()
      * @hide
      */
-    @AutoPowerSaverMode
+    @AutoPowerSaveModeTriggers
     @SystemApi
     @TestApi
     @RequiresPermission(android.Manifest.permission.POWER_SAVER)
-    public int getPowerSaveMode() {
+    public int getPowerSaveModeTrigger() {
         try {
-            return mService.getPowerSaveMode();
+            return mService.getPowerSaveModeTrigger();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index c74cbff..7958ddd 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -23,7 +23,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.hardware.vibrator.V1_0.EffectStrength;
-import android.hardware.vibrator.V1_2.Effect;
+import android.hardware.vibrator.V1_3.Effect;
 import android.net.Uri;
 import android.util.MathUtils;
 
@@ -94,6 +94,18 @@
      */
     public static final int EFFECT_HEAVY_CLICK = Effect.HEAVY_CLICK;
 
+    /**
+     * A texture effect meant to replicate soft ticks.
+     *
+     * Unlike normal effects, texture effects are meant to be called repeatedly, generally in
+     * response to some motion, in order to replicate the feeling of some texture underneath the
+     * user's fingers.
+     *
+     * @see #get(int)
+     * @hide
+     */
+    public static final int EFFECT_TEXTURE_TICK = Effect.TEXTURE_TICK;
+
     /** {@hide} */
     @TestApi
     public static final int EFFECT_STRENGTH_LIGHT = EffectStrength.LIGHT;
@@ -746,6 +758,7 @@
                 case EFFECT_CLICK:
                 case EFFECT_DOUBLE_CLICK:
                 case EFFECT_TICK:
+                case EFFECT_TEXTURE_TICK:
                 case EFFECT_THUD:
                 case EFFECT_POP:
                 case EFFECT_HEAVY_CLICK:
@@ -798,7 +811,7 @@
             out.writeInt(mEffectStrength);
         }
 
-        public static final @android.annotation.NonNull Parcelable.Creator<Prebaked> CREATOR =
+        public static final @NonNull Parcelable.Creator<Prebaked> CREATOR =
             new Parcelable.Creator<Prebaked>() {
                 @Override
                 public Prebaked createFromParcel(Parcel in) {
@@ -813,7 +826,7 @@
             };
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<VibrationEffect> CREATOR =
+    public static final @NonNull Parcelable.Creator<VibrationEffect> CREATOR =
             new Parcelable.Creator<VibrationEffect>() {
                 @Override
                 public VibrationEffect createFromParcel(Parcel in) {
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 40238d2..3420007 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -66,22 +66,14 @@
  */
 public class ZygoteProcess {
 
-    /**
-     * @hide for internal use only.
-     */
-    public static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000;
+    private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000;
 
     /**
-     * @hide for internal use only.
-     *
      * Use a relatively short delay, because for app zygote, this is in the critical path of
      * service launch.
      */
-    public static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50;
+    private static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50;
 
-    /**
-     * @hide for internal use only
-     */
     private static final String LOG_TAG = "ZygoteProcess";
 
     /**
@@ -141,7 +133,7 @@
     /**
      * State for communicating with the zygote process.
      */
-    public static class ZygoteState {
+    private static class ZygoteState implements AutoCloseable {
         final LocalSocketAddress mZygoteSocketAddress;
         final LocalSocketAddress mUsapSocketAddress;
 
@@ -178,12 +170,12 @@
          * address
          * @throws IOException
          */
-        public static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
-                                          @Nullable LocalSocketAddress usapSocketAddress)
+        static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
+                @Nullable LocalSocketAddress usapSocketAddress)
                 throws IOException {
 
-            DataInputStream zygoteInputStream = null;
-            BufferedWriter zygoteOutputWriter = null;
+            DataInputStream zygoteInputStream;
+            BufferedWriter zygoteOutputWriter;
             final LocalSocket zygoteSessionSocket = new LocalSocket();
 
             if (zygoteSocketAddress == null) {
@@ -357,8 +349,6 @@
 
     /**
      * Queries the zygote for the list of ABIS it supports.
-     *
-     * @throws ZygoteStartFailedEx if the query failed.
      */
     @GuardedBy("mLock")
     private static List<String> getAbiList(BufferedWriter writer, DataInputStream inputStream)
@@ -411,52 +401,24 @@
          * the child or -1 on failure, followed by boolean to
          * indicate whether a wrapper process was used.
          */
-        String msgStr = Integer.toString(args.size()) + "\n"
-                        + String.join("\n", args) + "\n";
+        String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
 
-        // Should there be a timeout on this?
-        Process.ProcessStartResult result = new Process.ProcessStartResult();
-
-        // TODO (chriswailes): Move branch body into separate function.
         if (useUsapPool && mUsapPoolEnabled && isValidUsapCommand(args)) {
-            LocalSocket usapSessionSocket = null;
-
             try {
-                usapSessionSocket = zygoteState.getUsapSessionSocket();
-
-                final BufferedWriter usapWriter =
-                        new BufferedWriter(
-                                new OutputStreamWriter(usapSessionSocket.getOutputStream()),
-                                Zygote.SOCKET_BUFFER_SIZE);
-                final DataInputStream usapReader =
-                        new DataInputStream(usapSessionSocket.getInputStream());
-
-                usapWriter.write(msgStr);
-                usapWriter.flush();
-
-                result.pid = usapReader.readInt();
-                // USAPs can't be used to spawn processes that need wrappers.
-                result.usingWrapper = false;
-
-                if (result.pid < 0) {
-                    throw new ZygoteStartFailedEx("USAP specialization failed");
-                }
-
-                return result;
+                return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);
             } catch (IOException ex) {
                 // If there was an IOException using the USAP pool we will log the error and
                 // attempt to start the process through the Zygote.
                 Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "
-                               + ex.getMessage());
-            } finally {
-                try {
-                    usapSessionSocket.close();
-                } catch (IOException ex) {
-                    Log.e(LOG_TAG, "Failed to close USAP session socket: " + ex.getMessage());
-                }
+                        + ex.getMessage());
             }
         }
 
+        return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
+    }
+
+    private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
+            ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
         try {
             final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
             final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
@@ -467,20 +429,48 @@
             // Always read the entire result from the input stream to avoid leaving
             // bytes in the stream for future process starts to accidentally stumble
             // upon.
+            Process.ProcessStartResult result = new Process.ProcessStartResult();
             result.pid = zygoteInputStream.readInt();
             result.usingWrapper = zygoteInputStream.readBoolean();
+
+            if (result.pid < 0) {
+                throw new ZygoteStartFailedEx("fork() failed");
+            }
+
+            return result;
         } catch (IOException ex) {
             zygoteState.close();
             Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                     + ex.toString());
             throw new ZygoteStartFailedEx(ex);
         }
+    }
 
-        if (result.pid < 0) {
-            throw new ZygoteStartFailedEx("fork() failed");
+    private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
+            ZygoteState zygoteState, String msgStr)
+            throws ZygoteStartFailedEx, IOException {
+        try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
+            final BufferedWriter usapWriter =
+                    new BufferedWriter(
+                            new OutputStreamWriter(usapSessionSocket.getOutputStream()),
+                            Zygote.SOCKET_BUFFER_SIZE);
+            final DataInputStream usapReader =
+                    new DataInputStream(usapSessionSocket.getInputStream());
+
+            usapWriter.write(msgStr);
+            usapWriter.flush();
+
+            Process.ProcessStartResult result = new Process.ProcessStartResult();
+            result.pid = usapReader.readInt();
+            // USAPs can't be used to spawn processes that need wrappers.
+            result.usingWrapper = false;
+
+            if (result.pid >= 0) {
+                return result;
+            } else {
+                throw new ZygoteStartFailedEx("USAP specialization failed");
+            }
         }
-
-        return result;
     }
 
     /**
@@ -557,7 +547,7 @@
                                                       boolean useUnspecializedAppProcessPool,
                                                       @Nullable String[] extraArgs)
                                                       throws ZygoteStartFailedEx {
-        ArrayList<String> argsForZygote = new ArrayList<String>();
+        ArrayList<String> argsForZygote = new ArrayList<>();
 
         // --runtime-args, --setuid=, --setgid=,
         // and --setgroups= must go first
@@ -627,17 +617,7 @@
         }
 
         if (packagesForUid != null && packagesForUid.length > 0) {
-            final StringBuilder sb = new StringBuilder();
-            sb.append("--packages-for-uid=");
-
-            // TODO (chriswailes): Replace with String.join
-            for (int i = 0; i < packagesForUid.length; ++i) {
-                if (i != 0) {
-                    sb.append(',');
-                }
-                sb.append(packagesForUid[i]);
-            }
-            argsForZygote.add(sb.toString());
+            argsForZygote.add("--packages-for-uid=" + String.join(",", packagesForUid));
         }
 
         if (sandboxId != null) {
@@ -647,9 +627,7 @@
         argsForZygote.add(processClass);
 
         if (extraArgs != null) {
-            for (String arg : extraArgs) {
-                argsForZygote.add(arg);
-            }
+            Collections.addAll(argsForZygote, extraArgs);
         }
 
         synchronized(mLock) {
@@ -671,11 +649,13 @@
                     Boolean.parseBoolean(USAP_POOL_ENABLED_DEFAULT));
         }
 
-        if (origVal != mUsapPoolEnabled) {
+        boolean valueChanged = origVal != mUsapPoolEnabled;
+
+        if (valueChanged) {
             Log.i(LOG_TAG, "usapPoolEnabled = " + mUsapPoolEnabled);
         }
 
-        return origVal != mUsapPoolEnabled;
+        return valueChanged;
     }
 
     private boolean mIsFirstPropCheck = true;
@@ -805,10 +785,10 @@
         if (state == null || state.isClosed()) {
             Slog.e(LOG_TAG, "Can't set API blacklist exemptions: no zygote connection");
             return false;
-        }
-        if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) {
+        } else if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) {
             return true;
         }
+
         try {
             state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1));
             state.mZygoteOutputWriter.newLine();
@@ -832,17 +812,15 @@
     }
 
     private void maybeSetHiddenApiAccessLogSampleRate(ZygoteState state) {
-        if (state == null || state.isClosed()) {
+        if (state == null || state.isClosed() || mHiddenApiAccessLogSampleRate == -1) {
             return;
         }
-        if (mHiddenApiAccessLogSampleRate == -1) {
-            return;
-        }
+
         try {
             state.mZygoteOutputWriter.write(Integer.toString(1));
             state.mZygoteOutputWriter.newLine();
             state.mZygoteOutputWriter.write("--hidden-api-log-sampling-rate="
-                    + Integer.toString(mHiddenApiAccessLogSampleRate));
+                    + mHiddenApiAccessLogSampleRate);
             state.mZygoteOutputWriter.newLine();
             state.mZygoteOutputWriter.flush();
             int status = state.mZygoteInputStream.readInt();
@@ -855,17 +833,15 @@
     }
 
     private void maybeSetHiddenApiAccessStatslogSampleRate(ZygoteState state) {
-        if (state == null || state.isClosed()) {
+        if (state == null || state.isClosed() || mHiddenApiAccessStatslogSampleRate == -1) {
             return;
         }
-        if (mHiddenApiAccessStatslogSampleRate == -1) {
-            return;
-        }
+
         try {
             state.mZygoteOutputWriter.write(Integer.toString(1));
             state.mZygoteOutputWriter.newLine();
             state.mZygoteOutputWriter.write("--hidden-api-statslog-sampling-rate="
-                    + Integer.toString(mHiddenApiAccessStatslogSampleRate));
+                    + mHiddenApiAccessStatslogSampleRate);
             state.mZygoteOutputWriter.newLine();
             state.mZygoteOutputWriter.flush();
             int status = state.mZygoteInputStream.readInt();
@@ -942,8 +918,8 @@
      * Only the app zygote supports this function.
      * TODO preloadPackageForAbi() can probably be removed and the callers an use this instead.
      */
-    public boolean preloadApp(ApplicationInfo appInfo, String abi) throws ZygoteStartFailedEx,
-                                                                          IOException {
+    public boolean preloadApp(ApplicationInfo appInfo, String abi)
+            throws ZygoteStartFailedEx, IOException {
         synchronized (mLock) {
             ZygoteState state = openZygoteSocketIfNeeded(abi);
             state.mZygoteOutputWriter.write("2");
@@ -971,10 +947,10 @@
      * Instructs the zygote to pre-load the classes and native libraries at the given paths
      * for the specified abi. Not all zygotes support this function.
      */
-    public boolean preloadPackageForAbi(String packagePath, String libsPath, String libFileName,
-                                        String cacheKey, String abi) throws ZygoteStartFailedEx,
-                                                                            IOException {
-        synchronized(mLock) {
+    public boolean preloadPackageForAbi(
+            String packagePath, String libsPath, String libFileName, String cacheKey, String abi)
+            throws ZygoteStartFailedEx, IOException {
+        synchronized (mLock) {
             ZygoteState state = openZygoteSocketIfNeeded(abi);
             state.mZygoteOutputWriter.write("5");
             state.mZygoteOutputWriter.newLine();
@@ -1049,8 +1025,7 @@
 
             try {
                 Thread.sleep(ZYGOTE_CONNECT_RETRY_DELAY_MS);
-            } catch (InterruptedException ie) {
-            }
+            } catch (InterruptedException ignored) { }
         }
         Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket "
                 + zygoteSocketAddress.getName());
diff --git a/core/java/android/content/DynamicAndroidClient.java b/core/java/android/os/image/DynamicSystemClient.java
similarity index 64%
rename from core/java/android/content/DynamicAndroidClient.java
rename to core/java/android/os/image/DynamicSystemClient.java
index 571cba4..33a6ee8 100644
--- a/core/java/android/content/DynamicAndroidClient.java
+++ b/core/java/android/os/image/DynamicSystemClient.java
@@ -13,12 +13,18 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.content;
+package android.os.image;
 
+import android.annotation.BytesLong;
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+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;
@@ -34,12 +40,28 @@
 import java.util.concurrent.Executor;
 
 /**
- * This class contains methods and constants used to start DynamicAndroid
- * installation, and a listener for progress update.
+ * <p>This class contains methods and constants used to start a {@code DynamicSystem} installation,
+ * and a listener for status updates.</p>
+ *
+ * <p>{@code DynamicSystem} allows user to run certified system images in a non destructive manner
+ * without needing to prior OEM unlock. While running in {@code DynamicSystem}, persitent storage
+ * for factory reset protection (FRP) remains unchanged. The new system is installed in a
+ * temporarily allocated partition. After the installation is completed, the device will be running
+ * in the new system on next reboot. Then, when the user reboots the device again, it will leave
+ * {@code DynamicSystem} and go back into the original system. Since the userdata for
+ * {@code DynamicSystem} is also newly created during the installation, running in
+ * {@code DynamicSystem} doesn't change user's app data.</p>
+ *
+ * <p>With {@link #setOnStatusChangedListener}, API users can register an
+ * {@link #OnStatusChangedListener} and get status updates and cause when the installation is
+ * started, stopped, or cancelled. It also sends progress updates during the installation. With
+ * {@link #start}, API users can start an installation with the {@link Uri} to a gzipped system
+ * image. The {@link Uri} can be a web URL or a content Uri to a local path.</p>
+ *
  * @hide
  */
 @SystemApi
-public class DynamicAndroidClient {
+public class DynamicSystemClient {
     /** @hide */
     @IntDef(prefix = { "STATUS_" }, value = {
             STATUS_UNKNOWN,
@@ -64,23 +86,23 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface StatusChangedCause {}
 
-    private static final String TAG = "DynAndroidClient";
+    private static final String TAG = "DynSystemClient";
 
     private static final long DEFAULT_USERDATA_SIZE = (10L << 30);
 
 
-    /** Listener for installation status update. */
+    /** Listener for installation status updates. */
     public interface OnStatusChangedListener {
         /**
          * This callback is called when installation status is changed, and when the
-         * client is {@link #bind} to DynamicAndroid installation service.
+         * client is {@link #bind} to {@code DynamicSystem} installation service.
          *
-         * @param status status code, also defined in {@code DynamicAndroidClient}.
-         * @param cause cause code, also defined in {@code DynamicAndroidClient}.
+         * @param status status code, also defined in {@code DynamicSystemClient}.
+         * @param cause cause code, also defined in {@code DynamicSystemClient}.
          * @param progress number of bytes installed.
          */
         void onStatusChanged(@InstallationStatus int status, @StatusChangedCause int cause,
-                long progress);
+                @BytesLong long progress);
     }
 
     /*
@@ -98,7 +120,7 @@
     /** Installation is finished but the user has not launched it. */
     public static final int STATUS_READY = 3;
 
-    /** Device is running in Dynamic Android. */
+    /** Device is running in {@code DynamicSystem}. */
     public static final int STATUS_IN_USE = 4;
 
     /*
@@ -113,7 +135,7 @@
     /** Status changed because installation is cancelled. */
     public static final int CAUSE_INSTALL_CANCELLED = 2;
 
-    /** Installation failed due to IOException. */
+    /** Installation failed due to {@code IOException}. */
     public static final int CAUSE_ERROR_IO = 3;
 
     /** Installation failed because the image URL source is not supported. */
@@ -141,7 +163,7 @@
     public static final int MSG_UNREGISTER_LISTENER = 2;
 
     /**
-     * Message for status update.
+     * Message for status updates.
      * @hide
      */
     public static final int MSG_POST_STATUS = 3;
@@ -150,7 +172,7 @@
      * Messages keys
      */
     /**
-     * Message key, for progress update.
+     * Message key, for progress updates.
      * @hide
      */
     public static final String KEY_INSTALLED_SIZE = "KEY_INSTALLED_SIZE";
@@ -163,14 +185,14 @@
      * @hide
      */
     public static final String ACTION_START_INSTALL =
-            "android.content.action.START_INSTALL";
+            "android.os.image.action.START_INSTALL";
 
     /**
-     * Intent action: notify user if we are currently running in Dynamic Android.
+     * Intent action: notify user if we are currently running in {@code DynamicSystem}.
      * @hide
      */
     public static final String ACTION_NOTIFY_IF_IN_USE =
-            "android.content.action.NOTIFY_IF_IN_USE";
+            "android.os.image.action.NOTIFY_IF_IN_USE";
 
     /*
      * Intent Keys
@@ -195,16 +217,16 @@
 
 
     private static class IncomingHandler extends Handler {
-        private final WeakReference<DynamicAndroidClient> mWeakClient;
+        private final WeakReference<DynamicSystemClient> mWeakClient;
 
-        IncomingHandler(DynamicAndroidClient service) {
+        IncomingHandler(DynamicSystemClient service) {
             super(Looper.getMainLooper());
             mWeakClient = new WeakReference<>(service);
         }
 
         @Override
         public void handleMessage(Message msg) {
-            DynamicAndroidClient service = mWeakClient.get();
+            DynamicSystemClient service = mWeakClient.get();
 
             if (service != null) {
                 service.handleMessage(msg);
@@ -212,9 +234,9 @@
         }
     }
 
-    private class DynAndroidServiceConnection implements ServiceConnection {
+    private class DynSystemServiceConnection implements ServiceConnection {
         public void onServiceConnected(ComponentName className, IBinder service) {
-            Slog.v(TAG, "DynAndroidService connected");
+            Slog.v(TAG, "DynSystemService connected");
 
             mService = new Messenger(service);
 
@@ -232,13 +254,13 @@
         }
 
         public void onServiceDisconnected(ComponentName className) {
-            Slog.v(TAG, "DynAndroidService disconnected");
+            Slog.v(TAG, "DynSystemService disconnected");
             mService = null;
         }
     }
 
     private final Context mContext;
-    private final DynAndroidServiceConnection mConnection;
+    private final DynSystemServiceConnection mConnection;
     private final Messenger mMessenger;
 
     private boolean mBound;
@@ -247,12 +269,16 @@
     private Messenger mService;
 
     /**
+     * Create a new {@code DynamicSystem} client.
+     *
+     * @param context a {@link Context} will be used to bind the installation service.
+     *
      * @hide
      */
     @SystemApi
-    public DynamicAndroidClient(@NonNull Context context) {
+    public DynamicSystemClient(@NonNull Context context) {
         mContext = context;
-        mConnection = new DynAndroidServiceConnection();
+        mConnection = new DynSystemServiceConnection();
         mMessenger = new Messenger(new IncomingHandler(this));
     }
 
@@ -261,8 +287,8 @@
      * the executor.
      */
     public void setOnStatusChangedListener(
-            @NonNull OnStatusChangedListener listener,
-            @NonNull @CallbackExecutor Executor executor) {
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnStatusChangedListener listener) {
         mListener = listener;
         mExecutor = executor;
     }
@@ -278,12 +304,15 @@
     }
 
     /**
-     * Bind to DynamicAndroidInstallationService.
+     * Bind to {@code DynamicSystem} installation service. Binding to the installation service
+     * allows it to send status updates to {@link #OnStatusChangedListener}. It is recommanded
+     * to bind before calling {@link #start} and get status updates.
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
     public void bind() {
         Intent intent = new Intent();
-        intent.setClassName("com.android.dynandroid",
-                "com.android.dynandroid.DynamicAndroidInstallationService");
+        intent.setClassName("com.android.dynsystem",
+                "com.android.dynsystem.DynamicSystemInstallationService");
 
         mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
 
@@ -291,8 +320,10 @@
     }
 
     /**
-     * Unbind from DynamicAndroidInstallationService.
+     * Unbind from {@code DynamicSystem} installation service. Unbinding from the installation
+     * service stops it from sending following status updates.
      */
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
     public void unbind() {
         if (!mBound) {
             return;
@@ -315,27 +346,40 @@
     }
 
     /**
-     * Start installing DynamicAndroid from URL with default userdata size.
+     * Start installing {@code DynamicSystem} from URL with default userdata size.
+     *
+     * Calling this function will first start an Activity to confirm device credential, using
+     * {@link KeyguardManager}. If it's confirmed, the installation service will be started.
+     *
+     * This function doesn't require prior calling {@link #bind}.
      *
      * @param systemUrl A network URL or a file URL to system image.
      * @param systemSize size of system image.
      */
-    public void start(String systemUrl, long systemSize) {
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+    public void start(@NonNull String systemUrl, @BytesLong long systemSize) {
         start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE);
     }
 
     /**
-     * Start installing DynamicAndroid from URL.
+     * Start installing {@code DynamicSystem} from URL.
+     *
+     * Calling this function will first start an Activity to confirm device credential, using
+     * {@link KeyguardManager}. If it's confirmed, the installation service will be started.
+     *
+     * This function doesn't require prior calling {@link #bind}.
      *
      * @param systemUrl A network URL or a file URL to system image.
      * @param systemSize size of system image.
      * @param userdataSize bytes reserved for userdata.
      */
-    public void start(String systemUrl, long systemSize, long userdataSize) {
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+    public void start(@NonNull String systemUrl, @BytesLong long systemSize,
+            @BytesLong long userdataSize) {
         Intent intent = new Intent();
 
-        intent.setClassName("com.android.dynandroid",
-                "com.android.dynandroid.VerificationActivity");
+        intent.setClassName("com.android.dynsystem",
+                "com.android.dynsystem.VerificationActivity");
 
         intent.setAction(ACTION_START_INSTALL);
 
diff --git a/core/java/android/os/DynamicAndroidManager.java b/core/java/android/os/image/DynamicSystemManager.java
similarity index 81%
rename from core/java/android/os/DynamicAndroidManager.java
rename to core/java/android/os/image/DynamicSystemManager.java
index 5238896..0458c2a 100644
--- a/core/java/android/os/DynamicAndroidManager.java
+++ b/core/java/android/os/image/DynamicSystemManager.java
@@ -14,50 +14,51 @@
  * limitations under the License.
  */
 
-package android.os;
+package android.os.image;
 
 import android.annotation.RequiresPermission;
 import android.annotation.SystemService;
 import android.content.Context;
 import android.gsi.GsiProgress;
+import android.os.RemoteException;
 
 /**
- * The DynamicAndroidManager offers a mechanism to use a new Android image temporarily. After the
+ * The DynamicSystemManager offers a mechanism to use a new system image temporarily. After the
  * installation, the device can reboot into this image with a new created /data. This image will
  * last until the next reboot and then the device will go back to the original image. However the
  * installed image and the new created /data are not deleted but disabled. Thus the application can
  * either re-enable the installed image by calling {@link #toggle} or use the {@link #remove} to
  * delete it completely. In other words, there are three device states: no installation, installed
- * and running. The procedure to install a DynamicAndroid starts with a {@link #startInstallation},
+ * and running. The procedure to install a DynamicSystem starts with a {@link #startInstallation},
  * followed by a series of {@link #write} and ends with a {@link commit}. Once the installation is
  * complete, the device state changes from no installation to the installed state and a followed
- * reboot will change its state to running. Note one instance of dynamic android can exist on a
- * given device thus the {@link #startInstallation} will fail if the device is currently running a
- * DynamicAndroid.
+ * reboot will change its state to running. Note one instance of DynamicSystem can exist on a given
+ * device thus the {@link #startInstallation} will fail if the device is currently running a
+ * DynamicSystem.
  *
  * @hide
  */
-@SystemService(Context.DYNAMIC_ANDROID_SERVICE)
-public class DynamicAndroidManager {
-    private static final String TAG = "DynamicAndroidManager";
+@SystemService(Context.DYNAMIC_SYSTEM_SERVICE)
+public class DynamicSystemManager {
+    private static final String TAG = "DynamicSystemManager";
 
-    private final IDynamicAndroidService mService;
+    private final IDynamicSystemService mService;
 
     /** {@hide} */
-    public DynamicAndroidManager(IDynamicAndroidService service) {
+    public DynamicSystemManager(IDynamicSystemService service) {
         mService = service;
     }
 
-    /** The DynamicAndroidManager.Session represents a started session for the installation. */
+    /** The DynamicSystemManager.Session represents a started session for the installation. */
     public class Session {
         private Session() {}
         /**
-         * Write a chunk of the DynamicAndroid system image
+         * Write a chunk of the DynamicSystem system image
          *
          * @return {@code true} if the call succeeds. {@code false} if there is any native runtime
          *     error.
          */
-        @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+        @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
         public boolean write(byte[] buf) {
             try {
                 return mService.write(buf);
@@ -72,7 +73,7 @@
          * @return {@code true} if the call succeeds. {@code false} if there is any native runtime
          *     error.
          */
-        @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+        @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
         public boolean commit() {
             try {
                 return mService.commit();
@@ -82,16 +83,16 @@
         }
     }
     /**
-     * Start DynamicAndroid installation. This call may take an unbounded amount of time. The caller
+     * Start DynamicSystem installation. This call may take an unbounded amount of time. The caller
      * may use another thread to call the getStartProgress() to get the progress.
      *
      * @param systemSize system size in bytes
      * @param userdataSize userdata size in bytes
      * @return {@code true} if the call succeeds. {@code false} either the device does not contain
-     *     enough space or a DynamicAndroid is currently in use where the {@link #isInUse} would be
+     *     enough space or a DynamicSystem is currently in use where the {@link #isInUse} would be
      *     true.
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
     public Session startInstallation(long systemSize, long userdataSize) {
         try {
             if (mService.startInstallation(systemSize, userdataSize)) {
@@ -112,7 +113,7 @@
      *     status field can be IGsiService.STATUS_NO_OPERATION, IGsiService.STATUS_WORKING or
      *     IGsiService.STATUS_COMPLETE.
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
     public GsiProgress getInstallationProgress() {
         try {
             return mService.getInstallationProgress();
@@ -129,7 +130,7 @@
      * @return {@code true} if the call succeeds. {@code false} if there is no installation
      *     currently.
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
     public boolean abort() {
         try {
             return mService.abort();
@@ -138,8 +139,8 @@
         }
     }
 
-    /** @return {@code true} if the device is running a dynamic android */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+    /** @return {@code true} if the device is running a dynamic system */
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
     public boolean isInUse() {
         try {
             return mService.isInUse();
@@ -148,8 +149,8 @@
         }
     }
 
-    /** @return {@code true} if the device has a dynamic android installed */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+    /** @return {@code true} if the device has a dynamic system installed */
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
     public boolean isInstalled() {
         try {
             return mService.isInstalled();
@@ -159,11 +160,11 @@
     }
 
     /**
-     * Remove DynamicAndroid installation if present
+     * Remove DynamicSystem installation if present
      *
      * @return {@code true} if the call succeeds. {@code false} if there is no installed image.
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
     public boolean remove() {
         try {
             return mService.remove();
@@ -173,11 +174,11 @@
     }
 
     /**
-     * Enable DynamicAndroid when it's not enabled, otherwise, disable it.
+     * Enable DynamicSystem when it's not enabled, otherwise, disable it.
      *
      * @return {@code true} if the call succeeds. {@code false} if there is no installed image.
      */
-    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+    @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
     public boolean toggle() {
         try {
             return mService.toggle();
diff --git a/core/java/android/os/IDynamicAndroidService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl
similarity index 83%
rename from core/java/android/os/IDynamicAndroidService.aidl
rename to core/java/android/os/image/IDynamicSystemService.aidl
index 0b28799..15f5b68 100644
--- a/core/java/android/os/IDynamicAndroidService.aidl
+++ b/core/java/android/os/image/IDynamicSystemService.aidl
@@ -13,15 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.os;
+package android.os.image;
 
 import android.gsi.GsiProgress;
 
 /** {@hide} */
-interface IDynamicAndroidService
+interface IDynamicSystemService
 {
     /**
-     * Start DynamicAndroid installation. This call may take 60~90 seconds. The caller
+     * Start DynamicSystem installation. This call may take 60~90 seconds. The caller
      * may use another thread to call the getStartProgress() to get the progress.
      *
      * @param systemSize system size in bytes
@@ -53,26 +53,26 @@
     boolean isInUse();
 
     /**
-     * @return true if the device has an DynamicAndroid image installed
+     * @return true if the device has an DynamicSystem image installed
      */
     boolean isInstalled();
 
     /**
-     * Remove DynamicAndroid installation if present
+     * Remove DynamicSystem installation if present
      *
      * @return true if the call succeeds
      */
     boolean remove();
 
     /**
-     * Enable DynamicAndroid when it's not enabled, otherwise, disable it.
+     * Enable DynamicSystem when it's not enabled, otherwise, disable it.
      *
      * @return true if the call succeeds
      */
     boolean toggle();
 
     /**
-     * Write a chunk of the DynamicAndroid system image
+     * Write a chunk of the DynamicSystem system image
      *
      * @return true if the call succeeds
      */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d4908ca..53c7eda 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -73,6 +73,7 @@
 import android.os.DropBoxManager;
 import android.os.IBinder;
 import android.os.LocaleList;
+import android.os.PowerManager.AutoPowerSaveModeTriggers;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -875,7 +876,8 @@
 
     /**
      * Activity Action: Show screen for controlling app usage properties for an app.
-     * Input: Intent's extra EXTRA_PACKAGE_NAME must specify the application package name.
+     * Input: Intent's extra {@link android.content.Intent#EXTRA_PACKAGE_NAME} must specify the
+     * application package name.
      * Output: Nothing.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@@ -12599,12 +12601,11 @@
         /**
          * Battery level [1-100] at which low power mode automatically turns on.
          * If 0, it will not automatically turn on. For Q and newer, it will only automatically
-         * turn on if the value is greater than 0 and the {@link #AUTOMATIC_POWER_SAVER_MODE}
+         * turn on if the value is greater than 0 and the {@link #AUTOMATIC_POWER_SAVE_MODE}
          * setting is also set to
-         * {@link android.os.PowerManager.AutoPowerSaverMode#POWER_SAVER_MODE_PERCENTAGE}.
-         *
-         * @see #AUTOMATIC_POWER_SAVER_MODE
-         * @see android.os.PowerManager#getPowerSaveMode()
+         * {@link android.os.PowerManager.AutoPowerSaveMode#POWER_SAVE_MODE_TRIGGER_PERCENTAGE}.
+         * @see #AUTOMATIC_POWER_SAVE_MODE
+         * @see android.os.PowerManager#getPowerSaveModeTrigger()
          * @hide
          */
         public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level";
@@ -12614,22 +12615,22 @@
 
         /**
          * Whether battery saver is currently set to trigger based on percentage, dynamic power
-         * savings trigger, or none. See {@link android.os.PowerManager.AutoPowerSaverMode} for
+         * savings trigger, or none. See {@link AutoPowerSaveModeTriggers} for
          * accepted values.
          *
          *  @hide
          */
         @TestApi
-        public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode";
+        public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
 
-        private static final Validator AUTOMATIC_POWER_SAVER_MODE_VALIDATOR =
+        private static final Validator AUTOMATIC_POWER_SAVE_MODE_VALIDATOR =
                 new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1"});
 
         /**
          * The setting that backs the disable threshold for the setPowerSavingsWarning api in
          * PowerManager
          *
-         * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int)
+         * @see android.os.PowerManager#setDynamicPowerSaveHint(boolean, int)
          * @hide
          */
         @TestApi
@@ -12639,9 +12640,9 @@
                 new SettingsValidators.InclusiveIntegerRangeValidator(0, 100);
 
         /**
-         * The setting which backs the setDynamicPowerSavings api in PowerManager.
+         * The setting which backs the setDynamicPowerSaveHint api in PowerManager.
          *
-         * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int)
+         * @see android.os.PowerManager#setDynamicPowerSaveHint(boolean, int)
          * @hide
          */
         @TestApi
@@ -13630,7 +13631,7 @@
             VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR);
             VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL_MAX,
                     LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR);
-            VALIDATORS.put(AUTOMATIC_POWER_SAVER_MODE, AUTOMATIC_POWER_SAVER_MODE_VALIDATOR);
+            VALIDATORS.put(AUTOMATIC_POWER_SAVE_MODE, AUTOMATIC_POWER_SAVE_MODE_VALIDATOR);
             VALIDATORS.put(DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
                     DYNAMIC_POWER_SAVINGS_VALIDATOR);
             VALIDATORS.put(BLUETOOTH_ON, BLUETOOTH_ON_VALIDATOR);
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index df11397..fb07aba 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -298,12 +298,12 @@
     /**
      * Disables the Content Capture service for the given user.
      */
-    public final void disableContentCaptureServices() {
-        if (sDebug) Log.d(TAG, "disableContentCaptureServices()");
+    public final void disableSelf() {
+        if (sDebug) Log.d(TAG, "disableSelf()");
 
         final IContentCaptureServiceCallback callback = mCallback;
         if (callback == null) {
-            Log.w(TAG, "disableContentCaptureServices(): no server callback");
+            Log.w(TAG, "disableSelf(): no server callback");
             return;
         }
         try {
@@ -367,7 +367,6 @@
             stateFlags = initialState;
         } else {
             stateFlags |= ContentCaptureSession.STATE_DISABLED;
-
         }
         setClientState(clientReceiver, stateFlags, mClientInterface.asBinder());
     }
diff --git a/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java b/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java
index 6ecd82f..fb60619 100644
--- a/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java
+++ b/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java
@@ -139,6 +139,7 @@
         mSettingsActivity = settingsActivity;
     }
 
+    @NonNull
     public ServiceInfo getServiceInfo() {
         return mServiceInfo;
     }
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 23607eb..333868a 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -476,7 +476,7 @@
      * @param hideSilentStatusIcons whether or not status bar icons should be hidden for silent
      *                              notifications
      */
-    public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
+    public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) {
         // optional
     }
 
@@ -2255,7 +2255,7 @@
                 } break;
 
                 case MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED: {
-                    onStatusBarIconsBehaviorChanged((Boolean) msg.obj);
+                    onSilentStatusBarIconsVisibilityChanged((Boolean) msg.obj);
                 } break;
             }
         }
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index de10ffb..da6ef4c 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -52,14 +52,14 @@
         DEFAULT_FLAGS.put("settings_slice_injection", "true");
         DEFAULT_FLAGS.put("settings_systemui_theme", "true");
         DEFAULT_FLAGS.put("settings_mainline_module", "true");
-        DEFAULT_FLAGS.put("settings_dynamic_android", "false");
+        DEFAULT_FLAGS.put("settings_dynamic_system", "false");
         DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false");
         DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
         DEFAULT_FLAGS.put(SAFETY_HUB, "false");
         DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
         DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "true");
         DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true");
-        DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "false");
+        DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "true");
         DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
     }
 
diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java
index bf46e95..30d3d7d 100644
--- a/core/java/android/util/StatsLog.java
+++ b/core/java/android/util/StatsLog.java
@@ -22,6 +22,7 @@
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.app.IActivityManager;
 import android.content.Context;
 import android.os.IStatsManager;
@@ -199,6 +200,16 @@
         }
     }
 
+    /**
+     * Write an event to stats log using the raw format.
+     *
+     * @param buffer    The encoded buffer of data to write..
+     * @param size      The number of bytes from the buffer to write.
+     * @hide
+     */
+    @SystemApi
+    public static native void writeRaw(@NonNull byte[] buffer, int size);
+
     private static void enforceDumpCallingPermission(Context context) {
         context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission.");
     }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index cd075bf..0043d32 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -88,10 +88,10 @@
     private static native void nativeDestroy(long nativeObject);
     private static native void nativeDisconnect(long nativeObject);
 
-    private static native GraphicBuffer nativeScreenshot(IBinder displayToken,
+    private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
             Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
             boolean captureSecureLayers);
-    private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
+    private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
             Rect sourceCrop, float frameScale);
 
     private static native long nativeCreateTransaction();
@@ -431,7 +431,52 @@
     public static final int METADATA_TASK_ID = 3;
 
     /**
+     * A wrapper around GraphicBuffer that contains extra information about how to
+     * interpret the screenshot GraphicBuffer.
+     * @hide
+     */
+    public static class ScreenshotGraphicBuffer {
+        private final GraphicBuffer mGraphicBuffer;
+        private final ColorSpace mColorSpace;
+
+        public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
+            mGraphicBuffer = graphicBuffer;
+            mColorSpace = colorSpace;
+        }
+
+       /**
+        * Create ScreenshotGraphicBuffer from existing native GraphicBuffer object.
+        * @param width The width in pixels of the buffer
+        * @param height The height in pixels of the buffer
+        * @param format The format of each pixel as specified in {@link PixelFormat}
+        * @param usage Hint indicating how the buffer will be used
+        * @param unwrappedNativeObject The native object of GraphicBuffer
+        * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
+        */
+        private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format,
+                int usage, long unwrappedNativeObject, int namedColorSpace) {
+            GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format,
+                    usage, unwrappedNativeObject);
+            ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
+            return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace);
+        }
+
+        public ColorSpace getColorSpace() {
+            return mColorSpace;
+        }
+
+        public GraphicBuffer getGraphicBuffer() {
+            return mGraphicBuffer;
+        }
+    }
+
+    /**
      * Builder class for {@link SurfaceControl} objects.
+     *
+     * By default the surface will be hidden, and have "unset" bounds, meaning it can
+     * be as large as the bounds of its parent if a buffer or child so requires.
+     *
+     * It is necessary to set at least a name via {@link Builder#setName}
      */
     public static class Builder {
         private SurfaceSession mSession;
@@ -466,11 +511,11 @@
         @NonNull
         public SurfaceControl build() {
             if (mWidth < 0 || mHeight < 0) {
-                throw new IllegalArgumentException(
+                throw new IllegalStateException(
                         "width and height must be positive or unset");
             }
             if ((mWidth > 0 || mHeight > 0) && (isColorLayerSet() || isContainerLayerSet())) {
-                throw new IllegalArgumentException(
+                throw new IllegalStateException(
                         "Only buffer layers can set a valid buffer size.");
             }
             return new SurfaceControl(
@@ -860,7 +905,9 @@
      * Release the local reference to the server-side surface. The surface
      * may continue to exist on-screen as long as its parent continues
      * to exist. To explicitly remove a surface from the screen use
-     * {@link Transaction#reparent} with a null-parent.
+     * {@link Transaction#reparent} with a null-parent. After release,
+     * {@link #isValid} will return false and other methods will throw
+     * an exception.
      *
      * Always call release() when you're done with a SurfaceControl.
      */
@@ -902,7 +949,8 @@
 
     /**
      * Check whether this instance points to a valid layer with the system-compositor. For
-     * example this may be false if construction failed, or the layer was released.
+     * example this may be false if construction failed, or the layer was released
+     * ({@link #release}).
      *
      * @return Whether this SurfaceControl is valid.
      */
@@ -1815,10 +1863,10 @@
             throw new IllegalArgumentException("consumer must not be null");
         }
 
-        final GraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, height,
-                useIdentityTransform, rotation);
+        final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width,
+                height, useIdentityTransform, rotation);
         try {
-            consumer.attachAndQueueBuffer(buffer);
+            consumer.attachAndQueueBuffer(buffer.getGraphicBuffer());
         } catch (RuntimeException e) {
             Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
         }
@@ -1861,17 +1909,16 @@
         }
 
         SurfaceControl.rotateCropForSF(sourceCrop, rotation);
-        final GraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, height,
-                useIdentityTransform, rotation);
+        final ScreenshotGraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width,
+                height, useIdentityTransform, rotation);
 
         if (buffer == null) {
             Log.w(TAG, "Failed to take screenshot");
             return null;
         }
-        // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
-        // should continue to fix screenshot.
-        return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(buffer),
-                ColorSpace.get(ColorSpace.Named.SRGB));
+        return Bitmap.wrapHardwareBuffer(
+                HardwareBuffer.createFromGraphicBuffer(buffer.getGraphicBuffer()),
+                buffer.getColorSpace());
     }
 
     /**
@@ -1897,8 +1944,8 @@
      * @return Returns a GraphicBuffer that contains the captured content.
      * @hide
      */
-    public static GraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, int width,
-            int height, boolean useIdentityTransform, int rotation) {
+    public static ScreenshotGraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop,
+            int width, int height, boolean useIdentityTransform, int rotation) {
         if (display == null) {
             throw new IllegalArgumentException("displayToken must not be null");
         }
@@ -1917,7 +1964,7 @@
      *
      * @hide
      */
-    public static GraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
+    public static ScreenshotGraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
             Rect sourceCrop, int width, int height, boolean useIdentityTransform,
             int rotation) {
         if (display == null) {
@@ -1951,7 +1998,7 @@
      * @return Returns a GraphicBuffer that contains the layer capture.
      * @hide
      */
-    public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
+    public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
             float frameScale) {
         return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale);
     }
@@ -2042,8 +2089,7 @@
         }
 
         /**
-         * Close the transaction, if the transaction was not already applied this will cancel the
-         * transaction.
+         * Release the native transaction object, without applying it.
          */
         @Override
         public void close() {
@@ -2128,8 +2174,8 @@
         }
 
         /**
-         * Set the default buffer size for the SurfaceControl, if there is an
-         * {@link Surface} assosciated with the control, then
+         * Set the default buffer size for the SurfaceControl, if there is a
+         * {@link Surface} associated with the control, then
          * this will be the default size for buffers dequeued from it.
          * @param sc The surface to set the buffer size for.
          * @param w The default width
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index ee8d663..e931448 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -491,7 +491,7 @@
         if (mBackgroundControl == null) {
             return;
         }
-        if ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0) {
+        if ((mSubLayer > 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) {
             mBackgroundControl.show();
             mBackgroundControl.setLayer(Integer.MIN_VALUE);
         } else {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index a4d80dc..4851476 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -142,7 +142,7 @@
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768704)
     protected OnHierarchyChangeListener mOnHierarchyChangeListener;
 
     // The view contained within this ViewGroup that has or contains focus.
@@ -239,7 +239,7 @@
             @ViewDebug.FlagToString(mask = FLAG_PADDING_NOT_NULL, equals = FLAG_PADDING_NOT_NULL,
                     name = "PADDING_NOT_NULL")
     }, formatToHexString = true)
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769411)
     protected int mGroupFlags;
 
     /**
@@ -300,7 +300,7 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769377)
     protected static final int FLAG_USE_CHILD_DRAWING_ORDER = 0x400;
 
     /**
@@ -314,7 +314,7 @@
      *
      * {@hide}
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769647)
     protected static final int FLAG_SUPPORT_STATIC_TRANSFORMATIONS = 0x800;
 
     // UNUSED FLAG VALUE: 0x1000;
@@ -368,7 +368,7 @@
      * When set, this ViewGroup should not intercept touch events.
      * {@hide}
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123983692)
     protected static final int FLAG_DISALLOW_INTERCEPT = 0x80000;
 
     /**
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 35ed7bf..46a59f0 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -54,6 +54,16 @@
     int NAV_BAR_RIGHT = 1 << 1;
     int NAV_BAR_BOTTOM = 1 << 2;
 
+    // Navigation bar interaction modes
+    int NAV_BAR_MODE_3BUTTON = 0;
+    int NAV_BAR_MODE_2BUTTON = 1;
+    int NAV_BAR_MODE_GESTURAL = 2;
+
+    // Associated overlays for each nav bar mode
+    String NAV_BAR_MODE_3BUTTON_OVERLAY = "com.android.internal.systemui.navbar.threebutton";
+    String NAV_BAR_MODE_2BUTTON_OVERLAY = "com.android.internal.systemui.navbar.twobutton";
+    String NAV_BAR_MODE_GESTURAL_OVERLAY = "com.android.internal.systemui.navbar.gestural";
+
     /**
      * Broadcast sent when a user activity is detected.
      */
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index a3e6549..9e546a8 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -32,6 +32,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Log;
 import android.view.contentcapture.ContentCaptureSession.FlushReason;
 
@@ -52,11 +53,13 @@
     private static final String TAG = ContentCaptureManager.class.getSimpleName();
 
     /** @hide */
+    public static final int RESULT_CODE_OK = 0;
+    /** @hide */
     public static final int RESULT_CODE_TRUE = 1;
     /** @hide */
     public static final int RESULT_CODE_FALSE = 2;
     /** @hide */
-    public static final int RESULT_CODE_NOT_SERVICE = -1;
+    public static final int RESULT_CODE_SECURITY_EXCEPTION = -1;
 
     /**
      * Timeout for calls to system_server.
@@ -243,6 +246,7 @@
     @UiThread
     public void onActivityCreated(@NonNull IBinder applicationToken,
             @NonNull ComponentName activityComponent, int flags) {
+        if (mOptions.lite) return;
         synchronized (mLock) {
             mFlags |= flags;
             getMainContentCaptureSession().start(applicationToken, activityComponent, mFlags);
@@ -252,18 +256,21 @@
     /** @hide */
     @UiThread
     public void onActivityResumed() {
+        if (mOptions.lite) return;
         getMainContentCaptureSession().notifySessionLifecycle(/* started= */ true);
     }
 
     /** @hide */
     @UiThread
     public void onActivityPaused() {
+        if (mOptions.lite) return;
         getMainContentCaptureSession().notifySessionLifecycle(/* started= */ false);
     }
 
     /** @hide */
     @UiThread
     public void onActivityDestroyed() {
+        if (mOptions.lite) return;
         getMainContentCaptureSession().destroy();
     }
 
@@ -276,6 +283,7 @@
      */
     @UiThread
     public void flush(@FlushReason int reason) {
+        if (mOptions.lite) return;
         getMainContentCaptureSession().flush(reason);
     }
 
@@ -285,7 +293,7 @@
      */
     @Nullable
     public ComponentName getServiceComponentName() {
-        if (!isContentCaptureEnabled()) return null;
+        if (!isContentCaptureEnabled() && !mOptions.lite) return null;
 
         final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
         try {
@@ -297,6 +305,35 @@
     }
 
     /**
+     * Gets the (optional) intent used to launch the service-specific settings.
+     *
+     * <p>This method is static because it's called by Settings, which might not be whitelisted
+     * for content capture (in which case the ContentCaptureManager on its context would be null).
+     *
+     * @hide
+     */
+    // TODO: use "lite" options as it's done by activities from the content capture service
+    @Nullable
+    public static ComponentName getServiceSettingsComponentName() {
+        final IBinder binder = ServiceManager
+                .checkService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
+        if (binder == null) return null;
+
+        final IContentCaptureManager service = IContentCaptureManager.Stub.asInterface(binder);
+        final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
+        try {
+            service.getServiceSettingsActivity(resultReceiver);
+            final int resultCode = resultReceiver.getIntResult();
+            if (resultCode == RESULT_CODE_SECURITY_EXCEPTION) {
+                throw new SecurityException(resultReceiver.getStringResult());
+            }
+            return resultReceiver.getParcelableResult();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Checks whether content capture is enabled for this activity.
      *
      * <p>There are many reasons it could be disabled, such as:
@@ -311,6 +348,8 @@
      * </ul>
      */
     public boolean isContentCaptureEnabled() {
+        if (mOptions.lite) return false;
+
         final MainContentCaptureSession mainSession;
         synchronized (mLock) {
             mainSession = mMainSession;
@@ -365,7 +404,7 @@
                 return true;
             case RESULT_CODE_FALSE:
                 return false;
-            case RESULT_CODE_NOT_SERVICE:
+            case RESULT_CODE_SECURITY_EXCEPTION:
                 throw new SecurityException("caller is not user's ContentCapture service");
             default:
                 Log.wtf(TAG, "received invalid result: " + resultCode);
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 6d41b28..ed1ca2a 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -135,11 +135,18 @@
     public static final int STATE_SERVICE_DIED = 0x400;
 
     /**
+     * Session is disabled because the service package is being udpated.
+     *
+     * @hide
+     */
+    public static final int STATE_SERVICE_UPDATING = 0x800;
+
+    /**
      * Session is enabled, after the service died and came back to live.
      *
      * @hide
      */
-    public static final int STATE_SERVICE_RESURRECTED = 0x800;
+    public static final int STATE_SERVICE_RESURRECTED = 0x1000;
 
     private static final int INITIAL_CHILDREN_CAPACITY = 5;
 
diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
index e3b0372..15fbaa2 100644
--- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl
+++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
@@ -67,4 +67,9 @@
      * Returns whether the content capture feature is enabled for the calling user.
      */
     void isContentCaptureFeatureEnabled(in IResultReceiver result);
+
+    /**
+     * Returns a ComponentName with the name of custom service activity, if defined.
+     */
+    void getServiceSettingsActivity(in IResultReceiver result);
 }
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 666af59..790b8f9 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -230,7 +230,8 @@
 
     /**
      * Callback from {@code system_server} after call to
-     * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int, IBinder)}
+     * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int,
+     * IResultReceiver)}.
      *
      * @param resultCode session state
      * @param binder handle to {@code IContentCaptureDirectManager}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index cb44f79..0f2e702e 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -86,7 +86,8 @@
             new File("/data/misc/textclassifier/lang_id.model");
 
     // Actions
-    private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX = "actions_suggestions.model";
+    private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX =
+            "actions_suggestions\\.(.*)\\.model";
     private static final File UPDATED_ACTIONS_MODEL =
             new File("/data/misc/textclassifier/actions_suggestions.model");
 
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 702b507..54fff9b 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -237,7 +237,7 @@
                     if (DEBUG) {
                         Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
                     }
-                    if (isDestroyed()) {
+                    if (mChooserListAdapter == null || isDestroyed()) {
                         break;
                     }
                     unbindRemainingServices();
@@ -822,6 +822,7 @@
             mRefinementResultReceiver = null;
         }
         unbindRemainingServices();
+        mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
         mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
         if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
             mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback);
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 5c144d3..0a83fcc 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -481,7 +481,11 @@
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[" + mComponentName + "]";
+        return getClass().getSimpleName() + "[" + mComponentName
+                + " " + System.identityHashCode(this)
+                + (mService != null ? " (bound)" : " (unbound)")
+                + (mDestroyed ? " (destroyed)" : "")
+                + "]";
     }
 
     /**
diff --git a/core/java/com/android/internal/os/ZygoteConfig.java b/core/java/com/android/internal/os/ZygoteConfig.java
index c8ff51e..c6af8c2 100644
--- a/core/java/com/android/internal/os/ZygoteConfig.java
+++ b/core/java/com/android/internal/os/ZygoteConfig.java
@@ -24,14 +24,14 @@
 public class ZygoteConfig {
 
     /** If {@code true}, enables the unspecialized app process (USAP) pool feature */
-    public static final String USAP_POOL_ENABLED = "blastula_pool_enabled";
+    public static final String USAP_POOL_ENABLED = "usap_pool_enabled";
 
     /** The threshold used to determine if the pool should be refilled */
-    public static final String USAP_POOL_REFILL_THRESHOLD = "blastula_refill_threshold";
+    public static final String USAP_POOL_REFILL_THRESHOLD = "usap_refill_threshold";
 
     /** The maximum number of processes to keep in the USAP pool */
-    public static final String USAP_POOL_SIZE_MAX = "blastula_pool_size_max";
+    public static final String USAP_POOL_SIZE_MAX = "usap_pool_size_max";
 
     /** The minimum number of processes to keep in the USAP pool */
-    public static final String USAP_POOL_SIZE_MIN = "blastula_pool_size_min";
+    public static final String USAP_POOL_SIZE_MIN = "usap_pool_size_min";
 }
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index 3f3aba9..5d1911b 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -353,6 +353,8 @@
             return null;
         }
 
+        Log.i(TAG, "USAP Pool status change: " + (newStatus ? "ENABLED" : "DISABLED"));
+
         mUsapPoolEnabled = newStatus;
 
         if (newStatus) {
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 41e2fc8..b36c3fa 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -42,7 +42,7 @@
     long getLong(in String key, in long defaultValue, in int userId);
     @UnsupportedAppUsage
     String getString(in String key, in String defaultValue, in int userId);
-    void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId);
+    void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange);
     void resetKeyStore(int userId);
     VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId,
             in ICheckCredentialProgressCallback progressCallback);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 30f4d6f..dd48c15 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -669,17 +669,25 @@
     /**
      * Clear any lock pattern or password.
      */
-    public void clearLock(byte[] savedCredential, int userHandle) {
+    public boolean clearLock(byte[] savedCredential, int userHandle) {
+        return clearLock(savedCredential, userHandle, false);
+    }
+
+    /**
+     * Clear any lock pattern or password, with the option to ignore incorrect existing credential.
+     */
+    public boolean clearLock(byte[] savedCredential, int userHandle, boolean allowUntrustedChange) {
         final int currentQuality = getKeyguardStoredPasswordQuality(userHandle);
         setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle);
 
         try{
             getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE,
-                    savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle);
+                    savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle,
+                    allowUntrustedChange);
         } catch (Exception e) {
             Log.e(TAG, "Failed to clear lock", e);
             setKeyguardStoredPasswordQuality(currentQuality, userHandle);
-            return;
+            return false;
         }
 
         if (userHandle == UserHandle.USER_SYSTEM) {
@@ -689,6 +697,7 @@
         }
 
         onAfterChangingPassword(userHandle);
+        return true;
     }
 
     /**
@@ -726,19 +735,28 @@
     /**
      * Save a lock pattern.
      * @param pattern The new pattern to save.
+     * @param savedPattern The previously saved pattern, converted to byte[] format
      * @param userId the user whose pattern is to be saved.
+     *
+     * @return whether this was successful or not.
      */
-    public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) {
-        this.saveLockPattern(pattern, null, userId);
+    public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
+            int userId) {
+        return saveLockPattern(pattern, savedPattern, userId, false);
     }
+
     /**
      * Save a lock pattern.
      * @param pattern The new pattern to save.
      * @param savedPattern The previously saved pattern, converted to byte[] format
      * @param userId the user whose pattern is to be saved.
+     * @param allowUntrustedChange whether we want to allow saving a new password if the existing
+     * password being provided is incorrect.
+     *
+     * @return whether this was successful or not.
      */
-    public void saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
-            int userId) {
+    public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
+            int userId, boolean allowUntrustedChange) {
         if (!hasSecureLockScreen()) {
             throw new UnsupportedOperationException(
                     "This operation requires the lock screen feature.");
@@ -753,11 +771,11 @@
         setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId);
         try {
             getLockSettings().setLockCredential(bytePattern, CREDENTIAL_TYPE_PATTERN, savedPattern,
-                    PASSWORD_QUALITY_SOMETHING, userId);
+                    PASSWORD_QUALITY_SOMETHING, userId, allowUntrustedChange);
         } catch (Exception e) {
             Log.e(TAG, "Couldn't save lock pattern", e);
             setKeyguardStoredPasswordQuality(currentQuality, userId);
-            return;
+            return false;
         }
         // Update the device encryption password.
         if (userId == UserHandle.USER_SYSTEM
@@ -771,6 +789,7 @@
 
         reportPatternWasChosen(userId);
         onAfterChangingPassword(userId);
+        return true;
     }
 
     private void updateCryptoUserInfo(int userId) {
@@ -873,17 +892,20 @@
      * password.
      * @param password The password to save
      * @param savedPassword The previously saved lock password, or null if none
-     * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
+     * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
+     * android.content.ComponentName)}
      * @param userHandle The userId of the user to change the password for
      *
+     * @return whether this was successful or not.
+     *
      * @deprecated Pass password as a byte array
      */
     @Deprecated
-    public void saveLockPassword(String password, String savedPassword, int requestedQuality,
+    public boolean saveLockPassword(String password, String savedPassword, int requestedQuality,
             int userHandle) {
         byte[] passwordBytes = password != null ? password.getBytes() : null;
         byte[] savedPasswordBytes = savedPassword != null ? savedPassword.getBytes() : null;
-        saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle);
+        return saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle);
     }
 
     /**
@@ -893,11 +915,34 @@
      * @param password The password to save
      * @param savedPassword The previously saved lock password, or null if none
      * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
-     *          android.content.ComponentName)}
+     * android.content.ComponentName)}
      * @param userHandle The userId of the user to change the password for
+     *
+     * @return whether this was successful or not.
      */
-    public void saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality,
+    public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality,
             int userHandle) {
+        return saveLockPassword(password, savedPassword, requestedQuality,
+                userHandle, false);
+    }
+
+    /**
+     * Save a lock password.  Does not ensure that the password is as good
+     * as the requested mode, but will adjust the mode to be as good as the
+     * password.
+     * @param password The password to save
+     * @param savedPassword The previously saved lock password, or null if none
+     * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
+     * android.content.ComponentName)}
+     * @param userHandle The userId of the user to change the password for
+     * @param allowUntrustedChange whether we want to allow saving a new password if the existing
+     * password being provided is incorrect.
+     *
+     * @return whether this method saved the new password successfully or not. This flow will fail
+     * and return false if the given credential is wrong and allowUntrustedChange is false.
+     */
+    public boolean saveLockPassword(byte[] password, byte[] savedPassword,
+            int requestedQuality, int userHandle, boolean allowUntrustedChange) {
         if (!hasSecureLockScreen()) {
             throw new UnsupportedOperationException(
                     "This operation requires the lock screen feature.");
@@ -919,16 +964,17 @@
         setKeyguardStoredPasswordQuality(newKeyguardQuality, userHandle);
         try {
             getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
-                    requestedQuality, userHandle);
+                    requestedQuality, userHandle, allowUntrustedChange);
         } catch (Exception e) {
             Log.e(TAG, "Unable to save lock password", e);
             setKeyguardStoredPasswordQuality(currentQuality, userHandle);
-            return;
+            return false;
         }
 
         updateEncryptionPasswordIfNeeded(password, passwordQuality, userHandle);
         updatePasswordHistory(password, userHandle);
         onAfterChangingPassword(userHandle);
+        return true;
     }
 
     /**
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index cd34d2e..664f7f4 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -1,10 +1,10 @@
 
 genrule {
-    name: "android_util_StatsLog.cpp",
+    name: "android_util_StatsLogInternal.cpp",
     tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLog.cpp",
+    cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLogInternal.cpp",
     out: [
-        "android_util_StatsLog.cpp",
+        "android_util_StatsLogInternal.cpp",
     ],
 }
 
@@ -111,6 +111,7 @@
         "android_util_Binder.cpp",
         "android_util_EventLog.cpp",
         "android_util_Log.cpp",
+        "android_util_StatsLog.cpp",
         "android_util_MemoryIntArray.cpp",
         "android_util_PathParser.cpp",
         "android_util_Process.cpp",
@@ -306,7 +307,7 @@
         "server_configurable_flags",
     ],
 
-    generated_sources: ["android_util_StatsLog.cpp"],
+    generated_sources: ["android_util_StatsLogInternal.cpp"],
 
     local_include_dirs: ["android/graphics"],
     export_include_dirs: [
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 20bed1b..ccd0b66 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -127,6 +127,7 @@
 extern int register_android_content_AssetManager(JNIEnv* env);
 extern int register_android_util_EventLog(JNIEnv* env);
 extern int register_android_util_StatsLog(JNIEnv* env);
+extern int register_android_util_StatsLogInternal(JNIEnv* env);
 extern int register_android_util_Log(JNIEnv* env);
 extern int register_android_util_MemoryIntArray(JNIEnv* env);
 extern int register_android_util_PathParser(JNIEnv* env);
@@ -1400,6 +1401,7 @@
     REG_JNI(register_android_util_MemoryIntArray),
     REG_JNI(register_android_util_PathParser),
     REG_JNI(register_android_util_StatsLog),
+    REG_JNI(register_android_util_StatsLogInternal),
     REG_JNI(register_android_app_admin_SecurityLog),
     REG_JNI(register_android_content_AssetManager),
     REG_JNI(register_android_content_StringBlock),
diff --git a/core/jni/android_util_StatsLog.cpp b/core/jni/android_util_StatsLog.cpp
new file mode 100644
index 0000000..e749d34
--- /dev/null
+++ b/core/jni/android_util_StatsLog.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#define LOG_NAMESPACE "StatsLog.tag."
+#define LOG_TAG "StatsLog_println"
+
+#include <assert.h>
+#include <cutils/properties.h>
+
+#include "jni.h"
+#include <nativehelper/JNIHelp.h>
+#include "utils/misc.h"
+#include "core_jni_helpers.h"
+#include "stats_event_list.h"
+
+namespace android {
+
+static void android_util_StatsLog_writeRaw(JNIEnv* env, jobject clazz, jbyteArray buf, jint size)
+{
+    if (buf == NULL) {
+        return;
+    }
+    jint actualSize = env->GetArrayLength(buf);
+    if (actualSize < size) {
+        return;
+    }
+
+    jbyte* bufferArray = env->GetByteArrayElements(buf, NULL);
+    if (bufferArray == NULL) {
+        return;
+    }
+    const uint32_t statsEventTag = 1937006964;
+    struct iovec vec[2];
+    vec[0].iov_base = (void*) &statsEventTag;
+    vec[0].iov_len = sizeof(statsEventTag);
+    vec[1].iov_base = (void*) bufferArray;
+    vec[1].iov_len = size;
+    write_to_statsd(vec, 2);
+
+    env->ReleaseByteArrayElements(buf, bufferArray, 0);
+}
+
+/*
+ * JNI registration.
+ */
+static const JNINativeMethod gMethods[] = {
+    /* name, signature, funcPtr */
+    { "writeRaw", "([BI)V", (void*) android_util_StatsLog_writeRaw },
+};
+
+int register_android_util_StatsLog(JNIEnv* env)
+{
+    return RegisterMethodsOrDie(env, "android/util/StatsLog", gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 4a6c72b..94f96ba 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -126,6 +126,41 @@
     jfieldID white;
 } gDisplayPrimariesClassInfo;
 
+static struct {
+    jclass clazz;
+    jmethodID builder;
+} gScreenshotGraphicBufferClassInfo;
+
+class JNamedColorSpace {
+public:
+    // ColorSpace.Named.SRGB.ordinal() = 0;
+    static constexpr jint SRGB = 0;
+
+    // ColorSpace.Named.DISPLAY_P3.ordinal() = 6;
+    static constexpr jint DISPLAY_P3 = 6;
+};
+
+constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
+    switch (dataspace) {
+        case ui::Dataspace::DISPLAY_P3:
+            return JNamedColorSpace::DISPLAY_P3;
+        default:
+            return JNamedColorSpace::SRGB;
+    }
+}
+
+constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
+    switch (colorMode) {
+        case ui::ColorMode::DISPLAY_P3:
+        case ui::ColorMode::BT2100_PQ:
+        case ui::ColorMode::BT2100_HLG:
+        case ui::ColorMode::DISPLAY_BT2020:
+            return ui::Dataspace::DISPLAY_P3;
+        default:
+            return ui::Dataspace::V0_SRGB;
+    }
+}
+
 // ----------------------------------------------------------------------------
 
 static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
@@ -210,9 +245,12 @@
     if (displayToken == NULL) {
         return NULL;
     }
+    const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
+    const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode);
+
     Rect sourceCrop = rectFromObj(env, sourceCropObj);
     sp<GraphicBuffer> buffer;
-    status_t res = ScreenshotClient::capture(displayToken, ui::Dataspace::V0_SRGB,
+    status_t res = ScreenshotClient::capture(displayToken, dataspace,
             ui::PixelFormat::RGBA_8888,
             sourceCrop, width, height,
             useIdentityTransform, rotation, captureSecureLayers, &buffer);
@@ -220,13 +258,15 @@
         return NULL;
     }
 
-    return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
-            gGraphicBufferClassInfo.builder,
+    const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
+    return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
+            gScreenshotGraphicBufferClassInfo.builder,
             buffer->getWidth(),
             buffer->getHeight(),
             buffer->getPixelFormat(),
             (jint)buffer->getUsage(),
-            (jlong)buffer.get());
+            (jlong)buffer.get(),
+            namedColorSpace);
 }
 
 static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
@@ -243,20 +283,23 @@
     }
 
     sp<GraphicBuffer> buffer;
-    status_t res = ScreenshotClient::captureChildLayers(layerHandle, ui::Dataspace::V0_SRGB,
+    const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
+    status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
                                                         ui::PixelFormat::RGBA_8888, sourceCrop,
                                                         frameScale, &buffer);
     if (res != NO_ERROR) {
         return NULL;
     }
 
-    return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
-                                       gGraphicBufferClassInfo.builder,
+    const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
+    return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
+                                       gScreenshotGraphicBufferClassInfo.builder,
                                        buffer->getWidth(),
                                        buffer->getHeight(),
                                        buffer->getPixelFormat(),
                                        (jint)buffer->getUsage(),
-                                       (jlong)buffer.get());
+                                       (jlong)buffer.get(),
+                                       namedColorSpace);
 }
 
 static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
@@ -1306,9 +1349,13 @@
             (void*)nativeSetOverrideScalingMode },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
             (void*)nativeGetHandle },
-    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)Landroid/graphics/GraphicBuffer;",
+    {"nativeScreenshot",
+            "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
+            "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
             (void*)nativeScreenshot },
-    {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;",
+    {"nativeCaptureLayers",
+            "(Landroid/os/IBinder;Landroid/graphics/Rect;F)"
+            "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
             (void*)nativeCaptureLayers },
     {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
             (void*)nativeSetInputWindowInfo },
@@ -1386,6 +1433,14 @@
     gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
             "createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;");
 
+    jclass screenshotGraphicsBufferClazz = FindClassOrDie(env,
+            "android/view/SurfaceControl$ScreenshotGraphicBuffer");
+    gScreenshotGraphicBufferClassInfo.clazz =
+            MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
+    gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env,
+            screenshotGraphicsBufferClazz,
+            "createFromNative", "(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");
+
     jclass displayedContentSampleClazz = FindClassOrDie(env,
             "android/hardware/display/DisplayedContentSample");
     gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 25caafb..b4be3f5 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2316,4 +2316,7 @@
     // OPEN: Settings > Face > Remove face
     // OS: Q
     DIALOG_FACE_REMOVE = 1693;
+
+    // Settings > Display > Theme
+    DARK_UI_SETTINGS = 1698;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 305fc97..cb8ece7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1849,8 +1849,8 @@
     <permission android:name="android.permission.HARDWARE_TEST"
         android:protectionLevel="signature" />
 
-    <!-- @hide Allows an application to manage DynamicAndroid image -->
-    <permission android:name="android.permission.MANAGE_DYNAMIC_ANDROID"
+    <!-- @hide Allows an application to manage DynamicSystem image -->
+    <permission android:name="android.permission.MANAGE_DYNAMIC_SYSTEM"
         android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows access to Broadcast Radio
diff --git a/core/res/res/drawable-car/car_dialog_button_background.xml b/core/res/res/drawable-car/car_dialog_button_background.xml
index dc742d5..67506cb 100644
--- a/core/res/res/drawable-car/car_dialog_button_background.xml
+++ b/core/res/res/drawable-car/car_dialog_button_background.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 <ripple xmlns:android="http://schemas.android.com/apk/res/android"
-        android:color="@*android:color/car_card_ripple_background">
+        android:color="?android:attr/colorControlHighlight">
     <item android:id="@android:id/mask">
         <color android:color="@*android:color/car_white_1000" />
     </item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 14edf6f..14202f2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3222,6 +3222,12 @@
          -->
     <integer name="config_navBarOpacityMode">0</integer>
 
+    <!-- Controls the navigation bar interaction mode:
+         0: 3 button mode (back, home, overview buttons)
+         1: 2 button mode (back, home buttons + swipe up for overview)
+         2: gestures only for back, home and overview -->
+    <integer name="config_navBarInteractionMode">0</integer>
+
     <!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
          These values are in DPs and will be converted to pixel sizes internally. -->
     <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">16x16</string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 24fd3a8..79bf738 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -802,7 +802,7 @@
     <string name="permgrouprequest_visual">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your photos and videos?</string>
     <!-- Subtitle of the message shown to the user when the apps requests permission to access photos and videos [CHAR LIMIT=150]-->
-    <string name="permgrouprequestdetail_visual">Locations and other people in your photos and videos can be identified by the app</string>
+    <string name="permgrouprequestdetail_visual">This includes any locations tagged in your photos and videos</string>
 
     <!-- Title for the capability of an accessibility service to retrieve window content. -->
     <string name="capability_title_canRetrieveWindowContent">Retrieve window content</string>
@@ -1584,7 +1584,7 @@
     <!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=50] -->
     <string name="face_error_hw_not_available">Face hardware not available.</string>
     <!-- Error message shown when the face hardware timer has expired and the user needs to restart the operation. [CHAR LIMIT=50] -->
-    <string name="face_error_timeout">Face time out reached. Try again.</string>
+    <string name="face_error_timeout">Face timeout reached. Try again.</string>
     <!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=50] -->
     <string name="face_error_no_space">Face can\u2019t be stored.</string>
     <!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] -->
@@ -1596,11 +1596,11 @@
     <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=50] -->
     <string name="face_error_lockout_permanent">Too many attempts. Facial authentication disabled.</string>
     <!-- Generic error message shown when the face hardware can't recognize the face. [CHAR LIMIT=50] -->
-    <string name="face_error_unable_to_process">Try again.</string>
+    <string name="face_error_unable_to_process">Can\u2019t verify face. Try again.</string>
     <!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=50] -->
-    <string name="face_error_not_enrolled">No face enrolled.</string>
+    <string name="face_error_not_enrolled">You haven\u2019t set up face authentication.</string>
     <!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=60] -->
-    <string name="face_error_hw_not_present">This device does not have a face authentication sensor.</string>
+    <string name="face_error_hw_not_present">Face authentication is not supported on this device.</string>
 
     <!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] -->
     <string name="face_name_template">Face <xliff:g id="faceId" example="1">%d</xliff:g></string>
@@ -3283,18 +3283,36 @@
     <string name="dump_heap_notification"><xliff:g id="proc">%1$s</xliff:g> exceeded memory
         limit</string>
 
+    <!-- Notification text to tell the user that a heap dump that they initiated for a process is ready [CHAR LIMIT=NONE] -->
+    <string name="dump_heap_ready_notification">
+        <xliff:g id="proc" example="com.android.example">%1$s</xliff:g> heap dump ready</string>
+
     <!-- Notification details to tell the user that a process has exceeded its memory limit. -->
     <string name="dump_heap_notification_detail">Heap dump collected. Tap to share.</string>
 
     <!-- Title of dialog prompting the user to share a heap dump. -->
     <string name="dump_heap_title">Share heap dump?</string>
 
-    <!-- Text of dialog prompting the user to share a heap dump. -->
-    <string name="dump_heap_text">The process <xliff:g id="proc">%1$s</xliff:g> has exceeded
-        its process memory limit of <xliff:g id="size">%2$s</xliff:g>.  A heap dump is available
+    <!-- Text of dialog prompting the user to share a heap dump for an application [CHAR LIMIT=NONE] -->
+    <string name="dump_heap_text">The
+        <xliff:g id="proc" example="com.android.example">%1$s</xliff:g> process has exceeded
+        its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available
         for you to share with its developer.  Be careful: this heap dump can contain any
         of your personal information that the application has access to.</string>
 
+    <!-- Text of dialog prompting the user to share a heap dump for a system process [CHAR LIMIT=NONE] -->
+    <string name="dump_heap_system_text">The
+        <xliff:g id="proc" example="Android System">%1$s</xliff:g> process has exceeded
+        its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available
+        for you to share. Be careful: this heap dump can contain any sensitive personal information
+        that the process has access to.</string>
+
+    <!-- Text of dialog prompting the user to share a heap dump that they initiated [CHAR LIMIT=NONE] -->
+    <string name="dump_heap_ready_text">A heap dump of
+        <xliff:g id="proc" example="com.android.example">%1$s</xliff:g>\u2019s process is available
+        for you to share. Be careful: this heap dump may contain any sensitive personal information
+        that the process has access to.</string>
+
     <!-- Displayed in the title of the chooser for things to do with text that
          is to be sent to another application. For example, I can send
          text through SMS or IM.  A dialog with those choices would be shown,
@@ -5302,6 +5320,21 @@
     <string name="battery_saver_sticky_disabled_notification_title">Battery Saver won\u2019t reactivate until battery low again</string>
     <!-- Summary of notification letting users know why battery saver didn't turn back on automatically after the device was unplugged [CHAR_LIMIT=NONE] -->
     <string name="battery_saver_sticky_disabled_notification_summary">Battery has been charged to a sufficient level. Battery Saver won\u2019t reactivate until the battery is low again.</string>
+    <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] -->
+    <string name="battery_saver_charged_notification_title" product="default">Phone <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string>
+    <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] -->
+    <string name="battery_saver_charged_notification_title" product="tablet">Tablet <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string>
+    <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] -->
+    <string name="battery_saver_charged_notification_title" product="device">Device <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string>
+    <!-- Summary of notification letting users know that battery saver is now off [CHAR_LIMIT=NONE] -->
+    <string name="battery_saver_off_notification_summary">Battery Saver is off. Features no longer restricted.</string>
+    <!-- Alternative summary of notification letting users know that battery saver has been turned off.
+     If it's easy to translate the difference between "Battery Saver turned off. Features no longer restricted."
+     and "Battery Saver is off. Features no longer restricted." into the target language,
+     then translate "Battery Saver turned off. Features no longer restricted."
+     If the translation doesn't make a difference or the difference is hard to capture in the target language,
+     then translate "Battery Saver is off. Features no longer restricted." instead. [CHAR_LIMIT=NONE] -->
+    <string name="battery_saver_off_alternative_notification_summary">Battery Saver turned off. Features no longer restricted.</string>
 
     <!-- Description of media type: folder or directory that contains additional files. [CHAR LIMIT=32] -->
     <string name="mime_type_folder">Folder</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 93c8458..012f736 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2115,8 +2115,11 @@
   <java-symbol type="string" name="device_storage_monitor_notification_channel" />
   <java-symbol type="string" name="dlg_ok" />
   <java-symbol type="string" name="dump_heap_notification" />
+  <java-symbol type="string" name="dump_heap_ready_notification" />
   <java-symbol type="string" name="dump_heap_notification_detail" />
   <java-symbol type="string" name="dump_heap_text" />
+  <java-symbol type="string" name="dump_heap_ready_text" />
+  <java-symbol type="string" name="dump_heap_system_text" />
   <java-symbol type="string" name="dump_heap_title" />
   <java-symbol type="string" name="factorytest_failed" />
   <java-symbol type="string" name="factorytest_no_action" />
@@ -2832,6 +2835,7 @@
   <java-symbol type="string" name="config_packagedKeyboardName" />
   <java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" />
   <java-symbol type="integer" name="config_navBarOpacityMode" />
+  <java-symbol type="integer" name="config_navBarInteractionMode" />
   <java-symbol type="color" name="system_bar_background_semi_transparent" />
 
   <!-- EditText suggestion popup. -->
@@ -3649,6 +3653,9 @@
   <java-symbol type="string" name="battery_saver_notification_channel_name" />
   <java-symbol type="string" name="battery_saver_sticky_disabled_notification_title" />
   <java-symbol type="string" name="battery_saver_sticky_disabled_notification_summary" />
+  <java-symbol type="string" name="battery_saver_charged_notification_title" />
+  <java-symbol type="string" name="battery_saver_off_notification_summary" />
+  <java-symbol type="string" name="battery_saver_off_alternative_notification_summary" />
   <java-symbol type="string" name="dynamic_mode_notification_channel_name" />
   <java-symbol type="string" name="dynamic_mode_notification_title" />
   <java-symbol type="string" name="dynamic_mode_notification_summary" />
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 85947bd..8fc6a96 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -129,7 +129,7 @@
                     Settings.Global.AUTOFILL_LOGGING_LEVEL,
                     Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE,
                     Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
-                    Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
+                    Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
                     Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
                     Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST,
                     Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
index 72d1ab1..e1ccd75 100644
--- a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
@@ -64,7 +64,9 @@
                         null,
                         null,
                         null,
-                        null);
+                        null,
+                        0,
+                        0);
 
         List<LabeledIntent> intents = mLegacyIntentClassificationFactory.create(
                 InstrumentationRegistry.getContext(),
@@ -98,7 +100,9 @@
                         null,
                         null,
                         null,
-                        null);
+                        null,
+                        0,
+                        0);
 
         List<LabeledIntent> intents = mLegacyIntentClassificationFactory.create(
                 InstrumentationRegistry.getContext(),
diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
index ccf8607..2e97e63 100644
--- a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
@@ -82,7 +82,9 @@
                         null,
                         null,
                         null,
-                        createRemoteActionTemplates());
+                        createRemoteActionTemplates(),
+                        0,
+                        0);
 
         List<LabeledIntent> intents =
                 mTemplateClassificationIntentFactory.create(
@@ -121,7 +123,9 @@
                         null,
                         null,
                         null,
-                        createRemoteActionTemplates());
+                        createRemoteActionTemplates(),
+                        0,
+                        0);
 
         List<LabeledIntent> intents =
                 mTemplateClassificationIntentFactory.create(
@@ -156,7 +160,9 @@
                         null,
                         null,
                         null,
-                        null);
+                        null,
+                        0,
+                        0);
 
         mTemplateClassificationIntentFactory.create(
                 InstrumentationRegistry.getContext(),
@@ -189,7 +195,9 @@
                         null,
                         null,
                         null,
-                        new RemoteActionTemplate[0]);
+                        new RemoteActionTemplate[0],
+                        0,
+                        0);
 
         mTemplateClassificationIntentFactory.create(
                 InstrumentationRegistry.getContext(),
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 185fa07..8c2375e 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -599,7 +599,7 @@
 
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
-        verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
+        verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
         // First invocation is from onCreate
         assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
                 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
@@ -629,7 +629,7 @@
         ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
         mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
-        verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
+        verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
         // First invocation is from onCreate
         assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
                 is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index a0d14f9..afb5071 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -308,6 +308,8 @@
         <permission name="android.permission.STATUS_BAR_SERVICE"/>
         <permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"/>
         <permission name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS"/>
+        <permission name="android.permission.SET_WALLPAPER" />
+        <permission name="android.permission.SET_WALLPAPER_COMPONENT" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.statementservice">
@@ -330,9 +332,9 @@
         <permission name="android.permission.CONTROL_VPN"/>
     </privapp-permissions>
 
-    <privapp-permissions package="com.android.dynandroid">
+    <privapp-permissions package="com.android.dynsystem">
         <permission name="android.permission.REBOOT"/>
-        <permission name="android.permission.MANAGE_DYNAMIC_ANDROID"/>
+        <permission name="android.permission.MANAGE_DYNAMIC_SYSTEM"/>
     </privapp-permissions>
 
 </permissions>
diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java
index 9db7533..b6d8fa1 100644
--- a/graphics/java/android/graphics/text/MeasuredText.java
+++ b/graphics/java/android/graphics/text/MeasuredText.java
@@ -42,7 +42,7 @@
  * String text = "Hello, Android.";
  * MeasuredText mt = new MeasuredText.Builder(text.toCharArray())
  *      .appendStyleRun(paint, 7, false)  // Use paint for "Hello, "
- *      .appendStyleRun(bigPaint, 8, false)  // Use bigPaint for "Hello, "
+ *      .appendStyleRun(bigPaint, 8, false)  // Use bigPaint for "Android."
  *      .build();
  * </code>
  * </pre>
diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java
index 8507c83..5384061 100644
--- a/location/java/android/location/GnssClock.java
+++ b/location/java/android/location/GnssClock.java
@@ -16,6 +16,8 @@
 
 package android.location;
 
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
 import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -36,6 +38,8 @@
     private static final int HAS_BIAS_UNCERTAINTY = (1<<4);
     private static final int HAS_DRIFT = (1<<5);
     private static final int HAS_DRIFT_UNCERTAINTY = (1<<6);
+    private static final int HAS_ELAPSED_REALTIME_NANOS = (1 << 7);
+    private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS = (1 << 8);
 
     // End enumerations in sync with gps.h
 
@@ -49,6 +53,8 @@
     private double mDriftNanosPerSecond;
     private double mDriftUncertaintyNanosPerSecond;
     private int mHardwareClockDiscontinuityCount;
+    private long mElapsedRealtimeNanos;
+    private long mElapsedRealtimeUncertaintyNanos;
 
     /**
      * @hide
@@ -74,6 +80,8 @@
         mDriftNanosPerSecond = clock.mDriftNanosPerSecond;
         mDriftUncertaintyNanosPerSecond = clock.mDriftUncertaintyNanosPerSecond;
         mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount;
+        mElapsedRealtimeNanos = clock.mElapsedRealtimeNanos;
+        mElapsedRealtimeUncertaintyNanos = clock.mElapsedRealtimeUncertaintyNanos;
     }
 
     /**
@@ -167,6 +175,7 @@
      * <p>This value is often effectively zero (it is the reference clock by which all other times
      * and time uncertainties are measured), and thus this field may often be 0, or not provided.
      */
+    @FloatRange(from = 0.0f)
     public double getTimeUncertaintyNanos() {
         return mTimeUncertaintyNanos;
     }
@@ -176,7 +185,7 @@
      * @hide
      */
     @TestApi
-    public void setTimeUncertaintyNanos(double timeUncertaintyNanos) {
+    public void setTimeUncertaintyNanos(@FloatRange(from = 0.0f) double timeUncertaintyNanos) {
         setFlag(HAS_TIME_UNCERTAINTY);
         mTimeUncertaintyNanos = timeUncertaintyNanos;
     }
@@ -297,6 +306,7 @@
      *
      * <p>The value is only available if {@link #hasBiasUncertaintyNanos()} is {@code true}.
      */
+    @FloatRange(from = 0.0f)
     public double getBiasUncertaintyNanos() {
         return mBiasUncertaintyNanos;
     }
@@ -306,7 +316,7 @@
      * @hide
      */
     @TestApi
-    public void setBiasUncertaintyNanos(double biasUncertaintyNanos) {
+    public void setBiasUncertaintyNanos(@FloatRange(from = 0.0f) double biasUncertaintyNanos) {
         setFlag(HAS_BIAS_UNCERTAINTY);
         mBiasUncertaintyNanos = biasUncertaintyNanos;
     }
@@ -379,6 +389,7 @@
      * <p>The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is
      * {@code true}.
      */
+    @FloatRange(from = 0.0f)
     public double getDriftUncertaintyNanosPerSecond() {
         return mDriftUncertaintyNanosPerSecond;
     }
@@ -388,7 +399,8 @@
      * @hide
      */
     @TestApi
-    public void setDriftUncertaintyNanosPerSecond(double driftUncertaintyNanosPerSecond) {
+    public void setDriftUncertaintyNanosPerSecond(
+            @FloatRange(from = 0.0f) double driftUncertaintyNanosPerSecond) {
         setFlag(HAS_DRIFT_UNCERTAINTY);
         mDriftUncertaintyNanosPerSecond = driftUncertaintyNanosPerSecond;
     }
@@ -404,6 +416,90 @@
     }
 
     /**
+     * Returns {@code true} if {@link #getElapsedRealtimeNanos()} is available, {@code false}
+     * otherwise.
+     */
+    public boolean hasElapsedRealtimeNanos() {
+        return isFlagSet(HAS_ELAPSED_REALTIME_NANOS);
+    }
+
+    /**
+     * Returns the elapsed real-time of this clock since system boot, in nanoseconds.
+     *
+     * <p>The value is only available if {@link #hasElapsedRealtimeNanos()} is
+     * {@code true}.
+     */
+    public long getElapsedRealtimeNanos() {
+        return mElapsedRealtimeNanos;
+    }
+
+    /**
+     * Sets the elapsed real-time of this clock since system boot, in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void setElapsedRealtimeNanos(long elapsedRealtimeNanos) {
+        setFlag(HAS_ELAPSED_REALTIME_NANOS);
+        mElapsedRealtimeNanos = elapsedRealtimeNanos;
+    }
+
+    /**
+     * Resets the elapsed real-time of this clock since system boot, in nanoseconds.
+     * @hide
+     */
+    @TestApi
+    public void resetElapsedRealtimeNanos() {
+        resetFlag(HAS_ELAPSED_REALTIME_NANOS);
+        mElapsedRealtimeNanos = 0;
+    }
+
+    /**
+     * Returns {@code true} if {@link #getElapsedRealtimeUncertaintyNanos()} is available, {@code
+     * false} otherwise.
+     */
+    public boolean hasElapsedRealtimeUncertaintyNanos() {
+        return isFlagSet(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
+    }
+
+    /**
+     * Gets the estimate of the relative precision of the alignment of the
+     * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     *
+     * <p>The value is only available if {@link #hasElapsedRealtimeUncertaintyNanos()} is
+     * {@code true}.
+     */
+    @IntRange(from = 0)
+    public long getElapsedRealtimeUncertaintyNanos() {
+        return mElapsedRealtimeUncertaintyNanos;
+    }
+
+    /**
+     * Sets the estimate of the relative precision of the alignment of the
+     * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     * @hide
+     */
+    @TestApi
+    public void setElapsedRealtimeUncertaintyNanos(
+            @IntRange(from = 0) long elapsedRealtimeUncertaintyNanos) {
+        setFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
+        mElapsedRealtimeUncertaintyNanos = elapsedRealtimeUncertaintyNanos;
+    }
+
+    /**
+     * Resets the estimate of the relative precision of the alignment of the
+     * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in
+     * nanoseconds (68% confidence).
+     * @hide
+     */
+    @TestApi
+    public void resetElapsedRealtimeUncertaintyNanos() {
+        resetFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
+        mElapsedRealtimeUncertaintyNanos = Long.MAX_VALUE;
+    }
+
+    /**
      * Gets count of hardware clock discontinuities.
      *
      * <p>When this value stays the same, vs. a value in a previously reported {@link GnssClock}, it
@@ -446,6 +542,8 @@
             gpsClock.mDriftNanosPerSecond = parcel.readDouble();
             gpsClock.mDriftUncertaintyNanosPerSecond = parcel.readDouble();
             gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt();
+            gpsClock.mElapsedRealtimeNanos = parcel.readLong();
+            gpsClock.mElapsedRealtimeUncertaintyNanos = parcel.readLong();
 
             return gpsClock;
         }
@@ -468,6 +566,8 @@
         parcel.writeDouble(mDriftNanosPerSecond);
         parcel.writeDouble(mDriftUncertaintyNanosPerSecond);
         parcel.writeInt(mHardwareClockDiscontinuityCount);
+        parcel.writeLong(mElapsedRealtimeNanos);
+        parcel.writeLong(mElapsedRealtimeUncertaintyNanos);
     }
 
     @Override
@@ -514,6 +614,16 @@
                 "HardwareClockDiscontinuityCount",
                 mHardwareClockDiscontinuityCount));
 
+        builder.append(String.format(
+                format,
+                "ElapsedRealtimeNanos",
+                hasElapsedRealtimeNanos() ? mElapsedRealtimeNanos : null));
+
+        builder.append(String.format(
+                format,
+                "ElapsedRealtimeUncertaintyNanos",
+                hasElapsedRealtimeUncertaintyNanos() ? mElapsedRealtimeUncertaintyNanos : null));
+
         return builder.toString();
     }
 
@@ -528,6 +638,8 @@
         resetDriftNanosPerSecond();
         resetDriftUncertaintyNanosPerSecond();
         setHardwareClockDiscontinuityCount(Integer.MIN_VALUE);
+        resetElapsedRealtimeNanos();
+        resetElapsedRealtimeUncertaintyNanos();
     }
 
     private void setFlag(int flag) {
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index e5fd0d3..b4be219 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -238,6 +238,8 @@
      *    window after the end of that call.
      * 3. If the device is in a emergency callback state, this is provided by querying
      *    TelephonyManager.
+     * 4. If the user has recently sent an Emergency SMS and telephony reports that it is in
+     *    emergency SMS mode, this is provided by querying TelephonyManager.
      * @return true if is considered in user initiated emergency mode for NI purposes
      */
     public boolean getInEmergency() {
@@ -246,7 +248,9 @@
                 && ((SystemClock.elapsedRealtime() - mCallEndElapsedRealtimeMillis)
                         < mEmergencyExtensionMillis);
         boolean isInEmergencyCallback = mTelephonyManager.getEmergencyCallbackMode();
-        return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension;
+        boolean isInEmergencySmsMode = mTelephonyManager.isInEmergencySmsMode();
+        return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension
+                || isInEmergencySmsMode;
     }
 
     public void setEmergencyExtensionSeconds(int emergencyExtensionSeconds) {
diff --git a/media/apex/java/android/media/MediaController2.java b/media/apex/java/android/media/MediaController2.java
index 2743a34..1e8438e 100644
--- a/media/apex/java/android/media/MediaController2.java
+++ b/media/apex/java/android/media/MediaController2.java
@@ -22,8 +22,8 @@
 import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE;
 import static android.media.MediaConstants.KEY_SESSION2LINK;
 import static android.media.MediaConstants.KEY_TOKEN_EXTRAS;
-import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR;
-import static android.media.Session2Command.RESULT_INFO_SKIPPED;
+import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR;
+import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED;
 import static android.media.Session2Token.TYPE_SESSION;
 
 import android.annotation.NonNull;
@@ -329,7 +329,7 @@
                     MediaController2.this, command, args);
             if (resultReceiver != null) {
                 if (result == null) {
-                    resultReceiver.send(Session2Command.RESULT_INFO_SKIPPED, null);
+                    resultReceiver.send(RESULT_INFO_SKIPPED, null);
                 } else {
                     resultReceiver.send(result.getResultCode(), result.getResultData());
                 }
diff --git a/media/apex/java/android/media/MediaSession2.java b/media/apex/java/android/media/MediaSession2.java
index d63de09..a900d87 100644
--- a/media/apex/java/android/media/MediaSession2.java
+++ b/media/apex/java/android/media/MediaSession2.java
@@ -22,8 +22,8 @@
 import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE;
 import static android.media.MediaConstants.KEY_SESSION2LINK;
 import static android.media.MediaConstants.KEY_TOKEN_EXTRAS;
-import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR;
-import static android.media.Session2Command.RESULT_INFO_SKIPPED;
+import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR;
+import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED;
 import static android.media.Session2Token.TYPE_SESSION;
 
 import android.annotation.NonNull;
@@ -415,7 +415,7 @@
                     MediaSession2.this, controllerInfo, command, args);
             if (resultReceiver != null) {
                 if (result == null) {
-                    resultReceiver.send(Session2Command.RESULT_INFO_SKIPPED, null);
+                    resultReceiver.send(RESULT_INFO_SKIPPED, null);
                 } else {
                     resultReceiver.send(result.getResultCode(), result.getResultData());
                 }
diff --git a/media/apex/java/android/media/Session2Command.java b/media/apex/java/android/media/Session2Command.java
index 6822ea5..7f73dc1 100644
--- a/media/apex/java/android/media/Session2Command.java
+++ b/media/apex/java/android/media/Session2Command.java
@@ -48,22 +48,6 @@
      */
     public static final int COMMAND_CODE_CUSTOM = 0;
 
-    /**
-     * Result code representing that the command is skipped or canceled. For an example, a seek
-     * command can be skipped if it is followed by another seek command.
-     */
-    public static final int RESULT_INFO_SKIPPED = 1;
-
-    /**
-     * Result code representing that the command is successfully completed.
-     */
-    public static final int RESULT_SUCCESS = 0;
-
-    /**
-     * Result code represents that call is ended with an unknown error.
-     */
-    public static final int RESULT_ERROR_UNKNOWN_ERROR = -1;
-
     public static final @android.annotation.NonNull Parcelable.Creator<Session2Command> CREATOR =
             new Parcelable.Creator<Session2Command>() {
                 @Override
@@ -185,6 +169,22 @@
         private final Bundle mResultData;
 
         /**
+         * Result code representing that the command is skipped or canceled. For an example, a seek
+         * command can be skipped if it is followed by another seek command.
+         */
+        public static final int RESULT_INFO_SKIPPED = 1;
+
+        /**
+         * Result code representing that the command is successfully completed.
+         */
+        public static final int RESULT_SUCCESS = 0;
+
+        /**
+         * Result code represents that call is ended with an unknown error.
+         */
+        public static final int RESULT_ERROR_UNKNOWN_ERROR = -1;
+
+        /**
          * Constructor of {@link Result}.
          *
          * @param resultCode result code
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 005f2d4..a08aec3 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -552,6 +552,13 @@
          */
         public static final int STATUS_INTERNAL_ERROR = 4;
 
+        /**
+         * The key is not yet usable to decrypt media because the start
+         * time is in the future. The key will become usable when
+         * its start time is reached.
+         */
+        public static final int STATUS_USABLE_IN_FUTURE = 5;
+
         /** @hide */
         @IntDef({
             STATUS_USABLE,
@@ -559,6 +566,7 @@
             STATUS_OUTPUT_NOT_ALLOWED,
             STATUS_PENDING,
             STATUS_INTERNAL_ERROR,
+            STATUS_USABLE_IN_FUTURE,
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface KeyStatusCode {}
diff --git a/media/java/android/media/projection/OWNERS b/media/java/android/media/projection/OWNERS
new file mode 100644
index 0000000..7e7335d
--- /dev/null
+++ b/media/java/android/media/projection/OWNERS
@@ -0,0 +1 @@
+michaelwr@google.com
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index e1dc406..1f2480b 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -148,6 +148,7 @@
     AHardwareBuffer_getNativeHandle; # introduced=26
     AHardwareBuffer_isSupported; # introduced=29
     AHardwareBuffer_lock; # introduced=26
+    AHardwareBuffer_lockAndGetInfo; # introduced=29
     AHardwareBuffer_lockPlanes; # introduced=29
     AHardwareBuffer_recvHandleFromUnixSocket; # introduced=26
     AHardwareBuffer_release; # introduced=26
diff --git a/packages/DynamicAndroidInstallationService/Android.mk b/packages/DynamicSystemInstallationService/Android.mk
similarity index 86%
rename from packages/DynamicAndroidInstallationService/Android.mk
rename to packages/DynamicSystemInstallationService/Android.mk
index 13d96ac..16aca1b 100644
--- a/packages/DynamicAndroidInstallationService/Android.mk
+++ b/packages/DynamicSystemInstallationService/Android.mk
@@ -8,7 +8,7 @@
 
 LOCAL_USE_AAPT2 := true
 
-LOCAL_PACKAGE_NAME := DynamicAndroidInstallationService
+LOCAL_PACKAGE_NAME := DynamicSystemInstallationService
 LOCAL_CERTIFICATE := platform
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_PRIVATE_PLATFORM_APIS := true
diff --git a/packages/DynamicAndroidInstallationService/AndroidManifest.xml b/packages/DynamicSystemInstallationService/AndroidManifest.xml
similarity index 80%
rename from packages/DynamicAndroidInstallationService/AndroidManifest.xml
rename to packages/DynamicSystemInstallationService/AndroidManifest.xml
index 32acad4..2911117 100644
--- a/packages/DynamicAndroidInstallationService/AndroidManifest.xml
+++ b/packages/DynamicSystemInstallationService/AndroidManifest.xml
@@ -1,10 +1,10 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.dynandroid"
+        package="com.android.dynsystem"
         android:sharedUserId="android.uid.system">
 
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
     <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.MANAGE_DYNAMIC_ANDROID" />
+    <uses-permission android:name="android.permission.MANAGE_DYNAMIC_SYSTEM" />
     <uses-permission android:name="android.permission.REBOOT" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
 
@@ -13,24 +13,24 @@
         android:label="@string/app_name">
 
         <service
-            android:name=".DynamicAndroidInstallationService"
+            android:name=".DynamicSystemInstallationService"
             android:enabled="true"
             android:exported="true"
-            android:permission="android.permission.MANAGE_DYNAMIC_ANDROID"
-            android:process=":dynandroid">
+            android:permission="android.permission.MANAGE_DYNAMIC_SYSTEM"
+            android:process=":dynsystem">
             <intent-filter>
-                <action android:name="android.content.action.NOTIFY_IF_IN_USE" />
+                <action android:name="android.os.image.action.NOTIFY_IF_IN_USE" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </service>
 
         <activity android:name=".VerificationActivity"
             android:exported="true"
-            android:permission="android.permission.MANAGE_DYNAMIC_ANDROID"
+            android:permission="android.permission.MANAGE_DYNAMIC_SYSTEM"
             android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar"
-            android:process=":dynandroid">
+            android:process=":dynsystem">
             <intent-filter>
-                <action android:name="android.content.action.START_INSTALL" />
+                <action android:name="android.os.image.action.START_INSTALL" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
diff --git a/packages/DynamicAndroidInstallationService/MODULE_LICENSE_APACHE2 b/packages/DynamicSystemInstallationService/MODULE_LICENSE_APACHE2
similarity index 100%
rename from packages/DynamicAndroidInstallationService/MODULE_LICENSE_APACHE2
rename to packages/DynamicSystemInstallationService/MODULE_LICENSE_APACHE2
diff --git a/packages/DynamicAndroidInstallationService/NOTICE b/packages/DynamicSystemInstallationService/NOTICE
similarity index 100%
rename from packages/DynamicAndroidInstallationService/NOTICE
rename to packages/DynamicSystemInstallationService/NOTICE
diff --git a/packages/DynamicAndroidInstallationService/res/drawable/ic_system_update_googblue_24dp.xml b/packages/DynamicSystemInstallationService/res/drawable/ic_system_update_googblue_24dp.xml
similarity index 100%
rename from packages/DynamicAndroidInstallationService/res/drawable/ic_system_update_googblue_24dp.xml
rename to packages/DynamicSystemInstallationService/res/drawable/ic_system_update_googblue_24dp.xml
diff --git a/packages/DynamicAndroidInstallationService/res/values/strings.xml b/packages/DynamicSystemInstallationService/res/values/strings.xml
similarity index 64%
rename from packages/DynamicAndroidInstallationService/res/values/strings.xml
rename to packages/DynamicSystemInstallationService/res/values/strings.xml
index 03c7c28..a72e4e2 100644
--- a/packages/DynamicAndroidInstallationService/res/values/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values/strings.xml
@@ -12,14 +12,14 @@
     <!-- password page description [CHAR LIMIT=128] -->
     <string name="keyguard_description">Please enter your password and continue to AndroidOnTap installation</string>
 
-    <!-- Displayed on notification: DynAndroid installation is completed [CHAR LIMIT=128] -->
+    <!-- Displayed on notification: AndroidOnTap installation is completed [CHAR LIMIT=128] -->
     <string name="notification_install_completed">New system is ready, you can reboot into it or discard it.</string>
-    <!-- Displayed on notification: DynAndroid installation is in progress [CHAR LIMIT=128] -->
+    <!-- Displayed on notification: AndroidOnTap installation is in progress [CHAR LIMIT=128] -->
     <string name="notification_install_inprogress">Installation is in progress.</string>
-    <!-- Displayed on notification: DynAndroid installation is in progress [CHAR LIMIT=128] -->
+    <!-- Displayed on notification: AndroidOnTap installation is in progress [CHAR LIMIT=128] -->
     <string name="notification_install_failed">Installation Failed.</string>
     <!-- Displayed on notification: We are running in AndroidOnTap [CHAR LIMIT=128] -->
-    <string name="notification_dynandroid_in_use">We are running in AndroidOnTap.</string>
+    <string name="notification_dynsystem_in_use">We are running in AndroidOnTap.</string>
 
     <!-- Action on notification: Cancel installation [CHAR LIMIT=16] -->
     <string name="notification_action_cancel">Cancel</string>
@@ -28,11 +28,11 @@
     <!-- Action on notification: Uninstall AndroidOnTap [CHAR LIMIT=16] -->
     <string name="notification_action_uninstall">Uninstall</string>
     <!-- Action on notification: Reboot to AndroidOnTap [CHAR LIMIT=16] -->
-    <string name="notification_action_reboot_to_dynandroid">Reboot</string>
+    <string name="notification_action_reboot_to_dynsystem">Reboot</string>
 
-    <!-- Toast when installed DynamicAndroid is discarded [CHAR LIMIT=64] -->
-    <string name="toast_dynandroid_discarded">Installed AndroidOnTap is discarded.</string>
-    <!-- Toast when we fail to launch into DynamicAndroid [CHAR LIMIT=64] -->
-    <string name="toast_failed_to_reboot_to_dynandroid">Failed to reboot into AndroidOnTap.</string>
+    <!-- Toast when installed AndroidOnTap is discarded [CHAR LIMIT=64] -->
+    <string name="toast_dynsystem_discarded">Installed AndroidOnTap is discarded.</string>
+    <!-- Toast when we fail to launch into AndroidOnTap [CHAR LIMIT=64] -->
+    <string name="toast_failed_to_reboot_to_dynsystem">Failed to reboot into AndroidOnTap.</string>
 
 </resources>
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
similarity index 84%
rename from packages/DynamicAndroidInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
rename to packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
index dd1be89..38576ee 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
@@ -14,20 +14,20 @@
  * limitations under the License.
  */
 
-package com.android.dynandroid;
+package com.android.dynsystem;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.DynamicAndroidClient;
 import android.content.Intent;
 import android.os.UserHandle;
+import android.os.image.DynamicSystemClient;
 import android.util.Log;
 
 
 /**
  * A BoardcastReceiver waiting for ACTION_BOOT_COMPLETED and ask
  * the service to display a notification if we are currently running
- * in DynamicAndroid.
+ * in DynamicSystem.
  */
 public class BootCompletedReceiver extends BroadcastReceiver {
 
@@ -41,9 +41,9 @@
 
         if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
             Intent startServiceIntent = new Intent(
-                    context, DynamicAndroidInstallationService.class);
+                    context, DynamicSystemInstallationService.class);
 
-            startServiceIntent.setAction(DynamicAndroidClient.ACTION_NOTIFY_IF_IN_USE);
+            startServiceIntent.setAction(DynamicSystemClient.ACTION_NOTIFY_IF_IN_USE);
             context.startServiceAsUser(startServiceIntent, UserHandle.SYSTEM);
         }
     }
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
similarity index 78%
rename from packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
rename to packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
index d942bab..df2c571 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
@@ -14,28 +14,28 @@
  * limitations under the License.
  */
 
-package com.android.dynandroid;
+package com.android.dynsystem;
 
-import static android.content.DynamicAndroidClient.ACTION_NOTIFY_IF_IN_USE;
-import static android.content.DynamicAndroidClient.ACTION_START_INSTALL;
-import static android.content.DynamicAndroidClient.CAUSE_ERROR_EXCEPTION;
-import static android.content.DynamicAndroidClient.CAUSE_ERROR_INVALID_URL;
-import static android.content.DynamicAndroidClient.CAUSE_ERROR_IO;
-import static android.content.DynamicAndroidClient.CAUSE_INSTALL_CANCELLED;
-import static android.content.DynamicAndroidClient.CAUSE_INSTALL_COMPLETED;
-import static android.content.DynamicAndroidClient.CAUSE_NOT_SPECIFIED;
-import static android.content.DynamicAndroidClient.STATUS_IN_PROGRESS;
-import static android.content.DynamicAndroidClient.STATUS_IN_USE;
-import static android.content.DynamicAndroidClient.STATUS_NOT_STARTED;
-import static android.content.DynamicAndroidClient.STATUS_READY;
 import static android.os.AsyncTask.Status.FINISHED;
 import static android.os.AsyncTask.Status.PENDING;
 import static android.os.AsyncTask.Status.RUNNING;
+import static android.os.image.DynamicSystemClient.ACTION_NOTIFY_IF_IN_USE;
+import static android.os.image.DynamicSystemClient.ACTION_START_INSTALL;
+import static android.os.image.DynamicSystemClient.CAUSE_ERROR_EXCEPTION;
+import static android.os.image.DynamicSystemClient.CAUSE_ERROR_INVALID_URL;
+import static android.os.image.DynamicSystemClient.CAUSE_ERROR_IO;
+import static android.os.image.DynamicSystemClient.CAUSE_INSTALL_CANCELLED;
+import static android.os.image.DynamicSystemClient.CAUSE_INSTALL_COMPLETED;
+import static android.os.image.DynamicSystemClient.CAUSE_NOT_SPECIFIED;
+import static android.os.image.DynamicSystemClient.STATUS_IN_PROGRESS;
+import static android.os.image.DynamicSystemClient.STATUS_IN_USE;
+import static android.os.image.DynamicSystemClient.STATUS_NOT_STARTED;
+import static android.os.image.DynamicSystemClient.STATUS_READY;
 
-import static com.android.dynandroid.InstallationAsyncTask.RESULT_ERROR_EXCEPTION;
-import static com.android.dynandroid.InstallationAsyncTask.RESULT_ERROR_INVALID_URL;
-import static com.android.dynandroid.InstallationAsyncTask.RESULT_ERROR_IO;
-import static com.android.dynandroid.InstallationAsyncTask.RESULT_OK;
+import static com.android.dynsystem.InstallationAsyncTask.RESULT_ERROR_EXCEPTION;
+import static com.android.dynsystem.InstallationAsyncTask.RESULT_ERROR_INVALID_URL;
+import static com.android.dynsystem.InstallationAsyncTask.RESULT_ERROR_IO;
+import static com.android.dynsystem.InstallationAsyncTask.RESULT_OK;
 
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -43,16 +43,16 @@
 import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Context;
-import android.content.DynamicAndroidClient;
 import android.content.Intent;
 import android.os.Bundle;
-import android.os.DynamicAndroidManager;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.image.DynamicSystemClient;
+import android.os.image.DynamicSystemManager;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -60,31 +60,31 @@
 import java.util.ArrayList;
 
 /**
- * This class is the service in charge of DynamicAndroid installation.
+ * This class is the service in charge of DynamicSystem installation.
  * It also posts status to notification bar and wait for user's
  * cancel and confirm commnands.
  */
-public class DynamicAndroidInstallationService extends Service
+public class DynamicSystemInstallationService extends Service
         implements InstallationAsyncTask.InstallStatusListener {
 
-    private static final String TAG = "DynAndroidInstallationService";
+    private static final String TAG = "DynSystemInstallationService";
 
     /*
      * Intent actions
      */
     private static final String ACTION_CANCEL_INSTALL =
-            "com.android.dynandroid.ACTION_CANCEL_INSTALL";
+            "com.android.dynsystem.ACTION_CANCEL_INSTALL";
     private static final String ACTION_DISCARD_INSTALL =
-            "com.android.dynandroid.ACTION_DISCARD_INSTALL";
-    private static final String ACTION_REBOOT_TO_DYN_ANDROID =
-            "com.android.dynandroid.ACTION_REBOOT_TO_DYN_ANDROID";
+            "com.android.dynsystem.ACTION_DISCARD_INSTALL";
+    private static final String ACTION_REBOOT_TO_DYN_SYSTEM =
+            "com.android.dynsystem.ACTION_REBOOT_TO_DYN_SYSTEM";
     private static final String ACTION_REBOOT_TO_NORMAL =
-            "com.android.dynandroid.ACTION_REBOOT_TO_NORMAL";
+            "com.android.dynsystem.ACTION_REBOOT_TO_NORMAL";
 
     /*
      * For notification
      */
-    private static final String NOTIFICATION_CHANNEL_ID = "com.android.dynandroid";
+    private static final String NOTIFICATION_CHANNEL_ID = "com.android.dynsystem";
     private static final int NOTIFICATION_ID = 1;
 
     /*
@@ -97,15 +97,15 @@
     final Messenger mMessenger = new Messenger(new IncomingHandler(this));
 
     static class IncomingHandler extends Handler {
-        private final WeakReference<DynamicAndroidInstallationService> mWeakService;
+        private final WeakReference<DynamicSystemInstallationService> mWeakService;
 
-        IncomingHandler(DynamicAndroidInstallationService service) {
+        IncomingHandler(DynamicSystemInstallationService service) {
             mWeakService = new WeakReference<>(service);
         }
 
         @Override
         public void handleMessage(Message msg) {
-            DynamicAndroidInstallationService service = mWeakService.get();
+            DynamicSystemInstallationService service = mWeakService.get();
 
             if (service != null) {
                 service.handleMessage(msg);
@@ -113,7 +113,7 @@
         }
     }
 
-    private DynamicAndroidManager mDynAndroid;
+    private DynamicSystemManager mDynSystem;
     private NotificationManager mNM;
 
     private long mSystemSize;
@@ -130,7 +130,7 @@
 
         prepareNotification();
 
-        mDynAndroid = (DynamicAndroidManager) getSystemService(Context.DYNAMIC_ANDROID_SERVICE);
+        mDynSystem = (DynamicSystemManager) getSystemService(Context.DYNAMIC_SYSTEM_SERVICE);
     }
 
     @Override
@@ -156,8 +156,8 @@
             executeCancelCommand();
         } else if (ACTION_DISCARD_INSTALL.equals(action)) {
             executeDiscardCommand();
-        } else if (ACTION_REBOOT_TO_DYN_ANDROID.equals(action)) {
-            executeRebootToDynAndroidCommand();
+        } else if (ACTION_REBOOT_TO_DYN_SYSTEM.equals(action)) {
+            executeRebootToDynSystemCommand();
         } else if (ACTION_REBOOT_TO_NORMAL.equals(action)) {
             executeRebootToNormalCommand();
         } else if (ACTION_NOTIFY_IF_IN_USE.equals(action)) {
@@ -215,17 +215,17 @@
             return;
         }
 
-        if (isInDynamicAndroid()) {
-            Log.e(TAG, "We are already running in DynamicAndroid");
+        if (isInDynamicSystem()) {
+            Log.e(TAG, "We are already running in DynamicSystem");
             return;
         }
 
-        String url = intent.getStringExtra(DynamicAndroidClient.KEY_SYSTEM_URL);
-        mSystemSize = intent.getLongExtra(DynamicAndroidClient.KEY_SYSTEM_SIZE, 0);
-        mUserdataSize = intent.getLongExtra(DynamicAndroidClient.KEY_USERDATA_SIZE, 0);
+        String url = intent.getStringExtra(DynamicSystemClient.KEY_SYSTEM_URL);
+        mSystemSize = intent.getLongExtra(DynamicSystemClient.KEY_SYSTEM_SIZE, 0);
+        mUserdataSize = intent.getLongExtra(DynamicSystemClient.KEY_USERDATA_SIZE, 0);
 
         mInstallTask = new InstallationAsyncTask(
-                url, mSystemSize, mUserdataSize, mDynAndroid, this);
+                url, mSystemSize, mUserdataSize, mDynSystem, this);
 
         mInstallTask.execute();
 
@@ -251,7 +251,7 @@
     }
 
     private void executeDiscardCommand() {
-        if (isInDynamicAndroid()) {
+        if (isInDynamicSystem()) {
             Log.e(TAG, "We are now running in AOT, please reboot to normal system first");
             return;
         }
@@ -262,16 +262,16 @@
         }
 
         Toast.makeText(this,
-                getString(R.string.toast_dynandroid_discarded),
+                getString(R.string.toast_dynsystem_discarded),
                 Toast.LENGTH_LONG).show();
 
         resetTaskAndStop();
         postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED);
 
-        mDynAndroid.remove();
+        mDynSystem.remove();
     }
 
-    private void executeRebootToDynAndroidCommand() {
+    private void executeRebootToDynSystemCommand() {
         if (mInstallTask == null || mInstallTask.getStatus() != FINISHED) {
             Log.e(TAG, "Trying to reboot to AOT while there is no complete installation");
             return;
@@ -282,10 +282,10 @@
             mNM.cancel(NOTIFICATION_ID);
 
             Toast.makeText(this,
-                    getString(R.string.toast_failed_to_reboot_to_dynandroid),
+                    getString(R.string.toast_failed_to_reboot_to_dynsystem),
                     Toast.LENGTH_LONG).show();
 
-            mDynAndroid.remove();
+            mDynSystem.remove();
 
             return;
         }
@@ -293,12 +293,12 @@
         PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
 
         if (powerManager != null) {
-            powerManager.reboot("dynandroid");
+            powerManager.reboot("dynsystem");
         }
     }
 
     private void executeRebootToNormalCommand() {
-        if (!isInDynamicAndroid()) {
+        if (!isInDynamicSystem()) {
             Log.e(TAG, "It's already running in normal system.");
             return;
         }
@@ -346,7 +346,7 @@
     }
 
     private PendingIntent createPendingIntent(String action) {
-        Intent intent = new Intent(this, DynamicAndroidInstallationService.class);
+        Intent intent = new Intent(this, DynamicSystemInstallationService.class);
         intent.setAction(action);
         return PendingIntent.getService(this, 0, intent, 0);
     }
@@ -375,8 +375,8 @@
                 builder.setContentText(getString(R.string.notification_install_completed));
 
                 builder.addAction(new Notification.Action.Builder(
-                        null, getString(R.string.notification_action_reboot_to_dynandroid),
-                        createPendingIntent(ACTION_REBOOT_TO_DYN_ANDROID)).build());
+                        null, getString(R.string.notification_action_reboot_to_dynsystem),
+                        createPendingIntent(ACTION_REBOOT_TO_DYN_SYSTEM)).build());
 
                 builder.addAction(new Notification.Action.Builder(
                         null, getString(R.string.notification_action_discard),
@@ -385,7 +385,7 @@
                 break;
 
             case STATUS_IN_USE:
-                builder.setContentText(getString(R.string.notification_dynandroid_in_use));
+                builder.setContentText(getString(R.string.notification_dynsystem_in_use));
 
                 builder.addAction(new Notification.Action.Builder(
                         null, getString(R.string.notification_action_uninstall),
@@ -409,7 +409,7 @@
     }
 
     private boolean verifyRequest(Intent intent) {
-        String url = intent.getStringExtra(DynamicAndroidClient.KEY_SYSTEM_URL);
+        String url = intent.getStringExtra(DynamicSystemClient.KEY_SYSTEM_URL);
 
         return VerificationActivity.isVerified(url);
     }
@@ -443,16 +443,16 @@
     private void notifyOneClient(Messenger client, int status, int cause) throws RemoteException {
         Bundle bundle = new Bundle();
 
-        bundle.putLong(DynamicAndroidClient.KEY_INSTALLED_SIZE, mInstalledSize);
+        bundle.putLong(DynamicSystemClient.KEY_INSTALLED_SIZE, mInstalledSize);
 
         client.send(Message.obtain(null,
-                  DynamicAndroidClient.MSG_POST_STATUS, status, cause, bundle));
+                  DynamicSystemClient.MSG_POST_STATUS, status, cause, bundle));
     }
 
     private int getStatus() {
-        if (isInDynamicAndroid()) {
+        if (isInDynamicSystem()) {
             return STATUS_IN_USE;
-        } else if (isDynamicAndroidInstalled()) {
+        } else if (isDynamicSystemInstalled()) {
             return STATUS_READY;
         } else if (mInstallTask == null) {
             return STATUS_NOT_STARTED;
@@ -479,17 +479,17 @@
         }
     }
 
-    private boolean isInDynamicAndroid() {
-        return mDynAndroid.isInUse();
+    private boolean isInDynamicSystem() {
+        return mDynSystem.isInUse();
     }
 
-    private boolean isDynamicAndroidInstalled() {
-        return mDynAndroid.isInstalled();
+    private boolean isDynamicSystemInstalled() {
+        return mDynSystem.isInstalled();
     }
 
     void handleMessage(Message msg) {
         switch (msg.what) {
-            case DynamicAndroidClient.MSG_REGISTER_LISTENER:
+            case DynamicSystemClient.MSG_REGISTER_LISTENER:
                 try {
                     Messenger client = msg.replyTo;
 
@@ -505,7 +505,7 @@
                 }
 
                 break;
-            case DynamicAndroidClient.MSG_UNREGISTER_LISTENER:
+            case DynamicSystemClient.MSG_UNREGISTER_LISTENER:
                 mClients.remove(msg.replyTo);
                 break;
             default:
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
similarity index 90%
rename from packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
rename to packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
index 03fc773..052fc0a 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.dynandroid;
+package com.android.dynsystem;
 
 import android.gsi.GsiProgress;
 import android.os.AsyncTask;
-import android.os.DynamicAndroidManager;
+import android.os.image.DynamicSystemManager;
 import android.util.Log;
 import android.webkit.URLUtil;
 
@@ -60,9 +60,9 @@
     private final String mUrl;
     private final long mSystemSize;
     private final long mUserdataSize;
-    private final DynamicAndroidManager mDynamicAndroid;
+    private final DynamicSystemManager mDynSystem;
     private final InstallStatusListener mListener;
-    private DynamicAndroidManager.Session mInstallationSession;
+    private DynamicSystemManager.Session mInstallationSession;
 
     private int mResult = NO_RESULT;
 
@@ -70,11 +70,11 @@
 
 
     InstallationAsyncTask(String url, long systemSize, long userdataSize,
-            DynamicAndroidManager dynAndroid, InstallStatusListener listener) {
+            DynamicSystemManager dynSystem, InstallStatusListener listener) {
         mUrl = url;
         mSystemSize = systemSize;
         mUserdataSize = userdataSize;
-        mDynamicAndroid = dynAndroid;
+        mDynSystem = dynSystem;
         mListener = listener;
     }
 
@@ -98,7 +98,7 @@
 
             Thread thread = new Thread(() -> {
                 mInstallationSession =
-                        mDynamicAndroid.startInstallation(mSystemSize, mUserdataSize);
+                        mDynSystem.startInstallation(mSystemSize, mUserdataSize);
             });
 
 
@@ -106,12 +106,12 @@
 
             while (thread.isAlive()) {
                 if (isCancelled()) {
-                    boolean aborted = mDynamicAndroid.abort();
-                    Log.d(TAG, "Called DynamicAndroidManager.abort(), result = " + aborted);
+                    boolean aborted = mDynSystem.abort();
+                    Log.d(TAG, "Called DynamicSystemManager.abort(), result = " + aborted);
                     return RESULT_OK;
                 }
 
-                GsiProgress progress = mDynamicAndroid.getInstallationProgress();
+                GsiProgress progress = mDynSystem.getInstallationProgress();
                 installedSize = progress.bytes_processed;
 
                 if (installedSize > reportedInstalledSize + minStepToReport) {
@@ -146,7 +146,7 @@
                         ? bytes : Arrays.copyOf(bytes, numBytesRead);
 
                 if (!mInstallationSession.write(writeBuffer)) {
-                    throw new IOException("Failed write() to DynamicAndroid");
+                    throw new IOException("Failed write() to DynamicSystem");
                 }
 
                 installedSize += numBytesRead;
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/VerificationActivity.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java
similarity index 87%
rename from packages/DynamicAndroidInstallationService/src/com/android/dynandroid/VerificationActivity.java
rename to packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java
index c18c4fe..f05930f 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/VerificationActivity.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java
@@ -14,19 +14,19 @@
  * limitations under the License.
  */
 
-package com.android.dynandroid;
+package com.android.dynsystem;
 
-import static android.content.DynamicAndroidClient.KEY_SYSTEM_SIZE;
-import static android.content.DynamicAndroidClient.KEY_SYSTEM_URL;
-import static android.content.DynamicAndroidClient.KEY_USERDATA_SIZE;
+import static android.os.image.DynamicSystemClient.KEY_SYSTEM_SIZE;
+import static android.os.image.DynamicSystemClient.KEY_SYSTEM_URL;
+import static android.os.image.DynamicSystemClient.KEY_USERDATA_SIZE;
 
 import android.app.Activity;
 import android.app.KeyguardManager;
 import android.content.Context;
-import android.content.DynamicAndroidClient;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.UserHandle;
+import android.os.image.DynamicSystemClient;
 import android.util.Log;
 
 
@@ -88,8 +88,8 @@
         sVerifiedUrl = url;
 
         // start service
-        Intent intent = new Intent(this, DynamicAndroidInstallationService.class);
-        intent.setAction(DynamicAndroidClient.ACTION_START_INSTALL);
+        Intent intent = new Intent(this, DynamicSystemInstallationService.class);
+        intent.setAction(DynamicSystemClient.ACTION_START_INSTALL);
         intent.putExtra(KEY_SYSTEM_URL, url);
         intent.putExtra(KEY_SYSTEM_SIZE, systemSize);
         intent.putExtra(KEY_USERDATA_SIZE, userdataSize);
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index b34f445..b025df4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -185,14 +185,14 @@
      */
     public static void revertScheduleToNoneIfNeeded(Context context) {
         ContentResolver resolver = context.getContentResolver();
-        final int currentMode = Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
-                PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+        final int currentMode = Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+                PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
         boolean providerConfigured = !TextUtils.isEmpty(context.getString(
                 com.android.internal.R.string.config_batterySaverScheduleProvider));
-        if (currentMode == PowerManager.POWER_SAVER_MODE_DYNAMIC && !providerConfigured) {
+        if (currentMode == PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC && !providerConfigured) {
             Global.putInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
-            Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
-                    PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+            Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+                    PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
         }
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index a33f9a8..de7202c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -844,7 +844,7 @@
                 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL_MAX,
                 GlobalSettingsProto.LowPowerMode.TRIGGER_LEVEL_MAX);
         dumpSetting(s, p,
-                Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
+                Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
                 GlobalSettingsProto.LowPowerMode.AUTOMATIC_POWER_SAVER_MODE);
         dumpSetting(s, p,
                 Settings.Global.LOW_POWER_MODE_STICKY,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 9e46ad6..7337cdb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -19,6 +19,12 @@
 import static android.os.Process.ROOT_UID;
 import static android.os.Process.SHELL_UID;
 import static android.os.Process.SYSTEM_UID;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -33,6 +39,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
@@ -3235,7 +3243,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 176;
+            private static final int SETTINGS_VERSION = 177;
 
             private final int mUserId;
 
@@ -4311,6 +4319,57 @@
                     currentVersion = 176;
                 }
 
+                if (currentVersion == 176) {
+                    // Version 176: Migrate the existing swipe up setting into the resource overlay
+                    //              for the navigation bar interaction mode.
+
+                    final IOverlayManager overlayManager = IOverlayManager.Stub.asInterface(
+                            ServiceManager.getService(Context.OVERLAY_SERVICE));
+                    int navBarMode = -1;
+
+                    // Migrate the swipe up setting only if it is set
+                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
+                    final Setting swipeUpSetting = secureSettings.getSettingLocked(
+                            Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED);
+                    if (swipeUpSetting != null && !swipeUpSetting.isNull()) {
+                        navBarMode = swipeUpSetting.getValue().equals("1")
+                                ? NAV_BAR_MODE_2BUTTON
+                                : NAV_BAR_MODE_3BUTTON;
+                    }
+
+                    // Temporary: Only for migration for dogfooders, to be removed
+                    try {
+                        final OverlayInfo info = overlayManager.getOverlayInfo(
+                                "com.android.internal.experiment.navbar.type.inset",
+                                UserHandle.USER_CURRENT);
+                        if (info != null && info.isEnabled()) {
+                            navBarMode = NAV_BAR_MODE_GESTURAL;
+                        }
+                    } catch (RemoteException e) {
+                        // Ingore, fall through
+                    }
+
+                    if (navBarMode != -1) {
+                        try {
+                            overlayManager.setEnabled(NAV_BAR_MODE_3BUTTON_OVERLAY,
+                                    navBarMode == NAV_BAR_MODE_3BUTTON,
+                                    UserHandle.USER_CURRENT);
+                            overlayManager.setEnabled(NAV_BAR_MODE_2BUTTON_OVERLAY,
+                                    navBarMode == NAV_BAR_MODE_2BUTTON,
+                                    UserHandle.USER_CURRENT);
+                            overlayManager.setEnabled(NAV_BAR_MODE_GESTURAL_OVERLAY,
+                                    navBarMode == NAV_BAR_MODE_GESTURAL,
+                                    UserHandle.USER_CURRENT);
+                        } catch (RemoteException e) {
+                            throw new IllegalStateException(
+                                    "Failed to set nav bar interaction mode overlay");
+                        }
+                    }
+
+                    currentVersion = 177;
+                }
+
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 441f88c..d6e61eb 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -182,6 +182,10 @@
     <!-- Permission needed to run keyguard manager tests in CTS -->
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" />
 
+    <!-- Permission needed to test wallpaper component -->
+    <uses-permission android:name="android.permission.SET_WALLPAPER" />
+    <uses-permission android:name="android.permission.SET_WALLPAPER_COMPONENT" />
+
     <application android:label="@string/app_label"
                  android:defaultToDeviceProtectedStorage="true"
                  android:directBootAware="true">
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
index 3d2f570..0a0530c0 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
@@ -60,6 +60,7 @@
 
     boolean areCaptionsEnabled();
     void setCaptionsEnabled(boolean isEnabled);
+    boolean isCaptionStreamOptedOut();
 
     void getCaptionsComponentState(boolean fromTooltip);
 
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 5714556..2f2f84a 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -444,15 +444,15 @@
     <!-- Minutes displayed in words on the typographic clock face. [CHAR LIMIT=20] -->
     <string-array name="type_clock_minutes">
         <item>O\u2019Clock</item>
-        <item>O\u2019One</item>
-        <item>O\u2019Two</item>
-        <item>O\u2019Three</item>
-        <item>O\u2019Four</item>
-        <item>O\u2019Five</item>
-        <item>O\u2019Six</item>
-        <item>O\u2019Seven</item>
-        <item>O\u2019Eight</item>
-        <item>O\u2019Nine</item>
+        <item>Oh One</item>
+        <item>Oh Two</item>
+        <item>Oh Three</item>
+        <item>Oh Four</item>
+        <item>Oh Five</item>
+        <item>Oh Six</item>
+        <item>Oh Seven</item>
+        <item>Oh Eight</item>
+        <item>Oh Nine</item>
         <item>Ten</item>
         <item>Eleven</item>
         <item>Twelve</item>
diff --git a/packages/SystemUI/res/color/caption_tint_color_selector.xml b/packages/SystemUI/res/color/caption_tint_color_selector.xml
new file mode 100644
index 0000000..30843ec
--- /dev/null
+++ b/packages/SystemUI/res/color/caption_tint_color_selector.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2019 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"
+          xmlns:sysui="http://schemas.android.com/apk/res-auto">
+    <item sysui:optedOut="true"
+          android:color="?android:attr/colorButtonNormal"/>
+
+    <item android:color="?android:attr/colorAccent"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index 6c8110b..a02962e 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -92,7 +92,6 @@
                     android:layout_width="@dimen/multi_user_avatar_expanded_size"
                     android:layout_height="@dimen/multi_user_avatar_expanded_size"
                     android:layout_gravity="center"
-                    android:tint="?android:attr/colorAccent"
                     android:scaleType="centerInside"/>
             </com.android.systemui.statusbar.phone.MultiUserSwitch>
 
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 1d0a242..d1c80c4 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -15,6 +15,7 @@
 -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:sysui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/volume_dialog_container"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
@@ -117,16 +118,17 @@
             android:clipToPadding="false"
             android:translationZ="@dimen/volume_dialog_elevation"
             android:background="@drawable/rounded_bg_full">
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.systemui.volume.CaptionsToggleImageButton
                 android:id="@+id/odi_captions_icon"
                 android:src="@drawable/ic_volume_odi_captions_disabled"
                 style="@style/VolumeButtons"
                 android:background="@drawable/rounded_ripple"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:tint="@color/accent_tint_color_selector"
+                android:tint="@color/caption_tint_color_selector"
                 android:layout_gravity="center"
-                android:soundEffectsEnabled="false" />
+                android:soundEffectsEnabled="false"
+                sysui:optedOut="false"/>
         </FrameLayout>
 
     </LinearLayout>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 27d2bcd..e0bcf24 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -146,5 +146,9 @@
         <attr name="showAirplaneMode" format="boolean" />
     </declare-styleable>
 
+    <declare-styleable name="CaptionsToggleImageButton">
+        <attr name="optedOut" format="boolean" />
+    </declare-styleable>
+
 </resources>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 265c620..62309fd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -549,11 +549,11 @@
     <!-- Content description of the do not disturb tile in quick settings when on in alarms only (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_dnd_alarms_on">alarms only</string>
      <!-- Content description of the do not disturb tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
-    <string name="accessibility_quick_settings_dnd">Do not disturb.</string>
+    <string name="accessibility_quick_settings_dnd">Do Not Disturb.</string>
     <!-- Announcement made when do not disturb changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
-    <string name="accessibility_quick_settings_dnd_changed_off">Do not disturb turned off.</string>
+    <string name="accessibility_quick_settings_dnd_changed_off">Do Not Disturb turned off.</string>
     <!-- Announcement made when do not disturb changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
-    <string name="accessibility_quick_settings_dnd_changed_on">Do not disturb turned on.</string>
+    <string name="accessibility_quick_settings_dnd_changed_on">Do Not Disturb turned on.</string>
     <!-- Content description of the bluetooth tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_bluetooth">Bluetooth.</string>
     <!-- Content description of the bluetooth tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -699,7 +699,7 @@
     <!-- QuickSettings: Onboarding text that introduces users to long press on an option in order to view the option's menu in Settings [CHAR LIMIT=NONE] -->
     <string name="quick_settings_header_onboarding_text">Touch &amp; hold icons for more options</string>
     <!-- QuickSettings: Do not disturb [CHAR LIMIT=NONE] -->
-    <string name="quick_settings_dnd_label">Do not disturb</string>
+    <string name="quick_settings_dnd_label">Do Not Disturb</string>
     <!-- QuickSettings: Do not disturb - Priority only [CHAR LIMIT=NONE] -->
     <string name="quick_settings_dnd_priority_label">Priority only</string>
     <!-- QuickSettings: Do not disturb - Alarms only [CHAR LIMIT=NONE] -->
@@ -1814,14 +1814,14 @@
     <string name="tuner_full_zen_title">Show with volume controls</string>
 
     <!-- SysUI Tuner: Label for screen about do not disturb settings [CHAR LIMIT=60] -->
-    <string name="volume_and_do_not_disturb">Do not disturb</string>
+    <string name="volume_and_do_not_disturb">Do Not Disturb</string>
 
     <!-- SysUI Tuner: Switch to control whether volume buttons enter/exit do
          not disturb [CHAR LIMIT=60] -->
     <string name="volume_dnd_silent">Volume buttons shortcut</string>
 
     <!-- SysUI Tuner: Switch to control volume up behavior [CHAR LIMIT=60] -->
-    <string name="volume_up_silent">Exit do not disturb on volume up</string>
+    <string name="volume_up_silent">Exit Do Not Disturb on volume up</string>
 
     <!-- Name of the battery icon in status bar [CHAR LIMIT=30] -->
     <string name="battery">Battery</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index ce65b5a..fd92e9e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -1,5 +1,7 @@
 package com.android.keyguard;
 
+import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
@@ -24,8 +26,8 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
 import com.android.keyguard.clock.ClockManager;
-import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.ClockPlugin;
@@ -37,37 +39,65 @@
 import java.util.Arrays;
 import java.util.TimeZone;
 
+import javax.inject.Inject;
+import javax.inject.Named;
+
 /**
  * Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
  */
 public class KeyguardClockSwitch extends RelativeLayout {
 
+    /**
+     * Controller used to track StatusBar state to know when to show the big_clock_container.
+     */
+    private final StatusBarStateController mStatusBarStateController;
+
+    /**
+     * Color extractor used to apply colors from wallpaper to custom clock faces.
+     */
+    private final SysuiColorExtractor mSysuiColorExtractor;
+
+    /**
+     * Manager used to know when to show a custom clock face.
+     */
+    private final ClockManager mClockManager;
+
+    /**
+     * Layout transition that scales the default clock face.
+     */
     private final Transition mTransition;
+
     /**
      * Optional/alternative clock injected via plugin.
      */
     private ClockPlugin mClockPlugin;
+
     /**
      * Default clock.
      */
     private TextClock mClockView;
+
     /**
      * Frame for default and custom clock.
      */
     private FrameLayout mSmallClockFrame;
+
     /**
      * Container for big custom clock.
      */
     private ViewGroup mBigClockContainer;
+
     /**
      * Status area (date and other stuff) shown below the clock. Plugin can decide whether or not to
      * show it below the alternate clock.
      */
     private View mKeyguardStatusArea;
+
     /**
      * Maintain state so that a newly connected plugin can be initialized.
      */
     private float mDarkAmount;
+
     /**
      * If the Keyguard Slice has a header (big center-aligned text.)
      */
@@ -96,22 +126,20 @@
      *
      * The color palette changes when the wallpaper is changed.
      */
-    private SysuiColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> {
+    private final OnColorsChangedListener mColorsListener = (extractor, which) -> {
         if ((which & WallpaperManager.FLAG_LOCK) != 0) {
-            if (extractor instanceof SysuiColorExtractor) {
-                updateColors((SysuiColorExtractor) extractor);
-            } else {
-                updateColors(Dependency.get(SysuiColorExtractor.class));
-            }
+            updateColors();
         }
     };
 
-    public KeyguardClockSwitch(Context context) {
-        this(context, null);
-    }
-
-    public KeyguardClockSwitch(Context context, AttributeSet attrs) {
+    @Inject
+    public KeyguardClockSwitch(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
+            StatusBarStateController statusBarStateController, SysuiColorExtractor colorExtractor,
+            ClockManager clockManager) {
         super(context, attrs);
+        mStatusBarStateController = statusBarStateController;
+        mSysuiColorExtractor = colorExtractor;
+        mClockManager = clockManager;
         mTransition = new ClockBoundsTransition();
     }
 
@@ -133,22 +161,18 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        Dependency.get(ClockManager.class).addOnClockChangedListener(mClockChangedListener);
-        StatusBarStateController stateController = Dependency.get(StatusBarStateController.class);
-        stateController.addCallback(mStateListener);
-        mStateListener.onStateChanged(stateController.getState());
-        SysuiColorExtractor colorExtractor = Dependency.get(SysuiColorExtractor.class);
-        colorExtractor.addOnColorsChangedListener(mColorsListener);
-        updateColors(colorExtractor);
+        mClockManager.addOnClockChangedListener(mClockChangedListener);
+        mStatusBarStateController.addCallback(mStateListener);
+        mSysuiColorExtractor.addOnColorsChangedListener(mColorsListener);
+        updateColors();
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
-        Dependency.get(ClockManager.class).removeOnClockChangedListener(mClockChangedListener);
-        Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
-        Dependency.get(SysuiColorExtractor.class)
-                .removeOnColorsChangedListener(mColorsListener);
+        mClockManager.removeOnClockChangedListener(mClockChangedListener);
+        mStatusBarStateController.removeCallback(mStateListener);
+        mSysuiColorExtractor.removeOnColorsChangedListener(mColorsListener);
         setClockPlugin(null);
     }
 
@@ -271,14 +295,11 @@
         return mClockView.getTextSize();
     }
 
+    /**
+     * Refresh the time of the clock, due to either time tick broadcast or doze time tick alarm.
+     */
     public void refresh() {
         mClockView.refresh();
-    }
-
-    /**
-     * Notifies that time tick alarm from doze service fired.
-     */
-    public void dozeTimeTick() {
         if (mClockPlugin != null) {
             mClockPlugin.onTimeTick();
         }
@@ -293,9 +314,9 @@
         }
     }
 
-    private void updateColors(SysuiColorExtractor colorExtractor) {
-        ColorExtractor.GradientColors colors = colorExtractor.getColors(WallpaperManager.FLAG_LOCK,
-                true);
+    private void updateColors() {
+        ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors(
+                WallpaperManager.FLAG_LOCK, true);
         mSupportsDarkText = colors.supportsDarkText();
         mColorPalette = colors.getColorPalette();
         if (mClockPlugin != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 9dd9717..ae8bc52 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -28,9 +28,12 @@
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.systemui.util.InjectionInflationController;
+
 // TODO(multi-display): Support multiple external displays
 public class KeyguardDisplayManager {
     protected static final String TAG = "KeyguardDisplayManager";
@@ -38,6 +41,7 @@
 
     private final MediaRouter mMediaRouter;
     private final DisplayManager mDisplayService;
+    private final InjectionInflationController mInjectableInflater;
     private final Context mContext;
 
     private boolean mShowing;
@@ -75,8 +79,10 @@
         }
     };
 
-    public KeyguardDisplayManager(Context context) {
+    public KeyguardDisplayManager(Context context,
+            InjectionInflationController injectableInflater) {
         mContext = context;
+        mInjectableInflater = injectableInflater;
         mMediaRouter = mContext.getSystemService(MediaRouter.class);
         mDisplayService = mContext.getSystemService(DisplayManager.class);
         mDisplayService.registerDisplayListener(mDisplayListener, null /* handler */);
@@ -110,7 +116,7 @@
         final int displayId = display.getDisplayId();
         Presentation presentation = mPresentations.get(displayId);
         if (presentation == null) {
-            presentation = new KeyguardPresentation(mContext, display);
+            presentation = new KeyguardPresentation(mContext, display, mInjectableInflater);
             presentation.setOnDismissListener(dialog -> {
                 if (null != mPresentations.get(displayId)) {
                     mPresentations.remove(displayId);
@@ -201,6 +207,7 @@
     private final static class KeyguardPresentation extends Presentation {
         private static final int VIDEO_SAFE_REGION = 80; // Percentage of display width & height
         private static final int MOVE_CLOCK_TIMEOUT = 10000; // 10s
+        private final InjectionInflationController mInjectableInflater;
         private View mClock;
         private int mUsableWidth;
         private int mUsableHeight;
@@ -217,8 +224,10 @@
             }
         };
 
-        KeyguardPresentation(Context context, Display display) {
+        KeyguardPresentation(Context context, Display display,
+                InjectionInflationController injectionInflater) {
             super(context, display, R.style.keyguard_presentation_theme);
+            mInjectableInflater = injectionInflater;
             getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
             setCancelable(false);
         }
@@ -239,7 +248,9 @@
             mMarginLeft = (100 - VIDEO_SAFE_REGION) * p.x / 200;
             mMarginTop = (100 - VIDEO_SAFE_REGION) * p.y / 200;
 
-            setContentView(R.layout.keyguard_presentation);
+            LayoutInflater inflater = mInjectableInflater.injectable(
+                    LayoutInflater.from(getContext()));
+            setContentView(inflater.inflate(R.layout.keyguard_presentation, null));
             mClock = findViewById(R.id.clock);
 
             // Avoid screen burn in
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 808e264..0369e4c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -214,7 +214,6 @@
     public void dozeTimeTick() {
         refreshTime();
         mKeyguardSlice.refresh();
-        mClockView.dozeTimeTick();
     }
 
     private void refreshTime() {
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index 870ac87..32c1242 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -141,6 +141,8 @@
     @Override
     public void onTimeTick() {
         mAnalogClock.onTimeChanged();
+        mDigitalClock.refresh();
+        mLockClock.refresh();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
index 7401819..34b2fd8 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
@@ -136,6 +136,8 @@
     @Override
     public void onTimeTick() {
         mAnalogClock.onTimeChanged();
+        mDigitalClock.refresh();
+        mLockClock.refresh();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 14e910f..8e3afd8 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -43,6 +43,7 @@
 import android.graphics.drawable.ShapeDrawable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
 import android.util.AttributeSet;
@@ -457,30 +458,38 @@
     void updateHeight() {
         if (usingActivityView()) {
             Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
-            int desiredHeight;
+            float desiredHeight;
             if (data == null) {
                 // This is a contentIntent based bubble, lets allow it to be the max height
                 // as it was forced into this mode and not prepared to be small
                 desiredHeight = mStackView.getMaxExpandedHeight();
             } else {
-                desiredHeight = data.getDesiredHeight() > 0
-                        ? data.getDesiredHeight()
-                        : mMinHeight;
+                boolean useRes = data.getDesiredHeightResId() != 0;
+                float desiredPx;
+                if (useRes) {
+                    desiredPx = getDimenForPackageUser(data.getDesiredHeightResId(),
+                            mEntry.notification.getPackageName(),
+                            mEntry.notification.getUser().getIdentifier());
+                } else {
+                    desiredPx = data.getDesiredHeight()
+                            * getContext().getResources().getDisplayMetrics().density;
+                }
+                desiredHeight = desiredPx > 0 ? desiredPx : mMinHeight;
             }
             int chromeHeight = mPermissionView.getVisibility() != View.VISIBLE
                     ? mHeaderHeight
                     : mPermissionHeight;
             int max = mStackView.getMaxExpandedHeight() - chromeHeight - mPointerView.getHeight()
                     - mPointerMargin;
-            int height = Math.min(desiredHeight, max);
+            float height = Math.min(desiredHeight, max);
             height = Math.max(height, mMinHeight);
             LayoutParams lp = (LayoutParams) mActivityView.getLayoutParams();
             mNeedsNewHeight =  lp.height != height;
             if (!mKeyboardVisible) {
                 // If the keyboard is visible... don't adjust the height because that will cause
                 // a configuration change and the keyboard will be lost.
-                lp.height = height;
-                mBubbleHeight = height;
+                lp.height = (int) height;
+                mBubbleHeight = (int) height;
                 mActivityView.setLayoutParams(lp);
                 mNeedsNewHeight = false;
             }
@@ -712,4 +721,23 @@
                 mStackView.getNormalizedXPosition(),
                 mStackView.getNormalizedYPosition());
     }
+
+    private int getDimenForPackageUser(int resId, String pkg, int userId) {
+        Resources r;
+        if (pkg != null) {
+            try {
+                if (userId == UserHandle.USER_ALL) {
+                    userId = UserHandle.USER_SYSTEM;
+                }
+                r = mPm.getResourcesForApplicationAsUser(pkg, userId);
+                return r.getDimensionPixelSize(resId);
+            } catch (PackageManager.NameNotFoundException ex) {
+                // Uninstalled, don't care
+            } catch (Resources.NotFoundException e) {
+                // Invalid res id, return 0 and user our default
+                Log.e(TAG, "Couldn't find desired height res id", e);
+            }
+        }
+        return 0;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 6c4be06..c243899 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -211,7 +211,7 @@
         mDozeService.requestWakeUp();
     }
 
-    private boolean isExecutingTransition() {
+    public boolean isExecutingTransition() {
         return !mQueuedRequests.isEmpty();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 031f562..7189a48 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -198,6 +198,14 @@
     }
 
     private void onProximityFar(boolean far) {
+        // Proximity checks are asynchronous and the user might have interacted with the phone
+        // when a new event is arriving. This means that a state transition might have happened
+        // and the proximity check is now obsolete.
+        if (mMachine.isExecutingTransition()) {
+            Log.w(TAG, "onProximityFar called during transition. Ignoring sensor response.");
+            return;
+        }
+
         final boolean near = !far;
         final DozeMachine.State state = mMachine.getState();
         final boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
index 477e7d7e..d1939d0 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
@@ -85,7 +85,9 @@
             Bitmap bitmap = bitmaps[0];
             if (bitmap != null) {
                 int[] histogram = processHistogram(bitmap);
-                return computePercentile85(bitmap, histogram);
+                Float val = computePercentile85(bitmap, histogram);
+                bitmaps[0] = null;
+                return val;
             }
             Log.e(TAG, "Per85ComputeTask: Can't get bitmap");
             return DEFAULT_PER85;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 676e594..d70d0d8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -90,6 +90,7 @@
 import com.android.systemui.statusbar.phone.NotificationPanelView;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.util.InjectionInflationController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -710,7 +711,10 @@
         mContext.registerReceiver(mDelayedLockBroadcastReceiver, delayedActionFilter,
                 SYSTEMUI_PERMISSION, null /* scheduler */);
 
-        mKeyguardDisplayManager = new KeyguardDisplayManager(mContext);
+        InjectionInflationController injectionInflationController =
+                new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent());
+        mKeyguardDisplayManager = new KeyguardDisplayManager(mContext,
+                injectionInflationController);
 
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
 
diff --git a/packages/SystemUI/src/com/android/systemui/media/OWNERS b/packages/SystemUI/src/com/android/systemui/media/OWNERS
new file mode 100644
index 0000000..69ea57b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/OWNERS
@@ -0,0 +1 @@
+per-file MediaProjectionPermissionActivity.java = michaelwr@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index be63bad..aeaceb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -79,7 +79,7 @@
             }
         });
         NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
-        onStatusBarIconsBehaviorChanged(noMan.shouldHideSilentStatusBarIcons());
+        onSilentStatusBarIconsVisibilityChanged(noMan.shouldHideSilentStatusBarIcons());
     }
 
     @Override
@@ -144,7 +144,7 @@
     }
 
     @Override
-    public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
+    public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) {
         for (NotificationSettingsListener listener : mSettingsListeners) {
             listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons);
         }
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 813faa9..520df97 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
@@ -36,6 +36,7 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Outline;
 import android.graphics.Paint;
 import android.graphics.PointF;
 import android.graphics.PorterDuff;
@@ -58,6 +59,7 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
 import android.view.ViewTreeObserver;
 import android.view.WindowInsets;
 import android.view.accessibility.AccessibilityEvent;
@@ -394,6 +396,16 @@
             }
         }
     };
+    private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() {
+        @Override
+        public void getOutline(View view, Outline outline) {
+            if (mAmbientState.isDarkAtAll() && !mAmbientState.isFullyDark()) {
+                outline.setRoundRect(mBackgroundAnimationRect, mCornerRadius);
+            } else {
+                ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
+            }
+        }
+    };
     private PorterDuffXfermode mSrcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
     private boolean mPulsing;
     private boolean mGroupExpandedForMeasure;
@@ -520,6 +532,7 @@
         mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated);
         mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);
         addOnExpandedHeightListener(mRoundnessManager::setExpanded);
+        setOutlineProvider(mOutlineProvider);
 
         // Blocking helper manager wants to know the expanded state, update as well.
         NotificationBlockingHelperManager blockingHelperManager =
@@ -1298,6 +1311,7 @@
     public void updateClipping() {
         boolean clipped = mRequestedClipBounds != null && !mInHeadsUpPinnedMode
                 && !mHeadsUpAnimatingAway;
+        boolean clipToOutline = false;
         if (mIsClipped != clipped) {
             mIsClipped = clipped;
         }
@@ -1306,12 +1320,15 @@
                 && mAmbientState.isFullyDark() && mShowDarkShelf) {
             setClipBounds(null);
         } else if (mAmbientState.isDarkAtAll()) {
-            setClipBounds(mBackgroundAnimationRect);
+            clipToOutline = true;
+            invalidateOutline();
         } else if (clipped) {
             setClipBounds(mRequestedClipBounds);
         } else {
             setClipBounds(null);
         }
+
+        setClipToOutline(clipToOutline);
     }
 
     /**
@@ -4805,6 +4822,9 @@
         if (!wasDarkAtAll && nowDarkAtAll) {
             resetExposedMenuView(true /* animate */, true /* animate */);
         }
+        if (nowFullyDark != wasFullyDark || wasDarkAtAll != nowDarkAtAll) {
+            invalidateOutline();
+        }
         updateAlgorithmHeightAndPadding();
         updateBackgroundDimming();
         updatePanelTranslation();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 5a7df1f..ca45209 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.hardware.biometrics.BiometricSourceType;
+import android.metrics.LogMaker;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemClock;
@@ -26,6 +27,8 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.LatencyTracker;
 import com.android.keyguard.KeyguardConstants;
 import com.android.keyguard.KeyguardUpdateMonitor;
@@ -140,6 +143,8 @@
         }
     };
 
+    private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
+
     public BiometricUnlockController(Context context,
             DozeScrimController dozeScrimController,
             KeyguardViewMediator keyguardViewMediator,
@@ -253,6 +258,8 @@
             Trace.endSection();
             return;
         }
+        mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
+                .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
         startWakeAndUnlock(calculateMode(biometricSourceType));
     }
 
@@ -420,12 +427,16 @@
 
     @Override
     public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
+        mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
+                .setType(MetricsEvent.TYPE_FAILURE).setSubtype(toSubtype(biometricSourceType)));
         cleanup();
     }
 
     @Override
     public void onBiometricError(int msgId, String errString,
             BiometricSourceType biometricSourceType) {
+        mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
+                .setType(MetricsEvent.TYPE_ERROR).setSubtype(toSubtype(biometricSourceType)));
         cleanup();
     }
 
@@ -501,4 +512,20 @@
     public boolean isBiometricUnlock() {
         return isWakeAndUnlock() || mMode == MODE_UNLOCK;
     }
+
+    /**
+     * Translates biometric source type for logging purpose.
+     */
+    private int toSubtype(BiometricSourceType biometricSourceType) {
+        switch (biometricSourceType) {
+            case FINGERPRINT:
+                return 0;
+            case FACE:
+                return 1;
+            case IRIS:
+                return 2;
+            default:
+                return 3;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index ef82b34..e9a9606 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -50,8 +50,6 @@
 import android.graphics.Region;
 import android.graphics.Region.Op;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.util.AttributeSet;
@@ -150,10 +148,6 @@
     private final NavigationBarTransitions mBarTransitions;
     private final OverviewProxyService mOverviewProxyService;
 
-    // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
-    final static boolean WORKAROUND_INVALID_LAYOUT = true;
-    final static int MSG_CHECK_INVALID_LAYOUT = 8686;
-
     // performs manual animation in sync with layout transitions
     private final NavTransitionListener mTransitionListener = new NavTransitionListener();
 
@@ -260,29 +254,6 @@
         }
     };
 
-    private class H extends Handler {
-        public void handleMessage(Message m) {
-            switch (m.what) {
-                case MSG_CHECK_INVALID_LAYOUT:
-                    final String how = "" + m.obj;
-                    final int w = getWidth();
-                    final int h = getHeight();
-                    final int vw = getCurrentView().getWidth();
-                    final int vh = getCurrentView().getHeight();
-
-                    if (h != vh || w != vw) {
-                        Log.w(TAG, String.format(
-                            "*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)",
-                            how, w, h, vw, vh));
-                        if (WORKAROUND_INVALID_LAYOUT) {
-                            requestLayout();
-                        }
-                    }
-                    break;
-            }
-        }
-    }
-
     private final AccessibilityDelegate mQuickStepAccessibilityDelegate
             = new AccessibilityDelegate() {
         private AccessibilityAction mToggleOverviewAction;
@@ -450,7 +421,7 @@
                 mQuickScrubAction, null /* swipeLeftEdgeAction */, null /* swipeRightEdgeAction */
         };
 
-        mPrototypeController = new NavigationPrototypeController(mHandler, mContext);
+        mPrototypeController = new NavigationPrototypeController(mContext);
         mPrototypeController.register();
         mPrototypeController.setOnPrototypeChangedListener(mPrototypeListener);
         mColorAdaptionController = new NavBarTintController(this, getLightTransitionsController());
@@ -591,8 +562,6 @@
         getHomeButton().abortCurrentGesture();
     }
 
-    private H mHandler = new H();
-
     public View getCurrentView() {
         return mCurrentView;
     }
@@ -1193,23 +1162,23 @@
     }
 
     @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int w = MeasureSpec.getSize(widthMeasureSpec);
+        int h = MeasureSpec.getSize(heightMeasureSpec);
         if (DEBUG) Log.d(TAG, String.format(
-                    "onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
+                "onMeasure: (%dx%d) old: (%dx%d)", w, h, getMeasuredWidth(), getMeasuredHeight()));
 
         final boolean newVertical = w > 0 && h > w;
         if (newVertical != mIsVertical) {
             mIsVertical = newVertical;
             if (DEBUG) {
-                Log.d(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w,
+                Log.d(TAG, String.format("onMeasure: h=%d, w=%d, vert=%s", h, w,
                         mIsVertical ? "y" : "n"));
             }
             reorient();
             notifyVerticalChangedListener(newVertical);
         }
-
-        postCheckForInvalidLayout("sizeChanged");
-        super.onSizeChanged(w, h, oldw, oldh);
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     }
 
     private void notifyVerticalChangedListener(boolean newVertical) {
@@ -1264,28 +1233,6 @@
         return uiCarModeChanged;
     }
 
-    /*
-    @Override
-    protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
-        if (DEBUG) Log.d(TAG, String.format(
-                    "onLayout: %s (%d,%d,%d,%d)",
-                    changed?"changed":"notchanged", left, top, right, bottom));
-        super.onLayout(changed, left, top, right, bottom);
-    }
-
-    // uncomment this for extra defensiveness in WORKAROUND_INVALID_LAYOUT situations: if all else
-    // fails, any touch on the display will fix the layout.
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (DEBUG) Log.d(TAG, "onInterceptTouchEvent: " + ev.toString());
-        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            postCheckForInvalidLayout("touch");
-        }
-        return super.onInterceptTouchEvent(ev);
-    }
-    */
-
-
     private String getResourceName(int resId) {
         if (resId != 0) {
             final android.content.res.Resources res = getContext().getResources();
@@ -1299,10 +1246,6 @@
         }
     }
 
-    private void postCheckForInvalidLayout(final String how) {
-        mHandler.obtainMessage(MSG_CHECK_INVALID_LAYOUT, 0, 0, how).sendToTarget();
-    }
-
     private static String visibilityToString(int vis) {
         switch (vis) {
             case View.INVISIBLE:
@@ -1471,7 +1414,7 @@
         void onVerticalChanged(boolean isVertical);
     }
 
-    private final Consumer<Boolean> mDockedListener = exists -> mHandler.post(() -> {
+    private final Consumer<Boolean> mDockedListener = exists -> post(() -> {
         mDockedStackExists = exists;
         updateRecentsIcon();
     });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
index 979de07..9ea8b64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
@@ -67,8 +67,8 @@
 
     private final Context mContext;
 
-    public NavigationPrototypeController(Handler handler, Context context) {
-        super(handler);
+    public NavigationPrototypeController(Context context) {
+        super(new Handler());
         mContext = context;
         updateSwipeLTRBackSetting();
     }
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 253bdfb..b902e43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -92,6 +92,7 @@
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
 import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
 import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -141,6 +142,7 @@
     private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties()
             .setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
 
+    private final InjectionInflationController mInjectionInflationController;
     private final PowerManager mPowerManager;
     private final AccessibilityManager mAccessibilityManager;
     private final NotificationWakeUpCoordinator mWakeUpCoordinator;
@@ -336,10 +338,12 @@
 
     @Inject
     public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
+            InjectionInflationController injectionInflationController,
             NotificationWakeUpCoordinator coordinator,
             PulseExpansionHandler pulseExpansionHandler) {
         super(context, attrs);
         setWillNotDraw(!DEBUG);
+        mInjectionInflationController = injectionInflationController;
         mFalsingManager = FalsingManager.getInstance(context);
         mPowerManager = context.getSystemService(PowerManager.class);
         mWakeUpCoordinator = coordinator;
@@ -475,10 +479,11 @@
         // Re-inflate the status view group.
         int index = indexOfChild(mKeyguardStatusView);
         removeView(mKeyguardStatusView);
-        mKeyguardStatusView = (KeyguardStatusView) LayoutInflater.from(mContext).inflate(
-                R.layout.keyguard_status_view,
-                this,
-                false);
+        mKeyguardStatusView = (KeyguardStatusView) mInjectionInflationController
+                .injectable(LayoutInflater.from(mContext)).inflate(
+                    R.layout.keyguard_status_view,
+                    this,
+                    false);
         addView(mKeyguardStatusView, index);
 
         // Re-associate the clock container with the keyguard clock switch.
@@ -490,10 +495,11 @@
         index = indexOfChild(mKeyguardBottomArea);
         removeView(mKeyguardBottomArea);
         KeyguardBottomAreaView oldBottomArea = mKeyguardBottomArea;
-        mKeyguardBottomArea = (KeyguardBottomAreaView) LayoutInflater.from(mContext).inflate(
-                R.layout.keyguard_bottom_area,
-                this,
-                false);
+        mKeyguardBottomArea = (KeyguardBottomAreaView) mInjectionInflationController
+                .injectable(LayoutInflater.from(mContext)).inflate(
+                    R.layout.keyguard_bottom_area,
+                    this,
+                    false);
         mKeyguardBottomArea.initFrom(oldBottomArea);
         addView(mKeyguardBottomArea, index);
         initBottomArea();
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 a8ae5f6..9609057 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -114,17 +114,19 @@
             if (mSingleTapEnabled) {
                 mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
                         "SINGLE_TAP");
+                return true;
             }
-            return mSingleTapEnabled;
+            return false;
         }
 
         @Override
         public boolean onDoubleTap(MotionEvent e) {
-            if (mDoubleTapEnabled) {
+            if (mDoubleTapEnabled || mSingleTapEnabled) {
                 mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
                         "DOUBLE_TAP");
+                return true;
             }
-            return mDoubleTapEnabled;
+            return false;
         }
     };
     private final TunerService.Tunable mTunable = (key, newValue) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
index 3c8ed6e..b53ff0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
@@ -16,9 +16,11 @@
 
 package com.android.systemui.statusbar.policy;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.content.Context;
 
+import com.android.internal.util.Preconditions;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.settings.CurrentUserTracker;
@@ -69,7 +71,8 @@
     }
 
     @Override
-    public void addCallback(Callback callback) {
+    public void addCallback(@NonNull Callback callback) {
+        Preconditions.checkNotNull(callback, "Callback must not be null. b/128895449");
         mCallbacks.add(callback);
         if (mCallbacks.size() != 0 && !mListening) {
             mListening = true;
@@ -81,7 +84,8 @@
     }
 
     @Override
-    public void removeCallback(Callback callback) {
+    public void removeCallback(@NonNull Callback callback) {
+        Preconditions.checkNotNull(callback, "Callback must not be null. b/128895449");
         if (mCallbacks.remove(callback) && mCallbacks.size() == 0 && mListening) {
             mListening = false;
             mKeyguardUpdateMonitor.removeCallback(this);
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index e6b6672..7705e4e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -23,6 +23,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 
+import com.android.keyguard.KeyguardClockSwitch;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.qs.QSCarrierGroup;
 import com.android.systemui.qs.QSFooterImpl;
@@ -130,6 +131,11 @@
          * Creates the QSCarrierGroup
          */
         QSCarrierGroup createQSCarrierGroup();
+
+        /**
+         * Creates the KeyguardClockSwitch.
+         */
+        KeyguardClockSwitch createKeyguardClockSwitch();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
new file mode 100644
index 0000000..8ec66e4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 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 android.util.AttributeSet;
+
+import com.android.keyguard.AlphaOptimizedImageButton;
+import com.android.systemui.R;
+
+/** Toggle button in Volume Dialog that allows extra state for when streams are opted-out */
+public class CaptionsToggleImageButton extends AlphaOptimizedImageButton {
+
+    private static final int[] OPTED_OUT_STATE = new int[] { R.attr.optedOut };
+
+    private boolean mComponentEnabled = false;
+    private boolean mOptedOut = false;
+
+    public CaptionsToggleImageButton(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    public int[] onCreateDrawableState(int extraSpace) {
+        int[] state = super.onCreateDrawableState(extraSpace + 1);
+        if (mOptedOut) {
+            mergeDrawableStates(state, OPTED_OUT_STATE);
+        }
+        return state;
+    }
+
+    Runnable setComponentEnabled(boolean isComponentEnabled) {
+        this.mComponentEnabled = isComponentEnabled;
+
+        return this.setImageResourceAsync(this.mComponentEnabled
+                ? R.drawable.ic_volume_odi_captions
+                : R.drawable.ic_volume_odi_captions_disabled);
+    }
+
+    boolean getComponentEnabled() {
+        return this.mComponentEnabled;
+    }
+
+    /** Sets whether or not the current stream has opted out of captions */
+    void setOptedOut(boolean isOptedOut) {
+        this.mOptedOut = isOptedOut;
+        refreshDrawableState();
+    }
+
+    boolean getOptedOut() {
+        return this.mOptedOut;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 2fa8889..a3db533 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -282,6 +282,13 @@
                 Settings.Secure.ODI_CAPTIONS_ENABLED, isEnabled ? 1 : 0);
     }
 
+    @Override
+    public boolean isCaptionStreamOptedOut() {
+        int currentValue = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ODI_CAPTIONS_OPTED_OUT, 0);
+        return currentValue == 1;
+    }
+
     public void getCaptionsComponentState(boolean fromTooltip) {
         if (mDestroyed) return;
         mWorker.obtainMessage(W.GET_CAPTIONS_COMPONENT_STATE, fromTooltip).sendToTarget();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index cdda216..bd7824d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -133,7 +133,7 @@
     private ViewGroup mRinger;
     private ImageButton mRingerIcon;
     private ViewGroup mODICaptionsView;
-    private ImageButton mODICaptionsIcon;
+    private CaptionsToggleImageButton mODICaptionsIcon;
     private View mSettingsView;
     private ImageButton mSettingsIcon;
     private FrameLayout mZenIcon;
@@ -587,11 +587,15 @@
     }
 
     private void updateCaptionsIcon() {
-        mHandler.post(
-                mODICaptionsIcon.setImageResourceAsync(
-                        mController.areCaptionsEnabled()
-                                ? R.drawable.ic_volume_odi_captions
-                                : R.drawable.ic_volume_odi_captions_disabled));
+        boolean componentEnabled = mController.areCaptionsEnabled();
+        if (mODICaptionsIcon.getComponentEnabled() != componentEnabled) {
+            mHandler.post(mODICaptionsIcon.setComponentEnabled(componentEnabled));
+        }
+
+        boolean isOptedOut = mController.isCaptionStreamOptedOut();
+        if (mODICaptionsIcon.getOptedOut() != isOptedOut) {
+            mHandler.post(() -> mODICaptionsIcon.setOptedOut(isOptedOut));
+        }
     }
 
     private void onCaptionIconClicked() {
@@ -952,7 +956,7 @@
     }
 
     private void updateVolumeRowH(VolumeRow row) {
-        if (D.BUG) Log.d(TAG, "updateVolumeRowH s=" + row.stream);
+        if (D.BUG) Log.i(TAG, "updateVolumeRowH s=" + row.stream);
         if (mState == null) return;
         final StreamState ss = mState.states.get(row.stream);
         if (ss == null) return;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 29505a2..632b0c0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -39,10 +39,12 @@
 import android.widget.TextClock;
 
 import com.android.keyguard.clock.ClockManager;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.ClockPlugin;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.util.InjectionInflationController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -70,7 +72,10 @@
 
     @Before
     public void setUp() {
-        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+        InjectionInflationController inflationController = new InjectionInflationController(
+                SystemUIFactory.getInstance().getRootComponent());
+        LayoutInflater layoutInflater = inflationController
+                .injectable(LayoutInflater.from(getContext()));
         mKeyguardClockSwitch =
                 (KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
         mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
index 3582ab01..31ea39c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
@@ -24,8 +24,10 @@
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.LayoutInflater;
 
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.util.Assert;
+import com.android.systemui.util.InjectionInflationController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -48,7 +50,10 @@
     @Before
     public void setUp() {
         Assert.sMainLooper = TestableLooper.get(this).getLooper();
-        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+        InjectionInflationController inflationController = new InjectionInflationController(
+                SystemUIFactory.getInstance().getRootComponent());
+        LayoutInflater layoutInflater = inflationController
+                .injectable(LayoutInflater.from(getContext()));
         mKeyguardStatusView =
                 (KeyguardStatusView) layoutInflater.inflate(R.layout.keyguard_status_view, null);
         org.mockito.MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
index 2a01356..1a1acdf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
@@ -129,7 +129,7 @@
                 mock(NotificationListener.NotificationSettingsListener.class);
         mListener.addNotificationSettingsListener(settingsListener);
 
-        mListener.onStatusBarIconsBehaviorChanged(true);
+        mListener.onSilentStatusBarIconsVisibilityChanged(true);
 
         verify(settingsListener).onStatusBarIconsBehaviorChanged(true);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 5a1f24a..1bcf880 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -312,7 +312,6 @@
         return new BubbleMetadata.Builder()
                 .setIntent(bubbleIntent)
                 .setDeleteIntent(deleteIntent)
-                .setTitle("bubble title")
                 .setIcon(Icon.createWithResource(mContext, R.drawable.android))
                 .setDesiredHeight(314)
                 .build();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
index eec836f..dfe2913 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
@@ -23,7 +23,9 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.InjectionInflationController;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -35,7 +37,10 @@
     @Test
     public void testInflation_doesntCrash() {
         com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
-        LayoutInflater inflater = LayoutInflater.from(getContext());
+        InjectionInflationController inflationController = new InjectionInflationController(
+                SystemUIFactory.getInstance().getRootComponent());
+        LayoutInflater inflater = inflationController
+                .injectable(LayoutInflater.from(getContext()));
         inflater.inflate(R.layout.keyguard_presentation, null);
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 6889c57..232c6a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -27,6 +27,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardStatusView;
+import com.android.systemui.SystemUIFactory;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.AmbientPulseManager;
@@ -38,6 +39,7 @@
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -104,7 +106,10 @@
     private class TestableNotificationPanelView extends NotificationPanelView {
         TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator,
                 PulseExpansionHandler expansionHandler) {
-            super(NotificationPanelViewTest.this.mContext, null, coordinator, expansionHandler);
+            super(NotificationPanelViewTest.this.mContext, null,
+                    new InjectionInflationController(
+                            SystemUIFactory.getInstance().getRootComponent()),
+                    coordinator, expansionHandler);
             mNotificationStackScroller = mNotificationStackScrollLayout;
             mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
             mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index a15e89c..b522344 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -39,7 +39,10 @@
 	IconShapeRoundedRectOverlay \
 	IconShapeSquareOverlay \
 	IconShapeSquircleOverlay \
-	IconShapeTeardropOverlay
+	IconShapeTeardropOverlay \
+	NavigationBarMode3ButtonOverlay \
+	NavigationBarMode2ButtonOverlay \
+	NavigationBarModeGesturalOverlay
 
 include $(BUILD_PHONY_PACKAGE)
 include $(CLEAR_VARS)
diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk b/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk
new file mode 100644
index 0000000..410d6d8
--- /dev/null
+++ b/packages/overlays/NavigationBarMode2ButtonOverlay/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 := NavigationBarMode2Button
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := NavigationBarMode2ButtonOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/AndroidManifest.xml b/packages/overlays/NavigationBarMode2ButtonOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..970380f
--- /dev/null
+++ b/packages/overlays/NavigationBarMode2ButtonOverlay/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.internal.systemui.navbar.twobutton"
+        android:versionCode="1"
+        android:versionName="1.0">
+    <overlay android:targetPackage="android"
+        android:category="com.android.internal.navigation_bar_mode"
+        android:priority="1"/>
+
+    <application android:label="@string/navigation_bar_mode_title" android:hasCode="false"/>
+</manifest>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/config.xml b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/config.xml
new file mode 100644
index 0000000..b353322
--- /dev/null
+++ b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2019, 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>
+    <!-- Controls the navigation bar interaction mode:
+         0: 3 button mode (back, home, overview buttons)
+         1: 2 button mode (back, home buttons + swipe up for overview)
+         2: gestures only for back, home and overview -->
+    <integer name="config_navBarInteractionMode">1</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/strings.xml b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/strings.xml
new file mode 100644
index 0000000..1696ecf
--- /dev/null
+++ b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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">
+    <!-- Name of overlay [CHAR LIMIT=64] -->
+    <string name="navigation_bar_mode_title" translatable="false">2 Button Navigation Bar</string>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk b/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk
new file mode 100644
index 0000000..2bc9a6a
--- /dev/null
+++ b/packages/overlays/NavigationBarMode3ButtonOverlay/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 := NavigationBarMode3Button
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := NavigationBarMode3ButtonOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/AndroidManifest.xml b/packages/overlays/NavigationBarMode3ButtonOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..628fc1d
--- /dev/null
+++ b/packages/overlays/NavigationBarMode3ButtonOverlay/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.internal.systemui.navbar.threebutton"
+        android:versionCode="1"
+        android:versionName="1.0">
+    <overlay android:targetPackage="android"
+        android:category="com.android.internal.navigation_bar_mode"
+        android:priority="1"/>
+
+    <application android:label="@string/navigation_bar_mode_title" android:hasCode="false"/>
+</manifest>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/config.xml b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/config.xml
new file mode 100644
index 0000000..7bd0a14
--- /dev/null
+++ b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2019, 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>
+    <!-- Controls the navigation bar interaction mode:
+         0: 3 button mode (back, home, overview buttons)
+         1: 2 button mode (back, home buttons + swipe up for overview)
+         2: gestures only for back, home and overview -->
+    <integer name="config_navBarInteractionMode">0</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/strings.xml b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/strings.xml
new file mode 100644
index 0000000..201b9e9
--- /dev/null
+++ b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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">
+    <!-- Name of overlay [CHAR LIMIT=64] -->
+    <string name="navigation_bar_mode_title" translatable="false">3 Button Navigation Bar</string>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk b/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk
new file mode 100644
index 0000000..5f7e0eb
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/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 := NavigationBarModeGestural
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := NavigationBarModeGesturalOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/AndroidManifest.xml b/packages/overlays/NavigationBarModeGesturalOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..aff82d8
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/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.internal.systemui.navbar.gestural"
+        android:versionCode="1"
+        android:versionName="1.0">
+    <overlay android:targetPackage="android"
+        android:category="com.android.internal.navigation_bar_mode"
+        android:priority="1"/>
+
+    <application android:label="@string/navigation_bar_mode_title" android:hasCode="false"/>
+</manifest>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
new file mode 100644
index 0000000..48c3769
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2019, 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>
+    <!-- Controls the navigation bar interaction mode:
+         0: 3 button mode (back, home, overview buttons)
+         1: 2 button mode (back, home buttons + swipe up for overview)
+         2: gestures only for back, home and overview -->
+    <integer name="config_navBarInteractionMode">2</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/strings.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/strings.xml
new file mode 100644
index 0000000..8d38916
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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">
+    <!-- Name of overlay [CHAR LIMIT=64] -->
+    <string name="navigation_bar_mode_title" translatable="false">Gestural Navigation Bar</string>
+</resources>
\ No newline at end of file
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 7447331..95abd05 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -74,6 +74,9 @@
     // The view switched to summary mode (most relevant for notifications)
     TYPE_COLLAPSE = 14;
 
+    // The action results an error.
+    TYPE_ERROR = 15;
+
     // The notification was adjusted by the assistant. Enum value is
     // out of sequence due to b/122737498.
     TYPE_NOTIFICATION_ASSISTANT_ADJUSTMENT = 1573;
@@ -7138,6 +7141,14 @@
     // OS: Q
     DISPLAY_POLICY = 1696;
 
+    // Biometric authentication.
+    //    TYPE: SUCCESS, FAILURE or ERROR
+    //    SUBTYPE: 0 is fingerprint, 1 is face, 2 is iris and 3 is unknown.
+    // OS: Q
+    BIOMETRIC_AUTH = 1697;
+
+    // Settings > Display > Theme
+    DARK_UI_SETTINGS = 1698;
     // ---- End Q Constants, all Q constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/services/art-profile b/services/art-profile
index 6368c63..f0b9234 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -1136,7 +1136,7 @@
 Lcom/android/server/DropBoxManagerService$EntryFile;
 Lcom/android/server/DropBoxManagerService$FileList;
 Lcom/android/server/DropBoxManagerService;
-Lcom/android/server/DynamicAndroidService;
+Lcom/android/server/DynamicSystemService;
 Lcom/android/server/EntropyMixer$1;
 Lcom/android/server/EntropyMixer$2;
 Lcom/android/server/EntropyMixer;
@@ -4769,9 +4769,9 @@
 PLcom/android/server/DropBoxManagerService$EntryFile;->getFile(Ljava/io/File;)Ljava/io/File;
 PLcom/android/server/DropBoxManagerService;->checkPermission(ILjava/lang/String;)Z
 PLcom/android/server/DropBoxManagerService;->getNextEntry(Ljava/lang/String;JLjava/lang/String;)Landroid/os/DropBoxManager$Entry;
-PLcom/android/server/DynamicAndroidService;->connect(Landroid/os/IBinder$DeathRecipient;)Landroid/gsi/IGsiService;
-PLcom/android/server/DynamicAndroidService;->getGsiService()Landroid/gsi/IGsiService;
-PLcom/android/server/DynamicAndroidService;->isInUse()Z
+PLcom/android/server/DynamicSystemService;->connect(Landroid/os/IBinder$DeathRecipient;)Landroid/gsi/IGsiService;
+PLcom/android/server/DynamicSystemService;->getGsiService()Landroid/gsi/IGsiService;
+PLcom/android/server/DynamicSystemService;->isInUse()Z
 PLcom/android/server/EntropyMixer$1;->handleMessage(Landroid/os/Message;)V
 PLcom/android/server/EntropyMixer$2;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
 PLcom/android/server/EventLogTags;->writeBatterySaverMode(IIIIILjava/lang/String;I)V
@@ -15043,7 +15043,7 @@
 SPLcom/android/server/DropBoxManagerService;->onBootPhase(I)V
 SPLcom/android/server/DropBoxManagerService;->onStart()V
 SPLcom/android/server/DropBoxManagerService;->trimToFit()J
-SPLcom/android/server/DynamicAndroidService;-><init>(Landroid/content/Context;)V
+SPLcom/android/server/DynamicSystemService;-><init>(Landroid/content/Context;)V
 SPLcom/android/server/EntropyMixer;-><init>(Landroid/content/Context;)V
 SPLcom/android/server/EntropyMixer;-><init>(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
 SPLcom/android/server/EntropyMixer;->addDeviceSpecificEntropy()V
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 76d464d..87a265c 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -80,6 +80,7 @@
 import com.android.server.LocalServices;
 import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.infra.AbstractMasterSystemService;
+import com.android.server.infra.FrameworkResourcesServiceNameResolver;
 import com.android.server.infra.SecureSettingsServiceNameResolver;
 
 import java.io.FileDescriptor;
@@ -132,6 +133,12 @@
     @GuardedBy("sLock")
     private static int sVisibleDatasetsMaxCount = 0;
 
+    /**
+     * Object used to set the name of the augmented autofill service.
+     */
+    @NonNull
+    final FrameworkResourcesServiceNameResolver mAugmentedAutofillResolver;
+
     private final AutoFillUI mUi;
 
     private final LocalLog mRequestsHistory = new LocalLog(20);
@@ -200,6 +207,11 @@
                 getServiceForUserLocked(userId);
             }
         }
+
+        mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(),
+                com.android.internal.R.string.config_defaultAugmentedAutofillService);
+        mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
+                (u, s) -> getServiceForUserLocked(u).updateRemoteAugmentedAutofillService());
     }
 
     @Override // from AbstractMasterSystemService
@@ -521,7 +533,7 @@
                 new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT);
 
         strategy.calculateScores(callback, Arrays.asList(AutofillValue.forText(value1)),
-                new String[] { value2 }, null, algorithmName, null, null, null);
+                new String[] { value2 }, new String[] { null }, algorithmName, null, null, null);
     }
 
     // Called by Shell command.
@@ -549,37 +561,19 @@
                     + MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS + " (called with " + durationMs + ")");
         }
 
-        synchronized (mLock) {
-            final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
-            if (service != null) {
-                service.mAugmentedAutofillResolver.setTemporaryService(userId, serviceName,
-                        durationMs);
-            }
-        }
+        mAugmentedAutofillResolver.setTemporaryService(userId, serviceName, durationMs);
     }
 
     // Called by Shell command
     void resetTemporaryAugmentedAutofillService(@UserIdInt int userId) {
         enforceCallingPermissionForManagement();
-        synchronized (mLock) {
-            final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
-            if (service != null) {
-                service.mAugmentedAutofillResolver.resetTemporaryService(userId);
-            }
-        }
+        mAugmentedAutofillResolver.resetTemporaryService(userId);
     }
 
     // Called by Shell command
     boolean isDefaultAugmentedServiceEnabled(@UserIdInt int userId) {
         enforceCallingPermissionForManagement();
-
-        synchronized (mLock) {
-            final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
-            if (service != null) {
-                return service.mAugmentedAutofillResolver.isDefaultServiceEnabled(userId);
-            }
-        }
-        return false;
+        return mAugmentedAutofillResolver.isDefaultServiceEnabled(userId);
     }
 
     // Called by Shell command
@@ -590,7 +584,7 @@
         synchronized (mLock) {
             final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
             if (service != null) {
-                final boolean changed = service.mAugmentedAutofillResolver
+                final boolean changed = mAugmentedAutofillResolver
                         .setDefaultServiceEnabled(userId, enabled);
                 if (changed) {
                     service.updateRemoteAugmentedAutofillService();
@@ -1348,6 +1342,7 @@
                     pw.print(" sVerbose: "); pw.println(realVerbose);
                     // Dump per-user services
                     dumpLocked("", pw);
+                    mAugmentedAutofillResolver.dumpShort(pw); pw.println();
                     pw.print("Max partitions per session: "); pw.println(sPartitionMaxCount);
                     pw.print("Max visible datasets: "); pw.println(sVisibleDatasetsMaxCount);
                     if (sFullScreenMode != null) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index ad5e689..ff284dc 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -40,6 +40,7 @@
 import android.metrics.LogMaker;
 import android.os.AsyncTask;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -83,7 +84,6 @@
 import com.android.server.autofill.RemoteAugmentedAutofillService.RemoteAugmentedAutofillServiceCallbacks;
 import com.android.server.autofill.ui.AutoFillUI;
 import com.android.server.infra.AbstractPerUserSystemService;
-import com.android.server.infra.FrameworkResourcesServiceNameResolver;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -159,13 +159,6 @@
     /** When was {@link PruneTask} last executed? */
     private long mLastPrune = 0;
 
-    // TODO(b/128911469): move to AutofillManagerService
-    /**
-     * Object used to set the name of the augmented autofill service.
-     */
-    @NonNull
-    final FrameworkResourcesServiceNameResolver mAugmentedAutofillResolver;
-
     /**
      * Reference to the {@link RemoteAugmentedAutofillService}, is set on demand.
      */
@@ -195,11 +188,6 @@
         mFieldClassificationStrategy = new FieldClassificationStrategy(getContext(), userId);
         mAutofillCompatState = autofillCompatState;
 
-        mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(master.getContext(),
-                com.android.internal.R.string.config_defaultAugmentedAutofillService);
-        mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
-                (u, s) -> updateRemoteAugmentedAutofillService());
-
         updateLocked(disabled);
     }
 
@@ -951,8 +939,7 @@
                 .getString(R.string.config_defaultAutofillService));
 
         pw.print(prefix); pw.println("mAugmentedAutofillNamer: ");
-        pw.print(prefix2); mAugmentedAutofillResolver.dumpShort(pw); pw.println();
-        pw.print(prefix2); mAugmentedAutofillResolver.dumpShort(pw, mUserId); pw.println();
+        pw.print(prefix2); mMaster.mAugmentedAutofillResolver.dumpShort(pw, mUserId); pw.println();
 
         if (mRemoteAugmentedAutofillService != null) {
             pw.print(prefix); pw.println("RemoteAugmentedAutofillService: ");
@@ -1109,7 +1096,7 @@
     @GuardedBy("mLock")
     @Nullable RemoteAugmentedAutofillService getRemoteAugmentedAutofillServiceLocked() {
         if (mRemoteAugmentedAutofillService == null) {
-            final String serviceName = mAugmentedAutofillResolver.getServiceName(mUserId);
+            final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId);
             if (serviceName == null) {
                 if (mMaster.verbose) {
                     Slog.v(TAG, "getRemoteAugmentedAutofillServiceLocked(): not set");
@@ -1117,8 +1104,8 @@
                 return null;
             }
             final Pair<ServiceInfo, ComponentName> pair = RemoteAugmentedAutofillService
-                    .getComponentName(
-                            serviceName, mUserId, mAugmentedAutofillResolver.isTemporary(mUserId));
+                    .getComponentName(serviceName, mUserId,
+                            mMaster.mAugmentedAutofillResolver.isTemporary(mUserId));
             if (pair == null) return null;
 
             mRemoteAugmentedAutofillServiceInfo = pair.first;
@@ -1148,7 +1135,8 @@
     }
 
     /**
-     * Called when the {@link #mAugmentedAutofillResolver} changed (among other places).
+     * Called when the {@link AutofillManagerService#mAugmentedAutofillResolver}
+     * changed (among other places).
      */
     void updateRemoteAugmentedAutofillService() {
         synchronized (mLock) {
@@ -1225,6 +1213,18 @@
 
     @GuardedBy("mLock")
     boolean isWhitelistedForAugmentedAutofillLocked(@NonNull ComponentName componentName) {
+        if (Build.IS_USER && mMaster.mAugmentedAutofillResolver.isTemporary(mUserId)) {
+            final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId);
+            final ComponentName component = ComponentName.unflattenFromString(serviceName);
+            final String servicePackage = component == null ? null : component.getPackageName();
+            final String packageName = componentName.getPackageName();
+            if (!packageName.equals(servicePackage)) {
+                Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill while "
+                        + "using temporary service " + servicePackage);
+                return false;
+            }
+        }
+
         return mAugmentedWhitelistHelper.isWhitelisted(componentName);
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index ac8f61b..c62794d 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2659,17 +2659,16 @@
         mAugmentedAutofillDestroyer = triggerAugmentedAutofillLocked();
         if (mAugmentedAutofillDestroyer == null) {
             if (sVerbose) {
-                Slog.v(TAG, "canceling session " + id + " when server returned null and there is no"
-                        + " AugmentedAutofill for user. AutofillableIds: " + autofillableIds);
+                Slog.v(TAG, "canceling session " + id + " when service returned null and it cannot "
+                        + "be augmented. AutofillableIds: " + autofillableIds);
             }
             // Nothing to be done, but need to notify client.
             notifyUnavailableToClient(AutofillManager.STATE_FINISHED, autofillableIds);
             removeSelf();
         } else {
             if (sVerbose) {
-                Slog.v(TAG, "keeping session " + id + " when server returned null but "
-                        + "there is an AugmentedAutofill for user. AutofillableIds: "
-                        + autofillableIds);
+                Slog.v(TAG, "keeping session " + id + " when service returned null but "
+                        + "it can be augmented. AutofillableIds: " + autofillableIds);
             }
             mAugmentedAutofillableIds = autofillableIds;
         }
@@ -2687,7 +2686,10 @@
         // Check if Smart Suggestions is supported...
         final @SmartSuggestionMode int supportedModes = mService
                 .getSupportedSmartSuggestionModesLocked();
-        if (supportedModes == 0) return null;
+        if (supportedModes == 0) {
+            if (sVerbose) Slog.v(TAG, "triggerAugmentedAutofillLocked(): no supported modes");
+            return null;
+        }
 
         // ...then if the service is set for the user
 
@@ -2712,14 +2714,6 @@
             return null;
         }
 
-        if (sVerbose) {
-            Slog.v(TAG, "calling Augmented Autofill Service ("
-                    + remoteService.getComponentName().toShortString() + ") on view "
-                    + mCurrentViewId + " using suggestion mode "
-                    + getSmartSuggestionModeToString(mode)
-                    + " when server returned null for session " + this.id);
-        }
-
         final boolean isWhitelisted = mService
                 .isWhitelistedForAugmentedAutofillLocked(mComponentName);
 
@@ -2733,12 +2727,20 @@
 
         if (!isWhitelisted) {
             if (sVerbose) {
-                Slog.v(TAG, mComponentName.toShortString() + " is not whitelisted for "
-                        + "augmented autofill");
+                Slog.v(TAG, "triggerAugmentedAutofillLocked(): "
+                        + ComponentName.flattenToShortString(mComponentName) + " not whitelisted ");
             }
             return null;
         }
 
+        if (sVerbose) {
+            Slog.v(TAG, "calling Augmented Autofill Service ("
+                    + ComponentName.flattenToShortString(remoteService.getComponentName())
+                    + ") on view " + mCurrentViewId + " using suggestion mode "
+                    + getSmartSuggestionModeToString(mode)
+                    + " when server returned null for session " + this.id);
+        }
+
         final ViewState viewState = mViewStates.get(mCurrentViewId);
         viewState.setState(ViewState.STATE_TRIGGERED_AUGMENTED_AUTOFILL);
         final AutofillValue currentValue = viewState.getCurrentValue();
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 9995d8e..b2760e0 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -18,6 +18,12 @@
 
 import static android.Manifest.permission.MANAGE_CONTENT_CAPTURE;
 import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
+import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_FALSE;
+import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_OK;
+import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_SECURITY_EXCEPTION;
+import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_TRUE;
+
+import static com.android.internal.util.SyncResultReceiver.bundleFor;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -57,7 +63,6 @@
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
-import com.android.internal.util.SyncResultReceiver;
 import com.android.server.LocalServices;
 import com.android.server.infra.AbstractMasterSystemService;
 import com.android.server.infra.FrameworkResourcesServiceNameResolver;
@@ -167,6 +172,22 @@
     }
 
     @Override // from AbstractMasterSystemService
+    protected void onServicePackageUpdatingLocked(int userId) {
+        final ContentCapturePerUserService service = getServiceForUserLocked(userId);
+        if (service != null) {
+            service.onPackageUpdatingLocked();
+        }
+    }
+
+    @Override // from AbstractMasterSystemService
+    protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+        final ContentCapturePerUserService service = getServiceForUserLocked(userId);
+        if (service != null) {
+            service.onPackageUpdatedLocked();
+        }
+    }
+
+    @Override // from AbstractMasterSystemService
     protected void enforceCallingPermissionForManagement() {
         getContext().enforceCallingPermission(MANAGE_CONTENT_CAPTURE, mTag);
     }
@@ -414,8 +435,7 @@
         if (isService) return true;
 
         try {
-            result.send(ContentCaptureManager.RESULT_CODE_NOT_SERVICE,
-                    /* resultData= */ null);
+            result.send(RESULT_CODE_SECURITY_EXCEPTION, /* resultData= */ null);
         } catch (RemoteException e) {
             Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e);
         }
@@ -518,8 +538,7 @@
                 connectedServiceComponentName = service.getServiceComponentName();
             }
             try {
-                result.send(/* resultCode= */ 0,
-                        SyncResultReceiver.bundleFor(connectedServiceComponentName));
+                result.send(RESULT_CODE_OK, bundleFor(connectedServiceComponentName));
             } catch (RemoteException e) {
                 Slog.w(mTag, "Unable to send service component name: " + e);
             }
@@ -547,14 +566,40 @@
                 enabled = !mDisabledByDeviceConfig && !isDisabledBySettingsLocked(userId);
             }
             try {
-                result.send(enabled ? ContentCaptureManager.RESULT_CODE_TRUE
-                        : ContentCaptureManager.RESULT_CODE_FALSE, /* resultData= */null);
+                result.send(enabled ? RESULT_CODE_TRUE : RESULT_CODE_FALSE, /* resultData= */null);
             } catch (RemoteException e) {
                 Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e);
             }
         }
 
         @Override
+        public void getServiceSettingsActivity(@NonNull IResultReceiver result) {
+            try {
+                enforceCallingPermissionForManagement();
+            } catch (SecurityException e) {
+                try {
+                    result.send(RESULT_CODE_SECURITY_EXCEPTION, bundleFor(e.getMessage()));
+                } catch (RemoteException e2) {
+                    Slog.w(mTag, "Unable to send getServiceSettingsIntent() exception: " + e2);
+                    return;
+                }
+            }
+
+            final int userId = UserHandle.getCallingUserId();
+            final ComponentName componentName;
+            synchronized (mLock) {
+                final ContentCapturePerUserService service = getServiceForUserLocked(userId);
+                if (service == null) return;
+                componentName = service.getServiceSettingsActivityLocked();
+            }
+            try {
+                result.send(RESULT_CODE_OK, bundleFor(componentName));
+            } catch (RemoteException e) {
+                Slog.w(mTag, "Unable to send getServiceSettingsIntent(): " + e);
+            }
+        }
+
+        @Override
         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(getContext(), mTag, pw)) return;
 
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index d7d97b3..d909736 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -40,6 +40,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ServiceInfo;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.UserHandle;
@@ -74,7 +75,7 @@
         AbstractPerUserSystemService<ContentCapturePerUserService, ContentCaptureManagerService>
         implements ContentCaptureServiceCallbacks {
 
-    private static final String TAG = ContentCaptureManagerService.class.getSimpleName();
+    private static final String TAG = ContentCapturePerUserService.class.getSimpleName();
 
     @GuardedBy("mLock")
     private final ArrayMap<String, ContentCaptureServerSession> mSessions =
@@ -87,7 +88,8 @@
      * master's cache (for example, because a temporary service was set).
      */
     @GuardedBy("mLock")
-    private RemoteContentCaptureService mRemoteService;
+    @Nullable
+    RemoteContentCaptureService mRemoteService;
 
     private final ContentCaptureServiceRemoteCallback mRemoteServiceCallback =
             new ContentCaptureServiceRemoteCallback();
@@ -135,6 +137,10 @@
         }
 
         if (!disabled) {
+            if (mMaster.debug) {
+                Slog.d(TAG, "updateRemoteService(): creating new remote service for "
+                        + serviceComponentName);
+            }
             mRemoteService = new RemoteContentCaptureService(mMaster.getContext(),
                     ContentCaptureService.SERVICE_INTERFACE, serviceComponentName,
                     mRemoteServiceCallback, mUserId, this, mMaster.isBindInstantServiceAllowed(),
@@ -182,20 +188,40 @@
                 }
 
                 mZombie = false;
-                final int numSessions = mSessions.size();
-                if (mMaster.debug) {
-                    Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on "
-                            + numSessions + " sessions");
-                }
-
-                for (int i = 0; i < numSessions; i++) {
-                    final ContentCaptureServerSession session = mSessions.valueAt(i);
-                    session.resurrectLocked();
-                }
+                resurrectSessionsLocked();
             }
         }
     }
 
+    private void resurrectSessionsLocked() {
+        final int numSessions = mSessions.size();
+        if (mMaster.debug) {
+            Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on "
+                    + numSessions + " sessions");
+        }
+
+        for (int i = 0; i < numSessions; i++) {
+            final ContentCaptureServerSession session = mSessions.valueAt(i);
+            session.resurrectLocked();
+        }
+    }
+
+    void onPackageUpdatingLocked() {
+        final int numSessions = mSessions.size();
+        if (mMaster.debug) {
+            Slog.d(TAG, "Pausing " + numSessions + " sessions while package is updating");
+        }
+        for (int i = 0; i < numSessions; i++) {
+            final ContentCaptureServerSession session = mSessions.valueAt(i);
+            session.pauseLocked();
+        }
+    }
+
+    void onPackageUpdatedLocked() {
+        updateRemoteServiceLocked(!isEnabledLocked());
+        resurrectSessionsLocked();
+    }
+
     // TODO(b/119613670): log metrics
     @GuardedBy("mLock")
     public void startSessionLocked(@NonNull IBinder activityToken,
@@ -274,9 +300,12 @@
             return;
         }
 
+        // Make sure service is bound, just in case the initial connection failed somehow
+        mRemoteService.ensureBoundLocked();
+
         final ContentCaptureServerSession newSession = new ContentCaptureServerSession(
-                activityToken, this, mRemoteService, componentName, clientReceiver, taskId,
-                displayId, sessionId, uid, flags);
+                activityToken, this, componentName, clientReceiver, taskId, displayId, sessionId,
+                uid, flags);
         if (mMaster.verbose) {
             Slog.v(TAG, "startSession(): new session for "
                     + ComponentName.flattenToShortString(componentName) + " and id " + sessionId);
@@ -290,21 +319,6 @@
         return mWhitelistHelper.isWhitelisted(componentName);
     }
 
-    /**
-     * @throws IllegalArgumentException if packages or components are empty.
-     */
-    private void setWhitelist(@Nullable List<String> packages,
-            @Nullable List<ComponentName> components) {
-        // TODO(b/122595322): add CTS test for when it's null
-        synchronized (mLock) {
-            if (mMaster.verbose) {
-                Slog.v(TAG, "whitelisting packages: " + packages + " and activities: "
-                        + components);
-            }
-            mWhitelistHelper.setWhitelist(packages, components);
-        }
-    }
-
     // TODO(b/119613670): log metrics
     @GuardedBy("mLock")
     public void finishSessionLocked(@NonNull String sessionId) {
@@ -332,6 +346,18 @@
         mRemoteService.onUserDataRemovalRequest(request);
     }
 
+    @GuardedBy("mLock")
+    @Nullable
+    public ComponentName getServiceSettingsActivityLocked() {
+        if (mInfo == null) return null;
+
+        final String activityName = mInfo.getSettingsActivity();
+        if (activityName == null) return null;
+
+        final String packageName = mInfo.getServiceInfo().packageName;
+        return new ComponentName(packageName, activityName);
+    }
+
     /**
      * Asserts the component is owned by the caller.
      */
@@ -430,8 +456,13 @@
     }
 
     @GuardedBy("mLock")
+    @Nullable
     ContentCaptureOptions getOptionsForPackageLocked(@NonNull String packageName) {
         if (!mWhitelistHelper.isWhitelisted(packageName)) {
+            if (packageName.equals(getServicePackageName())) {
+                if (mMaster.verbose) Slog.v(mTag, "getOptionsForPackage() lite for " + packageName);
+                return new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel);
+            }
             if (mMaster.verbose) {
                 Slog.v(mTag, "getOptionsForPackage(" + packageName + "): not whitelisted");
             }
@@ -440,6 +471,14 @@
 
         final ArraySet<ComponentName> whitelistedComponents = mWhitelistHelper
                 .getWhitelistedComponents(packageName);
+        if (Build.IS_USER && isTemporaryServiceSetLocked()) {
+            final String servicePackageName = getServicePackageName();
+            if (!packageName.equals(servicePackageName)) {
+                Slog.w(mTag, "Ignoring package " + packageName
+                        + " while using temporary service " + servicePackageName);
+                return null;
+            }
+        }
         ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel,
                 mMaster.mDevCfgMaxBufferSize, mMaster.mDevCfgIdleFlushingFrequencyMs,
                 mMaster.mDevCfgTextChangeFlushingFrequencyMs, mMaster.mDevCfgLogHistorySize,
@@ -518,12 +557,16 @@
         @Override
         public void setContentCaptureWhitelist(List<String> packages,
                 List<ComponentName> activities) {
+            // TODO(b/122595322): add CTS test for when it's null
             if (mMaster.verbose) {
-                Slog.v(TAG, "setContentCaptureWhitelist(packages=" + packages + ", activities="
-                        + activities + ")");
+                Slog.v(TAG, "setContentCaptureWhitelist(" + (packages == null
+                        ? "null_packages" : packages.size() + " packages")
+                        + ", " + (activities == null
+                        ? "null_activities" : activities.size() + " activities") + ")");
             }
-            setWhitelist(packages, activities);
-
+            synchronized (mLock) {
+                mWhitelistHelper.setWhitelist(packages, activities);
+            }
             // TODO(b/119613670): log metrics
         }
 
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
index da19836..9b2c05f 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
@@ -15,6 +15,12 @@
  */
 package com.android.server.contentcapture;
 
+import static android.service.contentcapture.ContentCaptureService.setClientState;
+import static android.view.contentcapture.ContentCaptureSession.STATE_ACTIVE;
+import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED;
+import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_RESURRECTED;
+import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_UPDATING;
+
 import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.os.IBinder;
@@ -23,7 +29,6 @@
 import android.util.LocalLog;
 import android.util.Slog;
 import android.view.contentcapture.ContentCaptureContext;
-import android.view.contentcapture.ContentCaptureSession;
 import android.view.contentcapture.ContentCaptureSessionId;
 
 import com.android.internal.annotations.GuardedBy;
@@ -38,7 +43,6 @@
 
     final IBinder mActivityToken;
     private final ContentCapturePerUserService mService;
-    private final RemoteContentCaptureService mRemoteService;
 
     // NOTE: this is the "internal" context (like package and taskId), not the explicit content
     // set by apps - those are only send to the ContentCaptureService.
@@ -61,15 +65,13 @@
     private final int mUid;
 
     ContentCaptureServerSession(@NonNull IBinder activityToken,
-            @NonNull ContentCapturePerUserService service,
-            @NonNull RemoteContentCaptureService remoteService,
-            @NonNull ComponentName appComponentName, @NonNull IResultReceiver sessionStateReceiver,
+            @NonNull ContentCapturePerUserService service, @NonNull ComponentName appComponentName,
+            @NonNull IResultReceiver sessionStateReceiver,
             int taskId, int displayId, @NonNull String sessionId, int uid, int flags) {
         mActivityToken = activityToken;
         mService = service;
         mId = Preconditions.checkNotNull(sessionId);
         mUid = uid;
-        mRemoteService = remoteService;
         mContentCaptureContext = new ContentCaptureContext(/* clientContext= */ null,
                 appComponentName, taskId, displayId, flags);
         mSessionStateReceiver = sessionStateReceiver;
@@ -87,8 +89,12 @@
      */
     @GuardedBy("mLock")
     public void notifySessionStartedLocked(@NonNull IResultReceiver clientReceiver) {
-        mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver,
-                ContentCaptureSession.STATE_ACTIVE);
+        if (mService.mRemoteService == null) {
+            Slog.w(TAG, "notifySessionStartedLocked(): no remote service");
+            return;
+        }
+        mService.mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver,
+                STATE_ACTIVE);
     }
 
     /**
@@ -101,7 +107,11 @@
             logHistory.log("snapshot: id=" + mId);
         }
 
-        mRemoteService.onActivitySnapshotRequest(mId, snapshotData);
+        if (mService.mRemoteService == null) {
+            Slog.w(TAG, "sendActivitySnapshotLocked(): no remote service");
+            return;
+        }
+        mService.mRemoteService.onActivitySnapshotRequest(mId, snapshotData);
     }
 
     /**
@@ -134,7 +144,11 @@
         }
         // TODO(b/111276913): must call client to set session as FINISHED_BY_SERVER
         if (notifyRemoteService) {
-            mRemoteService.onSessionFinished(mId);
+            if (mService.mRemoteService == null) {
+                Slog.w(TAG, "destroyLocked(): no remote service");
+                return;
+            }
+            mService.mRemoteService.onSessionFinished(mId);
         }
     }
 
@@ -143,10 +157,27 @@
      */
     @GuardedBy("mLock")
     public void resurrectLocked() {
-        mRemoteService.onSessionStarted(new ContentCaptureContext(mContentCaptureContext,
+        final RemoteContentCaptureService remoteService = mService.mRemoteService;
+        if (remoteService == null) {
+            Slog.w(TAG, "destroyLocked(: no remote service");
+            return;
+        }
+        if (mService.isVerbose()) {
+            Slog.v(TAG, "resurrecting " + mActivityToken + " on " + remoteService);
+        }
+        remoteService.onSessionStarted(new ContentCaptureContext(mContentCaptureContext,
                 ContentCaptureContext.FLAG_RECONNECTED), mId, mUid, mSessionStateReceiver,
-                ContentCaptureSession.STATE_ACTIVE
-                        | ContentCaptureSession.STATE_SERVICE_RESURRECTED);
+                STATE_ACTIVE | STATE_SERVICE_RESURRECTED);
+    }
+
+    /**
+     * Called to pause the session while the service is being updated.
+     */
+    @GuardedBy("mLock")
+    public void pauseLocked() {
+        if (mService.isVerbose()) Slog.v(TAG, "pausing " + mActivityToken);
+        setClientState(mSessionStateReceiver, STATE_DISABLED | STATE_SERVICE_UPDATING,
+                /* binder= */ null);
     }
 
     @GuardedBy("mLock")
diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
index 2ce5059..df9ccbc 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
@@ -54,7 +54,7 @@
         mIdleUnbindTimeoutMs = idleUnbindTimeoutMs;
 
         // Bind right away, which will trigger a onConnected() on service's
-        scheduleBind();
+        ensureBoundLocked();
     }
 
     @Override // from AbstractRemoteService
@@ -89,6 +89,10 @@
         }
     }
 
+    public void ensureBoundLocked() {
+        scheduleBind();
+    }
+
     /**
      * Called by {@link ContentCaptureServerSession} to generate a call to the
      * {@link RemoteContentCaptureService} to indicate the session was created.
diff --git a/services/core/java/com/android/server/DynamicAndroidService.java b/services/core/java/com/android/server/DynamicSystemService.java
similarity index 92%
rename from services/core/java/com/android/server/DynamicAndroidService.java
rename to services/core/java/com/android/server/DynamicSystemService.java
index b02bfb1..f5bd11c 100644
--- a/services/core/java/com/android/server/DynamicAndroidService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -22,25 +22,25 @@
 import android.gsi.IGsiService;
 import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
-import android.os.IDynamicAndroidService;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
+import android.os.image.IDynamicSystemService;
 import android.util.Slog;
 
 /**
- * DynamicAndroidService implements IDynamicAndroidService. It provides permission check before
+ * DynamicSystemService implements IDynamicSystemService. It provides permission check before
  * passing requests to gsid
  */
-public class DynamicAndroidService extends IDynamicAndroidService.Stub implements DeathRecipient {
-    private static final String TAG = "DynamicAndroidService";
+public class DynamicSystemService extends IDynamicSystemService.Stub implements DeathRecipient {
+    private static final String TAG = "DynamicSystemService";
     private static final String NO_SERVICE_ERROR = "no gsiservice";
     private static final int GSID_ROUGH_TIMEOUT_MS = 8192;
 
     private Context mContext;
     private volatile IGsiService mGsiService;
 
-    DynamicAndroidService(Context context) {
+    DynamicSystemService(Context context) {
         mContext = context;
     }
 
@@ -93,9 +93,9 @@
 
     private void checkPermission() {
         if (mContext.checkCallingOrSelfPermission(
-                        android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+                        android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
                 != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Requires MANAGE_DYNAMIC_ANDROID permission");
+            throw new SecurityException("Requires MANAGE_DYNAMIC_SYSTEM permission");
         }
     }
 
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index b89223b..f0244c3 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -3597,10 +3597,18 @@
                 pw.println("    " + provider + ": " + location);
             }
 
-            mGeofenceManager.dump(pw);
-
-            pw.append("  ");
-            mBlacklist.dump(pw);
+            if (mGeofenceManager != null) {
+                mGeofenceManager.dump(pw);
+            } else {
+                pw.println("  Geofences: null");
+            }
+          
+            if (mBlacklist != null) {
+                pw.append("  ");
+                mBlacklist.dump(pw);
+            } else {
+                pw.println("  mBlacklist=null");
+            }
 
             if (mLocationControllerExtraPackage != null) {
                 pw.println(" Location controller extra package: " + mLocationControllerExtraPackage
@@ -3614,8 +3622,12 @@
                 }
             }
 
-            pw.append("  fudger: ");
-            mLocationFudger.dump(fd, pw, args);
+            if (mLocationFudger != null) {
+                pw.append("  fudger: ");
+                mLocationFudger.dump(fd, pw, args);
+            } else {
+                pw.println("  fudger: null");
+            }
 
             if (args.length > 0 && "short".equals(args[0])) {
                 return;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 10b67c1..2e5dd3b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1257,6 +1257,7 @@
                 }
                 scheduleWriteLocked();
             }
+            uidState.evalForegroundOps(mOpModeWatchers);
         }
 
         String[] uidPackageNames = getPackagesForUid(uid);
@@ -2414,8 +2415,6 @@
     private void commitUidPendingStateLocked(UidState uidState) {
         final boolean lastForeground = uidState.state <= UID_STATE_MAX_LAST_NON_RESTRICTED;
         final boolean nowForeground = uidState.pendingState <= UID_STATE_MAX_LAST_NON_RESTRICTED;
-        uidState.state = uidState.pendingState;
-        uidState.pendingStateCommitTime = 0;
         if (uidState.hasForegroundWatchers && lastForeground != nowForeground) {
             for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) {
                 if (!uidState.foregroundOps.valueAt(fgi)) {
@@ -2424,11 +2423,10 @@
                 final int code = uidState.foregroundOps.keyAt(fgi);
                 // For location ops we consider fg state only if the fg service
                 // is of location type, for all other ops any fg service will do.
-                final long resolvedLastRestrictedUidState = resolveFirstUnrestrictedUidState(code);
-                final boolean resolvedLastFg = uidState.state <= resolvedLastRestrictedUidState;
-                final boolean resolvedNowBg = uidState.pendingState
-                        <= resolvedLastRestrictedUidState;
-                if (resolvedLastFg == resolvedNowBg) {
+                final long firstUnrestrictedUidState = resolveFirstUnrestrictedUidState(code);
+                final boolean resolvedLastFg = uidState.state <= firstUnrestrictedUidState;
+                final boolean resolvedNowFg = uidState.pendingState <= firstUnrestrictedUidState;
+                if (resolvedLastFg == resolvedNowFg) {
                     continue;
                 }
                 final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code);
@@ -2460,6 +2458,8 @@
                 }
             }
         }
+        uidState.state = uidState.pendingState;
+        uidState.pendingStateCommitTime = 0;
     }
 
     private Ops getOpsRawLocked(int uid, String packageName, boolean edit,
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index 3e48445..c60dd6c 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -1251,8 +1251,6 @@
         if (getCurrentClient() instanceof InternalRemovalClient
                 || getCurrentClient() instanceof InternalEnumerateClient) {
             Slog.w(getTag(), "User switched while performing cleanup");
-            removeClient(getCurrentClient());
-            clearEnumerateState();
         }
         updateActiveGroup(userId, null);
         doTemplateCleanupForUser(userId);
diff --git a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
index 4289a25..54a4ad4 100644
--- a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.broadcastradio;
 
-import android.annotation.NonNull;
 import android.Manifest;
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -26,14 +25,13 @@
 import android.hardware.radio.ITuner;
 import android.hardware.radio.ITunerCallback;
 import android.hardware.radio.RadioManager;
-import android.os.ParcelableException;
 import android.os.RemoteException;
 import android.util.Slog;
 
-import com.android.internal.util.Preconditions;
 import com.android.server.SystemService;
 import com.android.server.broadcastradio.hal2.AnnouncementAggregator;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -45,16 +43,20 @@
 
     private final ServiceImpl mServiceImpl = new ServiceImpl();
 
-    private final com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1 =
-            new com.android.server.broadcastradio.hal1.BroadcastRadioService();
-    private final com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2 =
-            new com.android.server.broadcastradio.hal2.BroadcastRadioService();
+    private final com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1;
+    private final com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2;
 
     private final Object mLock = new Object();
-    private List<RadioManager.ModuleProperties> mModules = null;
+    private List<RadioManager.ModuleProperties> mV1Modules = null;
 
     public BroadcastRadioService(Context context) {
         super(context);
+
+        mHal1 = new com.android.server.broadcastradio.hal1.BroadcastRadioService();
+        mV1Modules = mHal1.loadModules();
+        OptionalInt max = mV1Modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max();
+        mHal2 = new com.android.server.broadcastradio.hal2.BroadcastRadioService(
+                max.isPresent() ? max.getAsInt() + 1 : 0);
     }
 
     @Override
@@ -62,14 +64,6 @@
         publishBinderService(Context.RADIO_SERVICE, mServiceImpl);
     }
 
-    /**
-     * Finds next available index for newly loaded modules.
-     */
-    private static int getNextId(@NonNull List<RadioManager.ModuleProperties> modules) {
-        OptionalInt max = modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max();
-        return max.isPresent() ? max.getAsInt() + 1 : 0;
-    }
-
     private class ServiceImpl extends IRadioService.Stub {
         private void enforcePolicyAccess() {
             if (PackageManager.PERMISSION_GRANTED != getContext().checkCallingPermission(
@@ -81,14 +75,10 @@
         @Override
         public List<RadioManager.ModuleProperties> listModules() {
             enforcePolicyAccess();
-            synchronized (mLock) {
-                if (mModules != null) return mModules;
-
-                mModules = mHal1.loadModules();
-                mModules.addAll(mHal2.loadModules(getNextId(mModules)));
-
-                return mModules;
-            }
+            List<RadioManager.ModuleProperties> modules = new ArrayList<>();
+            modules.addAll(mV1Modules);
+            modules.addAll(mHal2.listModules());
+            return modules;
         }
 
         @Override
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
index 954c001..b8810c8f 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
@@ -18,20 +18,22 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.hardware.broadcastradio.V2_0.IBroadcastRadio;
 import android.hardware.radio.IAnnouncementListener;
 import android.hardware.radio.ICloseHandle;
 import android.hardware.radio.ITuner;
 import android.hardware.radio.ITunerCallback;
 import android.hardware.radio.RadioManager;
-import android.hardware.broadcastradio.V2_0.IBroadcastRadio;
 import android.hidl.manager.V1_0.IServiceManager;
+import android.hidl.manager.V1_0.IServiceNotification;
+import android.os.IHwBinder.DeathRecipient;
 import android.os.RemoteException;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
+
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -39,52 +41,104 @@
 public class BroadcastRadioService {
     private static final String TAG = "BcRadio2Srv";
 
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private int mNextModuleId = 0;
+
+    @GuardedBy("mLock")
+    private final Map<String, Integer> mServiceNameToModuleIdMap = new HashMap<>();
+
+    @GuardedBy("mLock")
     private final Map<Integer, RadioModule> mModules = new HashMap<>();
 
-    private static @NonNull List<String> listByInterface(@NonNull String fqName) {
+    private IServiceNotification.Stub mServiceListener = new IServiceNotification.Stub() {
+        @Override
+        public void onRegistration(String fqName, String serviceName, boolean preexisting) {
+            Slog.v(TAG, "onRegistration(" + fqName + ", " + serviceName + ", " + preexisting + ")");
+            Integer moduleId;
+            synchronized (mLock) {
+                // If the service has been registered before, reuse its previous module ID.
+                moduleId = mServiceNameToModuleIdMap.get(serviceName);
+                boolean newService = false;
+                if (moduleId == null) {
+                    newService = true;
+                    moduleId = mNextModuleId;
+                }
+
+                RadioModule module = RadioModule.tryLoadingModule(moduleId, serviceName);
+                if (module == null) {
+                    return;
+                }
+                Slog.v(TAG, "loaded broadcast radio module " + moduleId + ": " + serviceName
+                        + " (HAL 2.0)");
+                mModules.put(moduleId, module);
+
+                if (newService) {
+                    mServiceNameToModuleIdMap.put(serviceName, moduleId);
+                    mNextModuleId++;
+                }
+
+                try {
+                    module.getService().linkToDeath(mDeathRecipient, moduleId);
+                } catch (RemoteException ex) {
+                    // Service has already died, so remove its entry from mModules.
+                    mModules.remove(moduleId);
+                }
+            }
+        }
+    };
+
+    private DeathRecipient mDeathRecipient = new DeathRecipient() {
+        @Override
+        public void serviceDied(long cookie) {
+            Slog.v(TAG, "serviceDied(" + cookie + ")");
+            synchronized (mLock) {
+                int moduleId = (int) cookie;
+                mModules.remove(moduleId);
+
+                for (Map.Entry<String, Integer> entry : mServiceNameToModuleIdMap.entrySet()) {
+                    if (entry.getValue() == moduleId) {
+                        Slog.i(TAG, "service " + entry.getKey()
+                                + " died; removed RadioModule with ID " + moduleId);
+                        return;
+                    }
+                }
+            }
+        }
+    };
+
+    public BroadcastRadioService(int nextModuleId) {
+        mNextModuleId = nextModuleId;
         try {
             IServiceManager manager = IServiceManager.getService();
             if (manager == null) {
-                Slog.e(TAG, "Failed to get HIDL Service Manager");
-                return Collections.emptyList();
+                Slog.e(TAG, "failed to get HIDL Service Manager");
+                return;
             }
-
-            List<String> list = manager.listByInterface(fqName);
-            if (list == null) {
-                Slog.e(TAG, "Didn't get interface list from HIDL Service Manager");
-                return Collections.emptyList();
-            }
-            return list;
+            manager.registerForNotifications(IBroadcastRadio.kInterfaceName, "", mServiceListener);
         } catch (RemoteException ex) {
-            Slog.e(TAG, "Failed fetching interface list", ex);
-            return Collections.emptyList();
+            Slog.e(TAG, "failed to register for service notifications: ", ex);
         }
     }
 
-    public @NonNull Collection<RadioManager.ModuleProperties> loadModules(int idx) {
-        Slog.v(TAG, "loadModules(" + idx + ")");
-
-        for (String serviceName : listByInterface(IBroadcastRadio.kInterfaceName)) {
-            Slog.v(TAG, "checking service: " + serviceName);
-
-            RadioModule module = RadioModule.tryLoadingModule(idx, serviceName);
-            if (module != null) {
-                Slog.i(TAG, "loaded broadcast radio module " + idx + ": " +
-                        serviceName + " (HAL 2.0)");
-                mModules.put(idx++, module);
-            }
+    public @NonNull Collection<RadioManager.ModuleProperties> listModules() {
+        synchronized (mLock) {
+            return mModules.values().stream().map(module -> module.mProperties)
+                    .collect(Collectors.toList());
         }
-
-        return mModules.values().stream().map(module -> module.mProperties).
-                collect(Collectors.toList());
     }
 
     public boolean hasModule(int id) {
-        return mModules.containsKey(id);
+        synchronized (mLock) {
+            return mModules.containsKey(id);
+        }
     }
 
     public boolean hasAnyModules() {
-        return !mModules.isEmpty();
+        synchronized (mLock) {
+            return !mModules.isEmpty();
+        }
     }
 
     public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig,
@@ -95,7 +149,10 @@
             throw new IllegalArgumentException("Non-audio sessions not supported with HAL 2.x");
         }
 
-        RadioModule module = mModules.get(moduleId);
+        RadioModule module = null;
+        synchronized (mLock) {
+            module = mModules.get(moduleId);
+        }
         if (module == null) {
             throw new IllegalArgumentException("Invalid module ID");
         }
@@ -111,12 +168,14 @@
             @NonNull IAnnouncementListener listener) {
         AnnouncementAggregator aggregator = new AnnouncementAggregator(listener);
         boolean anySupported = false;
-        for (RadioModule module : mModules.values()) {
-            try {
-                aggregator.watchModule(module, enabledTypes);
-                anySupported = true;
-            } catch (UnsupportedOperationException ex) {
-                Slog.v(TAG, "Announcements not supported for this module", ex);
+        synchronized (mLock) {
+            for (RadioModule module : mModules.values()) {
+                try {
+                    aggregator.watchModule(module, enabledTypes);
+                    anySupported = true;
+                } catch (UnsupportedOperationException ex) {
+                    Slog.v(TAG, "Announcements not supported for this module", ex);
+                }
             }
         }
         if (!anySupported) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index 816ba0b..832f8e1 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -20,8 +20,6 @@
 import android.annotation.Nullable;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.hardware.radio.ITuner;
-import android.hardware.radio.RadioManager;
 import android.hardware.broadcastradio.V2_0.AmFmRegionConfig;
 import android.hardware.broadcastradio.V2_0.Announcement;
 import android.hardware.broadcastradio.V2_0.DabTableEntry;
@@ -30,13 +28,12 @@
 import android.hardware.broadcastradio.V2_0.ICloseHandle;
 import android.hardware.broadcastradio.V2_0.ITunerSession;
 import android.hardware.broadcastradio.V2_0.Result;
-import android.os.ParcelableException;
+import android.hardware.radio.RadioManager;
 import android.os.RemoteException;
 import android.util.MutableInt;
 import android.util.Slog;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -78,6 +75,10 @@
         }
     }
 
+    public @NonNull IBroadcastRadio getService() {
+        return mService;
+    }
+
     public @NonNull TunerSession openSession(@NonNull android.hardware.radio.ITunerCallback userCb)
             throws RemoteException {
         TunerCallback cb = new TunerCallback(Objects.requireNonNull(userCb));
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 32f34b8..3010324 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -37,7 +37,6 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.ColorSpace;
-import android.graphics.GraphicBuffer;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.hardware.SensorManager;
@@ -1275,11 +1274,12 @@
         if (token == null) {
             return false;
         }
-        final GraphicBuffer gb = SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
-                token, new Rect(), 0 /* width */, 0 /* height */, false /* useIdentityTransform */,
-                0 /* rotation */);
+        final SurfaceControl.ScreenshotGraphicBuffer gb =
+                SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
+                        token, new Rect(), 0 /* width */, 0 /* height */,
+                        false /* useIdentityTransform */, 0 /* rotation */);
         try {
-            outSurface.attachAndQueueBuffer(gb);
+            outSurface.attachAndQueueBuffer(gb.getGraphicBuffer());
         } catch (RuntimeException e) {
             Slog.w(TAG, "Failed to take screenshot - " + e.getMessage());
         }
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 430203d..ed894ee 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -131,14 +131,10 @@
     private final boolean mRefreshServiceOnPackageUpdate;
 
     /**
-     * Name of the service's package that was active but then was removed because its package
-     * update.
-     *
-     * <p>It's a temporary state set / used by the {@link PackageMonitor} implementation, but
-     * defined here so it can be dumped.
+     * Name of the service packages whose APK are being updated, keyed by user id.
      */
     @GuardedBy("mLock")
-    private String mLastActivePackageName;
+    private SparseArray<String> mUpdatingPackageNames;
 
     /**
      * Default constructor.
@@ -565,6 +561,20 @@
     }
 
     /**
+     * Called before the package that provides the service for the given user is being updated.
+     */
+    protected void onServicePackageUpdatingLocked(@UserIdInt int userId) {
+        if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")");
+    }
+
+    /**
+     * Called after the package that provides the service for the given user is being updated.
+     */
+    protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+        if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")");
+    }
+
+    /**
      * Called after the service is removed from the cache.
      */
     @SuppressWarnings("unused")
@@ -602,8 +612,10 @@
             final int size = mServicesCache.size();
             pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
             pw.print(" Verbose: "); pw.println(realVerbose);
-            pw.print(" Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate);
-            pw.print(" Last active service on update: "); pw.println(mLastActivePackageName);
+            pw.print("Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate);
+            if (mUpdatingPackageNames != null) {
+                pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
+            }
             if (mServiceNameResolver != null) {
                 pw.print(prefix); pw.print("Name resolver: ");
                 mServiceNameResolver.dumpShort(pw); pw.println();
@@ -644,39 +656,49 @@
         final PackageMonitor monitor = new PackageMonitor() {
 
             @Override
-            public void onPackageUpdateStarted(String packageName, int uid) {
+            public void onPackageUpdateStarted(@NonNull String packageName, int uid) {
+                if (verbose) Slog.v(mTag, "onPackageUpdateStarted(): " + packageName);
+                final String activePackageName = getActiveServicePackageNameLocked();
+                if (!packageName.equals(activePackageName)) return;
+
+                final int userId = getChangingUserId();
                 synchronized (mLock) {
-                    final String activePackageName = getActiveServicePackageNameLocked();
-                    if (packageName.equals(activePackageName)) {
-                        final int userId = getChangingUserId();
-                        if (mRefreshServiceOnPackageUpdate) {
-                            if (debug) {
-                                Slog.d(mTag, "Removing service for user " + userId
-                                        + " because package " + activePackageName
-                                        + " is being updated");
-                            }
-                            mLastActivePackageName = activePackageName;
-                            removeCachedServiceLocked(userId);
-                        } else {
-                            if (debug) {
-                                Slog.d(mTag, "Holding service for user " + userId
-                                        + " while package " + activePackageName
-                                        + " is being updated");
-                            }
+                    if (mUpdatingPackageNames == null) {
+                        mUpdatingPackageNames = new SparseArray<String>(mServicesCache.size());
+                    }
+                    mUpdatingPackageNames.put(userId, packageName);
+                    onServicePackageUpdatingLocked(userId);
+                    if (mRefreshServiceOnPackageUpdate) {
+                        if (debug) {
+                            Slog.d(mTag, "Removing service for user " + userId + " because package "
+                                    + activePackageName + " is being updated");
+                        }
+                        removeCachedServiceLocked(userId);
+                    } else {
+                        if (debug) {
+                            Slog.d(mTag, "Holding service for user " + userId + " while package "
+                                    + activePackageName + " is being updated");
                         }
                     }
                 }
             }
 
             @Override
-            public void onPackageUpdateFinished(String packageName, int uid) {
+            public void onPackageUpdateFinished(@NonNull String packageName, int uid) {
+                if (verbose) Slog.v(mTag, "onPackageUpdateFinished(): " + packageName);
+                final int userId = getChangingUserId();
                 synchronized (mLock) {
-                    String activePackageName = getActiveServicePackageNameLocked();
-                    if (activePackageName == null) {
-                        activePackageName = mLastActivePackageName;
-                        mLastActivePackageName = null;
-                    }
-                    if (!packageName.equals(activePackageName)) {
+                    final String activePackageName = mUpdatingPackageNames == null ? null
+                            : mUpdatingPackageNames.get(userId);
+                    if (packageName.equals(activePackageName)) {
+                        if (mUpdatingPackageNames != null) {
+                            mUpdatingPackageNames.remove(userId);
+                            if (mUpdatingPackageNames.size() == 0) {
+                                mUpdatingPackageNames = null;
+                            }
+                        }
+                        onServicePackageUpdatedLocked(userId);
+                    } else {
                         handlePackageUpdateLocked(packageName);
                     }
                 }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 0c5fb79..3e134b2 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -323,8 +323,8 @@
             }
             Arrays.fill(newPasswordChars, '\u0000');
             final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
-            setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD,
-                    managedUserPassword, quality, managedUserId);
+            setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD, managedUserPassword,
+                    quality, managedUserId, false);
             // We store a private credential for the managed user that's unlocked by the primary
             // account holder's credential. As such, the user will never be prompted to enter this
             // password directly, so we always store a password.
@@ -1302,12 +1302,14 @@
                     if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
                         setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE,
                                 profilePasswordMap.get(managedUserId),
-                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
+                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId,
+                                false);
                     } else {
                         Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
                         // Supplying null here would lead to untrusted credential change
                         setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, null,
-                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
+                                DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId,
+                                true);
                     }
                     mStorage.removeChildProfileLock(managedUserId);
                     removeKeystoreProfileKey(managedUserId);
@@ -1330,8 +1332,8 @@
     // should call setLockCredentialInternal.
     @Override
     public void setLockCredential(byte[] credential, int type,
-            byte[] savedCredential, int requestedQuality, int userId)
-            throws RemoteException {
+            byte[] savedCredential, int requestedQuality, int userId,
+            boolean allowUntrustedChange) throws RemoteException {
 
         if (!mLockPatternUtils.hasSecureLockScreen()) {
             throw new UnsupportedOperationException(
@@ -1339,7 +1341,8 @@
         }
         checkWritePermission(userId);
         synchronized (mSeparateChallengeLock) {
-            setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId);
+            setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId,
+                    allowUntrustedChange);
             setSeparateProfileChallengeEnabledLocked(userId, true, null);
             notifyPasswordChanged(userId);
         }
@@ -1347,7 +1350,8 @@
     }
 
     private void setLockCredentialInternal(byte[] credential, @CredentialType int credentialType,
-            byte[] savedCredential, int requestedQuality, int userId) throws RemoteException {
+            byte[] savedCredential, int requestedQuality, int userId,
+            boolean allowUntrustedChange) throws RemoteException {
         // Normalize savedCredential and credential such that empty string is always represented
         // as null.
         if (savedCredential == null || savedCredential.length == 0) {
@@ -1359,7 +1363,7 @@
         synchronized (mSpManager) {
             if (isSyntheticPasswordBasedCredentialLocked(userId)) {
                 spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        requestedQuality, userId);
+                        requestedQuality, userId, allowUntrustedChange);
                 return;
             }
         }
@@ -1410,7 +1414,7 @@
                 initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
                         currentHandle.type, requestedQuality, userId);
                 spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
-                        requestedQuality, userId);
+                        requestedQuality, userId, allowUntrustedChange);
                 return;
             }
         }
@@ -1705,7 +1709,7 @@
             mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
             if (shouldReEnrollBaseZero) {
                 setLockCredentialInternal(credential, storedHash.type, credentialToVerify,
-                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
+                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId, false);
             }
         }
 
@@ -1796,7 +1800,7 @@
                         storedHash.type == CREDENTIAL_TYPE_PATTERN
                                 ? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
                                 : DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
-                                /* TODO(roosa): keep the same password quality */, userId);
+                                /* TODO(roosa): keep the same password quality */, userId, false);
                 if (!hasChallenge) {
                     notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId);
                     // Use credentials to create recoverable keystore snapshot.
@@ -1841,7 +1845,7 @@
                     /* TODO(roosa): keep the same password quality */;
             if (shouldReEnroll) {
                 setLockCredentialInternal(credential, storedHash.type, credential,
-                        reEnrollQuality, userId);
+                        reEnrollQuality, userId, false);
             } else {
                 // Now that we've cleared of all required GK migration, let's do the final
                 // migration to synthetic password.
@@ -2544,7 +2548,8 @@
 
     @GuardedBy("mSpManager")
     private void spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType,
-            byte[] savedCredential, int requestedQuality, int userId) throws RemoteException {
+            byte[] savedCredential, int requestedQuality, int userId,
+            boolean allowUntrustedChange) throws RemoteException {
         if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
         if (isManagedProfileWithUnifiedLock(userId)) {
             // get credential from keystore when managed profile has unified lock
@@ -2565,27 +2570,31 @@
         VerifyCredentialResponse response = authResult.gkResponse;
         AuthenticationToken auth = authResult.authToken;
 
-        // If existing credential is provided, then it must match.
+        // If existing credential is provided, the existing credential must match.
         if (savedCredential != null && auth == null) {
-            throw new RemoteException("Failed to enroll " +
-                    (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern"));
+            throw new IllegalStateException("Failed to enroll "
+                    + (credentialType == CREDENTIAL_TYPE_PASSWORD
+                    ? "password" : "pattern"));
         }
-
         boolean untrustedReset = false;
         if (auth != null) {
             onAuthTokenKnownForUser(userId, auth);
-        } else if (response != null
-                && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) {
+        } else if (response == null) {
+            throw new IllegalStateException("Password change failed.");
+        } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) {
             // We are performing an untrusted credential change, by DevicePolicyManager or other
             // internal callers that don't provide the existing credential
             Slog.w(TAG, "Untrusted credential change invoked");
             // Try to get a cached auth token, so we can keep SP unchanged.
             auth = mSpCache.get(userId);
+            if (!allowUntrustedChange) {
+                throw new IllegalStateException("Untrusted credential change was invoked but it was"
+                        + " not allowed. This is likely a bug. Auth token is null: "
+                        + Boolean.toString(auth == null));
+            }
             untrustedReset = true;
-        } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
-            Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " +
-                    (response != null ? "rate limit exceeded" : "failed"));
-            return;
+        } else /* responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
+            throw new IllegalStateException("Rate limit exceeded, so password was not changed.");
         }
 
         if (auth != null) {
diff --git a/services/core/java/com/android/server/media/projection/OWNERS b/services/core/java/com/android/server/media/projection/OWNERS
new file mode 100644
index 0000000..7e7335d
--- /dev/null
+++ b/services/core/java/com/android/server/media/projection/OWNERS
@@ -0,0 +1 @@
+michaelwr@google.com
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ca3c826..e43fc1f 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4106,9 +4106,11 @@
         if (r == null) {
             return;
         }
-        if (adjustment.getSignals() != null) {
-            Bundle.setDefusable(adjustment.getSignals(), true);
-            r.addAdjustment(adjustment);
+        if (mAssistants.isAdjustmentAllowed(adjustment.getKey())) {
+            if (adjustment.getSignals() != null) {
+                Bundle.setDefusable(adjustment.getSignals(), true);
+                r.addAdjustment(adjustment);
+            }
         }
     }
 
@@ -7313,6 +7315,12 @@
             }
         }
 
+        protected boolean isAdjustmentAllowed(String type) {
+            synchronized (mLock) {
+                return mAllowedAdjustments.contains(type);
+            }
+        }
+
         protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) {
             // There should be only one, but it's a list, so while we enforce
             // singularity elsewhere, we keep it general here, to avoid surprises.
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index b0d2704..15ed063 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -83,6 +83,9 @@
         if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) {
             return true;
         }
+        if (!Objects.equals(theTruth.targetOverlayableName, oldSettings.targetOverlayableName)) {
+            return true;
+        }
         if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) {
             return true;
         }
@@ -149,6 +152,7 @@
 
                 mSettings.init(overlayPackage.packageName, newUserId,
                         overlayPackage.overlayTarget,
+                        overlayPackage.targetOverlayableName,
                         overlayPackage.applicationInfo.getBaseCodePath(),
                         overlayPackage.isStaticOverlayPackage(),
                         overlayPackage.overlayPriority,
@@ -331,6 +335,7 @@
         }
 
         mSettings.init(packageName, userId, overlayPackage.overlayTarget,
+                overlayPackage.targetOverlayableName,
                 overlayPackage.applicationInfo.getBaseCodePath(),
                 overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
                 overlayPackage.overlayCategory);
@@ -395,7 +400,7 @@
                 if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) {
                     mListener.onOverlaysChanged(pkg.overlayTarget, userId);
                 }
-                mSettings.init(packageName, userId, pkg.overlayTarget,
+                mSettings.init(packageName, userId, pkg.overlayTarget, pkg.targetOverlayableName,
                         pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
                         pkg.overlayPriority, pkg.overlayCategory);
             }
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index 2b4ec03..667dfa1 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -65,12 +65,13 @@
     private final ArrayList<SettingsItem> mItems = new ArrayList<>();
 
     void init(@NonNull final String packageName, final int userId,
-            @NonNull final String targetPackageName, @NonNull final String baseCodePath,
-            boolean isStatic, int priority, String overlayCategory) {
+            @NonNull final String targetPackageName,  @Nullable final String targetOverlayableName,
+            @NonNull final String baseCodePath, boolean isStatic, int priority,
+            @Nullable String overlayCategory) {
         remove(packageName, userId);
         final SettingsItem item =
-                new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
-                        isStatic, priority, overlayCategory);
+                new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
+                        baseCodePath, isStatic, priority, overlayCategory);
         if (isStatic) {
             // All static overlays are always enabled.
             item.setEnabled(true);
@@ -302,16 +303,17 @@
             pw.println(item.mPackageName + ":" + item.getUserId() + " {");
             pw.increaseIndent();
 
-            pw.println("mPackageName.......: " + item.mPackageName);
-            pw.println("mUserId............: " + item.getUserId());
-            pw.println("mTargetPackageName.: " + item.getTargetPackageName());
-            pw.println("mBaseCodePath......: " + item.getBaseCodePath());
-            pw.println("mState.............: " + OverlayInfo.stateToString(item.getState()));
-            pw.println("mState.............: " + OverlayInfo.stateToString(item.getState()));
-            pw.println("mIsEnabled.........: " + item.isEnabled());
-            pw.println("mIsStatic..........: " + item.isStatic());
-            pw.println("mPriority..........: " + item.mPriority);
-            pw.println("mCategory..........: " + item.mCategory);
+            pw.println("mPackageName...........: " + item.mPackageName);
+            pw.println("mUserId................: " + item.getUserId());
+            pw.println("mTargetPackageName.....: " + item.getTargetPackageName());
+            pw.println("mTargetOverlayableName.: " + item.getTargetOverlayableName());
+            pw.println("mBaseCodePath..........: " + item.getBaseCodePath());
+            pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
+            pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
+            pw.println("mIsEnabled.............: " + item.isEnabled());
+            pw.println("mIsStatic..............: " + item.isStatic());
+            pw.println("mPriority..............: " + item.mPriority);
+            pw.println("mCategory..............: " + item.mCategory);
 
             pw.decreaseIndent();
             pw.println("}");
@@ -335,6 +337,7 @@
         private static final String ATTR_PACKAGE_NAME = "packageName";
         private static final String ATTR_STATE = "state";
         private static final String ATTR_TARGET_PACKAGE_NAME = "targetPackageName";
+        private static final String ATTR_TARGET_OVERLAYABLE_NAME = "targetOverlayableName";
         private static final String ATTR_IS_STATIC = "isStatic";
         private static final String ATTR_PRIORITY = "priority";
         private static final String ATTR_CATEGORY = "category";
@@ -387,6 +390,8 @@
             final int userId = XmlUtils.readIntAttribute(parser, ATTR_USER_ID);
             final String targetPackageName = XmlUtils.readStringAttribute(parser,
                     ATTR_TARGET_PACKAGE_NAME);
+            final String targetOverlayableName = XmlUtils.readStringAttribute(parser,
+                    ATTR_TARGET_OVERLAYABLE_NAME);
             final String baseCodePath = XmlUtils.readStringAttribute(parser, ATTR_BASE_CODE_PATH);
             final int state = XmlUtils.readIntAttribute(parser, ATTR_STATE);
             final boolean isEnabled = XmlUtils.readBooleanAttribute(parser, ATTR_IS_ENABLED);
@@ -394,8 +399,8 @@
             final int priority = XmlUtils.readIntAttribute(parser, ATTR_PRIORITY);
             final String category = XmlUtils.readStringAttribute(parser, ATTR_CATEGORY);
 
-            return new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
-                    state, isEnabled, isStatic, priority, category);
+            return new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
+                    baseCodePath, state, isEnabled, isStatic, priority, category);
         }
 
         public static void persist(@NonNull final ArrayList<SettingsItem> table,
@@ -422,6 +427,8 @@
             XmlUtils.writeStringAttribute(xml, ATTR_PACKAGE_NAME, item.mPackageName);
             XmlUtils.writeIntAttribute(xml, ATTR_USER_ID, item.mUserId);
             XmlUtils.writeStringAttribute(xml, ATTR_TARGET_PACKAGE_NAME, item.mTargetPackageName);
+            XmlUtils.writeStringAttribute(xml, ATTR_TARGET_OVERLAYABLE_NAME,
+                    item.mTargetOverlayableName);
             XmlUtils.writeStringAttribute(xml, ATTR_BASE_CODE_PATH, item.mBaseCodePath);
             XmlUtils.writeIntAttribute(xml, ATTR_STATE, item.mState);
             XmlUtils.writeBooleanAttribute(xml, ATTR_IS_ENABLED, item.mIsEnabled);
@@ -436,6 +443,7 @@
         private final int mUserId;
         private final String mPackageName;
         private final String mTargetPackageName;
+        private final String mTargetOverlayableName;
         private String mBaseCodePath;
         private @OverlayInfo.State int mState;
         private boolean mIsEnabled;
@@ -445,12 +453,14 @@
         private String mCategory;
 
         SettingsItem(@NonNull final String packageName, final int userId,
-                @NonNull final String targetPackageName, @NonNull final String baseCodePath,
+                @NonNull final String targetPackageName,
+                @Nullable final String targetOverlayableName, @NonNull final String baseCodePath,
                 final @OverlayInfo.State int state, final boolean isEnabled, final boolean isStatic,
-                final int priority, String category) {
+                final int priority,  @Nullable String category) {
             mPackageName = packageName;
             mUserId = userId;
             mTargetPackageName = targetPackageName;
+            mTargetOverlayableName = targetOverlayableName;
             mBaseCodePath = baseCodePath;
             mState = state;
             mIsEnabled = isEnabled || isStatic;
@@ -461,16 +471,21 @@
         }
 
         SettingsItem(@NonNull final String packageName, final int userId,
-                @NonNull final String targetPackageName, @NonNull final String baseCodePath,
-                final boolean isStatic, final int priority, String category) {
-            this(packageName, userId, targetPackageName, baseCodePath, OverlayInfo.STATE_UNKNOWN,
-                    false, isStatic, priority, category);
+                @NonNull final String targetPackageName,
+                @Nullable final String targetOverlayableName, @NonNull final String baseCodePath,
+                final boolean isStatic, final int priority, @Nullable String category) {
+            this(packageName, userId, targetPackageName, targetOverlayableName, baseCodePath,
+                    OverlayInfo.STATE_UNKNOWN, false, isStatic, priority, category);
         }
 
         private String getTargetPackageName() {
             return mTargetPackageName;
         }
 
+        private String getTargetOverlayableName() {
+            return mTargetOverlayableName;
+        }
+
         private int getUserId() {
             return mUserId;
         }
@@ -520,7 +535,7 @@
 
         private boolean setCategory(String category) {
             if (!Objects.equals(mCategory, category)) {
-                mCategory = category.intern();
+                mCategory = (category == null) ? null : category.intern();
                 invalidateCache();
                 return true;
             }
@@ -529,8 +544,8 @@
 
         private OverlayInfo getOverlayInfo() {
             if (mCache == null) {
-                mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath,
-                        mState, mUserId, mPriority, mIsStatic);
+                mCache = new OverlayInfo(mPackageName, mTargetPackageName, mTargetOverlayableName,
+                        mCategory, mBaseCodePath, mState, mUserId, mPriority, mIsStatic);
             }
             return mCache;
         }
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index e36ac23..40f2a2b 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1552,13 +1552,13 @@
                     oldPermAreModernStorageModel = false;
                 }
 
-                boolean shouldBeRestricted;
+                boolean shouldBeHidden;
                 boolean shouldBeFixed;
                 boolean shouldBeGranted = false;
                 boolean shouldBeRevoked = false;
                 int userFlags = -1;
                 if (useLegacyStoragePermissionModel) {
-                    shouldBeRestricted = isModernStoragePermission;
+                    shouldBeHidden = isModernStoragePermission;
                     shouldBeFixed = isQApp || isModernStoragePermission;
 
                     if (shouldBeFixed) {
@@ -1576,7 +1576,7 @@
                         shouldBeRevoked = !shouldBeGranted;
                     }
                 } else {
-                    shouldBeRestricted = isLegacyStoragePermission;
+                    shouldBeHidden = isLegacyStoragePermission;
                     shouldBeFixed = isLegacyStoragePermission;
 
                     if (shouldBeFixed) {
@@ -1636,7 +1636,12 @@
 
                     changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), userId,
                             FLAG_PERMISSION_HIDDEN,
-                            shouldBeRestricted ? FLAG_PERMISSION_HIDDEN : 0);
+                            shouldBeHidden ? FLAG_PERMISSION_HIDDEN : 0);
+
+                    if (shouldBeHidden) {
+                        changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm),
+                                userId, FLAG_PERMISSION_REVIEW_REQUIRED, 0);
+                    }
                 }
 
                 if (changed) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5a32aa0..55af357 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5126,7 +5126,7 @@
 
         // Start home.
         mActivityTaskManagerInternal.startHomeOnDisplay(mCurrentUserId, "startDockOrHome",
-                displayId, fromHomeKey);
+                displayId, true /* allowInstrumenting */, fromHomeKey);
     }
 
     /**
@@ -5214,13 +5214,15 @@
     private VibrationEffect getVibrationEffect(int effectId) {
         long[] pattern;
         switch (effectId) {
-            case HapticFeedbackConstants.CLOCK_TICK:
             case HapticFeedbackConstants.CONTEXT_CLICK:
                 return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
             case HapticFeedbackConstants.TEXT_HANDLE_MOVE:
                 if (!mHapticTextHandleEnabled) {
                     return null;
                 }
+                // fallthrough
+            case HapticFeedbackConstants.CLOCK_TICK:
+                return VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK);
             case HapticFeedbackConstants.KEYBOARD_RELEASE:
             case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE:
             case HapticFeedbackConstants.ENTRY_BUMP:
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 9b427f5..cfe11bf 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -4489,8 +4489,7 @@
         }
 
         @Override // Binder call
-        public boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled,
-                int disableThreshold) {
+        public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) {
             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER,
                     "updateDynamicPowerSavings");
             final long ident = Binder.clearCallingIdentity();
@@ -4503,7 +4502,7 @@
                     // abort updating if we weren't able to succeed on the threshold
                     success &= Settings.Global.putInt(resolver,
                             Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED,
-                            dynamicPowerSavingsEnabled ? 1 : 0);
+                            powerSaveHint ? 1 : 0);
                 }
                 return success;
             } finally {
@@ -4542,13 +4541,13 @@
         }
 
         @Override // Binder call
-        public int getPowerSaveMode() {
+        public int getPowerSaveModeTrigger() {
             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER, null);
             final long ident = Binder.clearCallingIdentity();
             try {
                 return Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
-                        PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+                        Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
+                        PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index 61daca7..fe0b9a6 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -45,6 +45,7 @@
 import com.android.server.power.BatterySaverStateMachineProto;
 
 import java.io.PrintWriter;
+import java.text.NumberFormat;
 
 /**
  * Decides when to enable / disable battery saver.
@@ -188,7 +189,7 @@
     @GuardedBy("mLock")
     private int mSettingBatterySaverTriggerThreshold;
 
-    /** Previously known value of Settings.Global.AUTOMATIC_POWER_SAVER_MODE. */
+    /** Previously known value of Settings.Global.AUTOMATIC_POWER_SAVE_MODE. */
     @GuardedBy("mLock")
     private int mSettingAutomaticBatterySaver;
 
@@ -248,7 +249,7 @@
 
     /** @return true if the automatic percentage based mode should be used */
     private boolean isAutomaticModeActiveLocked() {
-        return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_PERCENTAGE
+        return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE
                 && mSettingBatterySaverTriggerThreshold > 0;
     }
 
@@ -264,7 +265,7 @@
 
     /** @return true if the dynamic mode should be used */
     private boolean isDynamicModeActiveLocked() {
-        return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_DYNAMIC
+        return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC
                 && mDynamicPowerSavingsBatterySaver;
     }
 
@@ -304,7 +305,7 @@
                     Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
                     false, mSettingsObserver, UserHandle.USER_SYSTEM);
             cr.registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.AUTOMATIC_POWER_SAVER_MODE),
+                    Settings.Global.AUTOMATIC_POWER_SAVE_MODE),
                     false, mSettingsObserver, UserHandle.USER_SYSTEM);
             cr.registerContentObserver(Settings.Global.getUriFor(
                     Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED),
@@ -367,8 +368,8 @@
         final int lowPowerModeTriggerLevel = getGlobalSetting(
                 Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
         final int automaticBatterySaverMode = getGlobalSetting(
-                Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
-                PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+                Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
+                PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
         final int dynamicPowerSavingsDisableThreshold = getGlobalSetting(
                 Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
                 mDynamicPowerSavingsDefaultDisableThreshold);
@@ -791,7 +792,7 @@
 
         manager.notify(DYNAMIC_MODE_NOTIFICATION_ID,
                 buildNotification(DYNAMIC_MODE_NOTIF_CHANNEL_ID,
-                        R.string.dynamic_mode_notification_title,
+                        mContext.getResources().getString(R.string.dynamic_mode_notification_title),
                         R.string.dynamic_mode_notification_summary,
                         Intent.ACTION_POWER_USAGE_SUMMARY));
     }
@@ -801,10 +802,13 @@
         ensureNotificationChannelExists(manager, BATTERY_SAVER_NOTIF_CHANNEL_ID,
                 R.string.battery_saver_notification_channel_name);
 
+        final String percentage = NumberFormat.getPercentInstance()
+                .format((double) mBatteryLevel / 100.0);
         manager.notify(STICKY_AUTO_DISABLED_NOTIFICATION_ID,
                 buildNotification(BATTERY_SAVER_NOTIF_CHANNEL_ID,
-                        R.string.battery_saver_sticky_disabled_notification_title,
-                        R.string.battery_saver_sticky_disabled_notification_summary,
+                        mContext.getResources().getString(
+                                R.string.battery_saver_charged_notification_title, percentage),
+                        R.string.battery_saver_off_notification_summary,
                         Settings.ACTION_BATTERY_SAVER_SETTINGS));
     }
 
@@ -816,7 +820,7 @@
         manager.createNotificationChannel(channel);
     }
 
-    private Notification buildNotification(@NonNull String channelId, @StringRes int titleId,
+    private Notification buildNotification(@NonNull String channelId, @NonNull String title,
             @StringRes int summaryId, @NonNull String intentAction) {
         Resources res = mContext.getResources();
         Intent intent = new Intent(intentAction);
@@ -827,11 +831,12 @@
 
         return new Notification.Builder(mContext, channelId)
                 .setSmallIcon(R.drawable.ic_battery)
-                .setContentTitle(res.getString(titleId))
+                .setContentTitle(title)
                 .setContentText(summary)
                 .setContentIntent(batterySaverIntent)
                 .setStyle(new Notification.BigTextStyle().bigText(summary))
                 .setOnlyAlertOnce(true)
+                .setAutoCancel(true)
                 .build();
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index b262a00..fc7646f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -364,7 +364,7 @@
      *  - Use the secondary home defined in the config.
      */
     public abstract boolean startHomeOnDisplay(int userId, String reason, int displayId,
-            boolean fromHomeKey);
+            boolean allowInstrumenting, boolean fromHomeKey);
     /** Start home activities on all displays that support system decorations. */
     public abstract boolean startHomeOnAllDisplays(int userId, String reason);
     /** @return true if the given process is the factory test process. */
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index c91ee8e..b8e6b0c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6492,10 +6492,10 @@
 
         @Override
         public boolean startHomeOnDisplay(int userId, String reason, int displayId,
-                boolean fromHomeKey) {
+                boolean allowInstrumenting, boolean fromHomeKey) {
             synchronized (mGlobalLock) {
                 return mRootActivityContainer.startHomeOnDisplay(userId, reason, displayId,
-                        fromHomeKey);
+                        allowInstrumenting, fromHomeKey);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index d69ae3d..24b0213 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -845,6 +845,11 @@
         return mService.mAmInternal.getCurrentProfileIds();
     }
 
+    @VisibleForTesting
+    boolean isUserRunning(int userId, int flags) {
+        return mService.mAmInternal.isUserRunning(userId, flags);
+    }
+
     /**
      * @return the list of recent tasks for presentation.
      */
@@ -861,7 +866,7 @@
             boolean getTasksAllowed, boolean getDetailedTasks, int userId, int callingUid) {
         final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0;
 
-        if (!mService.mAmInternal.isUserRunning(userId, FLAG_AND_UNLOCKED)) {
+        if (!isUserRunning(userId, FLAG_AND_UNLOCKED)) {
             Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
             return new ArrayList<>();
         }
@@ -881,7 +886,7 @@
 
             if (isVisibleRecentTask(tr)) {
                 numVisibleTasks++;
-                if (isInVisibleRange(tr, numVisibleTasks)) {
+                if (isInVisibleRange(tr, numVisibleTasks, withExcluded)) {
                     // Fall through
                 } else {
                     // Not in visible range
@@ -908,51 +913,43 @@
                 continue;
             }
 
-            // Return the entry if desired by the caller.  We always return
-            // the first entry, because callers always expect this to be the
-            // foreground app.  We may filter others if the caller has
-            // not supplied RECENT_WITH_EXCLUDED and there is some reason
-            // we should exclude the entry.
-
-            if (i == 0
-                    || withExcluded
-                    || (tr.intent == null)
-                    || ((tr.intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
-                    == 0)) {
-                if (!getTasksAllowed) {
-                    // If the caller doesn't have the GET_TASKS permission, then only
-                    // allow them to see a small subset of tasks -- their own and home.
-                    if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
-                        if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
-                        continue;
-                    }
-                }
-                if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
-                    // Don't include auto remove tasks that are finished or finishing.
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                            "Skipping, auto-remove without activity: " + tr);
+            if (!getTasksAllowed) {
+                // If the caller doesn't have the GET_TASKS permission, then only
+                // allow them to see a small subset of tasks -- their own and home.
+                if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) {
+                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
                     continue;
                 }
-                if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) {
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                            "Skipping, unavail real act: " + tr);
-                    continue;
-                }
-
-                if (!tr.mUserSetupComplete) {
-                    // Don't include task launched while user is not done setting-up.
-                    if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
-                            "Skipping, user setup not complete: " + tr);
-                    continue;
-                }
-
-                final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr);
-                if (!getDetailedTasks) {
-                    rti.baseIntent.replaceExtras((Bundle)null);
-                }
-
-                res.add(rti);
             }
+
+            if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
+                // Don't include auto remove tasks that are finished or finishing.
+                if (DEBUG_RECENTS) {
+                    Slog.d(TAG_RECENTS, "Skipping, auto-remove without activity: " + tr);
+                }
+                continue;
+            }
+            if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) {
+                if (DEBUG_RECENTS) {
+                    Slog.d(TAG_RECENTS, "Skipping, unavail real act: " + tr);
+                }
+                continue;
+            }
+
+            if (!tr.mUserSetupComplete) {
+                // Don't include task launched while user is not done setting-up.
+                if (DEBUG_RECENTS) {
+                    Slog.d(TAG_RECENTS, "Skipping, user setup not complete: " + tr);
+                }
+                continue;
+            }
+
+            final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr);
+            if (!getDetailedTasks) {
+                rti.baseIntent.replaceExtras((Bundle) null);
+            }
+
+            res.add(rti);
         }
         return res;
     }
@@ -994,7 +991,7 @@
             final TaskRecord tr = mTasks.get(i);
             if (isVisibleRecentTask(tr)) {
                 numVisibleTasks++;
-                if (isInVisibleRange(tr, numVisibleTasks)) {
+                if (isInVisibleRange(tr, numVisibleTasks, false /* skipExcludedCheck */)) {
                     res.put(tr.taskId, true);
                 }
             }
@@ -1215,7 +1212,8 @@
                     continue;
                 } else {
                     numVisibleTasks++;
-                    if (isInVisibleRange(task, numVisibleTasks) || !isTrimmable(task)) {
+                    if (isInVisibleRange(task, numVisibleTasks, false /* skipExcludedCheck */)
+                            || !isTrimmable(task)) {
                         // Keep visible tasks in range
                         i++;
                         continue;
@@ -1329,14 +1327,17 @@
     /**
      * @return whether the given visible task is within the policy range.
      */
-    private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks) {
-        // Keep the last most task even if it is excluded from recents
-        final boolean isExcludeFromRecents =
-                (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
-                        == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
-        if (isExcludeFromRecents) {
-            if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true");
-            return numVisibleTasks == 1;
+    private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks,
+            boolean skipExcludedCheck) {
+        if (!skipExcludedCheck) {
+            // Keep the most recent task even if it is excluded from recents
+            final boolean isExcludeFromRecents =
+                    (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+                            == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+            if (isExcludeFromRecents) {
+                if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true");
+                return numVisibleTasks == 1;
+            }
         }
 
         if (mMinNumVisibleTasks >= 0 && numVisibleTasks <= mMinNumVisibleTasks) {
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 24cf7f1..46b5f3a 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -347,7 +347,8 @@
     }
 
     boolean startHomeOnDisplay(int userId, String reason, int displayId) {
-        return startHomeOnDisplay(userId, reason, displayId, false /*fromHomeKey*/);
+        return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
+                false /* fromHomeKey */);
     }
 
     /**
@@ -361,7 +362,8 @@
      *    If there are multiple activities matched, use first one.
      *  - Use the secondary home defined in the config.
      */
-    boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean fromHomeKey) {
+    boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
+            boolean fromHomeKey) {
         // Fallback to top focused display if the displayId is invalid.
         if (displayId == INVALID_DISPLAY) {
             displayId = getTopDisplayFocusedStack().mDisplayId;
@@ -383,7 +385,7 @@
             return false;
         }
 
-        if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
+        if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
             return false;
         }
 
diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
index e0d85e8..4379b7c 100644
--- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
+++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
@@ -41,7 +41,7 @@
         return new TaskScreenshotAnimatable(task, getBufferFromTask(task));
     }
 
-    private static GraphicBuffer getBufferFromTask(Task task) {
+    private static SurfaceControl.ScreenshotGraphicBuffer getBufferFromTask(Task task) {
         if (task == null) {
             return null;
         }
@@ -51,7 +51,10 @@
                 task.getSurfaceControl().getHandle(), tmpRect, 1f);
     }
 
-    private TaskScreenshotAnimatable(Task task, GraphicBuffer buffer) {
+    private TaskScreenshotAnimatable(Task task,
+            SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer) {
+        GraphicBuffer buffer = screenshotBuffer == null
+                ? null : screenshotBuffer.getGraphicBuffer();
         mTask = task;
         mWidth = (buffer != null) ? buffer.getWidth() : 1;
         mHeight = (buffer != null) ? buffer.getHeight() : 1;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index beb3d82..6fe8b43 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -279,8 +279,11 @@
             Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task);
             return null;
         }
-        final GraphicBuffer buffer = SurfaceControl.captureLayers(
-                task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
+        final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
+                SurfaceControl.captureLayers(
+                        task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
+        final GraphicBuffer buffer = screenshotBuffer != null ? screenshotBuffer.getGraphicBuffer()
+                : null;
         if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
             if (DEBUG_SCREENSHOT) {
                 Slog.w(TAG_WM, "Failed to take screenshot for " + task);
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index dddc6b7..166a33d 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -34,8 +34,6 @@
 import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
 
 import android.graphics.Bitmap;
-import android.graphics.ColorSpace;
-import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
 import android.hardware.HardwareBuffer;
 import android.os.Bundle;
@@ -738,17 +736,16 @@
         final Rect bounds = wallpaperWindowState.getBounds();
         bounds.offsetTo(0, 0);
 
-        GraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
+        SurfaceControl.ScreenshotGraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
                 wallpaperWindowState.getSurfaceControl().getHandle(), bounds, 1 /* frameScale */);
 
         if (wallpaperBuffer == null) {
             Slog.w(TAG_WM, "Failed to screenshot wallpaper");
             return null;
         }
-        // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
-        // should continue to fix screenshot.
-        return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer),
-                                         ColorSpace.get(ColorSpace.Named.SRGB));
+        return Bitmap.wrapHardwareBuffer(
+                HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer.getGraphicBuffer()),
+                wallpaperBuffer.getColorSpace());
     }
 
     private WindowState getTopVisibleWallpaper() {
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 63dca62..d5fbd2b 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -96,7 +96,7 @@
     }
     R val = static_cast<R>(effect);
     auto iter = hardware::hidl_enum_range<R>();
-    return val >= *iter.begin() && val < *std::prev(iter.end());
+    return val >= *iter.begin() && val <= *std::prev(iter.end());
 }
 
 static void vibratorInit(JNIEnv /* env */, jobject /* clazz */)
@@ -170,6 +170,9 @@
     } else if (isValidEffect<V1_2::Effect>(effect)) {
         ret = halCall(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(effect),
                            effectStrength, callback);
+    } else if (isValidEffect<V1_3::Effect>(effect)) {
+        ret = halCall(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(effect),
+                           effectStrength, callback);
     } else {
         ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
                 static_cast<int32_t>(effect));
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 65a7eec..7df7ef3 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -998,8 +998,9 @@
     template<class T>
     size_t getMeasurementCount(const T& data);
 
-    jobject translateGnssClock(
-            JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock);
+    template<class T>
+    void translateGnssClock(JavaObject& object, const T& data);
+
     void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
 };
 
@@ -1025,12 +1026,12 @@
 void GnssMeasurementCallback::translateAndSetGnssData(const T& data) {
     JNIEnv* env = getJniEnv();
 
-    jobject clock;
-    jobjectArray measurementArray;
+    JavaObject gnssClockJavaObject(env, "android/location/GnssClock");
+    translateGnssClock(gnssClockJavaObject, data);
+    jobject clock = gnssClockJavaObject.get();
 
-    clock = translateGnssClock(env, &data.clock);
     size_t count = getMeasurementCount(data);
-    measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count);
+    jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count);
     setMeasurementData(env, clock, measurementArray);
 
     env->DeleteLocalRef(clock);
@@ -1124,43 +1125,59 @@
     SET(ConstellationType, static_cast<int32_t>(measurement_V2_0->constellation));
 }
 
-jobject GnssMeasurementCallback::translateGnssClock(
-       JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) {
-    JavaObject object(env, "android/location/GnssClock");
+template<class T>
+void GnssMeasurementCallback::translateGnssClock(JavaObject& object, const T& data) {
+    translateGnssClock(object, data.clock);
+}
 
-    uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
+template<>
+void GnssMeasurementCallback::translateGnssClock(
+       JavaObject& object, const IGnssMeasurementCallback_V1_0::GnssClock& clock) {
+    uint32_t flags = static_cast<uint32_t>(clock.gnssClockFlags);
     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
-        SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
+        SET(LeapSecond, static_cast<int32_t>(clock.leapSecond));
     }
 
     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
-        SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
+        SET(TimeUncertaintyNanos, clock.timeUncertaintyNs);
     }
 
     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
-        SET(FullBiasNanos, clock->fullBiasNs);
+        SET(FullBiasNanos, clock.fullBiasNs);
     }
 
     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
-        SET(BiasNanos, clock->biasNs);
+        SET(BiasNanos, clock.biasNs);
     }
 
     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
-        SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
+        SET(BiasUncertaintyNanos, clock.biasUncertaintyNs);
     }
 
     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
-        SET(DriftNanosPerSecond, clock->driftNsps);
+        SET(DriftNanosPerSecond, clock.driftNsps);
     }
 
     if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
-        SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
+        SET(DriftUncertaintyNanosPerSecond, clock.driftUncertaintyNsps);
     }
 
-    SET(TimeNanos, clock->timeNs);
-    SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
+    SET(TimeNanos, clock.timeNs);
+    SET(HardwareClockDiscontinuityCount, clock.hwClockDiscontinuityCount);
+}
 
-    return object.get();
+template<>
+void GnssMeasurementCallback::translateGnssClock(
+       JavaObject& object, const IGnssMeasurementCallback_V2_0::GnssData& data) {
+    auto elapsedRealtime = data.elapsedRealtime;
+    uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags);
+    if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) {
+        SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs));
+    }
+    if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
+        SET(ElapsedRealtimeUncertaintyNanos, static_cast<uint64_t>(elapsedRealtime.timeUncertaintyNs));
+    }
+    translateGnssClock(object, data.clock);
 }
 
 template<class T>
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2d01471..633367a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5133,11 +5133,14 @@
         final boolean result;
         try {
             if (token == null) {
+                // This is the legacy reset password for DPM. Here we want to be able to override
+                // the old device password without necessarily knowing it.
                 if (!TextUtils.isEmpty(password)) {
                     mLockPatternUtils.saveLockPassword(password.getBytes(), null, quality,
-                            userHandle);
+                            userHandle, /*allowUntrustedChange */true);
                 } else {
-                    mLockPatternUtils.clearLock(null, userHandle);
+                    mLockPatternUtils.clearLock(null, userHandle,
+                            /*allowUntrustedChange */ true);
                 }
                 result = true;
             } else {
@@ -5246,12 +5249,11 @@
                 // would allow bypassing of the maximum time to lock.
                 mInjector.settingsGlobalPutInt(Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
             }
+            getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
+                    UserHandle.USER_SYSTEM, timeMs);
         } finally {
             mInjector.binderRestoreCallingIdentity(ident);
         }
-
-        getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
-                UserHandle.USER_SYSTEM, timeMs);
     }
 
     private void updateProfileLockTimeoutLocked(@UserIdInt int userId) {
@@ -5269,8 +5271,13 @@
         }
         policy.mLastMaximumTimeToLock = timeMs;
 
-        getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
-                userId, policy.mLastMaximumTimeToLock);
+        final long ident = mInjector.binderClearCallingIdentity();
+        try {
+            getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
+                    userId, policy.mLastMaximumTimeToLock);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(ident);
+        }
     }
 
     @Override
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 419f52c..d4ccb0b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -849,7 +849,7 @@
     private void startOtherServices() {
         final Context context = mSystemContext;
         VibratorService vibrator = null;
-        DynamicAndroidService dynamicAndroid = null;
+        DynamicSystemService dynamicSystem = null;
         IStorageManager storageManager = null;
         NetworkManagementService networkManagement = null;
         IpSecService ipSecService = null;
@@ -968,9 +968,9 @@
             ServiceManager.addService("vibrator", vibrator);
             traceEnd();
 
-            traceBeginAndSlog("StartDynamicAndroidService");
-            dynamicAndroid = new DynamicAndroidService(context);
-            ServiceManager.addService("dynamic_android", dynamicAndroid);
+            traceBeginAndSlog("StartDynamicSystemService");
+            dynamicSystem = new DynamicSystemService(context);
+            ServiceManager.addService("dynamic_system", dynamicSystem);
             traceEnd();
 
             if (!isWatch) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
index 2e5efbd..212d2a8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
@@ -112,7 +112,7 @@
                             Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 0) != 0,
                     mPersistedState.global.getOrDefault(
                             Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 90),
-                    mPersistedState.global.getOrDefault(Global.AUTOMATIC_POWER_SAVER_MODE, 0),
+                    mPersistedState.global.getOrDefault(Global.AUTOMATIC_POWER_SAVE_MODE, 0),
                     mPersistedState.global.getOrDefault(
                             Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0) != 0,
                     mPersistedState.global.getOrDefault(
@@ -321,7 +321,7 @@
     @Test
     public void testAutoBatterySaver() {
         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
-        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 0);
+        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, 0);
 
         assertEquals(false, mDevice.batterySaverEnabled);
         assertEquals(100, mPersistedState.batteryLevel);
@@ -789,7 +789,7 @@
                 .thenReturn(true);
         initDevice();
         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
-        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 0);
+        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, 0);
 
         mTarget.setBatterySaverEnabledManually(true);
 
@@ -906,8 +906,8 @@
     @Test
     public void testAutoBatterySaver_smartBatterySaverEnabled() {
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
-        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE,
-                PowerManager.POWER_SAVER_MODE_DYNAMIC);
+        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE,
+                PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
 
         assertEquals(false, mDevice.batterySaverEnabled);
@@ -1029,8 +1029,8 @@
         // Test dynamic threshold higher than automatic to make sure it doesn't interfere when it's
         // not enabled.
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
-        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE,
-                PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE,
+                PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
 
         assertEquals(false, mDevice.batterySaverEnabled);
@@ -1138,8 +1138,8 @@
         // not enabled.
         mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 30);
-        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE,
-                PowerManager.POWER_SAVER_MODE_DYNAMIC);
+        mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE,
+                PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
         mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1);
 
         assertEquals(false, mDevice.batterySaverEnabled);
diff --git a/services/tests/servicestests/src/com/android/server/DynamicAndroidServiceTest.java b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
similarity index 68%
rename from services/tests/servicestests/src/com/android/server/DynamicAndroidServiceTest.java
rename to services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
index 1494284..4a9dd97 100644
--- a/services/tests/servicestests/src/com/android/server/DynamicAndroidServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
@@ -16,28 +16,28 @@
 
 package com.android.server;
 
-import android.os.IDynamicAndroidService;
 import android.os.ServiceManager;
+import android.os.image.IDynamicSystemService;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 
-public class DynamicAndroidServiceTest extends AndroidTestCase {
-    private static final String TAG = "DynamicAndroidServiceTests";
-    private IDynamicAndroidService mService;
+public class DynamicSystemServiceTest extends AndroidTestCase {
+    private static final String TAG = "DynamicSystemServiceTests";
+    private IDynamicSystemService mService;
 
     @Override
     protected void setUp() throws Exception {
         mService =
-                IDynamicAndroidService.Stub.asInterface(
-                        ServiceManager.getService("dynamic_android"));
+                IDynamicSystemService.Stub.asInterface(
+                        ServiceManager.getService("dynamic_system"));
     }
 
     @LargeTest
     public void test1() {
-        assertTrue("dynamic_android service available", mService != null);
+        assertTrue("dynamic_system service available", mService != null);
         try {
             mService.startInstallation(1 << 20, 8 << 30);
-            fail("DynamicAndroidService did not throw SecurityException as expected");
+            fail("DynamicSystemService did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected
         } catch (Exception e) {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java
index 94d21dd..ca4330f 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java
@@ -61,12 +61,12 @@
         long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         // clear password
         mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
-                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, true);
         assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
 
         // set a new password
         mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(newPassword,
                 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
                         .getResponseCode());
@@ -81,7 +81,7 @@
         long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         // Untrusted change password
         mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true);
         assertNotEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
         assertNotEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
 
@@ -99,7 +99,7 @@
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         // Untrusted change password
         mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true);
 
         // Verify the password
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(newPassword,
@@ -124,10 +124,12 @@
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         // Untrusted change password
-        assertExpectException(IllegalStateException.class, /* messageRegex= */ null,
+        assertExpectException(
+                IllegalStateException.class,
+                /* messageRegex= */ "Untrusted credential reset not possible without cached SP",
                 () -> mService.setLockCredential(newPassword,
                         LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                        PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID));
+                        PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true));
         assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
 
         // Verify the new password doesn't work but the old one still does
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 6e0ba3c..255e694b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -85,9 +85,9 @@
 
         try {
             mService.setLockCredential("newpwd".getBytes(), CREDENTIAL_TYPE_PASSWORD,
-                    "badpwd".getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                    "badpwd".getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
             fail("Did not fail when enrolling using incorrect credential");
-        } catch (RemoteException expected) {
+        } catch (IllegalStateException expected) {
             assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
         }
         assertVerifyCredentials(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
@@ -97,7 +97,7 @@
         final String PASSWORD = "password";
         initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234);
         mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD.getBytes(),
-                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
         assertFalse(mService.havePassword(PRIMARY_USER_ID));
         assertFalse(mService.havePattern(PRIMARY_USER_ID));
         assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
@@ -108,7 +108,7 @@
         final String secondUnifiedPassword = "testManagedProfileUnifiedChallenge-pwd-2";
         mService.setLockCredential(firstUnifiedPassword.getBytes(),
                 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                null, PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
+                null, PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID, false);
         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
         final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
@@ -143,15 +143,16 @@
         mStorageManager.setIgnoreBadUnlock(true);
         // Change primary password and verify that profile SID remains
         mService.setLockCredential(secondUnifiedPassword.getBytes(),
-                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                firstUnifiedPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, firstUnifiedPassword.getBytes(),
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         mStorageManager.setIgnoreBadUnlock(false);
         assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
         assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
 
         // Clear unified challenge
         mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
-                secondUnifiedPassword.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+                secondUnifiedPassword.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID,
+                false);
         assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
         assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
         assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
@@ -162,7 +163,7 @@
         final String profilePassword = "testManagedProfileSeparateChallenge-profile";
         mService.setLockCredential(primaryPassword.getBytes(),
                 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID, false);
         /* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
          * credential as part of verifyCredential() before the new credential is committed in
          * StorageManager. So we relax the check in our mock StorageManager to allow that.
@@ -170,7 +171,7 @@
         mStorageManager.setIgnoreBadUnlock(true);
         mService.setLockCredential(profilePassword.getBytes(),
                 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID);
+                PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID, false);
         mStorageManager.setIgnoreBadUnlock(false);
 
         final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
@@ -197,7 +198,7 @@
         // Change primary credential and make sure we don't affect profile
         mStorageManager.setIgnoreBadUnlock(true);
         mService.setLockCredential("pwd".getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
-                primaryPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                primaryPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         mStorageManager.setIgnoreBadUnlock(false);
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
                 profilePassword.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
@@ -208,7 +209,7 @@
     private void testCreateCredential(int userId, String credential, int type, int quality)
             throws RemoteException {
         mService.setLockCredential(credential.getBytes(), type, null, quality,
-                userId);
+                userId, false);
         assertVerifyCredentials(userId, credential, type, -1);
     }
 
@@ -218,7 +219,7 @@
 
         try {
             mService.setLockCredential(credential.getBytes(), type, null, quality,
-                    userId);
+                    userId, false);
             fail("An exception should have been thrown.");
         } catch (UnsupportedOperationException e) {
             // Success - the exception was expected.
@@ -233,7 +234,7 @@
         final long sid = 1234;
         initializeStorageWithCredential(userId, oldCredential, oldType, sid);
         mService.setLockCredential(newCredential.getBytes(), newType, oldCredential.getBytes(),
-                quality, userId);
+                quality, userId, false);
         assertVerifyCredentials(userId, newCredential, newType, sid);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 6a07a45..58055e5 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -102,7 +102,7 @@
 
         disableSyntheticPassword();
         mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
         enableSyntheticPassword();
@@ -127,7 +127,7 @@
                 : PASSWORD_QUALITY_UNSPECIFIED;
         int type = password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
                 : LockPatternUtils.CREDENTIAL_TYPE_NONE;
-        mService.setLockCredential(password, type, null, quality, userId);
+        mService.setLockCredential(password, type, null, quality, userId, false);
     }
 
     public void testSyntheticPasswordChangeCredential() throws RemoteException {
@@ -137,7 +137,7 @@
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
                 newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
                         .getResponseCode());
@@ -166,12 +166,12 @@
         long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         // clear password
         mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
-                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
         assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
 
         // set a new password
         mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
                 badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
                         .getResponseCode());
@@ -186,7 +186,7 @@
 
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
                 badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
                         .getResponseCode());
@@ -245,7 +245,7 @@
         final byte[] password = "getASyntheticPassword".getBytes();
         initializeCredentialUnderSP(password, PRIMARY_USER_ID);
         mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
-                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
 
         reset(mAuthSecretService);
         mService.onUnlockUser(PRIMARY_USER_ID);
@@ -257,7 +257,7 @@
         final byte[] UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd".getBytes();
         disableSyntheticPassword();
         mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
         final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
@@ -294,9 +294,9 @@
                 "testManagedProfileSeparateChallengeMigration-profile".getBytes();
         disableSyntheticPassword();
         mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID, false);
         final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
         final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
         final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
@@ -404,7 +404,7 @@
         assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
 
         mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, password,
-                PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID, false);
 
         mLocalService.setLockCredentialWithToken(newPassword,
                 LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, token,
@@ -443,7 +443,7 @@
         // Set up pre-SP user password
         disableSyntheticPassword();
         mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         enableSyntheticPassword();
 
         long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
@@ -491,12 +491,12 @@
     public void testgetHashFactorPrimaryUser() throws RemoteException {
         final byte[] password = "password".getBytes();
         mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         final byte[] hashFactor = mService.getHashFactor(password, PRIMARY_USER_ID);
         assertNotNull(hashFactor);
 
         mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
-                password, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+                password, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
         final byte[] newHashFactor = mService.getHashFactor(null, PRIMARY_USER_ID);
         assertNotNull(newHashFactor);
         // Hash factor should never change after password change/removal
@@ -506,7 +506,7 @@
     public void testgetHashFactorManagedProfileUnifiedChallenge() throws RemoteException {
         final byte[] pattern = "1236".getBytes();
         mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
-                null, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+                null, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID, false);
         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
         assertNotNull(mService.getHashFactor(null, MANAGED_PROFILE_USER_ID));
     }
@@ -515,9 +515,9 @@
         final byte[] primaryPassword = "primary".getBytes();
         final byte[] profilePassword = "profile".getBytes();
         mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
         mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
-                PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
+                PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID, false);
         assertNotNull(mService.getHashFactor(profilePassword, MANAGED_PROFILE_USER_ID));
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index a8da80e..426122a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -353,7 +353,6 @@
         FileOutputStream fos = mPolicyFile.startWrite();
         fos.write(preupgradeXml.getBytes());
         mPolicyFile.finishWrite(fos);
-        FileInputStream fStream = new FileInputStream(mFile);
 
         // Setup managed services
         mListener = mListeners.new ManagedServiceInfo(
@@ -369,6 +368,8 @@
         dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS;
         when(mConditionProviders.getConfig()).thenReturn(dndConfig);
 
+        when(mAssistants.isAdjustmentAllowed(anyString())).thenReturn(true);
+
         try {
             mService.init(mTestableLooper.getLooper(),
                     mPackageManager, mPackageManagerClient, mockLightsManager,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 23bae88..de4fb98 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -37,6 +37,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseIntArray;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto;
@@ -118,6 +119,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 129138370)
     public void testOnIntentStarted() throws Exception {
         Intent intent = new Intent("action 1");
 
@@ -128,6 +130,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 129138370)
     public void testOnIntentFailed() throws Exception {
         testOnIntentStarted();
 
@@ -143,6 +146,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunched() throws Exception {
         testOnIntentStarted();
 
@@ -154,6 +158,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchFinished() throws Exception {
        testOnActivityLaunched();
 
@@ -168,6 +173,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchCancelled() throws Exception {
        testOnActivityLaunched();
 
@@ -181,6 +187,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchedTrampoline() throws Exception {
         testOnIntentStarted();
 
@@ -197,6 +204,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchFinishedTrampoline() throws Exception {
        testOnActivityLaunchedTrampoline();
 
@@ -211,6 +219,7 @@
     }
 
     @Test
+    @FlakyTest(bugId = 129138370)
     public void testOnActivityLaunchCancelledTrampoline() throws Exception {
        testOnActivityLaunchedTrampoline();
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 68e7470..08e6ce4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityManager.RECENT_WITH_EXCLUDED;
 import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -29,7 +30,9 @@
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
@@ -512,6 +515,52 @@
     }
 
     @Test
+    public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() {
+        // Create some set of tasks, some of which are visible and some are not
+        TaskRecord homeTask = setTaskActivityType(
+                createTaskBuilder("com.android.pkg1", ".HomeTask").build(),
+                ACTIVITY_TYPE_HOME);
+        homeTask.mUserSetupComplete = true;
+        mRecentTasks.add(homeTask);
+        TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
+                .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+                .build();
+        excludedTask1.mUserSetupComplete = true;
+        mRecentTasks.add(excludedTask1);
+
+        // Expect that the first visible excluded-from-recents task is visible
+        assertGetRecentTasksOrder(0 /* flags */, excludedTask1);
+    }
+
+    @Test
+    public void testVisibleTasks_excludedFromRecents_withExcluded() {
+        // Create some set of tasks, some of which are visible and some are not
+        TaskRecord t1 = createTaskBuilder("com.android.pkg1", ".Task1").build();
+        t1.mUserSetupComplete = true;
+        mRecentTasks.add(t1);
+        TaskRecord homeTask = setTaskActivityType(
+                createTaskBuilder("com.android.pkg1", ".HomeTask").build(),
+                ACTIVITY_TYPE_HOME);
+        homeTask.mUserSetupComplete = true;
+        mRecentTasks.add(homeTask);
+        TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1")
+                .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+                .build();
+        excludedTask1.mUserSetupComplete = true;
+        mRecentTasks.add(excludedTask1);
+        TaskRecord excludedTask2 = createTaskBuilder(".ExcludedTask2")
+                .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+                .build();
+        excludedTask2.mUserSetupComplete = true;
+        mRecentTasks.add(excludedTask2);
+        TaskRecord t2 = createTaskBuilder("com.android.pkg2", ".Task1").build();
+        t2.mUserSetupComplete = true;
+        mRecentTasks.add(t2);
+
+        assertGetRecentTasksOrder(RECENT_WITH_EXCLUDED, t2, excludedTask2, excludedTask1, t1);
+    }
+
+    @Test
     public void testVisibleTasks_minNum() {
         mRecentTasks.setOnlyTestVisibleRange();
         mRecentTasks.setParameters(5 /* min */, -1 /* max */, 25 /* ms */);
@@ -830,7 +879,7 @@
     }
 
     /**
-     * Ensures that the recent tasks list is in the provided order. Note that the expected tasks
+     * Ensures that the raw recent tasks list is in the provided order. Note that the expected tasks
      * should be ordered from least to most recent.
      */
     private void assertRecentTasksOrder(TaskRecord... expectedTasks) {
@@ -841,6 +890,22 @@
         }
     }
 
+    /**
+     * Ensures that the recent tasks list is in the provided order. Note that the expected tasks
+     * should be ordered from least to most recent.
+     */
+    private void assertGetRecentTasksOrder(int getRecentTaskFlags, TaskRecord... expectedTasks) {
+        doNothing().when(mRecentTasks).loadUserRecentsLocked(anyInt());
+        doReturn(true).when(mRecentTasks).isUserRunning(anyInt(), anyInt());
+        List<RecentTaskInfo> infos = mRecentTasks.getRecentTasks(MAX_VALUE, getRecentTaskFlags,
+                true /* getTasksAllowed */, false /* getDetailedTasks */,
+                TEST_USER_0_ID, 0).getList();
+        assertTrue(expectedTasks.length == infos.size());
+        for (int i = 0; i < infos.size(); i++)  {
+            assertTrue(expectedTasks[i].taskId == infos.get(i).taskId);
+        }
+    }
+
     private void assertNotRestoreTask(Runnable action) {
         // Verify stack count doesn't change because task with fullscreen mode and standard type
         // would have its own stack.
@@ -1018,7 +1083,7 @@
 
         @Override
         protected RecentTasks createRecentTasks() {
-            return new TestRecentTasks(this, mTaskPersister);
+            return spy(new TestRecentTasks(this, mTaskPersister));
         }
 
         @Override
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index 81553a3..afa35b4 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -51,6 +52,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public static final int TRANSPORT_TYPE_WWAN = 1;
 
     /**
@@ -58,6 +60,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     public static final int TRANSPORT_TYPE_WLAN = 2;
 
     /** @hide */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5f9ef3c..0a9b904 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1543,6 +1543,21 @@
             "allow_non_emergency_calls_in_ecm_bool";
 
     /**
+     * Time that the telephony framework stays in "emergency SMS mode" after an emergency SMS is
+     * sent to the network. This is used by carriers to configure the time
+     * {@link TelephonyManager#isInEmergencySmsMode()} will be true after an emergency SMS is sent.
+     * This is used by GNSS to override user location permissions so that the carrier network can
+     * get the user's location for emergency services.
+     *
+     * The default is 0, which means that this feature is disabled. The maximum value for this timer
+     * is 300000 mS (5 minutes).
+     *
+     * @hide
+     */
+    public static final String KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT =
+            "emergency_sms_mode_timer_ms_int";
+
+    /**
      * Flag indicating whether to allow carrier video calls to emergency numbers.
      * When {@code true}, video calls to emergency numbers will be allowed.  When {@code false},
      * video calls to emergency numbers will be initiated as audio-only calls instead.
@@ -1847,12 +1862,32 @@
             "use_wfc_home_network_mode_in_roaming_network_bool";
 
     /**
+     * Flag specifying whether the carrier is allowed to use metered network to download a
+     * certificate of Carrier-WiFi.
+     * {@code false} - default value.
+     *
+     * @hide
+     */
+    public static final String KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL =
+            "allow_metered_network_for_cert_download_bool";
+
+    /**
      * Carrier specified WiFi networks.
      * @hide
      */
     public static final String KEY_CARRIER_WIFI_STRING_ARRAY = "carrier_wifi_string_array";
 
     /**
+     * Base64 Encoding method the carrier will use for encoding encrypted IMSI and SSID.
+     * The value set as below:
+     * 2045 - RFC2045 (default value)
+     * 4648 - RFC4648
+     *
+     * @hide
+     */
+    public static final String KEY_IMSI_ENCODING_METHOD_INT = "imsi_encoding_method_int";
+
+    /**
      * Time delay (in ms) after which we show the notification to switch the preferred
      * network.
      * @hide
@@ -2667,6 +2702,14 @@
             "cdma_enhanced_roaming_indicator_for_home_network_int_array";
 
     /**
+     * Determines whether wifi calling location privacy policy is shown.
+     *
+     * @hide
+     */
+    public static final String KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL =
+            "show_wfc_location_privacy_policy_bool";
+
+    /**
      * Indicates use 3GPP application to replace 3GPP2 application even if it's a CDMA/CDMA-LTE
      * phone, becasue some carriers's CSIM application is present but not supported.
      * @hide
@@ -2917,6 +2960,7 @@
         sDefaults.putString(KEY_MMS_UA_PROF_URL_STRING, "");
         sDefaults.putString(KEY_MMS_USER_AGENT_STRING, "");
         sDefaults.putBoolean(KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL, true);
+        sDefaults.putInt(KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, 0);
         sDefaults.putBoolean(KEY_USE_RCS_PRESENCE_BOOL, false);
         sDefaults.putBoolean(KEY_FORCE_IMEI_BOOL, false);
         sDefaults.putInt(
@@ -2982,7 +3026,9 @@
         sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
         sDefaults.putBoolean(KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false);
         sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false);
+        sDefaults.putBoolean(KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL, false);
         sDefaults.putStringArray(KEY_CARRIER_WIFI_STRING_ARRAY, null);
+        sDefaults.putInt(KEY_IMSI_ENCODING_METHOD_INT, 2045);
         sDefaults.putInt(KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT, -1);
         sDefaults.putInt(KEY_EMERGENCY_NOTIFICATION_DELAY_INT, -1);
         sDefaults.putBoolean(KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL, true);
@@ -3073,6 +3119,7 @@
                 });
         sDefaults.putStringArray(KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY, new String[0]);
         sDefaults.putBoolean(KEY_USE_USIM_BOOL, false);
+        sDefaults.putBoolean(KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL, true);
         sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false);
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN,
                 false);
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
similarity index 65%
rename from telephony/java/android/telephony/DataSpecificRegistrationStates.java
rename to telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 8eb345a..fbf488e 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -1,7 +1,24 @@
+/*
+ * 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;
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -13,7 +30,8 @@
  * @hide
  */
 @SystemApi
-public final class DataSpecificRegistrationStates implements Parcelable{
+@TestApi
+public final class DataSpecificRegistrationInfo implements Parcelable {
     /**
      * @hide
      * The maximum number of simultaneous Data Calls that
@@ -53,27 +71,27 @@
     /**
      * Provides network support info for LTE VoPS and LTE Emergency bearer support
      */
-    private final LteVopsSupportInfo lteVopsSupportInfo;
+    private final LteVopsSupportInfo mLteVopsSupportInfo;
 
     /**
      * @hide
      */
-    DataSpecificRegistrationStates(
+    DataSpecificRegistrationInfo(
             int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
             boolean isEnDcAvailable, LteVopsSupportInfo lteVops) {
         this.maxDataCalls = maxDataCalls;
         this.isDcNrRestricted = isDcNrRestricted;
         this.isNrAvailable = isNrAvailable;
         this.isEnDcAvailable = isEnDcAvailable;
-        this.lteVopsSupportInfo = lteVops;
+        this.mLteVopsSupportInfo = lteVops;
     }
 
-    private DataSpecificRegistrationStates(Parcel source) {
+    private DataSpecificRegistrationInfo(Parcel source) {
         maxDataCalls = source.readInt();
         isDcNrRestricted = source.readBoolean();
         isNrAvailable = source.readBoolean();
         isEnDcAvailable = source.readBoolean();
-        lteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
+        mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
     }
 
     @Override
@@ -82,7 +100,7 @@
         dest.writeBoolean(isDcNrRestricted);
         dest.writeBoolean(isNrAvailable);
         dest.writeBoolean(isEnDcAvailable);
-        lteVopsSupportInfo.writeToParcel(dest, flags);
+        mLteVopsSupportInfo.writeToParcel(dest, flags);
     }
 
     @Override
@@ -98,7 +116,7 @@
                 .append(" isDcNrRestricted = " + isDcNrRestricted)
                 .append(" isNrAvailable = " + isNrAvailable)
                 .append(" isEnDcAvailable = " + isEnDcAvailable)
-                .append(lteVopsSupportInfo.toString())
+                .append(mLteVopsSupportInfo.toString())
                 .append(" }")
                 .toString();
     }
@@ -106,41 +124,41 @@
     @Override
     public int hashCode() {
         return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable,
-            lteVopsSupportInfo);
+                mLteVopsSupportInfo);
     }
 
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
 
-        if (!(o instanceof DataSpecificRegistrationStates)) return false;
+        if (!(o instanceof DataSpecificRegistrationInfo)) return false;
 
-        DataSpecificRegistrationStates other = (DataSpecificRegistrationStates) o;
+        DataSpecificRegistrationInfo other = (DataSpecificRegistrationInfo) o;
         return this.maxDataCalls == other.maxDataCalls
                 && this.isDcNrRestricted == other.isDcNrRestricted
                 && this.isNrAvailable == other.isNrAvailable
                 && this.isEnDcAvailable == other.isEnDcAvailable
-                && this.lteVopsSupportInfo.equals(other.lteVopsSupportInfo);
+                && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo);
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<DataSpecificRegistrationStates> CREATOR =
-            new Parcelable.Creator<DataSpecificRegistrationStates>() {
+    public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR =
+            new Parcelable.Creator<DataSpecificRegistrationInfo>() {
                 @Override
-                public DataSpecificRegistrationStates createFromParcel(Parcel source) {
-                    return new DataSpecificRegistrationStates(source);
+                public DataSpecificRegistrationInfo createFromParcel(Parcel source) {
+                    return new DataSpecificRegistrationInfo(source);
                 }
 
                 @Override
-                public DataSpecificRegistrationStates[] newArray(int size) {
-                    return new DataSpecificRegistrationStates[size];
+                public DataSpecificRegistrationInfo[] newArray(int size) {
+                    return new DataSpecificRegistrationInfo[size];
                 }
             };
 
     /**
-     * @return LteVopsSupportInfo
+     * @return The LTE VOPS (Voice over Packet Switched) support information
      */
     @NonNull
     public LteVopsSupportInfo getLteVopsSupportInfo() {
-        return lteVopsSupportInfo;
+        return mLteVopsSupportInfo;
     }
 }
diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.java b/telephony/java/android/telephony/LteVopsSupportInfo.java
index ee45f07..ec9f078 100644
--- a/telephony/java/android/telephony/LteVopsSupportInfo.java
+++ b/telephony/java/android/telephony/LteVopsSupportInfo.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -30,6 +31,7 @@
  * @hide
  */
 @SystemApi
+@TestApi
 public final class LteVopsSupportInfo implements Parcelable {
 
     /**@hide*/
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 9145b25..1dc2997 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.AccessNetworkConstants.TransportType;
@@ -38,6 +39,7 @@
  * @hide
  */
 @SystemApi
+@TestApi
 public final class NetworkRegistrationInfo implements Parcelable {
     /**
      * Network domain
@@ -174,10 +176,10 @@
     private CellIdentity mCellIdentity;
 
     @Nullable
-    private VoiceSpecificRegistrationStates mVoiceSpecificStates;
+    private VoiceSpecificRegistrationInfo mVoiceSpecificInfo;
 
     @Nullable
-    private DataSpecificRegistrationStates mDataSpecificStates;
+    private DataSpecificRegistrationInfo mDataSpecificInfo;
 
     /**
      * @param domain Network domain. Must be a {@link Domain}. For transport type
@@ -234,7 +236,7 @@
         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
                 emergencyOnly, availableServices, cellIdentity);
 
-        mVoiceSpecificStates = new VoiceSpecificRegistrationStates(cssSupported, roamingIndicator,
+        mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator,
                 systemIsInPrl, defaultRoamingIndicator);
     }
 
@@ -253,9 +255,9 @@
         this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
                 emergencyOnly, availableServices, cellIdentity);
 
-        mDataSpecificStates = new DataSpecificRegistrationStates(
+        mDataSpecificInfo = new DataSpecificRegistrationInfo(
                 maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo);
-        updateNrState(mDataSpecificStates);
+        updateNrState(mDataSpecificInfo);
     }
 
     private NetworkRegistrationInfo(Parcel source) {
@@ -269,10 +271,10 @@
         mAvailableServices = new ArrayList<>();
         source.readList(mAvailableServices, Integer.class.getClassLoader());
         mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader());
-        mVoiceSpecificStates = source.readParcelable(
-                VoiceSpecificRegistrationStates.class.getClassLoader());
-        mDataSpecificStates = source.readParcelable(
-                DataSpecificRegistrationStates.class.getClassLoader());
+        mVoiceSpecificInfo = source.readParcelable(
+                VoiceSpecificRegistrationInfo.class.getClassLoader());
+        mDataSpecificInfo = source.readParcelable(
+                DataSpecificRegistrationInfo.class.getClassLoader());
         mNrState = source.readInt();
     }
 
@@ -389,16 +391,16 @@
      * @hide
      */
     @Nullable
-    public VoiceSpecificRegistrationStates getVoiceSpecificStates() {
-        return mVoiceSpecificStates;
+    public VoiceSpecificRegistrationInfo getVoiceSpecificInfo() {
+        return mVoiceSpecificInfo;
     }
 
     /**
      * @return Data registration related info
      */
     @Nullable
-    public DataSpecificRegistrationStates getDataSpecificStates() {
-        return mDataSpecificStates;
+    public DataSpecificRegistrationInfo getDataSpecificInfo() {
+        return mDataSpecificInfo;
     }
 
     @Override
@@ -474,8 +476,8 @@
                         ? mAvailableServices.stream().map(type -> serviceTypeToString(type))
                         .collect(Collectors.joining(",")) : null) + "]")
                 .append(" cellIdentity=").append(mCellIdentity)
-                .append(" voiceSpecificStates=").append(mVoiceSpecificStates)
-                .append(" dataSpecificStates=").append(mDataSpecificStates)
+                .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
+                .append(" dataSpecificInfo=").append(mDataSpecificInfo)
                 .append(" nrState=").append(nrStateToString(mNrState))
                 .append("}").toString();
     }
@@ -484,7 +486,7 @@
     public int hashCode() {
         return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
                 mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
-                mCellIdentity, mVoiceSpecificStates, mDataSpecificStates, mNrState);
+                mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState);
     }
 
     @Override
@@ -505,8 +507,8 @@
                 && mEmergencyOnly == other.mEmergencyOnly
                 && mAvailableServices.equals(other.mAvailableServices)
                 && Objects.equals(mCellIdentity, other.mCellIdentity)
-                && Objects.equals(mVoiceSpecificStates, other.mVoiceSpecificStates)
-                && Objects.equals(mDataSpecificStates, other.mDataSpecificStates)
+                && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
+                && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
                 && mNrState == other.mNrState;
     }
 
@@ -521,8 +523,8 @@
         dest.writeBoolean(mEmergencyOnly);
         dest.writeList(mAvailableServices);
         dest.writeParcelable(mCellIdentity, 0);
-        dest.writeParcelable(mVoiceSpecificStates, 0);
-        dest.writeParcelable(mDataSpecificStates, 0);
+        dest.writeParcelable(mVoiceSpecificInfo, 0);
+        dest.writeParcelable(mDataSpecificInfo, 0);
         dest.writeInt(mNrState);
     }
 
@@ -543,7 +545,7 @@
      *
      * @param state data specific registration state contains the 5G NR indicators.
      */
-    private void updateNrState(DataSpecificRegistrationStates state) {
+    private void updateNrState(DataSpecificRegistrationInfo state) {
         mNrState = NR_STATE_NONE;
         if (state.isEnDcAvailable) {
             if (!state.isDcNrRestricted && state.isNrAvailable) {
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index df31f50..a794ba1 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1132,7 +1132,7 @@
     }
 
     /** @hide */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    @TestApi
     public void setVoiceRoamingType(@RoamingType int type) {
         NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -1153,7 +1153,7 @@
     }
 
     /** @hide */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    @TestApi
     public void setDataRoamingType(@RoamingType int type) {
         NetworkRegistrationInfo regState = getNetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
@@ -1855,6 +1855,7 @@
     /**
      * @hide
      */
+    @TestApi
     public void addNetworkRegistrationInfo(NetworkRegistrationInfo regState) {
         if (regState == null) return;
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 0d4d654..5df7bf7 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -7082,6 +7082,35 @@
     }
 
     /**
+     * Query Telephony to see if there has recently been an emergency SMS sent to the network by the
+     * user and we are still within the time interval after the emergency SMS was sent that we are
+     * considered in Emergency SMS mode.
+     *
+     * <p>This mode is used by other applications to allow them to perform special functionality,
+     * such as allow the GNSS service to provide user location to the carrier network for emergency
+     * when an emergency SMS is sent. This interval is set by
+     * {@link CarrierConfigManager#KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT}. If
+     * the carrier does not support this mode, this function will always return false.
+     *
+     * @return true if this device is in emergency SMS mode, false otherwise.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isInEmergencySmsMode() {
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.isInEmergencySmsMode();
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "getNetworkSelectionMode RemoteException", ex);
+        }
+        return false;
+    }
+
+    /**
      * Set the preferred network type.
      *
      * <p>Requires Permission:
diff --git a/telephony/java/android/telephony/VoiceSpecificRegistrationStates.java b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
similarity index 63%
rename from telephony/java/android/telephony/VoiceSpecificRegistrationStates.java
rename to telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
index d8ce5b4..18a533a 100644
--- a/telephony/java/android/telephony/VoiceSpecificRegistrationStates.java
+++ b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
@@ -1,5 +1,22 @@
+/*
+ * 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;
 
+import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -10,14 +27,14 @@
  * Class that stores information specific to voice network registration.
  * @hide
  */
-public class VoiceSpecificRegistrationStates implements Parcelable{
+public class VoiceSpecificRegistrationInfo implements Parcelable{
     /**
      * oncurrent services support indicator. if
      * registered on a CDMA system.
      * false - Concurrent services not supported,
      * true - Concurrent services supported
      */
-     public final boolean cssSupported;
+    public final boolean cssSupported;
 
     /**
      * TSB-58 Roaming Indicator if registered
@@ -40,15 +57,15 @@
      */
     public final int defaultRoamingIndicator;
 
-    VoiceSpecificRegistrationStates(boolean cssSupported, int roamingIndicator, int systemIsInPrl,
-            int defaultRoamingIndicator) {
+    VoiceSpecificRegistrationInfo(boolean cssSupported, int roamingIndicator, int systemIsInPrl,
+                                  int defaultRoamingIndicator) {
         this.cssSupported = cssSupported;
         this.roamingIndicator = roamingIndicator;
         this.systemIsInPrl = systemIsInPrl;
         this.defaultRoamingIndicator = defaultRoamingIndicator;
     }
 
-    private VoiceSpecificRegistrationStates(Parcel source) {
+    private VoiceSpecificRegistrationInfo(Parcel source) {
         this.cssSupported = source.readBoolean();
         this.roamingIndicator = source.readInt();
         this.systemIsInPrl = source.readInt();
@@ -70,7 +87,7 @@
 
     @Override
     public String toString() {
-        return "VoiceSpecificRegistrationStates {"
+        return "VoiceSpecificRegistrationInfo {"
                 + " mCssSupported=" + cssSupported
                 + " mRoamingIndicator=" + roamingIndicator
                 + " mSystemIsInPrl=" + systemIsInPrl
@@ -87,11 +104,11 @@
     public boolean equals(Object o) {
         if (this == o) return true;
 
-        if (o == null || !(o instanceof VoiceSpecificRegistrationStates)) {
+        if (o == null || !(o instanceof VoiceSpecificRegistrationInfo)) {
             return false;
         }
 
-        VoiceSpecificRegistrationStates other = (VoiceSpecificRegistrationStates) o;
+        VoiceSpecificRegistrationInfo other = (VoiceSpecificRegistrationInfo) o;
         return this.cssSupported == other.cssSupported
                 && this.roamingIndicator == other.roamingIndicator
                 && this.systemIsInPrl == other.systemIsInPrl
@@ -99,16 +116,16 @@
     }
 
 
-    public static final @android.annotation.NonNull Parcelable.Creator<VoiceSpecificRegistrationStates> CREATOR =
-            new Parcelable.Creator<VoiceSpecificRegistrationStates>() {
+    public static final @NonNull Parcelable.Creator<VoiceSpecificRegistrationInfo> CREATOR =
+            new Parcelable.Creator<VoiceSpecificRegistrationInfo>() {
                 @Override
-                public VoiceSpecificRegistrationStates createFromParcel(Parcel source) {
-                    return new VoiceSpecificRegistrationStates(source);
+                public VoiceSpecificRegistrationInfo createFromParcel(Parcel source) {
+                    return new VoiceSpecificRegistrationInfo(source);
                 }
 
                 @Override
-                public VoiceSpecificRegistrationStates[] newArray(int size) {
-                    return new VoiceSpecificRegistrationStates[size];
+                public VoiceSpecificRegistrationInfo[] newArray(int size) {
+                    return new VoiceSpecificRegistrationInfo[size];
                 }
             };
-}
\ No newline at end of file
+}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 10cc99e..d98f8d8 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1707,6 +1707,11 @@
      */
      int getNetworkSelectionMode(int subId);
 
+     /**
+     * Return true if the device is in emergency sms mode, false otherwise.
+     */
+     boolean isInEmergencySmsMode();
+
     /**
      * Get a list of SMS apps on a user.
      */
diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt
index 6765316..a87e2f5 100644
--- a/test-mock/api/test-current.txt
+++ b/test-mock/api/test-current.txt
@@ -3,6 +3,7 @@
 
   public class MockContext extends android.content.Context {
     method public android.view.Display getDisplay();
+    method public int getDisplayId();
   }
 
   @Deprecated public class MockPackageManager extends android.content.pm.PackageManager {
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index 5725f0c..4ce4406 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -31,6 +31,7 @@
     shared_libs: [
         "libstats_proto_host",
         "libprotobuf-cpp-full",
+        "libbase",
     ],
 
     proto: {
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index a8d970e..e66ead7 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -49,7 +49,9 @@
       exclusiveField(that.exclusiveField),
       uidField(that.uidField),
       whitelisted(that.whitelisted),
-      binaryFields(that.binaryFields) {}
+      binaryFields(that.binaryFields),
+      hasModule(that.hasModule),
+      moduleName(that.moduleName) {}
 
 AtomDecl::AtomDecl(int c, const string& n, const string& m)
     :code(c),
@@ -391,7 +393,12 @@
     AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name());
 
     if (atomField->options().GetExtension(os::statsd::allow_from_any_uid) == true) {
-      atomDecl.whitelisted = true;
+        atomDecl.whitelisted = true;
+    }
+
+    if (atomField->options().HasExtension(os::statsd::log_from_module)) {
+        atomDecl.hasModule = true;
+        atomDecl.moduleName = atomField->options().GetExtension(os::statsd::log_from_module);
     }
 
     vector<java_type_t> signature;
@@ -399,25 +406,49 @@
     if (atomDecl.primaryFields.size() != 0 && atomDecl.exclusiveField == 0) {
         errorCount++;
     }
-    atoms->signatures.insert(signature);
+
+    // Add the signature if does not already exist.
+    auto signature_to_modules_it = atoms->signatures_to_modules.find(signature);
+    if (signature_to_modules_it == atoms->signatures_to_modules.end()) {
+        set<string> modules;
+        if (atomDecl.hasModule) {
+            modules.insert(atomDecl.moduleName);
+        }
+        atoms->signatures_to_modules[signature] = modules;
+    } else {
+        if (atomDecl.hasModule) {
+            signature_to_modules_it->second.insert(atomDecl.moduleName);
+        }
+    }
     atoms->decls.insert(atomDecl);
 
     AtomDecl nonChainedAtomDecl(atomField->number(), atomField->name(), atom->name());
     vector<java_type_t> nonChainedSignature;
     if (get_non_chained_node(atom, &nonChainedAtomDecl, &nonChainedSignature)) {
-        atoms->non_chained_signatures.insert(nonChainedSignature);
+        auto it = atoms->non_chained_signatures_to_modules.find(signature);
+        if (it == atoms->non_chained_signatures_to_modules.end()) {
+            set<string> modules_non_chained;
+            if (atomDecl.hasModule) {
+                modules_non_chained.insert(atomDecl.moduleName);
+            }
+            atoms->non_chained_signatures_to_modules[nonChainedSignature] = modules_non_chained;
+        } else {
+            if (atomDecl.hasModule) {
+                it->second.insert(atomDecl.moduleName);
+            }
+        }
         atoms->non_chained_decls.insert(nonChainedAtomDecl);
     }
   }
 
   if (dbg) {
     printf("signatures = [\n");
-    for (set<vector<java_type_t>>::const_iterator it =
-             atoms->signatures.begin();
-         it != atoms->signatures.end(); it++) {
+    for (map<vector<java_type_t>, set<string>>::const_iterator it =
+             atoms->signatures_to_modules.begin();
+         it != atoms->signatures_to_modules.end(); it++) {
       printf("   ");
-      for (vector<java_type_t>::const_iterator jt = it->begin();
-           jt != it->end(); jt++) {
+      for (vector<java_type_t>::const_iterator jt = it->first.begin();
+           jt != it->first.end(); jt++) {
         printf(" %d", (int)*jt);
       }
       printf("\n");
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index 6b86b862..44746c9 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -93,6 +93,9 @@
 
     vector<int> binaryFields;
 
+    bool hasModule = false;
+    string moduleName;
+
     AtomDecl();
     AtomDecl(const AtomDecl& that);
     AtomDecl(int code, const string& name, const string& message);
@@ -104,10 +107,10 @@
 };
 
 struct Atoms {
-    set<vector<java_type_t>> signatures;
+    map<vector<java_type_t>, set<string>> signatures_to_modules;
     set<AtomDecl> decls;
     set<AtomDecl> non_chained_decls;
-    set<vector<java_type_t>> non_chained_signatures;
+    map<vector<java_type_t>, set<string>> non_chained_signatures_to_modules;
 };
 
 /**
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 0270c72..daee6d6 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -12,6 +12,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "android-base/strings.h"
+
 using namespace google::protobuf;
 using namespace std;
 
@@ -20,6 +22,10 @@
 
 int maxPushedAtomId = 2;
 
+const string DEFAULT_MODULE_NAME = "DEFAULT";
+const string DEFAULT_CPP_NAMESPACE = "android,util";
+const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
+
 using android::os::statsd::Atom;
 
 /**
@@ -97,40 +103,27 @@
     }
 }
 
-static int write_stats_log_cpp(FILE *out, const Atoms &atoms,
-                               const AtomDecl &attributionDecl) {
-    // Print prelude
-    fprintf(out, "// This file is autogenerated\n");
-    fprintf(out, "\n");
+static bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName) {
+    if (moduleName == DEFAULT_MODULE_NAME) {
+        return true;
+    }
+    return atomDecl.hasModule && (moduleName == atomDecl.moduleName);
+}
 
-    fprintf(out, "#include <mutex>\n");
-    fprintf(out, "#include <chrono>\n");
-    fprintf(out, "#include <thread>\n");
-    fprintf(out, "#ifdef __ANDROID__\n");
-    fprintf(out, "#include <cutils/properties.h>\n");
-    fprintf(out, "#endif\n");
-    fprintf(out, "#include <stats_event_list.h>\n");
-    fprintf(out, "#include <log/log.h>\n");
-    fprintf(out, "#include <statslog.h>\n");
-    fprintf(out, "#include <utils/SystemClock.h>\n");
-    fprintf(out, "\n");
+static bool signature_needed_for_module(const set<string>& modules, const string& moduleName) {
+    if (moduleName == DEFAULT_MODULE_NAME) {
+        return true;
+    }
+    return modules.find(moduleName) != modules.end();
+}
 
-    fprintf(out, "namespace android {\n");
-    fprintf(out, "namespace util {\n");
-    fprintf(out, "// the single event tag id for all stats logs\n");
-    fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
-    fprintf(out, "#ifdef __ANDROID__\n");
-    fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
-    fprintf(out, "#else\n");
-    fprintf(out, "const static bool kStatsdEnabled = false;\n");
-    fprintf(out, "#endif\n");
-
+static void write_atoms_info_cpp(FILE *out, const Atoms &atoms) {
     std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed",
-                                             "audio_state_changed",
-                                             "call_state_changed",
-                                             "phone_signal_strength_changed",
-                                             "mobile_bytes_transfer_by_fg_bg",
-                                             "mobile_bytes_transfer"};
+                                                 "audio_state_changed",
+                                                 "call_state_changed",
+                                                 "phone_signal_strength_changed",
+                                                 "mobile_bytes_transfer_by_fg_bg",
+                                                 "mobile_bytes_transfer"};
     fprintf(out,
             "const std::set<int> "
             "AtomsInfo::kNotTruncatingTimestampAtomWhiteList = {\n");
@@ -256,6 +249,56 @@
             "const std::map<int, std::vector<int>> "
             "AtomsInfo::kBytesFieldAtoms = "
             "getBinaryFieldAtoms();\n");
+}
+
+// Writes namespaces for the cpp and header files, returning the number of namespaces written.
+void write_namespace(FILE* out, const string& cppNamespaces) {
+    vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ",");
+    for (string cppNamespace : cppNamespaceVec) {
+        fprintf(out, "namespace %s {\n", cppNamespace.c_str());
+    }
+}
+
+// Writes namespace closing brackets for cpp and header files.
+void write_closing_namespace(FILE* out, const string& cppNamespaces) {
+    vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ",");
+    for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) {
+        fprintf(out, "} // namespace %s\n", it->c_str());
+    }
+}
+
+static int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl,
+                               const string& moduleName, const string& cppNamespace,
+                               const string& importHeader) {
+    // Print prelude
+    fprintf(out, "// This file is autogenerated\n");
+    fprintf(out, "\n");
+
+    fprintf(out, "#include <mutex>\n");
+    fprintf(out, "#include <chrono>\n");
+    fprintf(out, "#include <thread>\n");
+    fprintf(out, "#ifdef __ANDROID__\n");
+    fprintf(out, "#include <cutils/properties.h>\n");
+    fprintf(out, "#endif\n");
+    fprintf(out, "#include <stats_event_list.h>\n");
+    fprintf(out, "#include <log/log.h>\n");
+    fprintf(out, "#include <%s>\n", importHeader.c_str());
+    fprintf(out, "#include <utils/SystemClock.h>\n");
+    fprintf(out, "\n");
+
+    write_namespace(out, cppNamespace);
+    fprintf(out, "// the single event tag id for all stats logs\n");
+    fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
+    fprintf(out, "#ifdef __ANDROID__\n");
+    fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
+    fprintf(out, "#else\n");
+    fprintf(out, "const static bool kStatsdEnabled = false;\n");
+    fprintf(out, "#endif\n");
+
+    // AtomsInfo is only used by statsd internally and is not needed for other modules.
+    if (moduleName == DEFAULT_MODULE_NAME) {
+        write_atoms_info_cpp(out, atoms);
+    }
 
     fprintf(out, "int64_t lastRetryTimestampNs = -1;\n");
     fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n");
@@ -263,15 +306,19 @@
 
     // Print write methods
     fprintf(out, "\n");
-    for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin();
-        signature != atoms.signatures.end(); signature++) {
+    for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
+        signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) {
+        if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+            continue;
+        }
+        vector<java_type_t> signature = signature_to_modules_it->first;
         int argIndex;
 
         fprintf(out, "int\n");
         fprintf(out, "try_stats_write(int32_t code");
         argIndex = 1;
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-            arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+            arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 for (auto chainField : attributionDecl.fields) {
                     if (chainField.javaType == JAVA_TYPE_STRING) {
@@ -303,8 +350,8 @@
         fprintf(out, "    stats_event_list event(kStatsEventTag);\n");
         fprintf(out, "    event << android::elapsedRealtimeNano();\n\n");
         fprintf(out, "    event << code;\n\n");
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-            arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+            arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 for (const auto &chainField : attributionDecl.fields) {
                     if (chainField.javaType == JAVA_TYPE_STRING) {
@@ -387,15 +434,19 @@
         fprintf(out, "\n");
     }
 
-   for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin();
-       signature != atoms.signatures.end(); signature++) {
+   for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
+       signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) {
+       if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+           continue;
+       }
+       vector<java_type_t> signature = signature_to_modules_it->first;
        int argIndex;
 
        fprintf(out, "int\n");
        fprintf(out, "stats_write(int32_t code");
        argIndex = 1;
-       for (vector<java_type_t>::const_iterator arg = signature->begin();
-           arg != signature->end(); arg++) {
+       for (vector<java_type_t>::const_iterator arg = signature.begin();
+           arg != signature.end(); arg++) {
            if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                for (auto chainField : attributionDecl.fields) {
                    if (chainField.javaType == JAVA_TYPE_STRING) {
@@ -429,8 +480,8 @@
        fprintf(out, "      ret =  try_stats_write(code");
 
        argIndex = 1;
-       for (vector<java_type_t>::const_iterator arg = signature->begin();
-           arg != signature->end(); arg++) {
+       for (vector<java_type_t>::const_iterator arg = signature.begin();
+           arg != signature.end(); arg++) {
            if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                for (auto chainField : attributionDecl.fields) {
                    if (chainField.javaType == JAVA_TYPE_STRING) {
@@ -468,15 +519,19 @@
        fprintf(out, "\n");
    }
 
-    for (set<vector<java_type_t>>::const_iterator signature = atoms.non_chained_signatures.begin();
-        signature != atoms.non_chained_signatures.end(); signature++) {
+    for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
+            signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
+        if (!signature_needed_for_module(signature_it->second, moduleName)) {
+            continue;
+        }
+        vector<java_type_t> signature = signature_it->first;
         int argIndex;
 
         fprintf(out, "int\n");
         fprintf(out, "try_stats_write_non_chained(int32_t code");
         argIndex = 1;
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-            arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+            arg != signature.end(); arg++) {
             fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
             argIndex++;
         }
@@ -488,8 +543,8 @@
         fprintf(out, "    stats_event_list event(kStatsEventTag);\n");
         fprintf(out, "    event << android::elapsedRealtimeNano();\n\n");
         fprintf(out, "    event << code;\n\n");
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-            arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+            arg != signature.end(); arg++) {
             if (argIndex == 1) {
                 fprintf(out, "    event.begin();\n\n");
                 fprintf(out, "    event.begin();\n");
@@ -522,15 +577,19 @@
         fprintf(out, "\n");
     }
 
-   for (set<vector<java_type_t>>::const_iterator signature = atoms.non_chained_signatures.begin();
-       signature != atoms.non_chained_signatures.end(); signature++) {
+    for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
+            signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
+       if (!signature_needed_for_module(signature_it->second, moduleName)) {
+           continue;
+       }
+       vector<java_type_t> signature = signature_it->first;
        int argIndex;
 
        fprintf(out, "int\n");
        fprintf(out, "stats_write_non_chained(int32_t code");
        argIndex = 1;
-       for (vector<java_type_t>::const_iterator arg = signature->begin();
-           arg != signature->end(); arg++) {
+       for (vector<java_type_t>::const_iterator arg = signature.begin();
+           arg != signature.end(); arg++) {
            fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
            argIndex++;
        }
@@ -543,8 +602,8 @@
        fprintf(out, "      ret =  try_stats_write_non_chained(code");
 
        argIndex = 1;
-       for (vector<java_type_t>::const_iterator arg = signature->begin();
-           arg != signature->end(); arg++) {
+       for (vector<java_type_t>::const_iterator arg = signature.begin();
+           arg != signature.end(); arg++) {
            fprintf(out, ", arg%d",   argIndex);
            argIndex++;
        }
@@ -572,8 +631,7 @@
 
     // Print footer
     fprintf(out, "\n");
-    fprintf(out, "} // namespace util\n");
-    fprintf(out, "} // namespace android\n");
+    write_closing_namespace(out, cppNamespace);
 
     return 0;
 }
@@ -623,14 +681,23 @@
 }
 
 static void write_cpp_method_header(
-    FILE* out, const string& method_name, const set<vector<java_type_t>>& signatures,
-    const AtomDecl &attributionDecl) {
-    for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
-            signature != signatures.end(); signature++) {
+        FILE* out,
+        const string& method_name,
+        const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+        const AtomDecl &attributionDecl, const string& moduleName) {
+
+    for (auto signature_to_modules_it = signatures_to_modules.begin();
+            signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+        // Skip if this signature is not needed for the module.
+        if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
+            continue;
+        }
+
+        vector<java_type_t> signature = signature_to_modules_it->first;
         fprintf(out, "int %s(int32_t code", method_name.c_str());
         int argIndex = 1;
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-            arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 for (auto chainField : attributionDecl.fields) {
                     if (chainField.javaType == JAVA_TYPE_STRING) {
@@ -659,7 +726,8 @@
 }
 
 static int
-write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl)
+write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+        const string& moduleName, const string& cppNamespace)
 {
     // Print prelude
     fprintf(out, "// This file is autogenerated\n");
@@ -672,8 +740,7 @@
     fprintf(out, "#include <set>\n");
     fprintf(out, "\n");
 
-    fprintf(out, "namespace android {\n");
-    fprintf(out, "namespace util {\n");
+    write_namespace(out, cppNamespace);
     fprintf(out, "\n");
     fprintf(out, "/*\n");
     fprintf(out, " * API For logging statistics events.\n");
@@ -691,6 +758,10 @@
     // Print atom constants
     for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
         atom != atoms.decls.end(); atom++) {
+        // Skip if the atom is not needed for the module.
+        if (!atom_needed_for_module(*atom, moduleName)) {
+            continue;
+        }
         string constant = make_constant_name(atom->name);
         fprintf(out, "\n");
         fprintf(out, "    /**\n");
@@ -720,6 +791,11 @@
     fprintf(out, "//\n\n");
     for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
         atom != atoms.decls.end(); atom++) {
+        // Skip if the atom is not needed for the module.
+        if (!atom_needed_for_module(*atom, moduleName)) {
+            continue;
+        }
+
         for (vector<AtomField>::const_iterator field = atom->fields.begin();
             field != atom->fields.end(); field++) {
             if (field->javaType == JAVA_TYPE_ENUM) {
@@ -747,47 +823,51 @@
     fprintf(out, "};\n");
     fprintf(out, "\n");
 
-    fprintf(out, "struct StateAtomFieldOptions {\n");
-    fprintf(out, "  std::vector<int> primaryFields;\n");
-    fprintf(out, "  int exclusiveField;\n");
-    fprintf(out, "};\n");
-    fprintf(out, "\n");
+    // This metadata is only used by statsd, which uses the default libstatslog.
+    if (moduleName == DEFAULT_MODULE_NAME) {
 
-    fprintf(out, "struct AtomsInfo {\n");
-    fprintf(out,
-            "  const static std::set<int> "
-            "kNotTruncatingTimestampAtomWhiteList;\n");
-    fprintf(out, "  const static std::map<int, int> kAtomsWithUidField;\n");
-    fprintf(out,
-            "  const static std::set<int> kAtomsWithAttributionChain;\n");
-    fprintf(out,
-            "  const static std::map<int, StateAtomFieldOptions> "
-            "kStateAtomsFieldOptions;\n");
-    fprintf(out,
-            "  const static std::map<int, std::vector<int>> "
-            "kBytesFieldAtoms;");
-    fprintf(out,
-            "  const static std::set<int> kWhitelistedAtoms;\n");
-    fprintf(out, "};\n");
+        fprintf(out, "struct StateAtomFieldOptions {\n");
+        fprintf(out, "  std::vector<int> primaryFields;\n");
+        fprintf(out, "  int exclusiveField;\n");
+        fprintf(out, "};\n");
+        fprintf(out, "\n");
 
-    fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n",
-            maxPushedAtomId);
+        fprintf(out, "struct AtomsInfo {\n");
+        fprintf(out,
+                "  const static std::set<int> "
+                "kNotTruncatingTimestampAtomWhiteList;\n");
+        fprintf(out, "  const static std::map<int, int> kAtomsWithUidField;\n");
+        fprintf(out,
+                "  const static std::set<int> kAtomsWithAttributionChain;\n");
+        fprintf(out,
+                "  const static std::map<int, StateAtomFieldOptions> "
+                "kStateAtomsFieldOptions;\n");
+        fprintf(out,
+                "  const static std::map<int, std::vector<int>> "
+                "kBytesFieldAtoms;");
+        fprintf(out,
+                "  const static std::set<int> kWhitelistedAtoms;\n");
+        fprintf(out, "};\n");
+
+        fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n",
+                maxPushedAtomId);
+    }
 
     // Print write methods
     fprintf(out, "//\n");
     fprintf(out, "// Write methods\n");
     fprintf(out, "//\n");
-    write_cpp_method_header(out, "stats_write", atoms.signatures, attributionDecl);
+    write_cpp_method_header(out, "stats_write", atoms.signatures_to_modules, attributionDecl,
+            moduleName);
 
     fprintf(out, "//\n");
     fprintf(out, "// Write flattened methods\n");
     fprintf(out, "//\n");
-    write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures,
-        attributionDecl);
+    write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures_to_modules,
+        attributionDecl, moduleName);
 
     fprintf(out, "\n");
-    fprintf(out, "} // namespace util\n");
-    fprintf(out, "} // namespace android\n");
+    write_closing_namespace(out, cppNamespace);
 
     return 0;
 }
@@ -812,15 +892,19 @@
 }
 
 static void write_java_method(
-    FILE* out, const string& method_name, const set<vector<java_type_t>>& signatures,
-    const AtomDecl &attributionDecl) {
-    for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
-        signature != signatures.end(); signature++) {
+        FILE* out,
+        const string& method_name,
+        const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+        const AtomDecl &attributionDecl) {
+
+    for (auto signature_to_modules_it = signatures_to_modules.begin();
+            signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+        vector<java_type_t> signature = signature_to_modules_it->first;
         fprintf(out, "    /** @hide */\n");
         fprintf(out, "    public static native int %s(int code", method_name.c_str());
         int argIndex = 1;
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-            arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+            arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 for (auto chainField : attributionDecl.fields) {
                     fprintf(out, ", %s[] %s",
@@ -837,15 +921,17 @@
     }
 }
 
-static void write_java_work_source_method(FILE* out, const set<vector<java_type_t>>& signatures) {
+static void write_java_work_source_method(FILE* out,
+        const map<vector<java_type_t>, set<string>>& signatures_to_modules) {
     fprintf(out, "\n    // WorkSource methods.\n");
-    for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
-            signature != signatures.end(); signature++) {
+    for (auto signature_to_modules_it = signatures_to_modules.begin();
+            signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+        vector<java_type_t> signature = signature_to_modules_it->first;
         // Determine if there is Attribution in this signature.
         int attributionArg = -1;
         int argIndexMax = 0;
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-                arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
             argIndexMax++;
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 if (attributionArg > -1) {
@@ -865,8 +951,8 @@
         fprintf(out, "    /** @hide */\n");
         fprintf(out, "    public static void write(int code");
         int argIndex = 1;
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-                arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 fprintf(out, ", WorkSource ws");
             } else {
@@ -974,9 +1060,10 @@
 
     // Print write methods
     fprintf(out, "    // Write methods\n");
-    write_java_method(out, "write", atoms.signatures, attributionDecl);
-    write_java_method(out, "write_non_chained", atoms.non_chained_signatures, attributionDecl);
-    write_java_work_source_method(out, atoms.signatures);
+    write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl);
+    write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
+            attributionDecl);
+    write_java_work_source_method(out, atoms.signatures_to_modules);
 
     fprintf(out, "}\n");
 
@@ -1154,19 +1241,20 @@
 
 static int
 write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp_method_name,
-    const set<vector<java_type_t>>& signatures, const AtomDecl &attributionDecl)
-{
+        const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+        const AtomDecl &attributionDecl) {
     // Print write methods
-    for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
-        signature != signatures.end(); signature++) {
+    for (auto signature_to_modules_it = signatures_to_modules.begin();
+            signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+        vector<java_type_t> signature = signature_to_modules_it->first;
         int argIndex;
 
         fprintf(out, "static int\n");
         fprintf(out, "%s(JNIEnv* env, jobject clazz UNUSED, jint code",
-                jni_function_name(java_method_name, *signature).c_str());
+                jni_function_name(java_method_name, signature).c_str());
         argIndex = 1;
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-                arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 for (auto chainField : attributionDecl.fields) {
                     fprintf(out, ", %s %s", jni_array_type_name(chainField.javaType),
@@ -1187,8 +1275,8 @@
         argIndex = 1;
         bool hadStringOrChain = false;
         bool isKeyValuePairAtom = false;
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-                arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_STRING) {
                 hadStringOrChain = true;
                 fprintf(out, "    const char* str%d;\n", argIndex);
@@ -1288,8 +1376,8 @@
         argIndex = 1;
         fprintf(out, "\n    int ret =  android::util::%s(code",
                 cpp_method_name.c_str());
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-                arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 for (auto chainField : attributionDecl.fields) {
                     if (chainField.javaType == JAVA_TYPE_INT) {
@@ -1316,8 +1404,8 @@
 
         // Clean up strings
         argIndex = 1;
-        for (vector<java_type_t>::const_iterator arg = signature->begin();
-                arg != signature->end(); arg++) {
+        for (vector<java_type_t>::const_iterator arg = signature.begin();
+                arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_STRING) {
                 fprintf(out, "    if (str%d != NULL) {\n", argIndex);
                 fprintf(out, "        env->ReleaseStringUTFChars(arg%d, str%d);\n",
@@ -1357,13 +1445,15 @@
 }
 
 void write_jni_registration(FILE* out, const string& java_method_name,
-    const set<vector<java_type_t>>& signatures, const AtomDecl &attributionDecl) {
-    for (set<vector<java_type_t>>::const_iterator signature = signatures.begin();
-            signature != signatures.end(); signature++) {
+        const map<vector<java_type_t>, set<string>>& signatures_to_modules,
+        const AtomDecl &attributionDecl) {
+    for (auto signature_to_modules_it = signatures_to_modules.begin();
+            signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
+        vector<java_type_t> signature = signature_to_modules_it->first;
         fprintf(out, "    { \"%s\", \"%s\", (void*)%s },\n",
             java_method_name.c_str(),
-            jni_function_signature(*signature, attributionDecl).c_str(),
-            jni_function_name(java_method_name, *signature).c_str());
+            jni_function_signature(signature, attributionDecl).c_str(),
+            jni_function_name(java_method_name, signature).c_str());
     }
 }
 
@@ -1388,25 +1478,26 @@
     fprintf(out, "namespace android {\n");
     fprintf(out, "\n");
 
-    write_stats_log_jni(out, "write", "stats_write", atoms.signatures, attributionDecl);
+    write_stats_log_jni(out, "write", "stats_write", atoms.signatures_to_modules, attributionDecl);
     write_stats_log_jni(out, "write_non_chained", "stats_write_non_chained",
-        atoms.non_chained_signatures, attributionDecl);
+            atoms.non_chained_signatures_to_modules, attributionDecl);
 
     // Print registration function table
     fprintf(out, "/*\n");
     fprintf(out, " * JNI registration.\n");
     fprintf(out, " */\n");
     fprintf(out, "static const JNINativeMethod gRegisterMethods[] = {\n");
-    write_jni_registration(out, "write", atoms.signatures, attributionDecl);
-    write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures, attributionDecl);
+    write_jni_registration(out, "write", atoms.signatures_to_modules, attributionDecl);
+    write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
+            attributionDecl);
     fprintf(out, "};\n");
     fprintf(out, "\n");
 
     // Print registration function
-    fprintf(out, "int register_android_util_StatsLog(JNIEnv* env) {\n");
+    fprintf(out, "int register_android_util_StatsLogInternal(JNIEnv* env) {\n");
     fprintf(out, "    return RegisterMethodsOrDie(\n");
     fprintf(out, "            env,\n");
-    fprintf(out, "            \"android/util/StatsLog\",\n");
+    fprintf(out, "            \"android/util/StatsLogInternal\",\n");
     fprintf(out, "            gRegisterMethods, NELEM(gRegisterMethods));\n");
     fprintf(out, "}\n");
 
@@ -1426,6 +1517,10 @@
     fprintf(stderr, "  --help               this message\n");
     fprintf(stderr, "  --java FILENAME      the java file to output\n");
     fprintf(stderr, "  --jni FILENAME       the jni file to output\n");
+    fprintf(stderr, "  --module NAME        optional, module name to generate outputs for\n");
+    fprintf(stderr, "  --namespace COMMA,SEP,NAMESPACE   required for cpp/header with module\n");
+    fprintf(stderr, "                                    comma separated namespace of the files\n");
+    fprintf(stderr, "  --importHeader NAME  required for cpp/jni to say which header to import\n");
 }
 
 /**
@@ -1439,6 +1534,10 @@
     string javaFilename;
     string jniFilename;
 
+    string moduleName = DEFAULT_MODULE_NAME;
+    string cppNamespace = DEFAULT_CPP_NAMESPACE;
+    string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
+
     int index = 1;
     while (index < argc) {
         if (0 == strcmp("--help", argv[index])) {
@@ -1472,6 +1571,27 @@
                 return 1;
             }
             jniFilename = argv[index];
+        } else if (0 == strcmp("--module", argv[index])) {
+            index++;
+            if (index >= argc) {
+                print_usage();
+                return 1;
+            }
+            moduleName = argv[index];
+        } else if (0 == strcmp("--namespace", argv[index])) {
+            index++;
+            if (index >= argc) {
+                print_usage();
+                return 1;
+            }
+            cppNamespace = argv[index];
+        } else if (0 == strcmp("--importHeader", argv[index])) {
+            index++;
+            if (index >= argc) {
+                print_usage();
+                return 1;
+            }
+            cppHeaderImport = argv[index];
         }
         index++;
     }
@@ -1503,8 +1623,18 @@
             fprintf(stderr, "Unable to open file for write: %s\n", cppFilename.c_str());
             return 1;
         }
+        // If this is for a specific module, the namespace must also be provided.
+        if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) {
+            fprintf(stderr, "Must supply --namespace if supplying a specific module\n");
+            return 1;
+        }
+        // If this is for a specific module, the header file to import must also be provided.
+        if (moduleName != DEFAULT_MODULE_NAME && cppHeaderImport == DEFAULT_CPP_HEADER_IMPORT) {
+            fprintf(stderr, "Must supply --headerImport if supplying a specific module\n");
+            return 1;
+        }
         errorCount = android::stats_log_api_gen::write_stats_log_cpp(
-            out, atoms, attributionDecl);
+            out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport);
         fclose(out);
     }
 
@@ -1515,8 +1645,12 @@
             fprintf(stderr, "Unable to open file for write: %s\n", headerFilename.c_str());
             return 1;
         }
+        // If this is for a specific module, the namespace must also be provided.
+        if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) {
+            fprintf(stderr, "Must supply --namespace if supplying a specific module\n");
+        }
         errorCount = android::stats_log_api_gen::write_stats_log_header(
-            out, atoms, attributionDecl);
+            out, atoms, attributionDecl, moduleName, cppNamespace);
         fclose(out);
     }
 
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index 24ebf4d..c3e70382 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -213,4 +213,24 @@
     // by whitelisted sources
     NonWhitelistedAtom non_whitelisted_atom = 2;
   }
+}
+
+message ModuleOneAtom {
+    optional int32 field = 1;
+}
+
+message ModuleTwoAtom {
+    optional int32 field = 1;
+}
+
+message NoModuleAtom {
+    optional string field = 1;
+}
+
+message ModuleAtoms {
+    oneof event {
+        ModuleOneAtom module_one_atom = 1 [(android.os.statsd.log_from_module) = "module1"];
+        ModuleTwoAtom module_two_atom = 2 [(android.os.statsd.log_from_module) = "module2"];
+        NoModuleAtom no_module_atom = 3;
+    }
 }
\ No newline at end of file
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index dc585c1..bcf18ae 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -32,7 +32,7 @@
  * Return whether the set contains a vector of the elements provided.
  */
 static bool
-set_contains_vector(const set<vector<java_type_t>>& s, int count, ...)
+set_contains_vector(const map<vector<java_type_t>, set<string>>& s, int count, ...)
 {
     va_list args;
     vector<java_type_t> v;
@@ -86,17 +86,17 @@
     int errorCount = collate_atoms(Event::descriptor(), &atoms);
 
     EXPECT_EQ(0, errorCount);
-    EXPECT_EQ(3ul, atoms.signatures.size());
+    EXPECT_EQ(3ul, atoms.signatures_to_modules.size());
 
     // IntAtom, AnotherIntAtom
-    EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT);
+    EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT);
 
     // OutOfOrderAtom
-    EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT, JAVA_TYPE_INT);
+    EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT, JAVA_TYPE_INT);
 
     // AllTypesAtom
     EXPECT_SET_CONTAINS_SIGNATURE(
-        atoms.signatures,
+        atoms.signatures_to_modules,
         JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain
         JAVA_TYPE_DOUBLE,            // double
         JAVA_TYPE_FLOAT,             // float
@@ -228,8 +228,7 @@
 
 TEST(CollationTest, PassOnWhitelistedAtom) {
     Atoms atoms;
-    int errorCount =
-            collate_atoms(ListedAtoms::descriptor(), &atoms);
+    int errorCount = collate_atoms(ListedAtoms::descriptor(), &atoms);
     EXPECT_EQ(errorCount, 0);
     EXPECT_EQ(atoms.decls.size(), 2ul);
 }
@@ -246,5 +245,46 @@
     }
 }
 
+TEST(CollationTest, PassOnLogFromModuleAtom) {
+    Atoms atoms;
+    int errorCount = collate_atoms(ModuleAtoms::descriptor(), &atoms);
+    EXPECT_EQ(errorCount, 0);
+    EXPECT_EQ(atoms.decls.size(), 3ul);
+}
+
+TEST(CollationTest, RecognizeModuleAtom) {
+    Atoms atoms;
+    int errorCount = collate_atoms(ModuleAtoms::descriptor(), &atoms);
+    EXPECT_EQ(errorCount, 0);
+    EXPECT_EQ(atoms.decls.size(), 3ul);
+    for (const auto& atomDecl: atoms.decls) {
+        if (atomDecl.code == 1) {
+            EXPECT_TRUE(atomDecl.hasModule);
+            EXPECT_EQ(atomDecl.moduleName, "module1");
+        } else if (atomDecl.code == 2) {
+            EXPECT_TRUE(atomDecl.hasModule);
+            EXPECT_EQ(atomDecl.moduleName, "module2");
+        } else {
+            EXPECT_FALSE(atomDecl.hasModule);
+        }
+    }
+
+    EXPECT_EQ(atoms.signatures_to_modules.size(), 2u);
+    EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT);
+    EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_STRING);
+    for (auto signature_to_modules_it : atoms.signatures_to_modules) {
+        vector<java_type_t> signature = signature_to_modules_it.first;
+        if (signature[0] == JAVA_TYPE_STRING) {
+            EXPECT_EQ(signature_to_modules_it.second.size(), 0u);
+        } else if (signature[0] == JAVA_TYPE_INT) {
+            set<string> modules = signature_to_modules_it.second;
+            EXPECT_EQ(modules.size(), 2u);
+            // Assert that the set contains "module1" and "module2".
+            EXPECT_NE(modules.find("module1"), modules.end());
+            EXPECT_NE(modules.find("module2"), modules.end());
+        }
+    }
+}
+
 }  // namespace stats_log_api_gen
 }  // namespace android
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
index 01176f2..e595164 100644
--- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
+++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
@@ -345,7 +345,7 @@
     }
 
     /** Whether the primary registered cell of current entry is same as that of previous entry */
-    public boolean getIsSameRegisteredCell() {
+    public boolean isSameRegisteredCell() {
         return mIsSameRegisteredCell;
     }
 }
diff --git a/wifi/java/android/net/wifi/rtt/ResponderLocation.java b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
index 37d5f0a..e1d82f8 100644
--- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java
+++ b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
@@ -1169,6 +1169,8 @@
      * (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
      * <p>
      * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
+     *
+     * @hide
      */
     public boolean getRegisteredLocationDseIndication() {
         if (!mIsLciValid) {
@@ -1185,6 +1187,8 @@
      * (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
      * <p>
      * Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
+     *
+     * @hide
      */
     public boolean getDependentStationIndication() {
         if (!mIsLciValid) {
diff --git a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
index cd60f02..5184152 100644
--- a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
@@ -116,6 +116,6 @@
         assertEquals(expected.getCellularSignalStrengthDbm(),
                 actual.getCellularSignalStrengthDbm());
         assertEquals(expected.getCellularSignalStrengthDb(), actual.getCellularSignalStrengthDb());
-        assertEquals(expected.getIsSameRegisteredCell(), actual.getIsSameRegisteredCell());
+        assertEquals(expected.isSameRegisteredCell(), actual.isSameRegisteredCell());
     }
 }