Merge "Update task manager ui information on dialog opening" into tm-dev am: 02ee782a23 am: 4dafc8e525 am: 405a90c708

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17667592

Change-Id: Iea04d75ca169dcd381b435146b91b994dddcb17f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index df6fdaa..6892205 100644
--- a/Android.bp
+++ b/Android.bp
@@ -265,6 +265,60 @@
     ],
     aidl: {
         generate_get_transaction_name: true,
+        enforce_permissions: true,
+        enforce_permissions_exceptions: [
+            // Do not add entries to this list.
+            ":framework-annotations",
+            ":framework-blobstore-sources",
+            ":framework-core-sources",
+            ":framework-drm-sources",
+            ":framework-graphics-nonupdatable-sources",
+            ":framework-jobscheduler-sources",
+            ":framework-keystore-sources",
+            ":framework-identity-sources",
+            ":framework-location-sources",
+            ":framework-lowpan-sources",
+            ":framework-mca-effect-sources",
+            ":framework-mca-filterfw-sources",
+            ":framework-mca-filterpacks-sources",
+            ":framework-media-non-updatable-sources",
+            ":framework-mms-sources",
+            ":framework-omapi-sources",
+            ":framework-opengl-sources",
+            ":framework-rs-sources",
+            ":framework-sax-sources",
+            ":framework-telecomm-sources",
+            ":framework-telephony-common-sources",
+            ":framework-telephony-sources",
+            ":framework-vcn-util-sources",
+            ":framework-wifi-annotations",
+            ":framework-wifi-non-updatable-sources",
+            ":PacProcessor-aidl-sources",
+            ":ProxyHandler-aidl-sources",
+            ":net-utils-framework-common-srcs",
+            ":platform-compat-native-aidl",
+            ":credstore_aidl",
+            ":dumpstate_aidl",
+            ":framework_native_aidl",
+            ":gatekeeper_aidl",
+            ":gsiservice_aidl",
+            ":idmap2_aidl",
+            ":idmap2_core_aidl",
+            ":incidentcompanion_aidl",
+            ":inputconstants_aidl",
+            ":installd_aidl",
+            ":libaudioclient_aidl",
+            ":libbinder_aidl",
+            ":libbluetooth-binder-aidl",
+            ":libcamera_client_aidl",
+            ":libcamera_client_framework_aidl",
+            ":libupdate_engine_aidl",
+            ":logd_aidl",
+            ":resourcemanager_aidl",
+            ":storaged_aidl",
+            ":vold_aidl",
+            ":deviceproductinfoconstants_aidl",
+        ],
         local_include_dirs: [
             "media/aidl",
         ],
diff --git a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
index 4cd9741..086e185 100644
--- a/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
+++ b/apct-tests/perftests/core/src/android/view/HandwritingInitiatorPerfTest.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
+import android.util.DisplayMetrics;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputMethodManager;
 
@@ -59,10 +60,13 @@
     public void setup() {
         final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mContext = mInstrumentation.getTargetContext();
-        ViewConfiguration viewConfiguration = ViewConfiguration.get(mContext);
+        final ViewConfiguration viewConfiguration = ViewConfiguration.get(mContext);
         mTouchSlop = viewConfiguration.getScaledTouchSlop();
-        InputMethodManager inputMethodManager = mContext.getSystemService(InputMethodManager.class);
-        mHandwritingInitiator = new HandwritingInitiator(viewConfiguration, inputMethodManager);
+        final InputMethodManager inputMethodManager =
+                mContext.getSystemService(InputMethodManager.class);
+        final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+        mHandwritingInitiator = new HandwritingInitiator(viewConfiguration, inputMethodManager,
+                displayMetrics);
     }
 
     @Test
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 6ef6845..18ec5a4 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -23,6 +23,7 @@
 
 cc_defaults {
     name: "idmap2_defaults",
+    cpp_std: "gnu++2b",
     tidy: true,
     tidy_checks: [
         "modernize-*",
@@ -31,6 +32,7 @@
         "android-*",
         "misc-*",
         "readability-*",
+        "-readability-identifier-length",
     ],
     tidy_checks_as_errors: [
         "modernize-*",
@@ -54,7 +56,6 @@
         "-readability-convert-member-functions-to-static",
         "-readability-duplicate-include",
         "-readability-else-after-return",
-        "-readability-identifier-length",
         "-readability-named-parameter",
         "-readability-redundant-access-specifiers",
         "-readability-uppercase-literal-suffix",
@@ -115,6 +116,7 @@
         "libidmap2/proto/*.proto",
     ],
     host_supported: true,
+    tidy: false,
     proto: {
         type: "lite",
         export_proto_headers: true,
diff --git a/cmds/idmap2/tests/ResultTests.cpp b/cmds/idmap2/tests/ResultTests.cpp
index f2f8854..f9c4fa3 100644
--- a/cmds/idmap2/tests/ResultTests.cpp
+++ b/cmds/idmap2/tests/ResultTests.cpp
@@ -259,7 +259,8 @@
 }
 
 struct NoCopyContainer {
-  uint32_t value;  // NOLINT(misc-non-private-member-variables-in-classes)
+  uint32_t value = 0;  // NOLINT(misc-non-private-member-variables-in-classes)
+  NoCopyContainer() = default;
   NoCopyContainer(const NoCopyContainer&) = delete;
   NoCopyContainer& operator=(const NoCopyContainer&) = delete;
 };
@@ -268,7 +269,7 @@
   if (!succeed) {
     return Error("foo");
   }
-  std::unique_ptr<NoCopyContainer> p(new NoCopyContainer{0U});
+  std::unique_ptr<NoCopyContainer> p(new NoCopyContainer{});
   p->value = 42U;
   return std::move(p);
 }
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index 52f883b..50c2e75 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -52,7 +52,7 @@
 
       (new Telecom()).run(args);
     }
-
+    private static final String CALLING_PACKAGE = Telecom.class.getPackageName();
     private static final String COMMAND_SET_PHONE_ACCOUNT_ENABLED = "set-phone-account-enabled";
     private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled";
     private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account";
@@ -286,7 +286,7 @@
         final String label = nextArgRequired();
         PhoneAccount account = PhoneAccount.builder(handle, label)
                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER).build();
-        mTelecomService.registerPhoneAccount(account);
+        mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE);
         System.out.println("Success - " + handle + " registered.");
     }
 
@@ -316,7 +316,7 @@
                 .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
                 .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
                 .build();
-        mTelecomService.registerPhoneAccount(account);
+        mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE);
         System.out.println("Success - " + handle + " registered.");
     }
 
@@ -358,7 +358,7 @@
 
     private void runUnregisterPhoneAccount() throws RemoteException {
         final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
-        mTelecomService.unregisterPhoneAccount(handle);
+        mTelecomService.unregisterPhoneAccount(handle, CALLING_PACKAGE);
         System.out.println("Success - " + handle + " unregistered.");
     }
 
@@ -395,11 +395,11 @@
     }
 
     private void runGetDefaultDialer() throws RemoteException {
-        System.out.println(mTelecomService.getDefaultDialerPackage());
+        System.out.println(mTelecomService.getDefaultDialerPackage(CALLING_PACKAGE));
     }
 
     private void runGetSystemDialer() throws RemoteException {
-        System.out.println(mTelecomService.getSystemDialerPackage());
+        System.out.println(mTelecomService.getSystemDialerPackage(CALLING_PACKAGE));
     }
 
     private void runWaitOnHandler() throws RemoteException {
diff --git a/cmds/uinput/jni/com_android_commands_uinput_Device.cpp b/cmds/uinput/jni/com_android_commands_uinput_Device.cpp
index 06fa2aa..3f4163d 100644
--- a/cmds/uinput/jni/com_android_commands_uinput_Device.cpp
+++ b/cmds/uinput/jni/com_android_commands_uinput_Device.cpp
@@ -99,6 +99,7 @@
 
 std::unique_ptr<UinputDevice> UinputDevice::open(int32_t id, const char* name, int32_t vid,
                                                  int32_t pid, uint16_t bus, uint32_t ffEffectsMax,
+                                                 const char* port,
                                                  std::unique_ptr<DeviceCallback> callback) {
     android::base::unique_fd fd(::open(UINPUT_PATH, O_RDWR | O_NONBLOCK | O_CLOEXEC));
     if (!fd.ok()) {
@@ -131,6 +132,9 @@
         return nullptr;
     }
 
+    // set the physical port.
+    ::ioctl(fd, UI_SET_PHYS, port);
+
     if (::ioctl(fd, UI_DEV_CREATE) != 0) {
         ALOGE("Unable to create uinput device: %s.", strerror(errno));
         return nullptr;
@@ -240,17 +244,19 @@
 }
 
 static jlong openUinputDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jint id, jint vid,
-                              jint pid, jint bus, jint ffEffectsMax, jobject callback) {
+                              jint pid, jint bus, jint ffEffectsMax, jstring rawPort,
+                              jobject callback) {
     ScopedUtfChars name(env, rawName);
     if (name.c_str() == nullptr) {
         return 0;
     }
 
+    ScopedUtfChars port(env, rawPort);
     std::unique_ptr<uinput::DeviceCallback> cb =
             std::make_unique<uinput::DeviceCallback>(env, callback);
 
     std::unique_ptr<uinput::UinputDevice> d =
-            uinput::UinputDevice::open(id, name.c_str(), vid, pid, bus, ffEffectsMax,
+            uinput::UinputDevice::open(id, name.c_str(), vid, pid, bus, ffEffectsMax, port.c_str(),
                                        std::move(cb));
     return reinterpret_cast<jlong>(d.release());
 }
@@ -303,7 +309,7 @@
 
 static JNINativeMethod sMethods[] = {
         {"nativeOpenUinputDevice",
-         "(Ljava/lang/String;IIIII"
+         "(Ljava/lang/String;IIIIILjava/lang/String;"
          "Lcom/android/commands/uinput/Device$DeviceCallback;)J",
          reinterpret_cast<void*>(openUinputDevice)},
         {"nativeInjectEvent", "(JIII)V", reinterpret_cast<void*>(injectEvent)},
diff --git a/cmds/uinput/jni/com_android_commands_uinput_Device.h b/cmds/uinput/jni/com_android_commands_uinput_Device.h
index 5a9a06c..6da3d79 100644
--- a/cmds/uinput/jni/com_android_commands_uinput_Device.h
+++ b/cmds/uinput/jni/com_android_commands_uinput_Device.h
@@ -48,6 +48,7 @@
 public:
     static std::unique_ptr<UinputDevice> open(int32_t id, const char* name, int32_t vid,
                                               int32_t pid, uint16_t bus, uint32_t ff_effects_max,
+                                              const char* port,
                                               std::unique_ptr<DeviceCallback> callback);
 
     virtual ~UinputDevice();
diff --git a/cmds/uinput/src/com/android/commands/uinput/Device.java b/cmds/uinput/src/com/android/commands/uinput/Device.java
index 62bee7b..732b33d 100644
--- a/cmds/uinput/src/com/android/commands/uinput/Device.java
+++ b/cmds/uinput/src/com/android/commands/uinput/Device.java
@@ -61,7 +61,7 @@
     }
 
     private static native long nativeOpenUinputDevice(String name, int id, int vid, int pid,
-            int bus, int ffEffectsMax, DeviceCallback callback);
+            int bus, int ffEffectsMax, String port, DeviceCallback callback);
     private static native void nativeCloseUinputDevice(long ptr);
     private static native void nativeInjectEvent(long ptr, int type, int code, int value);
     private static native void nativeConfigure(int handle, int code, int[] configs);
@@ -69,7 +69,7 @@
 
     public Device(int id, String name, int vid, int pid, int bus,
             SparseArray<int[]> configuration, int ffEffectsMax,
-            SparseArray<InputAbsInfo> absInfo) {
+            SparseArray<InputAbsInfo> absInfo, String port) {
         mId = id;
         mThread = new HandlerThread("UinputDeviceHandler");
         mThread.start();
@@ -88,6 +88,11 @@
         } else {
             args.arg1 = id + ":" + vid + ":" + pid;
         }
+        if (port != null) {
+            args.arg2 = port;
+        } else {
+            args.arg2 = "uinput:" + id + ":" + vid + ":" + pid;
+        }
 
         mHandler.obtainMessage(MSG_OPEN_UINPUT_DEVICE, args).sendToTarget();
         mTimeToSend = SystemClock.uptimeMillis();
@@ -142,7 +147,7 @@
                 case MSG_OPEN_UINPUT_DEVICE:
                     SomeArgs args = (SomeArgs) msg.obj;
                     mPtr = nativeOpenUinputDevice((String) args.arg1, args.argi1, args.argi2,
-                            args.argi3, args.argi4, args.argi5,
+                            args.argi3, args.argi4, args.argi5, (String) args.arg2,
                             new DeviceCallback());
                     break;
                 case MSG_INJECT_EVENT:
diff --git a/cmds/uinput/src/com/android/commands/uinput/Event.java b/cmds/uinput/src/com/android/commands/uinput/Event.java
index c4ba050..9add310e 100644
--- a/cmds/uinput/src/com/android/commands/uinput/Event.java
+++ b/cmds/uinput/src/com/android/commands/uinput/Event.java
@@ -64,6 +64,7 @@
     private SparseArray<int[]> mConfiguration;
     private int mDuration;
     private int mFfEffectsMax = 0;
+    private String mInputport;
     private SparseArray<InputAbsInfo> mAbsInfo;
 
     public int getId() {
@@ -110,6 +111,10 @@
         return mAbsInfo;
     }
 
+    public String getPort() {
+        return mInputport;
+    }
+
     /**
      * Convert an event to String.
      */
@@ -124,6 +129,7 @@
             + ", configuration=" + mConfiguration
             + ", duration=" + mDuration
             + ", ff_effects_max=" + mFfEffectsMax
+            + ", port=" + mInputport
             + "}";
     }
 
@@ -178,6 +184,10 @@
             mEvent.mAbsInfo = absInfo;
         }
 
+        public void setInputport(String port) {
+            mEvent.mInputport = port;
+        }
+
         public Event build() {
             if (mEvent.mId == -1) {
                 throw new IllegalStateException("No event id");
@@ -262,6 +272,9 @@
                             case "duration":
                                 eb.setDuration(readInt());
                                 break;
+                            case "port":
+                                eb.setInputport(mReader.nextString());
+                                break;
                             default:
                                 mReader.skipValue();
                         }
diff --git a/cmds/uinput/src/com/android/commands/uinput/Uinput.java b/cmds/uinput/src/com/android/commands/uinput/Uinput.java
index f7601a2..740578e 100644
--- a/cmds/uinput/src/com/android/commands/uinput/Uinput.java
+++ b/cmds/uinput/src/com/android/commands/uinput/Uinput.java
@@ -123,7 +123,7 @@
         }
         int id = e.getId();
         Device d = new Device(id, e.getName(), e.getVendorId(), e.getProductId(), e.getBus(),
-                e.getConfiguration(), e.getFfEffectsMax(), e.getAbsInfo());
+                e.getConfiguration(), e.getFfEffectsMax(), e.getAbsInfo(), e.getPort());
         mDevices.append(id, d);
     }
 
diff --git a/core/api/current.txt b/core/api/current.txt
index b08ffc9..c5ab512 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8996,6 +8996,7 @@
   public final class CompanionDeviceManager {
     method @RequiresPermission(anyOf={android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH, android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER, android.Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING, android.Manifest.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION}, conditional=true) public void associate(@NonNull android.companion.AssociationRequest, @NonNull android.companion.CompanionDeviceManager.Callback, @Nullable android.os.Handler);
     method @RequiresPermission(anyOf={android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH, android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER, android.Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMING, android.Manifest.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION}, conditional=true) public void associate(@NonNull android.companion.AssociationRequest, @NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.Callback);
+    method @Nullable public android.content.IntentSender buildPermissionTransferUserConsentIntent(int) throws android.companion.DeviceNotAssociatedException;
     method @Deprecated public void disassociate(@NonNull String);
     method public void disassociate(int);
     method @Deprecated @NonNull public java.util.List<java.lang.String> getAssociations();
@@ -9003,6 +9004,7 @@
     method @Deprecated public boolean hasNotificationAccess(android.content.ComponentName);
     method public void requestNotificationAccess(android.content.ComponentName);
     method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
+    method public void startSystemDataTransfer(int) throws android.companion.DeviceNotAssociatedException;
     method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
     field public static final String EXTRA_ASSOCIATION = "android.companion.extra.ASSOCIATION";
     field @Deprecated public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -9018,11 +9020,13 @@
 
   public abstract class CompanionDeviceService extends android.app.Service {
     ctor public CompanionDeviceService();
+    method @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public final void dispatchMessageToSystem(int, int, @NonNull byte[]) throws android.companion.DeviceNotAssociatedException;
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method @Deprecated @MainThread public void onDeviceAppeared(@NonNull String);
     method @MainThread public void onDeviceAppeared(@NonNull android.companion.AssociationInfo);
     method @Deprecated @MainThread public void onDeviceDisappeared(@NonNull String);
     method @MainThread public void onDeviceDisappeared(@NonNull android.companion.AssociationInfo);
+    method public void onMessageDispatchedFromSystem(int, int, @NonNull byte[]);
     field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";
   }
 
@@ -18526,7 +18530,7 @@
 package android.hardware.input {
 
   public final class InputManager {
-    method public android.view.InputDevice getInputDevice(int);
+    method @Nullable public android.view.InputDevice getInputDevice(int);
     method public int[] getInputDeviceIds();
     method @FloatRange(from=0, to=1) public float getMaximumObscuringOpacityForTouch();
     method public void registerInputDeviceListener(android.hardware.input.InputManager.InputDeviceListener, android.os.Handler);
@@ -20081,14 +20085,14 @@
     method @Deprecated public int getVibrateSetting(int);
     method @Deprecated public boolean isBluetoothA2dpOn();
     method public boolean isBluetoothScoAvailableOffCall();
-    method public boolean isBluetoothScoOn();
+    method @Deprecated public boolean isBluetoothScoOn();
     method public boolean isCallScreeningModeSupported();
     method public static boolean isHapticPlaybackSupported();
     method public boolean isMicrophoneMute();
     method public boolean isMusicActive();
     method public static boolean isOffloadedPlaybackSupported(@NonNull android.media.AudioFormat, @NonNull android.media.AudioAttributes);
     method public boolean isRampingRingerEnabled();
-    method public boolean isSpeakerphoneOn();
+    method @Deprecated public boolean isSpeakerphoneOn();
     method public boolean isStreamMute(int);
     method public boolean isSurroundFormatEnabled(int);
     method public boolean isVolumeFixed();
@@ -20117,7 +20121,7 @@
     method public void setParameters(String);
     method public void setRingerMode(int);
     method @Deprecated public void setRouting(int, int, int);
-    method public void setSpeakerphoneOn(boolean);
+    method @Deprecated public void setSpeakerphoneOn(boolean);
     method @Deprecated public void setStreamMute(int, boolean);
     method @Deprecated public void setStreamSolo(int, boolean);
     method public void setStreamVolume(int, int, int);
@@ -20125,8 +20129,8 @@
     method @Deprecated public void setVibrateSetting(int, int);
     method @Deprecated public void setWiredHeadsetOn(boolean);
     method @Deprecated public boolean shouldVibrate(int);
-    method public void startBluetoothSco();
-    method public void stopBluetoothSco();
+    method @Deprecated public void startBluetoothSco();
+    method @Deprecated public void stopBluetoothSco();
     method public void unloadSoundEffects();
     method public void unregisterAudioDeviceCallback(android.media.AudioDeviceCallback);
     method public void unregisterAudioPlaybackCallback(@NonNull android.media.AudioManager.AudioPlaybackCallback);
@@ -32341,6 +32345,9 @@
     method public static android.os.VibrationEffect createWaveform(long[], int[], int);
     method public int describeContents();
     method @NonNull public static android.os.VibrationEffect.Composition startComposition();
+    method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform();
+    method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform(@NonNull android.os.VibrationEffect.VibrationParameter);
+    method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform(@NonNull android.os.VibrationEffect.VibrationParameter, @NonNull android.os.VibrationEffect.VibrationParameter);
     field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect> CREATOR;
     field public static final int DEFAULT_AMPLITUDE = -1; // 0xffffffff
     field public static final int EFFECT_CLICK = 0; // 0x0
@@ -32350,10 +32357,13 @@
   }
 
   public static final class VibrationEffect.Composition {
+    method @NonNull public android.os.VibrationEffect.Composition addEffect(@NonNull android.os.VibrationEffect);
+    method @NonNull public android.os.VibrationEffect.Composition addOffDuration(@NonNull java.time.Duration);
     method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int);
     method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float);
     method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
     method @NonNull public android.os.VibrationEffect compose();
+    method @NonNull public android.os.VibrationEffect.Composition repeatEffectIndefinitely(@NonNull android.os.VibrationEffect);
     field public static final int PRIMITIVE_CLICK = 1; // 0x1
     field public static final int PRIMITIVE_LOW_TICK = 8; // 0x8
     field public static final int PRIMITIVE_QUICK_FALL = 6; // 0x6
@@ -32364,15 +32374,34 @@
     field public static final int PRIMITIVE_TICK = 7; // 0x7
   }
 
+  public static final class VibrationEffect.Composition.UnreachableAfterRepeatingIndefinitelyException extends java.lang.IllegalStateException {
+  }
+
+  public static class VibrationEffect.VibrationParameter {
+    method @NonNull public static android.os.VibrationEffect.VibrationParameter targetAmplitude(@FloatRange(from=0, to=1) float);
+    method @NonNull public static android.os.VibrationEffect.VibrationParameter targetFrequency(@FloatRange(from=1) float);
+  }
+
+  public static final class VibrationEffect.WaveformBuilder {
+    method @NonNull public android.os.VibrationEffect.WaveformBuilder addSustain(@NonNull java.time.Duration);
+    method @NonNull public android.os.VibrationEffect.WaveformBuilder addTransition(@NonNull java.time.Duration, @NonNull android.os.VibrationEffect.VibrationParameter);
+    method @NonNull public android.os.VibrationEffect.WaveformBuilder addTransition(@NonNull java.time.Duration, @NonNull android.os.VibrationEffect.VibrationParameter, @NonNull android.os.VibrationEffect.VibrationParameter);
+    method @NonNull public android.os.VibrationEffect build();
+  }
+
   public abstract class Vibrator {
     method public final int areAllEffectsSupported(@NonNull int...);
     method public final boolean areAllPrimitivesSupported(@NonNull int...);
     method @NonNull public int[] areEffectsSupported(@NonNull int...);
     method @NonNull public boolean[] arePrimitivesSupported(@NonNull int...);
     method @RequiresPermission(android.Manifest.permission.VIBRATE) public abstract void cancel();
+    method @Nullable public android.os.vibrator.VibratorFrequencyProfile getFrequencyProfile();
     method public int getId();
     method @NonNull public int[] getPrimitiveDurations(@NonNull int...);
+    method public float getQFactor();
+    method public float getResonantFrequency();
     method public abstract boolean hasAmplitudeControl();
+    method public boolean hasFrequencyControl();
     method public abstract boolean hasVibrator();
     method @Deprecated @RequiresPermission(android.Manifest.permission.VIBRATE) public void vibrate(long);
     method @Deprecated @RequiresPermission(android.Manifest.permission.VIBRATE) public void vibrate(long, android.media.AudioAttributes);
@@ -32700,6 +32729,17 @@
 
 }
 
+package android.os.vibrator {
+
+  public final class VibratorFrequencyProfile {
+    method public float getMaxAmplitudeMeasurementInterval();
+    method @FloatRange(from=0, to=1) @NonNull public float[] getMaxAmplitudeMeasurements();
+    method public float getMaxFrequency();
+    method public float getMinFrequency();
+  }
+
+}
+
 package android.preference {
 
   @Deprecated public class CheckBoxPreference extends android.preference.TwoStatePreference {
@@ -44254,6 +44294,9 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
     method public void unregisterImsStateCallback(@NonNull android.telephony.ims.ImsStateCallback);
     field public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN = "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
+    field public static final int CAPABILITY_TYPE_NONE = 0; // 0x0
+    field public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1; // 0x1
+    field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
   }
 
   public final class ImsReasonInfo implements android.os.Parcelable {
@@ -44475,10 +44518,10 @@
     method public void unregisterFeatureProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.FeatureProvisioningCallback);
   }
 
-  public static class ProvisioningManager.FeatureProvisioningCallback {
+  public abstract static class ProvisioningManager.FeatureProvisioningCallback {
     ctor public ProvisioningManager.FeatureProvisioningCallback();
-    method public void onFeatureProvisioningChanged(int, int, boolean);
-    method public void onRcsFeatureProvisioningChanged(int, int, boolean);
+    method public abstract void onFeatureProvisioningChanged(int, int, boolean);
+    method public abstract void onRcsFeatureProvisioningChanged(int, int, boolean);
   }
 
   public class RcsUceAdapter {
@@ -44521,15 +44564,6 @@
     field public static final int CAPABILITY_TYPE_VOICE = 1; // 0x1
   }
 
-  public class RcsFeature {
-  }
-
-  public static class RcsFeature.RcsImsCapabilities {
-    field public static final int CAPABILITY_TYPE_NONE = 0; // 0x0
-    field public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1; // 0x1
-    field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
-  }
-
 }
 
 package android.telephony.ims.stub {
@@ -48132,7 +48166,7 @@
     method @NonNull public android.hardware.BatteryState getBatteryState();
     method public int getControllerNumber();
     method public String getDescriptor();
-    method public static android.view.InputDevice getDevice(int);
+    method @Nullable public static android.view.InputDevice getDevice(int);
     method public static int[] getDeviceIds();
     method public int getId();
     method public android.view.KeyCharacterMap getKeyCharacterMap();
@@ -52512,6 +52546,7 @@
 
   public final class AutofillManager {
     method public void cancel();
+    method public void clearAutofillRequestCallback();
     method public void commit();
     method public void disableAutofillServices();
     method @Nullable public android.content.ComponentName getAutofillServiceComponentName();
@@ -52537,6 +52572,7 @@
     method public void registerCallback(@Nullable android.view.autofill.AutofillManager.AutofillCallback);
     method public void requestAutofill(@NonNull android.view.View);
     method public void requestAutofill(@NonNull android.view.View, int, @NonNull android.graphics.Rect);
+    method public void setAutofillRequestCallback(@NonNull java.util.concurrent.Executor, @NonNull android.view.autofill.AutofillRequestCallback);
     method public void setUserData(@Nullable android.service.autofill.UserData);
     method public boolean showAutofillDialog(@NonNull android.view.View);
     method public boolean showAutofillDialog(@NonNull android.view.View, int);
@@ -52557,6 +52593,10 @@
     field public static final int EVENT_INPUT_UNAVAILABLE = 3; // 0x3
   }
 
+  public interface AutofillRequestCallback {
+    method public void onFillRequest(@Nullable android.view.inputmethod.InlineSuggestionsRequest, @NonNull android.os.CancellationSignal, @NonNull android.service.autofill.FillCallback);
+  }
+
   public final class AutofillValue implements android.os.Parcelable {
     method public int describeContents();
     method public static android.view.autofill.AutofillValue forDate(long);
@@ -52944,10 +52984,12 @@
     ctor public InlineSuggestionsRequest.Builder(@NonNull java.util.List<android.widget.inline.InlinePresentationSpec>);
     method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder addInlinePresentationSpecs(@NonNull android.widget.inline.InlinePresentationSpec);
     method @NonNull public android.view.inputmethod.InlineSuggestionsRequest build();
+    method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder setClientSupported(boolean);
     method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder setExtras(@NonNull android.os.Bundle);
     method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(@NonNull java.util.List<android.widget.inline.InlinePresentationSpec>);
     method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder setInlineTooltipPresentationSpec(@NonNull android.widget.inline.InlinePresentationSpec);
     method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder setMaxSuggestionCount(int);
+    method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder setServiceSupported(boolean);
     method @NonNull public android.view.inputmethod.InlineSuggestionsRequest.Builder setSupportedLocales(@NonNull android.os.LocaleList);
   }
 
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index b952216..e81d7f1 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -2,6 +2,7 @@
 package android {
 
   public static final class Manifest.permission {
+    field public static final String BLUETOOTH_STACK = "android.permission.BLUETOOTH_STACK";
     field public static final String CONTROL_AUTOMOTIVE_GNSS = "android.permission.CONTROL_AUTOMOTIVE_GNSS";
     field public static final String GET_INTENT_SENDER_INTENT = "android.permission.GET_INTENT_SENDER_INTENT";
     field public static final String MAKE_UID_VISIBLE = "android.permission.MAKE_UID_VISIBLE";
@@ -156,12 +157,12 @@
     method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
     method @NonNull public java.util.List<android.bluetooth.BluetoothCodecConfig> getHwOffloadFormatsSupportedForA2dp();
     method @NonNull public java.util.List<android.bluetooth.BluetoothLeAudioCodecConfig> getHwOffloadFormatsSupportedForLeAudio();
-    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void handleBluetoothActiveDeviceChanged(@Nullable android.bluetooth.BluetoothDevice, @Nullable android.bluetooth.BluetoothDevice, @NonNull android.media.BluetoothProfileConnectionInfo);
-    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setA2dpSuspended(boolean);
-    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setBluetoothHeadsetProperties(@NonNull String, boolean, boolean);
-    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setHfpEnabled(boolean);
-    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setHfpSamplingRate(int);
-    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setHfpVolume(int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void handleBluetoothActiveDeviceChanged(@Nullable android.bluetooth.BluetoothDevice, @Nullable android.bluetooth.BluetoothDevice, @NonNull android.media.BluetoothProfileConnectionInfo);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void setA2dpSuspended(boolean);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void setBluetoothHeadsetProperties(@NonNull String, boolean, boolean);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void setHfpEnabled(boolean);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void setHfpSamplingRate(int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK) public void setHfpVolume(int);
     method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
     field public static final int FLAG_FROM_KEY = 4096; // 0x1000
   }
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 650de2e0..03b4aa5 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -199,6 +199,7 @@
     field public static final String MANAGE_WEAK_ESCROW_TOKEN = "android.permission.MANAGE_WEAK_ESCROW_TOKEN";
     field public static final String MANAGE_WIFI_COUNTRY_CODE = "android.permission.MANAGE_WIFI_COUNTRY_CODE";
     field public static final String MARK_DEVICE_ORGANIZATION_OWNED = "android.permission.MARK_DEVICE_ORGANIZATION_OWNED";
+    field public static final String MEDIA_RESOURCE_OVERRIDE_PID = "android.permission.MEDIA_RESOURCE_OVERRIDE_PID";
     field public static final String MODIFY_APPWIDGET_BIND_PERMISSIONS = "android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS";
     field public static final String MODIFY_AUDIO_ROUTING = "android.permission.MODIFY_AUDIO_ROUTING";
     field public static final String MODIFY_CELL_BROADCASTS = "android.permission.MODIFY_CELL_BROADCASTS";
@@ -1050,7 +1051,7 @@
 
   public class WallpaperManager {
     method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void clearWallpaper(int, int);
-    method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public float getWallpaperDimAmount();
+    method @FloatRange(from=0.0f, to=1.0f) @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public float getWallpaperDimAmount();
     method public void setDisplayOffset(android.os.IBinder, int, int);
     method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponent(android.content.ComponentName);
     method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public void setWallpaperDimAmount(@FloatRange(from=0.0f, to=1.0f) float);
@@ -6334,7 +6335,7 @@
   }
 
   public final class MediaCodec {
-    method @NonNull @RequiresPermission("android.permission.MEDIA_RESOURCE_OVERRIDE_PID") public static android.media.MediaCodec createByCodecNameForClient(@NonNull String, int, int) throws java.io.IOException;
+    method @NonNull @RequiresPermission(android.Manifest.permission.MEDIA_RESOURCE_OVERRIDE_PID) public static android.media.MediaCodec createByCodecNameForClient(@NonNull String, int, int) throws java.io.IOException;
   }
 
   public class MediaPlayer implements android.media.AudioRouting android.media.VolumeAutomation {
@@ -11873,19 +11874,20 @@
 package android.service.voice {
 
   public class AlwaysOnHotwordDetector implements android.service.voice.HotwordDetector {
-    method @Nullable public android.content.Intent createEnrollIntent();
-    method @Nullable public android.content.Intent createReEnrollIntent();
-    method @Nullable public android.content.Intent createUnEnrollIntent();
-    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int getParameter(int);
+    method @Nullable public android.content.Intent createEnrollIntent() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method @Nullable public android.content.Intent createReEnrollIntent() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method @Nullable public android.content.Intent createUnEnrollIntent() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int getParameter(int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
     method public int getSupportedAudioCapabilities();
-    method public int getSupportedRecognitionModes();
-    method @Nullable @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public android.service.voice.AlwaysOnHotwordDetector.ModelParamRange queryParameter(int);
-    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int setParameter(int, int);
-    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int);
-    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition();
-    method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle);
-    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean stopRecognition();
-    method public final void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory);
+    method public int getSupportedRecognitionModes() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method @Nullable @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public android.service.voice.AlwaysOnHotwordDetector.ModelParamRange queryParameter(int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int setParameter(int, int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int, @NonNull byte[]) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean stopRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method public final void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
     field public static final int AUDIO_CAPABILITY_ECHO_CANCELLATION = 1; // 0x1
     field public static final int AUDIO_CAPABILITY_NOISE_SUPPRESSION = 2; // 0x2
     field public static final int MODEL_PARAM_THRESHOLD_FACTOR = 0; // 0x0
@@ -11992,10 +11994,10 @@
 
   public interface HotwordDetector {
     method public default void destroy();
-    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition();
-    method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle);
-    method public boolean stopRecognition();
-    method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory);
+    method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method public boolean stopRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+    method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
   }
 
   public static interface HotwordDetector.Callback {
@@ -12008,6 +12010,9 @@
     method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
   }
 
+  public static class HotwordDetector.IllegalDetectorStateException extends android.util.AndroidException {
+  }
+
   public final class HotwordRejectedResult implements android.os.Parcelable {
     method public int describeContents();
     method public int getConfidenceLevel();
@@ -15024,7 +15029,7 @@
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestAvailability(@NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestCapabilities(@NonNull java.util.Collection<android.net.Uri>, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
-    field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
+    field @Deprecated public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
     field public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1; // 0x1
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 7; // 0x7
     field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 6; // 0x6
@@ -15307,6 +15312,9 @@
     method public void addCapabilities(int);
     method public boolean isCapable(int);
     method public void removeCapabilities(int);
+    field public static final int CAPABILITY_TYPE_NONE = 0; // 0x0
+    field public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1; // 0x1
+    field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
   }
 
 }
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index 1b45e88..db375d4 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -99,15 +99,6 @@
     
 
 
-RethrowRemoteException: android.app.WallpaperManager#getWallpaperDimAmount():
-    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-RethrowRemoteException: android.app.WallpaperManager#getWallpaperDimmingAmount():
-    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-RethrowRemoteException: android.app.WallpaperManager#setWallpaperDimAmount(float):
-    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-RethrowRemoteException: android.app.WallpaperManager#setWallpaperDimmingAmount(float):
-    Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-
 
 SamShouldBeLast: android.accounts.AccountManager#addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
     
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 27f5b92..37edc03 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -36,7 +36,6 @@
     field public static final String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
     field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO";
     field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
-    field public static final String REQUEST_UNIQUE_ID_ATTESTATION = "android.permission.REQUEST_UNIQUE_ID_ATTESTATION";
     field public static final String RESET_APP_ERRORS = "android.permission.RESET_APP_ERRORS";
     field public static final String REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL = "android.permission.REVOKE_POST_NOTIFICATIONS_WITHOUT_KILL";
     field public static final String SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS = "android.permission.SET_AND_VERIFY_LOCKSCREEN_CREDENTIALS";
@@ -1250,10 +1249,12 @@
   }
 
   public final class InputManager {
+    method public void addUniqueIdAssociation(@NonNull String, @NonNull String);
     method public int getBlockUntrustedTouchesMode(@NonNull android.content.Context);
     method @Nullable public String getCurrentKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier);
     method @NonNull public java.util.List<java.lang.String> getKeyboardLayoutDescriptorsForInputDevice(@NonNull android.view.InputDevice);
     method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void removeKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String);
+    method public void removeUniqueIdAssociation(@NonNull String);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setBlockUntrustedTouchesMode(@NonNull android.content.Context, int);
     method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void setCurrentKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(@FloatRange(from=0, to=1) float);
@@ -1857,7 +1858,6 @@
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public String getUserType();
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.content.pm.UserInfo> getUsers(boolean, boolean, boolean);
     method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public boolean hasBaseUserRestriction(@NonNull String, @NonNull android.os.UserHandle);
-    method public static boolean isGuestUserEphemeral();
     method public static boolean isSplitSystemUser();
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo preCreateUser(@NonNull String) throws android.os.UserManager.UserOperationException;
   }
@@ -1871,9 +1871,6 @@
     method public static android.os.VibrationEffect get(int, boolean);
     method @Nullable public static android.os.VibrationEffect get(android.net.Uri, android.content.Context);
     method public abstract long getDuration();
-    method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform();
-    method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform(@NonNull android.os.VibrationEffect.VibrationParameter);
-    method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform(@NonNull android.os.VibrationEffect.VibrationParameter, @NonNull android.os.VibrationEffect.VibrationParameter);
     field public static final int EFFECT_POP = 4; // 0x4
     field public static final int EFFECT_STRENGTH_LIGHT = 0; // 0x0
     field public static final int EFFECT_STRENGTH_MEDIUM = 1; // 0x1
@@ -1891,33 +1888,8 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.Composed> CREATOR;
   }
 
-  public static final class VibrationEffect.Composition {
-    method @NonNull public android.os.VibrationEffect.Composition addEffect(@NonNull android.os.VibrationEffect);
-    method @NonNull public android.os.VibrationEffect.Composition addOffDuration(@NonNull java.time.Duration);
-    method @NonNull public android.os.VibrationEffect.Composition repeatEffectIndefinitely(@NonNull android.os.VibrationEffect);
-  }
-
-  public static final class VibrationEffect.Composition.UnreachableAfterRepeatingIndefinitelyException extends java.lang.IllegalStateException {
-  }
-
-  public static class VibrationEffect.VibrationParameter {
-    method @NonNull public static android.os.VibrationEffect.VibrationParameter targetAmplitude(@FloatRange(from=0, to=1) float);
-    method @NonNull public static android.os.VibrationEffect.VibrationParameter targetFrequency(@FloatRange(from=1) float);
-  }
-
-  public static final class VibrationEffect.WaveformBuilder {
-    method @NonNull public android.os.VibrationEffect.WaveformBuilder addSustain(@NonNull java.time.Duration);
-    method @NonNull public android.os.VibrationEffect.WaveformBuilder addTransition(@NonNull java.time.Duration, @NonNull android.os.VibrationEffect.VibrationParameter);
-    method @NonNull public android.os.VibrationEffect.WaveformBuilder addTransition(@NonNull java.time.Duration, @NonNull android.os.VibrationEffect.VibrationParameter, @NonNull android.os.VibrationEffect.VibrationParameter);
-    method @NonNull public android.os.VibrationEffect build();
-  }
-
   public abstract class Vibrator {
     method public int getDefaultVibrationIntensity(int);
-    method @Nullable public android.os.vibrator.VibratorFrequencyProfile getFrequencyProfile();
-    method public float getQFactor();
-    method public float getResonantFrequency();
-    method public boolean hasFrequencyControl();
     field public static final int VIBRATION_INTENSITY_HIGH = 3; // 0x3
     field public static final int VIBRATION_INTENSITY_LOW = 1; // 0x1
     field public static final int VIBRATION_INTENSITY_MEDIUM = 2; // 0x2
@@ -2102,13 +2074,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.os.vibrator.VibrationEffectSegment> CREATOR;
   }
 
-  public final class VibratorFrequencyProfile {
-    method public float getMaxAmplitudeMeasurementInterval();
-    method @FloatRange(from=0, to=1) @NonNull public float[] getMaxAmplitudeMeasurements();
-    method public float getMaxFrequency();
-    method public float getMinFrequency();
-  }
-
 }
 
 package android.permission {
@@ -2467,6 +2432,8 @@
 package android.service.voice {
 
   public class AlwaysOnHotwordDetector implements android.service.voice.HotwordDetector {
+    method public void overrideAvailability(int);
+    method public void resetAvailability();
     method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public void triggerHardwareRecognitionEventForTest(int, int, boolean, int, int, int, boolean, @NonNull android.media.AudioFormat, @Nullable byte[], @NonNull java.util.List<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra>);
   }
 
@@ -2826,6 +2793,7 @@
     method @NonNull public android.graphics.ColorSpace[] getSupportedWideColorGamut();
     method @Nullable public android.view.Display.Mode getSystemPreferredDisplayMode();
     method public int getType();
+    method @Nullable public String getUniqueId();
     method @Nullable public android.view.Display.Mode getUserPreferredDisplayMode();
     method public boolean hasAccess(int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE) public void setUserPreferredDisplayMode(@NonNull android.view.Display.Mode);
diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java
index e6cdcc0..0d6a079 100644
--- a/core/java/android/accounts/Account.java
+++ b/core/java/android/accounts/Account.java
@@ -31,7 +31,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 
-import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -87,12 +86,6 @@
         if (TextUtils.isEmpty(type)) {
             throw new IllegalArgumentException("the type must not be empty: " + type);
         }
-        if (name.length() > 200) {
-            throw new IllegalArgumentException("account name is longer than 200 characters");
-        }
-        if (type.length() > 200) {
-            throw new IllegalArgumentException("account type is longer than 200 characters");
-        }
         this.name = name;
         this.type = type;
         this.accessId = accessId;
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 28c273e..167de46 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -211,6 +211,7 @@
      *
      * @hide
      */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT)")
     oneway void setWallpaperDimAmount(float dimAmount);
 
     /**
@@ -219,6 +220,7 @@
      *
      * @hide
      */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT)")
     float getWallpaperDimAmount();
 
     /**
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 5d6e2bd..7964ae9 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -431,8 +431,7 @@
                     writeTo.write(buffer, 0, readByteCount);
                     writeTo.flush();
                 }
-            } catch (IOException ioe) {
-                Log.w(TAG, "Error while reading/writing to streams");
+            } catch (IOException ignored) {
             } finally {
                 IoUtils.closeQuietly(readFrom);
                 IoUtils.closeQuietly(writeTo);
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 0a18588..ea80369 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -2023,7 +2023,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT)
-    public float getWallpaperDimAmount() {
+    public @FloatRange (from = 0f, to = 1f) float getWallpaperDimAmount() {
         if (sGlobals.mService == null) {
             Log.w(TAG, "WallpaperService not running");
             throw new RuntimeException(new DeadSystemException());
diff --git a/core/java/android/app/admin/EnterprisePlatformSecurity_OWNERS b/core/java/android/app/admin/EnterprisePlatformSecurity_OWNERS
index f560434..0ec8253 100644
--- a/core/java/android/app/admin/EnterprisePlatformSecurity_OWNERS
+++ b/core/java/android/app/admin/EnterprisePlatformSecurity_OWNERS
@@ -1,4 +1,5 @@
 rubinxu@google.com
 acjohnston@google.com
 pgrafov@google.com
+ayushsha@google.com
 alexkershaw@google.com #{LAST_RESORT_SUGGESTION}
\ No newline at end of file
diff --git a/core/java/android/app/admin/WorkDeviceExperience_OWNERS b/core/java/android/app/admin/WorkDeviceExperience_OWNERS
index dcacaa2..7c90feb 100644
--- a/core/java/android/app/admin/WorkDeviceExperience_OWNERS
+++ b/core/java/android/app/admin/WorkDeviceExperience_OWNERS
@@ -2,4 +2,5 @@
 scottjonathan@google.com
 arangelov@google.com
 kholoudm@google.com
+eliselliott@google.com
 alexkershaw@google.com #{LAST_RESORT_SUGGESTION}
\ No newline at end of file
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 67f631f..88a7c0f 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -246,6 +246,9 @@
      * new changes to its data.  A backup operation using your application's
      * {@link android.app.backup.BackupAgent} subclass will be scheduled when you
      * call this method.
+     *
+     * <p>
+     * Note: This only works if your application is performing Key/Value backups.
      */
     public void dataChanged() {
         checkServiceBinder();
@@ -268,6 +271,8 @@
      * as the caller.
      *
      * @param packageName The package name identifying the application to back up.
+     * <p>
+     * Note: Only works for packages performing Key/Value backups.
      */
     public static void dataChanged(String packageName) {
         checkServiceBinder();
diff --git a/core/java/android/app/slice/ISliceManager.aidl b/core/java/android/app/slice/ISliceManager.aidl
index 6f73d02..f31e2bc 100644
--- a/core/java/android/app/slice/ISliceManager.aidl
+++ b/core/java/android/app/slice/ISliceManager.aidl
@@ -33,7 +33,7 @@
     // Perms.
     void grantSlicePermission(String callingPkg, String toPkg, in Uri uri);
     void revokeSlicePermission(String callingPkg, String toPkg, in Uri uri);
-    int checkSlicePermission(in Uri uri, String callingPkg, String pkg, int pid, int uid,
+    int checkSlicePermission(in Uri uri, String callingPkg, int pid, int uid,
             in String[] autoGrantPermissions);
     void grantPermissionFromUser(in Uri uri, String pkg, String callingPkg, boolean allSlices);
 }
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index 5497b78..ed4ea74 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -439,8 +439,8 @@
      */
     public @PermissionResult int checkSlicePermission(@NonNull Uri uri, int pid, int uid) {
         try {
-            return mService.checkSlicePermission(uri, mContext.getPackageName(), null, pid, uid,
-                    null);
+            return mService.checkSlicePermission(uri, mContext.getPackageName(), pid, uid,
+                    null /* autoGrantPermissions */);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -488,17 +488,13 @@
      * Does the permission check to see if a caller has access to a specific slice.
      * @hide
      */
-    public void enforceSlicePermission(Uri uri, String pkg, int pid, int uid,
-            String[] autoGrantPermissions) {
+    public void enforceSlicePermission(Uri uri, int pid, int uid, String[] autoGrantPermissions) {
         try {
             if (UserHandle.isSameApp(uid, Process.myUid())) {
                 return;
             }
-            if (pkg == null) {
-                throw new SecurityException("No pkg specified");
-            }
-            int result = mService.checkSlicePermission(uri, mContext.getPackageName(), pkg, pid,
-                    uid, autoGrantPermissions);
+            int result = mService.checkSlicePermission(uri, mContext.getPackageName(), pid, uid,
+                    autoGrantPermissions);
             if (result == PERMISSION_DENIED) {
                 throw new SecurityException("User " + uid + " does not have slice permission for "
                         + uri + ".");
diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index fb8a83b..e6c88a3 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -452,8 +452,8 @@
         String pkg = callingPkg != null ? callingPkg
                 : getContext().getPackageManager().getNameForUid(callingUid);
         try {
-            mSliceManager.enforceSlicePermission(sliceUri, pkg,
-                    callingPid, callingUid, mAutoGrantPermissions);
+            mSliceManager.enforceSlicePermission(sliceUri, callingPid, callingUid,
+                    mAutoGrantPermissions);
         } catch (SecurityException e) {
             return createPermissionSlice(getContext(), sliceUri, pkg);
         }
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index 257530b..75ab115 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -151,7 +151,7 @@
      * The Display name of the device to be shown in the CDM confirmation UI. Must be non-null for
      * "self-managed" association.
      */
-    private final @Nullable CharSequence mDisplayName;
+    private @Nullable CharSequence mDisplayName;
 
     /**
      * Whether the association is to be managed by the companion application.
@@ -302,6 +302,11 @@
     }
 
     /** @hide */
+    public void setDisplayName(CharSequence displayName) {
+        mDisplayName = displayName;
+    }
+
+    /** @hide */
     @NonNull
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public List<DeviceFilter<?>> getDeviceFilters() {
@@ -597,7 +602,9 @@
         boolean forceConfirmation = (flg & 0x20) != 0;
         boolean skipPrompt = (flg & 0x400) != 0;
         List<DeviceFilter<?>> deviceFilters = new ArrayList<>();
-        in.readParcelableList(deviceFilters, DeviceFilter.class.getClassLoader(), (Class<android.companion.DeviceFilter<?>>) (Class<?>) android.companion.DeviceFilter.class);
+        in.readParcelableList(deviceFilters, DeviceFilter.class.getClassLoader(),
+                (Class<android.companion.DeviceFilter<?>>) (Class<?>)
+                        android.companion.DeviceFilter.class);
         String deviceProfile = (flg & 0x4) == 0 ? null : in.readString();
         CharSequence displayName = (flg & 0x8) == 0 ? null : (CharSequence) in.readCharSequence();
         String packageName = (flg & 0x40) == 0 ? null : in.readString();
@@ -641,10 +648,10 @@
     };
 
     @DataClass.Generated(
-            time = 1643238443303L,
+            time = 1649179640045L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/core/java/android/companion/AssociationRequest.java",
-            inputSignatures = "public static final  java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_APP_STREAMING\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_AUTOMOTIVE_PROJECTION\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_COMPUTER\nprivate final  boolean mSingleDevice\nprivate final @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate final @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate final @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate final  boolean mSelfManaged\nprivate final  boolean mForceConfirmation\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.UserIdInt int mUserId\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate final  long mCreationTime\nprivate  boolean mSkipPrompt\npublic @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String getDeviceProfile()\npublic @android.annotation.Nullable java.lang.CharSequence getDisplayName()\npublic  boolean isSelfManaged()\npublic  boolean isForceConfirmation()\npublic  boolean isSingleDevice()\npublic  void setPackageName(java.lang.String)\npublic  void setUserId(int)\npublic  void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic  void setSkipPrompt(boolean)\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate  boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate  boolean mSelfManaged\nprivate  boolean mForceConfirmation\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDisplayName(java.lang.CharSequence)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setSelfManaged(boolean)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setForceConfirmation(boolean)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genConstDefs=false)")
+            inputSignatures = "public static final  java.lang.String DEVICE_PROFILE_WATCH\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_APP_STREAMING\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_AUTOMOTIVE_PROJECTION\npublic static final @android.annotation.RequiresPermission java.lang.String DEVICE_PROFILE_COMPUTER\nprivate final  boolean mSingleDevice\nprivate final @com.android.internal.util.DataClass.PluralOf(\"deviceFilter\") @android.annotation.NonNull java.util.List<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate final @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate final  boolean mSelfManaged\nprivate final  boolean mForceConfirmation\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.UserIdInt int mUserId\nprivate @android.annotation.Nullable java.lang.String mDeviceProfilePrivilegesDescription\nprivate final  long mCreationTime\nprivate  boolean mSkipPrompt\npublic @android.annotation.Nullable @android.companion.AssociationRequest.DeviceProfile java.lang.String getDeviceProfile()\npublic @android.annotation.Nullable java.lang.CharSequence getDisplayName()\npublic  boolean isSelfManaged()\npublic  boolean isForceConfirmation()\npublic  boolean isSingleDevice()\npublic  void setPackageName(java.lang.String)\npublic  void setUserId(int)\npublic  void setDeviceProfilePrivilegesDescription(java.lang.String)\npublic  void setSkipPrompt(boolean)\npublic  void setDisplayName(java.lang.CharSequence)\npublic @android.annotation.NonNull @android.compat.annotation.UnsupportedAppUsage java.util.List<android.companion.DeviceFilter<?>> getDeviceFilters()\nclass AssociationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate  boolean mSingleDevice\nprivate @android.annotation.Nullable java.util.ArrayList<android.companion.DeviceFilter<?>> mDeviceFilters\nprivate @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate @android.annotation.Nullable java.lang.CharSequence mDisplayName\nprivate  boolean mSelfManaged\nprivate  boolean mForceConfirmation\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setSingleDevice(boolean)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder addDeviceFilter(android.companion.DeviceFilter<?>)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDeviceProfile(java.lang.String)\npublic @android.annotation.NonNull android.companion.AssociationRequest.Builder setDisplayName(java.lang.CharSequence)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setSelfManaged(boolean)\npublic @android.annotation.RequiresPermission @android.annotation.NonNull android.companion.AssociationRequest.Builder setForceConfirmation(boolean)\npublic @android.annotation.NonNull @java.lang.Override android.companion.AssociationRequest build()\nclass Builder extends android.provider.OneTimeUseBuilder<android.companion.AssociationRequest> implements []\n@com.android.internal.util.DataClass(genConstructor=false, genToString=true, genEqualsHashCode=true, genHiddenGetters=true, genParcelable=true, genConstDefs=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 56939f0..10ab034 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -774,7 +774,8 @@
     }
 
     /**
-     * Dispatch a message to system for processing.
+     * Dispatch a message to system for processing. It should only be called by
+     * {@link CompanionDeviceService#dispatchMessageToSystem(int, int, byte[])}
      *
      * <p>Calling app must declare uses-permission
      * {@link android.Manifest.permission#DELIVER_COMPANION_MESSAGES}</p>
@@ -874,6 +875,66 @@
         }
     }
 
+    /**
+     * Build a permission sync user consent dialog.
+     *
+     * <p>Only the companion app which owns the association can call this method. Otherwise a null
+     * IntentSender will be returned from this method and an error will be logged.
+     * The The app should launch the {@link Activity} in the returned {@code intentSender}
+     * {@link IntentSender} by calling
+     * {@link Activity#startIntentSenderForResult(IntentSender, int, Intent, int, int, int)}.</p>
+     *
+     * <p>The permission transfer doesn't happen immediately after the call or user consented.
+     * The app needs to trigger the system data transfer manually by calling
+     * {@link #startSystemDataTransfer(int)}, when it confirms the communication channel between
+     * the two devices is established.</p>
+     *
+     * @param associationId The unique {@link AssociationInfo#getId ID} assigned to the association
+     *                      of the companion device recorded by CompanionDeviceManager
+     * @return An {@link IntentSender} that the app should use to launch the UI for
+     *         the user to confirm the system data transfer request.
+     */
+    @UserHandleAware
+    @Nullable
+    public IntentSender buildPermissionTransferUserConsentIntent(int associationId)
+            throws DeviceNotAssociatedException {
+        try {
+            PendingIntent pendingIntent = mService.buildPermissionTransferUserConsentIntent(
+                    mContext.getOpPackageName(),
+                    mContext.getUserId(),
+                    associationId);
+            if (pendingIntent == null) {
+                return null;
+            }
+            return pendingIntent.getIntentSender();
+        } catch (RemoteException e) {
+            ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Start system data transfer which has been previously approved by the user.
+     *
+     * <p>Before calling this method, the app needs to make sure there's a communication channel
+     * between two devices, and has prompted user consent dialogs built by one of these methods:
+     * {@link #buildPermissionTransferUserConsentIntent(int)}.
+     * The transfer may fail if the communication channel is disconnected during the transfer.</p>
+     *
+     * @param associationId The unique {@link AssociationInfo#getId ID} assigned to the Association
+     *                      of the companion device recorded by CompanionDeviceManager
+     * @throws DeviceNotAssociatedException Exception if the companion device is not associated
+     */
+    @UserHandleAware
+    public void startSystemDataTransfer(int associationId) throws DeviceNotAssociatedException {
+        try {
+            mService.startSystemDataTransfer(mContext.getUserId(), associationId);
+        } catch (RemoteException e) {
+            ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     private boolean checkFeaturePresent() {
         boolean featurePresent = mService != null;
         if (!featurePresent && DEBUG) {
diff --git a/core/java/android/companion/CompanionDeviceService.java b/core/java/android/companion/CompanionDeviceService.java
index 9e1bf4b..bb2189d 100644
--- a/core/java/android/companion/CompanionDeviceService.java
+++ b/core/java/android/companion/CompanionDeviceService.java
@@ -29,6 +29,7 @@
 import android.util.Log;
 
 import java.util.Objects;
+import java.util.concurrent.Executor;
 
 /**
  * A service that receives calls from the system when the associated companion device appears
@@ -152,11 +153,9 @@
      * @param messageId system assigned id of the message to be sent
      * @param associationId association id of the associated device
      * @param message message to be sent
-     *
-     * @hide
      */
-    @MainThread
-    public void onDispatchMessage(int messageId, int associationId, @NonNull byte[] message) {
+    public void onMessageDispatchedFromSystem(int messageId, int associationId,
+            @NonNull byte[] message) {
         // do nothing. Companion apps can override this function for system to send messages.
     }
 
@@ -167,17 +166,31 @@
      * <p>Calling app must declare uses-permission
      * {@link android.Manifest.permission#DELIVER_COMPANION_MESSAGES}</p>
      *
+     * <p>Note 1: messageId was assigned by the system, and sender should send the messageId along
+     * with the message to the receiver. messageId will later be used for verification purpose.
+     * Misusing the messageId will result in no action.</p>
+     *
+     * <p>Note 2: associationId should be local to your device which is calling this API. It's not
+     * the associationId on your remote device. If you don't have one, you can call
+     * {@link CompanionDeviceManager#associate(AssociationRequest, Executor,
+     * CompanionDeviceManager.Callback)} to create one. Misusing the associationId will result in
+     * {@link DeviceNotAssociatedException}.</p>
+     *
      * @param messageId id of the message
      * @param associationId id of the associated device
-     * @param message messaged received from the associated device
-     *
-     * @hide
+     * @param message message received from the associated device
      */
     @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES)
-    public final void dispatchMessage(int messageId, int associationId, @NonNull byte[] message) {
+    public final void dispatchMessageToSystem(int messageId, int associationId,
+            @NonNull byte[] message)
+            throws DeviceNotAssociatedException {
         CompanionDeviceManager companionDeviceManager =
                 getSystemService(CompanionDeviceManager.class);
-        companionDeviceManager.dispatchMessage(messageId, associationId, message);
+        if (companionDeviceManager != null) {
+            companionDeviceManager.dispatchMessage(messageId, associationId, message);
+        } else {
+            Log.e(LOG_TAG, "CompanionDeviceManager is null. Can't dispatch messages.");
+        }
     }
 
     /**
@@ -239,9 +252,11 @@
         }
 
         @Override
-        public void onDispatchMessage(int messageId, int associationId, @NonNull byte[] message) {
+        public void onMessageDispatchedFromSystem(int messageId, int associationId,
+                @NonNull byte[] message) {
             mMainHandler.postAtFrontOfQueue(
-                    () -> mService.onDispatchMessage(messageId, associationId, message));
+                    () -> mService.onMessageDispatchedFromSystem(messageId, associationId,
+                            message));
         }
     }
 }
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 68a6031f..f5b6938 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -62,7 +62,7 @@
     void createAssociation(in String packageName, in String macAddress, int userId,
         in byte[] certificate);
 
-    void dispatchMessage(in int messageId, in int associationId, in byte[] message);
+    void dispatchMessage(int messageId, int associationId, in byte[] message);
 
     void addOnAssociationsChangedListener(IOnAssociationsChangedListener listener, int userId);
 
@@ -71,4 +71,9 @@
     void notifyDeviceAppeared(int associationId);
 
     void notifyDeviceDisappeared(int associationId);
+
+    PendingIntent buildPermissionTransferUserConsentIntent(String callingPackage, int userId,
+        int associationId);
+
+    void startSystemDataTransfer(int userId, int associationId);
 }
diff --git a/core/java/android/companion/ICompanionDeviceService.aidl b/core/java/android/companion/ICompanionDeviceService.aidl
index 4e453573..3c90b86 100644
--- a/core/java/android/companion/ICompanionDeviceService.aidl
+++ b/core/java/android/companion/ICompanionDeviceService.aidl
@@ -22,5 +22,5 @@
 oneway interface ICompanionDeviceService {
     void onDeviceAppeared(in AssociationInfo associationInfo);
     void onDeviceDisappeared(in AssociationInfo associationInfo);
-    void onDispatchMessage(in int messageId, in int associationId, in byte[] message);
+    void onMessageDispatchedFromSystem(in int messageId, in int associationId, in byte[] message);
 }
diff --git a/core/java/android/companion/SystemDataTransferRequest.java b/core/java/android/companion/SystemDataTransferRequest.java
deleted file mode 100644
index e3b0369..0000000
--- a/core/java/android/companion/SystemDataTransferRequest.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.companion;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.provider.OneTimeUseBuilder;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * A request for users to allow the companion app to transfer system data to the companion devices.
- *
- * @hide
- */
-public final class SystemDataTransferRequest implements Parcelable {
-
-    private final int mAssociationId;
-    private final boolean mPermissionSyncAllPackages;
-    private final List<String> mPermissionSyncPackages;
-
-    /**
-     * @hide
-     */
-    public SystemDataTransferRequest(int associationId, boolean syncAllPackages,
-            @Nullable List<String> permissionSyncPackages) {
-        mAssociationId = associationId;
-        mPermissionSyncAllPackages = syncAllPackages;
-        mPermissionSyncPackages = permissionSyncPackages;
-    }
-
-    public int getAssociationId() {
-        return mAssociationId;
-    }
-
-    @NonNull
-    public boolean isPermissionSyncAllPackages() {
-        return mPermissionSyncAllPackages;
-    }
-
-    @NonNull
-    public List<String> getPermissionSyncPackages() {
-        return mPermissionSyncPackages;
-    }
-
-    /**
-     * A builder for {@link SystemDataTransferRequest}.
-     *
-     * <p>You have to call one of the below methods to create a valid request</p>
-     * <br>1. {@link #setPermissionSyncAllPackages()}
-     * <br>2. {@link #setPermissionSyncPackages(List)}
-     */
-    public static final class Builder extends OneTimeUseBuilder<SystemDataTransferRequest> {
-
-        private final int mAssociationId;
-        private boolean mPermissionSyncAllPackages;
-        private List<String> mPermissionSyncPackages = new ArrayList<>();
-
-        public Builder(int associationId) {
-            mAssociationId = associationId;
-        }
-
-        /**
-         * Call to sync permissions for all the packages. You can optionally call
-         * {@link #setPermissionSyncPackages(List)} to specify the packages to sync permissions.
-         *
-         * <p>The system will only sync permissions that are explicitly granted by the user.</p>
-         *
-         * <p>If a permission is granted or revoked by the system or a policy, even if the user has
-         * explicitly granted or revoked the permission earlier, the permission will be ignored.</p>
-         *
-         * <p>If a system or policy granted or revoked permission is granted or revoked by the user
-         * later, the permission will be ignored.</p>
-         *
-         * @see #setPermissionSyncPackages(List)
-         *
-         * @return the builder
-         */
-        @NonNull
-        public Builder setPermissionSyncAllPackages() {
-            mPermissionSyncAllPackages = true;
-            return this;
-        }
-
-        /**
-         * Set a list of packages to sync permissions. You can optionally call
-         * {@link #setPermissionSyncAllPackages()} to sync permissions for all the packages.
-         *
-         * @see #setPermissionSyncAllPackages()
-         *
-         * @param permissionSyncPackages packages to sync permissions
-         * @return builder
-         */
-        @NonNull
-        public Builder setPermissionSyncPackages(@NonNull List<String> permissionSyncPackages) {
-            mPermissionSyncPackages = permissionSyncPackages;
-            return this;
-        }
-
-        @Override
-        @NonNull
-        public SystemDataTransferRequest build() {
-            return new SystemDataTransferRequest(mAssociationId, mPermissionSyncAllPackages,
-                    mPermissionSyncPackages);
-        }
-    }
-
-    SystemDataTransferRequest(Parcel in) {
-        mAssociationId = in.readInt();
-        mPermissionSyncAllPackages = in.readBoolean();
-        mPermissionSyncPackages = Arrays.asList(in.createString8Array());
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeInt(mAssociationId);
-        dest.writeBoolean(mPermissionSyncAllPackages);
-        dest.writeString8Array(mPermissionSyncPackages.toArray(new String[0]));
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @NonNull
-    public static final Creator<SystemDataTransferRequest> CREATOR =
-            new Creator<SystemDataTransferRequest>() {
-                @Override
-                public SystemDataTransferRequest createFromParcel(Parcel in) {
-                    return new SystemDataTransferRequest(in);
-                }
-
-                @Override
-                public SystemDataTransferRequest[] newArray(int size) {
-                    return new SystemDataTransferRequest[size];
-                }
-            };
-}
diff --git a/core/java/android/companion/SystemDataTransferRequest.aidl b/core/java/android/companion/datatransfer/PermissionSyncRequest.aidl
similarity index 88%
rename from core/java/android/companion/SystemDataTransferRequest.aidl
rename to core/java/android/companion/datatransfer/PermissionSyncRequest.aidl
index 19ae60e..76a92e3 100644
--- a/core/java/android/companion/SystemDataTransferRequest.aidl
+++ b/core/java/android/companion/datatransfer/PermissionSyncRequest.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.companion;
+package android.companion.datatransfer;
 
-parcelable SystemDataTransferRequest;
+parcelable PermissionSyncRequest;
diff --git a/core/java/android/companion/datatransfer/PermissionSyncRequest.java b/core/java/android/companion/datatransfer/PermissionSyncRequest.java
new file mode 100644
index 0000000..973fca30
--- /dev/null
+++ b/core/java/android/companion/datatransfer/PermissionSyncRequest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion.datatransfer;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * The permission sync request class.
+ *
+ * @hide
+ */
+public class PermissionSyncRequest extends SystemDataTransferRequest implements Parcelable {
+
+    /** @hide */
+    public PermissionSyncRequest(int associationId) {
+        super(associationId, DATA_TYPE_PERMISSION_SYNC);
+    }
+
+    /** @hide */
+    @Override
+    public String toString() {
+        return "SystemDataTransferRequest("
+                + "associationId=" + mAssociationId
+                + ", userId=" + mUserId
+                + ", isUserConsented=" + mUserConsented
+                + ")";
+    }
+
+    /** @hide */
+    PermissionSyncRequest(Parcel in) {
+        super(in);
+    }
+
+    /** @hide */
+    @NonNull
+    public static final Creator<PermissionSyncRequest> CREATOR =
+            new Creator<PermissionSyncRequest>() {
+                @Override
+                public PermissionSyncRequest createFromParcel(Parcel in) {
+                    return new PermissionSyncRequest(in);
+                }
+
+                @Override
+                public PermissionSyncRequest[] newArray(int size) {
+                    return new PermissionSyncRequest[size];
+                }
+            };
+}
diff --git a/core/java/android/companion/datatransfer/SystemDataTransferRequest.java b/core/java/android/companion/datatransfer/SystemDataTransferRequest.java
new file mode 100644
index 0000000..38a553d
--- /dev/null
+++ b/core/java/android/companion/datatransfer/SystemDataTransferRequest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion.datatransfer;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.os.Parcel;
+
+/**
+ * A request for users to allow the companion app to transfer system data to the companion devices.
+ *
+ * @hide
+ */
+public abstract class SystemDataTransferRequest {
+
+    /** @hide */
+    public static final int DATA_TYPE_PERMISSION_SYNC = 1;
+
+    final int mAssociationId;
+
+    final int mDataType;
+
+    /**
+     * User id that the request belongs to.
+     * Populated by the system.
+     */
+    @UserIdInt
+    int mUserId;
+
+    /**
+     * Whether the request is consented by the user.
+     * Populated by the system
+     */
+    boolean mUserConsented = false;
+
+    /** @hide */
+    SystemDataTransferRequest(int associationId, int dataType) {
+        mAssociationId = associationId;
+        mDataType = dataType;
+    }
+
+    /** @hide */
+    public int getAssociationId() {
+        return mAssociationId;
+    }
+
+    /** @hide */
+    public int getDataType() {
+        return mDataType;
+    }
+
+    /** @hide */
+    public int getUserId() {
+        return mUserId;
+    }
+
+    /** @hide */
+    public boolean isUserConsented() {
+        return mUserConsented;
+    }
+
+    /** @hide */
+    public void setUserId(@UserIdInt int userId) {
+        mUserId = userId;
+    }
+
+    /** @hide */
+    public void setUserConsented(boolean isUserConsented) {
+        mUserConsented = isUserConsented;
+    }
+
+    /** @hide */
+    SystemDataTransferRequest(Parcel in) {
+        mAssociationId = in.readInt();
+        mDataType = in.readInt();
+        mUserId = in.readInt();
+        mUserConsented = in.readBoolean();
+    }
+
+    /** @hide */
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mAssociationId);
+        dest.writeInt(mDataType);
+        dest.writeInt(mUserId);
+        dest.writeBoolean(mUserConsented);
+    }
+
+    /** @hide */
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index f4de829..9708493 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -448,6 +448,12 @@
      */
     public boolean isApex;
 
+    /**
+     * Whether this is an active APEX package.
+     * @hide
+     */
+    public boolean isActiveApex;
+
     public PackageInfo() {
     }
 
@@ -534,6 +540,7 @@
             dest.writeInt(0);
         }
         dest.writeBoolean(isApex);
+        dest.writeBoolean(isActiveApex);
         dest.restoreAllowSquashing(prevAllowSquashing);
     }
 
@@ -598,5 +605,6 @@
             signingInfo = SigningInfo.CREATOR.createFromParcel(source);
         }
         isApex = source.readBoolean();
+        isActiveApex = source.readBoolean();
     }
 }
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 236c244..5f45c342 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -682,7 +682,9 @@
      * </ul>
      *
      * @param packageName The package to uninstall.
-     * @param statusReceiver Where to deliver the result.
+     * @param statusReceiver Where to deliver the result of the operation indicated by the extra
+     *                       {@link #EXTRA_STATUS}. Refer to the individual status codes
+     *                       on how to handle them.
      *
      * @see android.app.admin.DevicePolicyManager
      */
@@ -700,7 +702,9 @@
      *
      * @param packageName The package to uninstall.
      * @param flags Flags for uninstall.
-     * @param statusReceiver Where to deliver the result.
+     * @param statusReceiver Where to deliver the result of the operation indicated by the extra
+     *                       {@link #EXTRA_STATUS}. Refer to the individual status codes
+     *                       on how to handle them.
      *
      * @hide
      */
@@ -725,7 +729,9 @@
      * </ul>
      *
      * @param versionedPackage The versioned package to uninstall.
-     * @param statusReceiver Where to deliver the result.
+     * @param statusReceiver Where to deliver the result of the operation indicated by the extra
+     *                       {@link #EXTRA_STATUS}. Refer to the individual status codes
+     *                       on how to handle them.
      *
      * @see android.app.admin.DevicePolicyManager
      */
@@ -747,7 +753,9 @@
      *
      * @param versionedPackage The versioned package to uninstall.
      * @param flags Flags for uninstall.
-     * @param statusReceiver Where to deliver the result.
+     * @param statusReceiver Where to deliver the result of the operation indicated by the extra
+     *                       {@link #EXTRA_STATUS}. Refer to the individual status codes
+     *                       on how to handle them.
      *
      * @hide
      */
@@ -775,7 +783,9 @@
      *
      * @param packageName The package to install.
      * @param installReason Reason for install.
-     * @param statusReceiver Where to deliver the result.
+     * @param statusReceiver Where to deliver the result of the operation indicated by the extra
+     *                       {@link #EXTRA_STATUS}. Refer to the individual status codes
+     *                       on how to handle them.
      */
     @RequiresPermission(allOf = {
             Manifest.permission.INSTALL_PACKAGES,
@@ -797,8 +807,10 @@
      * Uninstall the given package for the user for which this installer was created if the package
      * will still exist for other users on the device.
      *
-     * @param packageName The package to install.
-     * @param statusReceiver Where to deliver the result.
+     * @param packageName The package to uninstall.
+     * @param statusReceiver Where to deliver the result of the operation indicated by the extra
+     *                       {@link #EXTRA_STATUS}. Refer to the individual status codes
+     *                       on how to handle them.
      */
     @RequiresPermission(Manifest.permission.DELETE_PACKAGES)
     public void uninstallExistingPackage(@NonNull String packageName,
@@ -1705,20 +1717,22 @@
         public @interface UserActionRequirement {}
 
         /**
-         * The installer did not call {@link SessionParams#setRequireUserAction(int)} to
-         * specify whether user action should be required for the install.
+         * This value is passed by the installer to {@link SessionParams#setRequireUserAction(int)}
+         * to indicate that user action is unspecified for this install.
+         * {@code requireUserAction} also defaults to this value unless modified by
+         * {@link SessionParams#setRequireUserAction(int)}
          */
         public static final int USER_ACTION_UNSPECIFIED = 0;
 
         /**
-         * The installer called {@link SessionParams#setRequireUserAction(int)} with
-         * {@code true} to require user action for the install to complete.
+         * This value is passed by the installer to {@link SessionParams#setRequireUserAction(int)}
+         * to indicate that user action is required for this install.
          */
         public static final int USER_ACTION_REQUIRED = 1;
 
         /**
-         * The installer called {@link SessionParams#setRequireUserAction(int)} with
-         * {@code false} to request that user action not be required for this install.
+         * This value is passed by the installer to {@link SessionParams#setRequireUserAction(int)}
+         * to indicate that user action is not required for this install.
          */
         public static final int USER_ACTION_NOT_REQUIRED = 2;
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a90f6d6..6f9ec9c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4247,6 +4247,7 @@
      */
     public static final String EXTRA_VERIFICATION_PACKAGE_NAME
             = "android.content.pm.extra.VERIFICATION_PACKAGE_NAME";
+
     /**
      * Extra field name for the result of a verification, either
      * {@link #VERIFICATION_ALLOW}, or {@link #VERIFICATION_REJECT}.
@@ -4256,6 +4257,14 @@
             = "android.content.pm.extra.VERIFICATION_RESULT";
 
     /**
+     * Extra field name for tracking whether user action
+     * was requested for a particular install, either {@code true} or {@code false}.
+     * @hide
+     */
+    public static final String EXTRA_USER_ACTION_REQUIRED
+            = "android.content.pm.extra.USER_ACTION_REQUIRED";
+
+    /**
      * Extra field name for the version code of a package pending verification.
      * @deprecated Use {@link #EXTRA_VERIFICATION_LONG_VERSION_CODE} instead.
      * @hide
@@ -4265,8 +4274,7 @@
             = "android.content.pm.extra.VERIFICATION_VERSION_CODE";
 
     /**
-     * Extra field name for the long version code of a package pending verification.
-     *
+     * Extra field name for the long version code of a package pending verification
      * @hide
      */
     public static final String EXTRA_VERIFICATION_LONG_VERSION_CODE =
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 76e9fcb..816460b 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -142,6 +142,22 @@
     public static final int FLAG_PROFILE = 0x00001000;
 
     /**
+     * Indicates that this user is created in ephemeral mode via
+     * {@link IUserManager} create user.
+     *
+     * When a user is created with {@link #FLAG_EPHEMERAL}, {@link #FLAG_EPHEMERAL_ON_CREATE}
+     * is set internally within the user manager.
+     *
+     * When {@link #FLAG_EPHEMERAL_ON_CREATE} is set {@link IUserManager.setUserEphemeral}
+     * has no effect because a user that was created ephemeral can never be made non-ephemeral.
+     *
+     * {@link #FLAG_EPHEMERAL_ON_CREATE} should NOT be set by client's of user manager
+     *
+     * @hide
+     */
+    public static final int FLAG_EPHEMERAL_ON_CREATE = 0x00002000;
+
+    /**
      * @hide
      */
     @IntDef(flag = true, prefix = "FLAG_", value = {
@@ -157,7 +173,8 @@
             FLAG_DEMO,
             FLAG_FULL,
             FLAG_SYSTEM,
-            FLAG_PROFILE
+            FLAG_PROFILE,
+            FLAG_EPHEMERAL_ON_CREATE
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface UserInfoFlag {
diff --git a/core/java/android/hardware/IConsumerIrService.aidl b/core/java/android/hardware/IConsumerIrService.aidl
index c79bd19..930c73f 100644
--- a/core/java/android/hardware/IConsumerIrService.aidl
+++ b/core/java/android/hardware/IConsumerIrService.aidl
@@ -19,8 +19,13 @@
 /** {@hide} */
 interface IConsumerIrService
 {
+    @RequiresNoPermission
     boolean hasIrEmitter();
+
+    @EnforcePermission("TRANSMIT_IR")
     void transmit(String packageName, int carrierFrequency, in int[] pattern);
+
+    @EnforcePermission("TRANSMIT_IR")
     int[] getCarrierFrequencies();
 }
 
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index a62bbf6..36b532f 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -41,6 +41,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.Trace;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
@@ -987,7 +988,8 @@
         @Override
         public void onDisplayEvent(int displayId, @DisplayEvent int event) {
             if (DEBUG) {
-                Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + event);
+                Log.d(TAG, "onDisplayEvent: displayId=" + displayId + ", event=" + eventToString(
+                        event));
             }
             handleDisplayEvent(displayId, event);
         }
@@ -1021,6 +1023,12 @@
 
         @Override
         public void handleMessage(Message msg) {
+            if (DEBUG) {
+                Trace.beginSection(
+                        "DisplayListenerDelegate(" + eventToString(msg.what)
+                                + ", display=" + msg.arg1
+                                + ", listener=" + mListener.getClass() + ")");
+            }
             switch (msg.what) {
                 case EVENT_DISPLAY_ADDED:
                     if ((mEventsMask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0) {
@@ -1047,6 +1055,9 @@
                     }
                     break;
             }
+            if (DEBUG) {
+                Trace.endSection();
+            }
         }
     }
 
@@ -1150,4 +1161,18 @@
             updateCallbackIfNeededLocked();
         }
     }
+
+    private static String eventToString(@DisplayEvent int event) {
+        switch (event) {
+            case EVENT_DISPLAY_ADDED:
+                return "ADDED";
+            case EVENT_DISPLAY_CHANGED:
+                return "CHANGED";
+            case EVENT_DISPLAY_REMOVED:
+                return "REMOVED";
+            case EVENT_DISPLAY_BRIGHTNESS_CHANGED:
+                return "BRIGHTNESS_CHANGED";
+        }
+        return "UNKNOWN";
+    }
 }
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index e1ffd4a..bb8af8f 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -38,6 +38,8 @@
 
 /** @hide */
 interface IInputManager {
+    // Gets the current VelocityTracker strategy
+    String getVelocityTrackerStrategy();
     // Gets input device information.
     InputDevice getInputDevice(int deviceId);
     int[] getInputDeviceIds();
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index cc5b275..f59b9f7 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -272,8 +272,15 @@
      */
     public static final int SWITCH_STATE_ON = 1;
 
+    private static String sVelocityTrackerStrategy;
+
     private InputManager(IInputManager im) {
         mIm = im;
+        try {
+            sVelocityTrackerStrategy = mIm.getVelocityTrackerStrategy();
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not get VelocityTracker strategy: " + ex);
+        }
     }
 
     /**
@@ -326,10 +333,19 @@
     }
 
     /**
+     * Get the current VelocityTracker strategy. Only works when the system has fully booted up.
+     * @hide
+     */
+    public String getVelocityTrackerStrategy() {
+        return sVelocityTrackerStrategy;
+    }
+
+    /**
      * Gets information about the input device with the specified id.
      * @param id The device id.
      * @return The input device or null if not found.
      */
+    @Nullable
     public InputDevice getInputDevice(int id) {
         synchronized (mInputDevicesLock) {
             populateInputDevicesLocked();
@@ -1377,6 +1393,7 @@
      * </p>
      * @hide
      */
+    @TestApi
     public void addUniqueIdAssociation(@NonNull String inputPort, @NonNull String displayUniqueId) {
         try {
             mIm.addUniqueIdAssociation(inputPort, displayUniqueId);
@@ -1393,6 +1410,7 @@
      * </p>
      * @hide
      */
+    @TestApi
     public void removeUniqueIdAssociation(@NonNull String inputPort) {
         try {
             mIm.removeUniqueIdAssociation(inputPort);
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
index 3a6d508..694d6d8c 100644
--- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
+++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
@@ -40,11 +40,11 @@
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -151,7 +151,7 @@
             return;
         }
 
-        List<String> parseErrors = new LinkedList<>();
+        List<String> parseErrors = new ArrayList<>();
         mKeyphrasePackageMap = new HashMap<>();
         for (ResolveInfo ri : ris) {
             try {
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 4fdd534..378b366 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -143,6 +143,7 @@
 import com.android.internal.inputmethod.InputMethodNavButtonFlags;
 import com.android.internal.inputmethod.InputMethodPrivilegedOperations;
 import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
+import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.internal.util.RingBuffer;
 import com.android.internal.view.IInlineSuggestionsRequestCallback;
 import com.android.internal.view.IInputContext;
@@ -1059,7 +1060,7 @@
     }
 
     private void notifyImeHidden() {
-        requestHideSelf(0);
+        requestHideSelf(0 /* flags */, SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API);
     }
 
     private void scheduleImeSurfaceRemoval() {
@@ -2907,9 +2908,13 @@
      * @param flags Provides additional operating flags.
      */
     public void requestHideSelf(int flags) {
+        requestHideSelf(flags, SoftInputShowHideReason.HIDE_SOFT_INPUT_FROM_IME);
+    }
+
+    private void requestHideSelf(int flags, @SoftInputShowHideReason int reason) {
         ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestHideSelf", mDumper,
                 null /* icProto */);
-        mPrivOps.hideMySoftInput(flags);
+        mPrivOps.hideMySoftInput(flags, reason);
     }
 
     /**
@@ -2930,7 +2935,9 @@
         if (mShowInputRequested) {
             // If the soft input area is shown, back closes it and we
             // consume the back key.
-            if (doIt) requestHideSelf(0);
+            if (doIt) {
+                requestHideSelf(0 /* flags */, SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_BACK_KEY);
+            }
             return true;
         } else if (mDecorViewVisible) {
             if (mCandidatesVisibility == View.VISIBLE) {
@@ -3081,7 +3088,8 @@
     private void onToggleSoftInput(int showFlags, int hideFlags) {
         if (DEBUG) Log.v(TAG, "toggleSoftInput()");
         if (isInputViewShown()) {
-            requestHideSelf(hideFlags);
+            requestHideSelf(
+                    hideFlags, SoftInputShowHideReason.HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT);
         } else {
             requestShowSelf(showFlags);
         }
@@ -3516,7 +3524,8 @@
      */
     public void onExtractingInputChanged(EditorInfo ei) {
         if (ei.inputType == InputType.TYPE_NULL) {
-            requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS);
+            requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS,
+                    SoftInputShowHideReason.HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED);
         }
     }
 
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 815e4f0..d71faee4 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1205,13 +1205,16 @@
         }
 
         static Uri readFrom(Parcel parcel) {
-            return new HierarchicalUri(
-                parcel.readString8(),
-                Part.readFrom(parcel),
-                PathPart.readFrom(parcel),
-                Part.readFrom(parcel),
-                Part.readFrom(parcel)
-            );
+            final String scheme = parcel.readString8();
+            final Part authority = Part.readFrom(parcel);
+            // In RFC3986 the path should be determined based on whether there is a scheme or
+            // authority present (https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3).
+            final boolean hasSchemeOrAuthority =
+                    (scheme != null && scheme.length() > 0) || !authority.isEmpty();
+            final PathPart path = PathPart.readFrom(hasSchemeOrAuthority, parcel);
+            final Part query = Part.readFrom(parcel);
+            final Part fragment = Part.readFrom(parcel);
+            return new HierarchicalUri(scheme, authority, path, query, fragment);
         }
 
         public int describeContents() {
@@ -2270,6 +2273,11 @@
             }
         }
 
+        static PathPart readFrom(boolean hasSchemeOrAuthority, Parcel parcel) {
+            final PathPart path = readFrom(parcel);
+            return hasSchemeOrAuthority ? makeAbsolute(path) : path;
+        }
+
         /**
          * Creates a path from the encoded string.
          *
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 3cde031..e5de3e1 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -131,4 +131,5 @@
     String getUserName();
     long getUserStartRealtime();
     long getUserUnlockRealtime();
+    boolean setUserEphemeral(int userId, boolean enableEphemeral);
 }
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index e06e732..14082f3 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -213,12 +213,6 @@
     public static final int SE_UID = 1068;
 
     /**
-     * Defines the UID/GID for the iorapd.
-     * @hide
-     */
-    public static final int IORAPD_UID = 1071;
-
-    /**
      * Defines the UID/GID for the NetworkStack app.
      * @hide
      */
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a64e63e..570d533 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1997,13 +1997,22 @@
      * @return Whether guest user is always ephemeral
      * @hide
      */
-    @TestApi
-    public static boolean isGuestUserEphemeral() {
+    public static boolean isGuestUserAlwaysEphemeral() {
         return Resources.getSystem()
                 .getBoolean(com.android.internal.R.bool.config_guestUserEphemeral);
     }
 
     /**
+     * @return true, when we want to enable user manager API and UX to allow
+     *           guest user ephemeral state change based on user input
+     * @hide
+     */
+    public static boolean isGuestUserAllowEphemeralStateChange() {
+        return Resources.getSystem()
+                .getBoolean(com.android.internal.R.bool.config_guestUserAllowEphemeralStateChange);
+    }
+
+    /**
      * Checks whether the device is running in a headless system user mode.
      *
      * <p>Headless system user mode means the {@link #isSystemUser() system user} runs system
@@ -3424,6 +3433,20 @@
             if (guest != null) {
                 Settings.Secure.putStringForUser(context.getContentResolver(),
                         Settings.Secure.SKIP_FIRST_USE_HINTS, "1", guest.id);
+
+                if (UserManager.isGuestUserAllowEphemeralStateChange()) {
+                    // Mark guest as (changeably) ephemeral if REMOVE_GUEST_ON_EXIT is 1
+                    // This is done so that a user via a UI controller can choose to
+                    // make a guest as ephemeral or not.
+                    // Settings.Global.REMOVE_GUEST_ON_EXIT holds the choice on what the guest state
+                    // should be, with default being ephemeral.
+                    boolean resetGuestOnExit = Settings.Global.getInt(context.getContentResolver(),
+                                                 Settings.Global.REMOVE_GUEST_ON_EXIT, 1) == 1;
+
+                    if (resetGuestOnExit && !guest.isEphemeral()) {
+                        setUserEphemeral(guest.id, true);
+                    }
+                }
             }
             return guest;
         } catch (ServiceSpecificException e) {
@@ -4941,6 +4964,31 @@
     }
 
     /**
+     * Set the user as ephemeral or non-ephemeral.
+     *
+     * If the user was initially created as ephemeral then this
+     * method has no effect and false is returned.
+     *
+     * @param userId the user's integer id
+     * @param enableEphemeral true: change user state to ephemeral,
+     *                        false: change user state to non-ephemeral
+     * @return true: user now has the desired ephemeral state,
+     *         false: desired user ephemeral state could not be set
+     *
+     * @hide
+     */
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MANAGE_USERS,
+            android.Manifest.permission.CREATE_USERS})
+    public boolean setUserEphemeral(@UserIdInt int userId, boolean enableEphemeral) {
+        try {
+            return mService.setUserEphemeral(userId, enableEphemeral);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Updates the context user's name.
      *
      * @param name the new name for the user
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index ec1c57d..237f6ed 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -413,10 +413,8 @@
      * {@link #startWaveform(VibrationEffect.VibrationParameter)}.
      *
      * @see VibrationEffect.WaveformBuilder
-     * @hide
      */
     @NonNull
-    @TestApi
     public static WaveformBuilder startWaveform() {
         return new WaveformBuilder();
     }
@@ -433,10 +431,8 @@
      * @return The {@link VibrationEffect.WaveformBuilder} started with the initial parameters.
      *
      * @see VibrationEffect.WaveformBuilder
-     * @hide
      */
     @NonNull
-    @TestApi
     public static WaveformBuilder startWaveform(@NonNull VibrationParameter initialParameter) {
         WaveformBuilder builder = startWaveform();
         builder.addTransition(Duration.ZERO, initialParameter);
@@ -458,10 +454,8 @@
      * @return The {@link VibrationEffect.WaveformBuilder} started with the initial parameters.
      *
      * @see VibrationEffect.WaveformBuilder
-     * @hide
      */
     @NonNull
-    @TestApi
     public static WaveformBuilder startWaveform(@NonNull VibrationParameter initialParameter1,
             @NonNull VibrationParameter initialParameter2) {
         WaveformBuilder builder = startWaveform();
@@ -875,9 +869,7 @@
         /**
          * Exception thrown when adding an element to a {@link Composition} that already ends in an
          * indefinitely repeating effect.
-         * @hide
          */
-        @TestApi
         public static final class UnreachableAfterRepeatingIndefinitelyException
                 extends IllegalStateException {
             UnreachableAfterRepeatingIndefinitelyException() {
@@ -946,10 +938,8 @@
          *
          * @throws UnreachableAfterRepeatingIndefinitelyException if the composition is currently
          * ending with a repeating effect.
-         * @hide
          */
         @NonNull
-        @TestApi
         public Composition addOffDuration(@NonNull Duration duration) {
             int durationMs = (int) duration.toMillis();
             Preconditions.checkArgumentNonnegative(durationMs, "Off period must be non-negative");
@@ -975,10 +965,8 @@
          *
          * @throws UnreachableAfterRepeatingIndefinitelyException if the composition is currently
          * ending with a repeating effect.
-         * @hide
          */
         @NonNull
-        @TestApi
         public Composition addEffect(@NonNull VibrationEffect effect) {
             return addSegments(effect);
         }
@@ -999,10 +987,8 @@
          * @throws IllegalArgumentException if the given effect is already repeating indefinitely.
          * @throws UnreachableAfterRepeatingIndefinitelyException if the composition is currently
          * ending with a repeating effect.
-         * @hide
          */
         @NonNull
-        @TestApi
         public Composition repeatEffectIndefinitely(@NonNull VibrationEffect effect) {
             Preconditions.checkArgument(effect.getDuration() < Long.MAX_VALUE,
                     "Can't repeat an indefinitely repeating effect. Consider addEffect instead.");
@@ -1216,9 +1202,7 @@
      *     .build();}</pre>
      *
      * @see VibrationEffect#startWaveform
-     * @hide
      */
-    @TestApi
     public static final class WaveformBuilder {
         // Epsilon used for float comparison of amplitude and frequency values on transitions.
         private static final float EPSILON = 1e-5f;
@@ -1399,10 +1383,8 @@
      * <p>Examples of concrete parameters are the vibration amplitude or frequency.
      *
      * @see VibrationEffect.WaveformBuilder
-     * @hide
      */
     @SuppressWarnings("UserHandleName") // This is not a regular set of parameters, no *Params.
-    @TestApi
     public static class VibrationParameter {
         VibrationParameter() {
         }
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 465d90d..7f0d634 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -212,9 +212,7 @@
      *
      * @return True if the hardware can control the frequency of the vibrations independently of
      * the vibration amplitude, false otherwise.
-     * @hide
      */
-    @TestApi
     public boolean hasFrequencyControl() {
         // We currently can only control frequency of the vibration using the compose PWLE method.
         return getInfo().hasCapability(
@@ -238,9 +236,7 @@
      * @return the resonant frequency of the vibrator, or {@link Float#NaN NaN} if it's unknown, not
      * applicable, or if this vibrator is a composite of multiple physical devices with different
      * frequencies.
-     * @hide
      */
-    @TestApi
     public float getResonantFrequency() {
         return getInfo().getResonantFrequencyHz();
     }
@@ -251,9 +247,7 @@
      * @return the Q factor of the vibrator, or {@link Float#NaN NaN} if it's unknown, not
      * applicable, or if this vibrator is a composite of multiple physical devices with different
      * Q factors.
-     * @hide
      */
-    @TestApi
     public float getQFactor() {
         return getInfo().getQFactor();
     }
@@ -268,9 +262,7 @@
      * frequency control. If this vibrator is a composite of multiple physical devices then this
      * will return a profile supported in all devices, or null if the intersection is empty or not
      * available.
-     * @hide
      */
-    @TestApi
     @Nullable
     public VibratorFrequencyProfile getFrequencyProfile() {
         VibratorInfo.FrequencyProfile frequencyProfile = getInfo().getFrequencyProfile();
diff --git a/core/java/android/os/vibrator/VibratorFrequencyProfile.java b/core/java/android/os/vibrator/VibratorFrequencyProfile.java
index afc0007..0f2aa15 100644
--- a/core/java/android/os/vibrator/VibratorFrequencyProfile.java
+++ b/core/java/android/os/vibrator/VibratorFrequencyProfile.java
@@ -18,7 +18,6 @@
 
 import android.annotation.FloatRange;
 import android.annotation.NonNull;
-import android.annotation.TestApi;
 import android.os.VibratorInfo;
 
 import com.android.internal.util.Preconditions;
@@ -39,9 +38,7 @@
  * frequency increment between each pair of amplitude values.
  *
  * <p>Vibrators without independent frequency control do not have a frequency profile.
- * @hide
  */
-@TestApi
 public final class VibratorFrequencyProfile {
 
     private final VibratorInfo.FrequencyProfile mFrequencyProfile;
diff --git a/core/java/android/permission/Permissions.md b/core/java/android/permission/Permissions.md
index dfe748b..e61ecd8 100644
--- a/core/java/android/permission/Permissions.md
+++ b/core/java/android/permission/Permissions.md
@@ -71,9 +71,9 @@
 
 A requested permission does not necessarily mean that the permission is granted. When and how a
 permission is granted depends on the protection level of the permission. If no protection level is
-set, the permission will always be granted. Such "normal" permissions can still be useful as it
-will be easy to find apps using a certain functionality on app stores and by checking `dumpsys
-package`.
+set, it will default to `normal` and the permission will always be granted if requested. Such
+`normal` permissions can still be useful as it will be easy to find apps using a certain
+functionality on app stores and by checking `dumpsys package`.
 
 #### Checking a permission
 
@@ -686,17 +686,37 @@
 these system apps and then enforcing the permissions in the API similar to other [install time
 permissions](#checking-a-permission).
 
-System apps are not different from regular apps, but the protection levels (e.g.
+System apps are not different from regular apps, but the protection flags (e.g.
 [privileged](#privileged-permissions), [preinstalled](#preinstalled-permissions)) mentioned in this
 section are more commonly used by system apps.
 
-### Multiple permission levels
+### Permission protection level
 
-It is possible to assign multiple protection levels to a permission. Very common combinations are
-for example adding `signature` to all permissions to make sure the platform signed apps can be
-granted the permission, e.g. `privileged|signature`.
+Every permission has a protection level (`android:protectionlevel`), which is a combination of one
+required protection (`PermissionInfo.getProtection()`) and multiple optional protection flags
+(`PermissionInfo.getProtectionFlags()`).
 
-The permission will be granted if the app qualifies for _any_ of the permission levels.
+The protection can be one of the following:
+
+- [`normal`](#requesting-a-permission): The permission will be granted to apps requesting it in
+their manifest.
+- [`dangerous`](#runtime-permissions): The permission will be a runtime permission.
+- [`signature`](#signature-permissions): The permission will be granted to apps being signed with
+the same certificate as the app defining the permission. If the permission is a platform permission,
+it means those apps need to be platform-signed.
+- `internal`: This is a no-op protection so that it won't allow granting the permission by itself.
+However, it will be useful when defining permissions that should only be granted according to its
+protection flags, e.g. `internal|role` for a role-only permission.
+
+There are various optional protection flags that can be added to protection level, in addition to
+the required protection, e.g. [appop](#app_op-permissions),
+[preinstalled](#preinstalled-permissions), [privileged](#privileged-permissions),
+[installer](#limited-permissions), [role](#role-protected-permissions) and
+[development](#development-permissions).
+
+The permission will be granted to an app if it meets _any_ of the protection or protection flags (an
+`OR` relationship). For example, `signature|privileged` allows the permission to be granted to
+platform-signed apps as well as privileged apps.
 
 ### App-op permissions
 
@@ -716,18 +736,15 @@
 #### Defining an app-op permission
 
 Only the platform can reasonably define an app-op permission. The permission is defined in the
-platforms manifest using the `appop` protection level
+platforms manifest using the `appop` protection flag:
 
 ```xml
 <manifest package="android">
     <permission android:name="android.permission.MY_APPOP_PERMISSION"
-        android:protectionLevel="appop|signature" />
+        android:protectionLevel="signature|appop" />
 </manifest>
 ```
 
-Almost always the protection level is app-op | something else, like
-[signature](#signature-permissions) (in the case above) or [privileged](#privileged-permissions).
-
 #### Checking an app-op permission
 
 The `PermissionChecker` utility can check app-op permissions with the [same syntax as runtime
@@ -913,12 +930,12 @@
 
 > Not recommended
 
-By adding the `development` protection level to any permissions the permission can be granted via
+By adding the `development` protection flag to any permissions the permission can be granted via
 the `pm grant` shell command. This appears to be useful for development and testing, but it is very
 highly discouraged. Any user can grant them permanently via adb, hence adding this tag removes
 all guarantees the permission might otherwise provide.
 
-### Other protection levels
+### Other protection flags
 
 There are other levels (such as `runtime`) but they are for special purposes on should not be
 used by platform developers.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 111c670..a51ee48 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10898,6 +10898,14 @@
         public static final String ADD_USERS_WHEN_LOCKED = "add_users_when_locked";
 
         /**
+         * Whether guest user should be removed on exit from guest mode.
+         * <p>
+         * Type: int
+         * @hide
+         */
+        public static final String REMOVE_GUEST_ON_EXIT = "remove_guest_on_exit";
+
+        /**
          * Whether applying ramping ringer on incoming phone call ringtone.
          * <p>1 = apply ramping ringer
          * <p>0 = do not apply ramping ringer
@@ -17252,6 +17260,12 @@
             public static final String AMBIENT_TILT_TO_BRIGHT = "ambient_tilt_to_bright";
 
             /**
+             * Whether touch and hold to edit WF is enabled
+             * @hide
+             */
+            public static final String TOUCH_AND_HOLD_WATCH_FACE = "touch_and_hold_watchface";
+
+            /**
              * Whether the current watchface is decomposable.
              * @hide
              */
@@ -17469,6 +17483,18 @@
              * @hide
              */
             public static final String WET_MODE_ON = "wet_mode_on";
+
+            /*
+             * Whether the screen-unlock (keyguard) sound is enabled.
+             * @hide
+             */
+            public static final String SCREEN_UNLOCK_SOUND_ENABLED = "screen_unlock_sound_enabled";
+
+            /*
+             * Whether charging sounds are enabled.
+             * @hide
+             */
+            public static final String CHARGING_SOUNDS_ENABLED = "charging_sounds_enabled";
         }
     }
 
diff --git a/core/java/android/security/attestationverification/AttestationVerificationManager.java b/core/java/android/security/attestationverification/AttestationVerificationManager.java
index db783ce..2e61db1 100644
--- a/core/java/android/security/attestationverification/AttestationVerificationManager.java
+++ b/core/java/android/security/attestationverification/AttestationVerificationManager.java
@@ -226,10 +226,10 @@
     public static final int PROFILE_SELF_TRUSTED = 2;
 
     /**
-     * A system-defined profile which verifies that the attesting environment environment is similar
-     * to the current device in terms of security model and security configuration. This category is
-     * fairly broad and most securely configured Android devices should qualify, along with a
-     * variety of non-Android devices.
+     * A system-defined profile which verifies that the attesting environment is similar to the
+     * current device in terms of security model and security configuration. This category is fairly
+     * broad and most securely configured Android devices should qualify, along with a variety of
+     * non-Android devices.
      */
     public static final int PROFILE_PEER_DEVICE = 3;
 
@@ -321,4 +321,52 @@
 
     /** Requirements bundle parameter for a challenge. */
     public static final String PARAM_CHALLENGE = "localbinding.challenge";
+
+    /** @hide */
+    public static String localBindingTypeToString(@LocalBindingType int localBindingType) {
+        final String text;
+        switch (localBindingType) {
+            case TYPE_UNKNOWN:
+                text = "UNKNOWN";
+                break;
+
+            case TYPE_APP_DEFINED:
+                text = "APP_DEFINED";
+                break;
+
+            case TYPE_PUBLIC_KEY:
+                text = "PUBLIC_KEY";
+                break;
+
+            case TYPE_CHALLENGE:
+                text = "CHALLENGE";
+                break;
+
+            default:
+                return Integer.toString(localBindingType);
+        }
+        return text + "(" + localBindingType + ")";
+    }
+
+    /** @hide */
+    public static String verificationResultCodeToString(@VerificationResult int resultCode) {
+        final String text;
+        switch (resultCode) {
+            case RESULT_UNKNOWN:
+                text = "UNKNOWN";
+                break;
+
+            case RESULT_SUCCESS:
+                text = "SUCCESS";
+                break;
+
+            case RESULT_FAILURE:
+                text = "FAILURE";
+                break;
+
+            default:
+                return Integer.toString(resultCode);
+        }
+        return text + "(" + resultCode + ")";
+    }
 }
diff --git a/core/java/android/service/autofill/FillContext.java b/core/java/android/service/autofill/FillContext.java
index 8331550..cc1b6cd 100644
--- a/core/java/android/service/autofill/FillContext.java
+++ b/core/java/android/service/autofill/FillContext.java
@@ -32,7 +32,7 @@
 
 import com.android.internal.util.DataClass;
 
-import java.util.LinkedList;
+import java.util.ArrayDeque;
 
 /**
  * This class represents a context for each fill request made via {@link
@@ -95,7 +95,7 @@
      * @hide
      */
     @NonNull public ViewNode[] findViewNodesByAutofillIds(@NonNull AutofillId[] ids) {
-        final LinkedList<ViewNode> nodesToProcess = new LinkedList<>();
+        final ArrayDeque<ViewNode> nodesToProcess = new ArrayDeque<>();
         final ViewNode[] foundNodes = new AssistStructure.ViewNode[ids.length];
 
         // Indexes of foundNodes that are not found yet
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index 1507c87..327cda3 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -97,7 +97,7 @@
      */
     public static final @RequestFlags int FLAG_VIEW_NOT_FOCUSED = 0x10;
 
-    // The flag value 0x20 has been used.
+    // The flag value 0x20 has been defined in AutofillManager.
 
     /**
      * Indicates the request supports fill dialog presentation for the fields, the
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
index 0d290ee..ce38bb8 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
@@ -135,7 +135,7 @@
         return null;
     }
 
-    private static class ServiceMetadata {
+    static class ServiceMetadata {
         @Nullable
         private final String mSettingsActivity;
         @Nullable
@@ -161,7 +161,7 @@
         }
     }
 
-    private static ServiceMetadata parseServiceMetadata(Context context, ServiceInfo serviceInfo) {
+    static ServiceMetadata parseServiceMetadata(Context context, ServiceInfo serviceInfo) {
         PackageManager pm = context.getPackageManager();
         final XmlResourceParser parser =
                 serviceInfo.loadXmlMetaData(pm, QuickAccessWalletService.SERVICE_META_DATA);
diff --git a/core/java/android/service/voice/AbstractHotwordDetector.java b/core/java/android/service/voice/AbstractHotwordDetector.java
index 01d5638..5b3b78b 100644
--- a/core/java/android/service/voice/AbstractHotwordDetector.java
+++ b/core/java/android/service/voice/AbstractHotwordDetector.java
@@ -22,6 +22,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityThread;
+import android.app.compat.CompatChanges;
 import android.media.AudioFormat;
 import android.media.permission.Identity;
 import android.os.Handler;
@@ -65,6 +66,13 @@
     }
 
     /**
+     * Method to be called for the detector to ready/register itself with underlying system
+     * services.
+     */
+    abstract void initialize(@Nullable PersistableBundle options,
+            @Nullable SharedMemory sharedMemory);
+
+    /**
      * Detect hotword from an externally supplied stream of data.
      *
      * @return true if the request to start recognition succeeded
@@ -73,7 +81,7 @@
     public boolean startRecognition(
             @NonNull ParcelFileDescriptor audioStream,
             @NonNull AudioFormat audioFormat,
-            @Nullable PersistableBundle options) {
+            @Nullable PersistableBundle options) throws IllegalDetectorStateException {
         if (DEBUG) {
             Slog.i(TAG, "#recognizeHotword");
         }
@@ -98,19 +106,22 @@
      * Set configuration and pass read-only data to hotword detection service.
      *
      * @param options Application configuration data to provide to the
-     * {@link HotwordDetectionService}. PersistableBundle does not allow any remotable objects or
-     * other contents that can be used to communicate with other processes.
+     *         {@link HotwordDetectionService}. PersistableBundle does not allow any remotable
+     *         objects or other contents that can be used to communicate with other processes.
      * @param sharedMemory The unrestricted data blob to provide to the
-     * {@link HotwordDetectionService}. Use this to provide the hotword models data or other
-     * such data to the trusted process.
-     *
-     * @throws IllegalStateException if this AlwaysOnHotwordDetector wasn't specified to use a
-     * {@link HotwordDetectionService} when it was created. In addition, if this
-     * AlwaysOnHotwordDetector is in an invalid or error state.
+     *         {@link HotwordDetectionService}. Use this to provide the hotword models data or other
+     *         such data to the trusted process.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of
+     *         Android Tiramisu or above and attempts to start a recognition when the detector is
+     *         not able based on the state. Because the caller receives updates via an asynchronous
+     *         callback and the state of the detector can change without caller's knowledge, a
+     *         checked exception is thrown.
+     * @throws IllegalStateException if this HotwordDetector wasn't specified to use a
+     *         {@link HotwordDetectionService} when it was created.
      */
     @Override
     public void updateState(@Nullable PersistableBundle options,
-            @Nullable SharedMemory sharedMemory) {
+            @Nullable SharedMemory sharedMemory) throws IllegalDetectorStateException {
         if (DEBUG) {
             Slog.d(TAG, "updateState()");
         }
@@ -156,9 +167,13 @@
         }
     }
 
-    protected void throwIfDetectorIsNoLongerActive() {
+    protected void throwIfDetectorIsNoLongerActive() throws IllegalDetectorStateException {
         if (!mIsDetectorActive.get()) {
             Slog.e(TAG, "attempting to use a destroyed detector which is no longer active");
+            if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                throw new IllegalDetectorStateException(
+                        "attempting to use a destroyed detector which is no longer active");
+            }
             throw new IllegalStateException(
                     "attempting to use a destroyed detector which is no longer active");
         }
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index bc42da6..d01e7fe 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.CAPTURE_AUDIO_HOTWORD;
 import static android.Manifest.permission.RECORD_AUDIO;
+import static android.service.voice.VoiceInteractionService.MULTIPLE_ACTIVE_HOTWORD_DETECTORS;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -27,6 +28,7 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.app.ActivityThread;
+import android.app.compat.CompatChanges;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
@@ -50,9 +52,11 @@
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.SharedMemory;
+import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IHotwordRecognitionStatusCallback;
 import com.android.internal.app.IVoiceInteractionManagerService;
 import com.android.internal.app.IVoiceInteractionSoundTriggerSession;
@@ -62,8 +66,11 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
+import java.util.Set;
 
 /**
  * A class that lets a VoiceInteractionService implementation interact with
@@ -275,11 +282,12 @@
      * The metadata of the Keyphrase, derived from the enrollment application.
      * This may be null if this keyphrase isn't supported by the enrollment application.
      */
+    @GuardedBy("mLock")
     @Nullable
     private KeyphraseMetadata mKeyphraseMetadata;
     private final KeyphraseEnrollmentInfo mKeyphraseEnrollmentInfo;
     private final IVoiceInteractionManagerService mModelManagementService;
-    private final IVoiceInteractionSoundTriggerSession mSoundTriggerSession;
+    private IVoiceInteractionSoundTriggerSession mSoundTriggerSession;
     private final SoundTriggerListener mInternalCallback;
     private final Callback mExternalCallback;
     private final Handler mHandler;
@@ -287,6 +295,9 @@
     private final int mTargetSdkVersion;
     private final boolean mSupportHotwordDetectionService;
 
+    @GuardedBy("mLock")
+    private boolean mIsAvailabilityOverriddenByTestApi = false;
+    @GuardedBy("mLock")
     private int mAvailability = STATE_NOT_READY;
 
     /**
@@ -788,8 +799,7 @@
     public AlwaysOnHotwordDetector(String text, Locale locale, Callback callback,
             KeyphraseEnrollmentInfo keyphraseEnrollmentInfo,
             IVoiceInteractionManagerService modelManagementService, int targetSdkVersion,
-            boolean supportHotwordDetectionService, @Nullable PersistableBundle options,
-            @Nullable SharedMemory sharedMemory) {
+            boolean supportHotwordDetectionService) {
         super(modelManagementService, callback,
                 supportHotwordDetectionService ? DETECTOR_TYPE_TRUSTED_HOTWORD_DSP
                         : DETECTOR_TYPE_NORMAL);
@@ -803,6 +813,12 @@
         mModelManagementService = modelManagementService;
         mTargetSdkVersion = targetSdkVersion;
         mSupportHotwordDetectionService = supportHotwordDetectionService;
+    }
+
+    @Override
+    void initialize(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory) {
+        // TODO: transition to use an API that is not updateState to provide
+        //  onHotwordDetectionServiceInitialized status to external callback
         if (mSupportHotwordDetectionService) {
             updateStateLocked(options, sharedMemory, mInternalCallback,
                     DETECTOR_TYPE_TRUSTED_HOTWORD_DSP);
@@ -810,30 +826,40 @@
         try {
             Identity identity = new Identity();
             identity.packageName = ActivityThread.currentOpPackageName();
-            mSoundTriggerSession = mModelManagementService.createSoundTriggerSessionAsOriginator(
-                    identity, mBinder);
+            mSoundTriggerSession =
+                    mModelManagementService.createSoundTriggerSessionAsOriginator(
+                            identity, mBinder);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
-        new RefreshAvailabiltyTask().execute();
+        new RefreshAvailabilityTask().execute();
     }
 
     /**
      * {@inheritDoc}
      *
-     * @throws IllegalStateException if this AlwaysOnHotwordDetector wasn't specified to use a
-     * {@link HotwordDetectionService} when it was created. In addition, if this
-     * AlwaysOnHotwordDetector is in an invalid or error state.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above and this AlwaysOnHotwordDetector wasn't specified to use a
+     *         {@link HotwordDetectionService} when it was created. In addition, the exception can
+     *         be thrown if this AlwaysOnHotwordDetector is in an invalid or error state.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if
+     *         this AlwaysOnHotwordDetector wasn't specified to use a
+     *         {@link HotwordDetectionService} when it was created. In addition, the exception can
+     *         be thrown if this AlwaysOnHotwordDetector is in an invalid or error state.
      */
     @Override
     public final void updateState(@Nullable PersistableBundle options,
-            @Nullable SharedMemory sharedMemory) {
+            @Nullable SharedMemory sharedMemory) throws IllegalDetectorStateException {
         synchronized (mLock) {
             if (!mSupportHotwordDetectionService) {
                 throw new IllegalStateException(
                         "updateState called, but it doesn't support hotword detection service");
             }
             if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+                if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                    throw new IllegalDetectorStateException(
+                            "updateState called on an invalid detector or error state");
+                }
                 throw new IllegalStateException(
                         "updateState called on an invalid detector or error state");
             }
@@ -843,6 +869,48 @@
     }
 
     /**
+     * Test API for manipulating the voice engine and sound model availability.
+     *
+     * After overriding the availability status, the client's
+     * {@link Callback#onAvailabilityChanged(int)} will be called to reflect the updated state.
+     *
+     * When this override is set, all system updates to availability will be ignored.
+     * @hide
+     */
+    @TestApi
+    public void overrideAvailability(int availability) {
+        synchronized (mLock) {
+            // ENROLLED state requires there to be metadata about the sound model so a fake one
+            // is created.
+            if (mKeyphraseMetadata == null && availability == STATE_KEYPHRASE_ENROLLED) {
+                Set<Locale> fakeSupportedLocales = new HashSet<>();
+                fakeSupportedLocales.add(mLocale);
+                mKeyphraseMetadata = new KeyphraseMetadata(1, mText, fakeSupportedLocales,
+                        AlwaysOnHotwordDetector.RECOGNITION_MODE_VOICE_TRIGGER);
+            }
+
+            mAvailability = availability;
+            mIsAvailabilityOverriddenByTestApi = true;
+            notifyStateChangedLocked();
+        }
+    }
+
+    /**
+     * Test API for clearing an availability override set by {@link #overrideAvailability(int)}
+     *
+     * This method will restore the availability to the current system state.
+     * @hide
+     */
+    @TestApi
+    public void resetAvailability() {
+        synchronized (mLock) {
+            mIsAvailabilityOverriddenByTestApi = false;
+        }
+        // Execute a refresh availability task - which should then notify of a change.
+        new RefreshAvailabilityTask().execute();
+    }
+
+    /**
      * Test API to simulate to trigger hardware recognition event for test.
      *
      * @hide
@@ -878,28 +946,46 @@
      * @see #RECOGNITION_MODE_USER_IDENTIFICATION
      * @see #RECOGNITION_MODE_VOICE_TRIGGER
      *
-     * @throws UnsupportedOperationException if the keyphrase itself isn't supported.
-     *         Callers should only call this method after a supported state callback on
-     *         {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
-     * @throws IllegalStateException if the detector is in an invalid or error state.
-     *         This may happen if another detector has been instantiated or the
-     *         {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above. Because the caller receives availability updates via an asynchronous
+     *         callback, it may be due to the availability changing while this call is performed.
+     *         - Throws if the detector is in an invalid or error state.
+     *           This may happen if another detector has been instantiated or the
+     *           {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
+     *         33 Android if the recognition isn't supported. Callers should only call this method
+     *         after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
+     *         avoid this exception.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below Android API level
+     *         33 if the detector is in an invalid or error state. This may happen if another
+     *         detector has been instantiated or the {@link VoiceInteractionService} hosting this
+     *         detector has been shut down.
      */
-    public @RecognitionModes int getSupportedRecognitionModes() {
+    public @RecognitionModes
+    int getSupportedRecognitionModes() throws IllegalDetectorStateException {
         if (DBG) Slog.d(TAG, "getSupportedRecognitionModes()");
         synchronized (mLock) {
             return getSupportedRecognitionModesLocked();
         }
     }
 
-    private int getSupportedRecognitionModesLocked() {
+    @GuardedBy("mLock")
+    private int getSupportedRecognitionModesLocked() throws IllegalDetectorStateException {
         if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+            if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                throw new IllegalDetectorStateException("getSupportedRecognitionModes called on an"
+                        + " invalid detector or error state");
+            }
             throw new IllegalStateException(
                     "getSupportedRecognitionModes called on an invalid detector or error state");
         }
 
         // This method only makes sense if we can actually support a recognition.
         if (mAvailability != STATE_KEYPHRASE_ENROLLED || mKeyphraseMetadata == null) {
+            if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                throw new IllegalDetectorStateException("Getting supported recognition modes for"
+                        + " the keyphrase is not supported");
+            }
             throw new UnsupportedOperationException(
                     "Getting supported recognition modes for the keyphrase is not supported");
         }
@@ -926,6 +1012,7 @@
         }
     }
 
+    @GuardedBy("mLock")
     private int getSupportedAudioCapabilitiesLocked() {
         try {
             ModuleProperties properties =
@@ -949,30 +1036,77 @@
      * @see #RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS
      *
      * @param recognitionFlags The flags to control the recognition properties.
+     * @param data Additional pass-through data to the system voice engine along with the
+     *             startRecognition request. This data is intended to provide additional parameters
+     *             when starting the opaque sound model.
      * @return Indicates whether the call succeeded or not.
-     * @throws UnsupportedOperationException if the recognition isn't supported.
-     *         Callers should only call this method after a supported state callback on
-     *         {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
-     * @throws IllegalStateException if the detector is in an invalid or error state.
-     *         This may happen if another detector has been instantiated or the
-     *         {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above and attempts to start a recognition when the detector is not able based on
+     *         the availability state. This can be thrown even if the state has been checked before
+     *         calling this method because the caller receives availability updates via an
+     *         asynchronous callback, it may be due to the availability changing while this call is
+     *         performed.
+     *         - Throws if the recognition isn't supported.
+     *           Callers should only call this method after a supported state callback on
+     *           {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+     *         - Also throws if the detector is in an invalid or error state.
+     *           This may happen if another detector has been instantiated or the
+     *           {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
+     *         33 Android if the recognition isn't supported. Callers should only call this method
+     *         after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
+     *         avoid this exception.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below Android API level
+     *         33 if the detector is in an invalid or error state. This may happen if another
+     *         detector has been instantiated or the {@link VoiceInteractionService} hosting this
+     *         detector has been shut down.
      */
     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
-    public boolean startRecognition(@RecognitionFlags int recognitionFlags) {
+    public boolean startRecognition(@RecognitionFlags int recognitionFlags, @NonNull byte[] data)
+            throws IllegalDetectorStateException {
+        synchronized (mLock) {
+            return startRecognitionLocked(recognitionFlags, data)
+                    == STATUS_OK;
+        }
+    }
+
+    /**
+     * Starts recognition for the associated keyphrase.
+     * Caller must be the active voice interaction service via
+     * Settings.Secure.VOICE_INTERACTION_SERVICE.
+     *
+     * @see #RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO
+     * @see #RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS
+     *
+     * @param recognitionFlags The flags to control the recognition properties.
+     * @return Indicates whether the call succeeded or not.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above and attempts to start a recognition when the detector is not able based on
+     *         the availability state. This can be thrown even if the state has been checked before
+     *         calling this method because the caller receives availability updates via an
+     *         asynchronous callback, it may be due to the availability changing while this call is
+     *         performed.
+     *         - Throws if the recognition isn't supported.
+     *           Callers should only call this method after a supported state callback on
+     *           {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+     *         - Also throws if the detector is in an invalid or error state.
+     *           This may happen if another detector has been instantiated or the
+     *           {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
+     *         33 if the recognition isn't supported. Callers should only call this method after a
+     *         supported state callback on {@link Callback#onAvailabilityChanged(int)} to avoid this
+     *         exception.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
+     *         detector is in an invalid or error state. This may happen if another detector has
+     *         been instantiated or the {@link VoiceInteractionService} hosting this detector has
+     *         been shut down.
+     */
+    @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
+    public boolean startRecognition(@RecognitionFlags int recognitionFlags)
+            throws IllegalDetectorStateException {
         if (DBG) Slog.d(TAG, "startRecognition(" + recognitionFlags + ")");
         synchronized (mLock) {
-            if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
-                throw new IllegalStateException(
-                        "startRecognition called on an invalid detector or error state");
-            }
-
-            // Check if we can start/stop a recognition.
-            if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
-                throw new UnsupportedOperationException(
-                        "Recognition for the given keyphrase is not supported");
-            }
-
-            return startRecognitionLocked(recognitionFlags) == STATUS_OK;
+            return startRecognitionLocked(recognitionFlags, null /* data */) == STATUS_OK;
         }
     }
 
@@ -983,7 +1117,8 @@
      */
     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
     @Override
-    public boolean startRecognition() {
+    public boolean startRecognition()
+            throws IllegalDetectorStateException {
         return startRecognition(0);
     }
 
@@ -993,28 +1128,44 @@
      * Settings.Secure.VOICE_INTERACTION_SERVICE.
      *
      * @return Indicates whether the call succeeded or not.
-     * @throws UnsupportedOperationException if the recognition isn't supported.
-     *         Callers should only call this method after a supported state callback on
-     *         {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
-     * @throws IllegalStateException if the detector is in an invalid or error state.
-     *         This may happen if another detector has been instantiated or the
-     *         {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of
+     *         API level 33 or above and attempts to stop a recognition when the detector is
+     *         not able based on the state. This can be thrown even if the state has been checked
+     *         before calling this method because the caller receives availability updates via an
+     *         asynchronous callback, it may be due to the availability changing while this call is
+     *         performed.
+     * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
+     *         33 if the recognition isn't supported. Callers should only call this method after a
+     *         supported state callback on {@link Callback#onAvailabilityChanged(int)} to avoid this
+     *         exception.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
+     *         detector is in an invalid or error state. This may happen if another detector has
+     *         been instantiated or the {@link VoiceInteractionService} hosting this detector has
+     *         been shut down.
      */
     // TODO: Remove this RequiresPermission since it isn't actually enforced. Also fix the javadoc
     // about permissions enforcement (when it throws vs when it just returns false) for other
     // methods in this class.
     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
     @Override
-    public boolean stopRecognition() {
+    public boolean stopRecognition() throws IllegalDetectorStateException {
         if (DBG) Slog.d(TAG, "stopRecognition()");
         synchronized (mLock) {
             if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+                if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                    throw new IllegalDetectorStateException(
+                            "stopRecognition called on an invalid detector or error state");
+                }
                 throw new IllegalStateException(
                         "stopRecognition called on an invalid detector or error state");
             }
 
             // Check if we can start/stop a recognition.
             if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
+                if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                    throw new IllegalDetectorStateException(
+                            "Recognition for the given keyphrase is not supported");
+                }
                 throw new UnsupportedOperationException(
                         "Recognition for the given keyphrase is not supported");
             }
@@ -1039,18 +1190,28 @@
      *         - {@link SoundTrigger#STATUS_BAD_VALUE} invalid input parameter
      *         - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence or
      *           if API is not supported by HAL
-     * @throws IllegalStateException if the detector is in an invalid or error state.
-     *         This may happen if another detector has been instantiated or the
-     *         {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         if the detector is in an invalid or error state. This may happen if another detector
+     *         has been instantiated or the {@link VoiceInteractionService} hosting this detector
+     *         has been shut down.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
+     *         detector is in an invalid or error state. This may happen if another detector has
+     *         been instantiated or the {@link VoiceInteractionService} hosting this detector has
+     *         been shut down.
      */
     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
-    public int setParameter(@ModelParams int modelParam, int value) {
+    public int setParameter(@ModelParams int modelParam, int value)
+            throws IllegalDetectorStateException {
         if (DBG) {
             Slog.d(TAG, "setParameter(" + modelParam + ", " + value + ")");
         }
 
         synchronized (mLock) {
             if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+                if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                    throw new IllegalDetectorStateException(
+                            "setParameter called on an invalid detector or error state");
+                }
                 throw new IllegalStateException(
                         "setParameter called on an invalid detector or error state");
             }
@@ -1071,18 +1232,27 @@
      *
      * @param modelParam   {@link ModelParams}
      * @return value of parameter
-     * @throws IllegalStateException if the detector is in an invalid or error state.
-     *         This may happen if another detector has been instantiated or the
-     *         {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         if the detector is in an invalid or error state. This may happen if another detector
+     *         has been instantiated or the {@link VoiceInteractionService} hosting this detector
+     *         has been shut down.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if
+     *         the detector is in an invalid or error state. This may happen if another detector has
+     *         been instantiated or the {@link VoiceInteractionService} hosting this detector has
+     *         been shut down.
      */
     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
-    public int getParameter(@ModelParams int modelParam) {
+    public int getParameter(@ModelParams int modelParam) throws IllegalDetectorStateException {
         if (DBG) {
             Slog.d(TAG, "getParameter(" + modelParam + ")");
         }
 
         synchronized (mLock) {
             if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+                if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                    throw new IllegalDetectorStateException(
+                            "getParameter called on an invalid detector or error state");
+                }
                 throw new IllegalStateException(
                         "getParameter called on an invalid detector or error state");
             }
@@ -1100,19 +1270,29 @@
      *
      * @param modelParam {@link ModelParams}
      * @return supported range of parameter, null if not supported
-     * @throws IllegalStateException if the detector is in an invalid or error state.
-     *         This may happen if another detector has been instantiated or the
-     *         {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         if the detector is in an invalid or error state. This may happen if another detector
+     *         has been instantiated or the {@link VoiceInteractionService} hosting this detector
+     *         has been shut down.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if
+     *         the detector is in an invalid or error state. This may happen if another detector has
+     *         been instantiated or the {@link VoiceInteractionService} hosting this detector has
+     *         been shut down.
      */
     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
     @Nullable
-    public ModelParamRange queryParameter(@ModelParams int modelParam) {
+    public ModelParamRange queryParameter(@ModelParams int modelParam)
+            throws IllegalDetectorStateException {
         if (DBG) {
             Slog.d(TAG, "queryParameter(" + modelParam + ")");
         }
 
         synchronized (mLock) {
             if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+                if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                    throw new IllegalDetectorStateException(
+                            "queryParameter called on an invalid detector or error state");
+                }
                 throw new IllegalStateException(
                         "queryParameter called on an invalid detector or error state");
             }
@@ -1129,15 +1309,25 @@
      * otherwise {@link #createReEnrollIntent()} should be preferred.
      *
      * @return An {@link Intent} to start enrollment for the given keyphrase.
-     * @throws UnsupportedOperationException if managing they keyphrase isn't supported.
-     *         Callers should only call this method after a supported state callback on
-     *         {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
-     * @throws IllegalStateException if the detector is in an invalid state.
-     *         This may happen if another detector has been instantiated or the
-     *         {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above.
+     *         - Thrown if managing they keyphrase isn't supported. Callers should only call this
+     *           method after a supported state callback on
+     *           {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+     *         - Thrown if the detector is in an invalid state. This may happen if another detector
+     *           has been instantiated or the {@link VoiceInteractionService} hosting this detector
+     *           has been shut down.
+     * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
+     *         33 if managing they keyphrase isn't supported. Callers should only call this method
+     *         after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
+     *         avoid this exception.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
+     *         detector is in an invalid state. This may happen if another detector has been
+     *         instantiated or the {@link VoiceInteractionService} hosting this detector has been
+     *         shut down.
      */
     @Nullable
-    public Intent createEnrollIntent() {
+    public Intent createEnrollIntent() throws IllegalDetectorStateException {
         if (DBG) Slog.d(TAG, "createEnrollIntent");
         synchronized (mLock) {
             return getManageIntentLocked(KeyphraseEnrollmentInfo.MANAGE_ACTION_ENROLL);
@@ -1151,15 +1341,25 @@
      * i.e. {@link #STATE_KEYPHRASE_ENROLLED}, otherwise invoking this may result in an error.
      *
      * @return An {@link Intent} to start un-enrollment for the given keyphrase.
-     * @throws UnsupportedOperationException if managing they keyphrase isn't supported.
-     *         Callers should only call this method after a supported state callback on
-     *         {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
-     * @throws IllegalStateException if the detector is in an invalid state.
-     *         This may happen if another detector has been instantiated or the
-     *         {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above.
+     *         - Thrown if managing they keyphrase isn't supported. Callers should only call this
+     *           method after a supported state callback on
+     *           {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+     *         - Thrown if the detector is in an invalid state. This may happen if another detector
+     *           has been instantiated or the {@link VoiceInteractionService} hosting this detector
+     *           has been shut down.
+     * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
+     *         33 if managing they keyphrase isn't supported. Callers should only call this method
+     *         after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
+     *         avoid this exception.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
+     *         detector is in an invalid state. This may happen if another detector has been
+     *         instantiated or the {@link VoiceInteractionService} hosting this detector has been
+     *         shut down.
      */
     @Nullable
-    public Intent createUnEnrollIntent() {
+    public Intent createUnEnrollIntent() throws IllegalDetectorStateException {
         if (DBG) Slog.d(TAG, "createUnEnrollIntent");
         synchronized (mLock) {
             return getManageIntentLocked(KeyphraseEnrollmentInfo.MANAGE_ACTION_UN_ENROLL);
@@ -1173,30 +1373,50 @@
      * i.e. {@link #STATE_KEYPHRASE_ENROLLED}, otherwise invoking this may result in an error.
      *
      * @return An {@link Intent} to start re-enrollment for the given keyphrase.
-     * @throws UnsupportedOperationException if managing they keyphrase isn't supported.
-     *         Callers should only call this method after a supported state callback on
-     *         {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
-     * @throws IllegalStateException if the detector is in an invalid or error state.
-     *         This may happen if another detector has been instantiated or the
-     *         {@link VoiceInteractionService} hosting this detector has been shut down.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above.
+     *         - Thrown if managing they keyphrase isn't supported. Callers should only call this
+     *           method after a supported state callback on
+     *           {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+     *         - Thrown if the detector is in an invalid state. This may happen if another detector
+     *           has been instantiated or the {@link VoiceInteractionService} hosting this detector
+     *           has been shut down.
+     * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
+     *         33 if managing they keyphrase isn't supported. Callers should only call this method
+     *         after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
+     *         avoid this exception.
+     * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
+     *         detector is in an invalid state. This may happen if another detector has been
+     *         instantiated or the {@link VoiceInteractionService} hosting this detector has been
+     *         shut down.
      */
     @Nullable
-    public Intent createReEnrollIntent() {
+    public Intent createReEnrollIntent() throws IllegalDetectorStateException {
         if (DBG) Slog.d(TAG, "createReEnrollIntent");
         synchronized (mLock) {
             return getManageIntentLocked(KeyphraseEnrollmentInfo.MANAGE_ACTION_RE_ENROLL);
         }
     }
 
-    private Intent getManageIntentLocked(@KeyphraseEnrollmentInfo.ManageActions int action) {
+    @GuardedBy("mLock")
+    private Intent getManageIntentLocked(@KeyphraseEnrollmentInfo.ManageActions int action)
+            throws IllegalDetectorStateException {
         if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+            if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                throw new IllegalDetectorStateException(
+                        "getManageIntent called on an invalid detector or error state");
+            }
             throw new IllegalStateException(
-                    "getManageIntent called on an invalid detector or error state");
+                "getManageIntent called on an invalid detector or error state");
         }
 
         // This method only makes sense if we can actually support a recognition.
         if (mAvailability != STATE_KEYPHRASE_ENROLLED
                 && mAvailability != STATE_KEYPHRASE_UNENROLLED) {
+            if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                throw new IllegalDetectorStateException(
+                        "Managing the given keyphrase is not supported");
+            }
             throw new UnsupportedOperationException(
                     "Managing the given keyphrase is not supported");
         }
@@ -1212,24 +1432,29 @@
     public void destroy() {
         synchronized (mLock) {
             if (mAvailability == STATE_KEYPHRASE_ENROLLED) {
-                stopRecognition();
+                try {
+                    stopRecognition();
+                } catch (Exception e) {
+                    Log.i(TAG, "failed to stopRecognition in destroy", e);
+                }
             }
 
             mAvailability = STATE_INVALID;
+            mIsAvailabilityOverriddenByTestApi = false;
             notifyStateChangedLocked();
-
-            if (mSupportHotwordDetectionService) {
-                try {
-                    mModelManagementService.shutdownHotwordDetectionService();
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
-            }
         }
         super.destroy();
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean isUsingHotwordDetectionService() {
+        return mSupportHotwordDetectionService;
+    }
+
+    /**
      * Reloads the sound models from the service.
      *
      * @hide
@@ -1244,6 +1469,15 @@
                 return;
             }
 
+            // Because this method reflects an update from the system service models, we should not
+            // update the client of an availability change when the availability has been overridden
+            // via a test API.
+            if (mIsAvailabilityOverriddenByTestApi) {
+                Slog.w(TAG, "Suppressing system availability update. "
+                        + "Availability is overridden by test API.");
+                return;
+            }
+
             // Stop the recognition before proceeding.
             // This is done because we want to stop the recognition on an older model if it changed
             // or was deleted.
@@ -1263,11 +1497,37 @@
             }
 
             // Execute a refresh availability task - which should then notify of a change.
-            new RefreshAvailabiltyTask().execute();
+            new RefreshAvailabilityTask().execute();
         }
     }
 
-    private int startRecognitionLocked(int recognitionFlags) {
+    @GuardedBy("mLock")
+    private int startRecognitionLocked(int recognitionFlags,
+            @Nullable byte[] data) throws IllegalDetectorStateException {
+        if (DBG) {
+            Slog.d(TAG, "startRecognition("
+                    + recognitionFlags
+                    + ", " + Arrays.toString(data) + ")");
+        }
+        if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
+            if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                throw new IllegalDetectorStateException(
+                        "startRecognition called on an invalid detector or error state");
+            }
+            throw new IllegalStateException(
+                    "startRecognition called on an invalid detector or error state");
+        }
+
+        // Check if we can start/stop a recognition.
+        if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
+            if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
+                throw new IllegalDetectorStateException(
+                        "Recognition for the given keyphrase is not supported");
+            }
+            throw new UnsupportedOperationException(
+                    "Recognition for the given keyphrase is not supported");
+        }
+
         KeyphraseRecognitionExtra[] recognitionExtra = new KeyphraseRecognitionExtra[1];
         // TODO: Do we need to do something about the confidence level here?
         recognitionExtra[0] = new KeyphraseRecognitionExtra(mKeyphraseMetadata.getId(),
@@ -1291,7 +1551,7 @@
             code = mSoundTriggerSession.startRecognition(
                     mKeyphraseMetadata.getId(), mLocale.toLanguageTag(), mInternalCallback,
                     new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
-                            recognitionExtra, null /* additional data */, audioCapabilities),
+                            recognitionExtra, data, audioCapabilities),
                     runInBatterySaver);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -1303,6 +1563,7 @@
         return code;
     }
 
+    @GuardedBy("mLock")
     private int stopRecognitionLocked() {
         int code;
         try {
@@ -1318,6 +1579,7 @@
         return code;
     }
 
+    @GuardedBy("mLock")
     private int setParameterLocked(@ModelParams int modelParam, int value) {
         try {
             int code = mSoundTriggerSession.setParameter(mKeyphraseMetadata.getId(), modelParam,
@@ -1333,6 +1595,7 @@
         }
     }
 
+    @GuardedBy("mLock")
     private int getParameterLocked(@ModelParams int modelParam) {
         try {
             return mSoundTriggerSession.getParameter(mKeyphraseMetadata.getId(), modelParam);
@@ -1341,6 +1604,7 @@
         }
     }
 
+    @GuardedBy("mLock")
     @Nullable
     private ModelParamRange queryParameterLocked(@ModelParams int modelParam) {
         try {
@@ -1357,15 +1621,19 @@
         }
     }
 
+    @GuardedBy("mLock")
     private void updateAndNotifyStateChangedLocked(int availability) {
         if (DBG) {
             Slog.d(TAG, "Hotword availability changed from " + mAvailability
                     + " -> " + availability);
         }
-        mAvailability = availability;
+        if (!mIsAvailabilityOverriddenByTestApi) {
+            mAvailability = availability;
+        }
         notifyStateChangedLocked();
     }
 
+    @GuardedBy("mLock")
     private void notifyStateChangedLocked() {
         Message message = Message.obtain(mHandler, MSG_AVAILABILITY_CHANGED);
         message.arg1 = mAvailability;
@@ -1487,7 +1755,7 @@
         }
     }
 
-    class RefreshAvailabiltyTask extends AsyncTask<Void, Void, Void> {
+    class RefreshAvailabilityTask extends AsyncTask<Void, Void, Void> {
 
         @Override
         public Void doInBackground(Void... params) {
@@ -1555,7 +1823,26 @@
         }
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (CompatChanges.isChangeEnabled(MULTIPLE_ACTIVE_HOTWORD_DETECTORS)) {
+            if (!(obj instanceof AlwaysOnHotwordDetector)) {
+                return false;
+            }
+            AlwaysOnHotwordDetector other = (AlwaysOnHotwordDetector) obj;
+            return TextUtils.equals(mText, other.mText) && mLocale.equals(other.mLocale);
+        }
+
+        return super.equals(obj);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mText, mLocale);
+    }
+
     /** @hide */
+    @Override
     public void dump(String prefix, PrintWriter pw) {
         synchronized (mLock) {
             pw.print(prefix); pw.print("Text="); pw.println(mText);
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index dfe0f54..19e248f 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -243,13 +243,26 @@
     /**
      * Called when the device hardware (such as a DSP) detected the hotword, to request second stage
      * validation before handing over the audio to the {@link AlwaysOnHotwordDetector}.
-     * <p>
-     * After {@code callback} is invoked or {@code timeoutMillis} has passed, and invokes the
+     *
+     * <p>After {@code callback} is invoked or {@code timeoutMillis} has passed, and invokes the
      * appropriate {@link AlwaysOnHotwordDetector.Callback callback}.
      *
+     * <p>When responding to a detection event, the
+     * {@link HotwordDetectedResult#getHotwordPhraseId()} must match a keyphrase ID listed
+     * in the eventPayload's
+     * {@link AlwaysOnHotwordDetector.EventPayload#getKeyphraseRecognitionExtras()} list. This is
+     * forcing the intention of the {@link HotwordDetectionService} to validate an event from the
+     * voice engine and not augment its result.
+     *
      * @param eventPayload Payload data for the hardware detection event. This may contain the
-     *                     trigger audio, if requested when calling
-     *                     {@link AlwaysOnHotwordDetector#startRecognition(int)}.
+     *             trigger audio, if requested when calling
+     *             {@link AlwaysOnHotwordDetector#startRecognition(int)}.
+     *             Each {@link AlwaysOnHotwordDetector} will be associated with at minimum a unique
+     *             keyphrase ID indicated by
+     *             {@link AlwaysOnHotwordDetector.EventPayload#getKeyphraseRecognitionExtras()}[0].
+     *             Any extra
+     *             {@link android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra}'s
+     *             in the eventPayload represent additional phrases detected by the voice engine.
      * @param timeoutMillis Timeout in milliseconds for the operation to invoke the callback. If
      *                      the application fails to abide by the timeout, system will close the
      *                      microphone and cancel the operation.
diff --git a/core/java/android/service/voice/HotwordDetector.java b/core/java/android/service/voice/HotwordDetector.java
index 96fd8bb..1a0dc89 100644
--- a/core/java/android/service/voice/HotwordDetector.java
+++ b/core/java/android/service/voice/HotwordDetector.java
@@ -23,10 +23,16 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.media.AudioFormat;
+import android.os.Build;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.os.SharedMemory;
+import android.util.AndroidException;
+
+import java.io.PrintWriter;
 
 /**
  * Basic functionality for hotword detectors.
@@ -37,6 +43,23 @@
 public interface HotwordDetector {
 
     /**
+     * Prior to API level 33, API calls of {@link android.service.voice.HotwordDetector} could
+     * return both {@link java.lang.IllegalStateException} or
+     * {@link java.lang.UnsupportedOperationException} depending on the detector's underlying state.
+     * This lead to confusing behavior as the underlying state of the detector can be modified
+     * without the knowledge of the caller via system service layer updates.
+     *
+     * This change ID, when enabled, changes the API calls to only throw checked exception
+     * {@link android.service.voice.HotwordDetector.IllegalDetectorStateException} when checking
+     * against state information modified by both the caller and the system services.
+     *
+     * @hide
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    long HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION = 226355112L;
+
+    /**
      * Indicates that it is a non-trusted hotword detector.
      *
      * @hide
@@ -74,16 +97,26 @@
      * Calling this again while recognition is active does nothing.
      *
      * @return true if the request to start recognition succeeded
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above and attempts to start a recognition when the detector is not able based on
+     *         the state. This can be thrown even if the state has been checked before calling this
+     *         method because the caller receives updates via an asynchronous callback, and the
+     *         state of the detector can change concurrently to the caller calling this method.
      */
     @RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
-    boolean startRecognition();
+    boolean startRecognition() throws IllegalDetectorStateException;
 
     /**
      * Stops hotword recognition.
      *
      * @return true if the request to stop recognition succeeded
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above and attempts to stop a recognition when the detector is not able based on
+     *         the state. This can be thrown even if the state has been checked before calling this
+     *         method because the caller receives updates via an asynchronous callback, and the
+     *         state of the detector can change concurrently to the caller calling this method.
      */
-    boolean stopRecognition();
+    boolean stopRecognition() throws IllegalDetectorStateException;
 
     /**
      * Starts hotword recognition on audio coming from an external connected microphone.
@@ -97,26 +130,37 @@
      *         PersistableBundle does not allow any remotable objects or other contents that can be
      *         used to communicate with other processes.
      * @return true if the request to start recognition succeeded
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above and attempts to start a recognition when the detector is not able based on
+     *         the state. This can be thrown even if the state has been checked before calling this
+     *         method because the caller receives updates via an asynchronous callback, and the
+     *         state of the detector can change concurrently to the caller calling this method.
      */
     boolean startRecognition(
             @NonNull ParcelFileDescriptor audioStream,
             @NonNull AudioFormat audioFormat,
-            @Nullable PersistableBundle options);
+            @Nullable PersistableBundle options) throws IllegalDetectorStateException;
 
     /**
      * Set configuration and pass read-only data to hotword detection service.
      *
      * @param options Application configuration data to provide to the
-     * {@link HotwordDetectionService}. PersistableBundle does not allow any remotable objects or
-     * other contents that can be used to communicate with other processes.
+     *         {@link HotwordDetectionService}. PersistableBundle does not allow any remotable
+     *         objects or other contents that can be used to communicate with other processes.
      * @param sharedMemory The unrestricted data blob to provide to the
-     * {@link HotwordDetectionService}. Use this to provide the hotword models data or other
-     * such data to the trusted process.
-     *
+     *         {@link HotwordDetectionService}. Use this to provide the hotword models data or other
+     *         such data to the trusted process.
+     * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
+     *         or above and the detector is not able to perform the operation based on the
+     *         underlying state. This can be thrown even if the state has been checked before
+     *         calling this method because the caller receives updates via an asynchronous callback,
+     *         and the state of the detector can change concurrently to the caller calling this
+     *         method.
      * @throws IllegalStateException if this HotwordDetector wasn't specified to use a
-     * {@link HotwordDetectionService} when it was created.
+     *         {@link HotwordDetectionService} when it was created.
      */
-    void updateState(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory);
+    void updateState(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory)
+            throws IllegalDetectorStateException;
 
     /**
      * Invalidates this hotword detector so that any future calls to this result
@@ -132,6 +176,13 @@
     /**
      * @hide
      */
+    default boolean isUsingHotwordDetectionService() {
+        throw new UnsupportedOperationException("Not implemented. Must override in a subclass.");
+    }
+
+    /**
+     * @hide
+     */
     static String detectorTypeToString(int detectorType) {
         switch (detectorType) {
             case DETECTOR_TYPE_NORMAL:
@@ -145,6 +196,11 @@
         }
     }
 
+    /** @hide */
+    default void dump(String prefix, PrintWriter pw) {
+        throw new UnsupportedOperationException("Not implemented. Must override in a subclass.");
+    }
+
     /**
      * The callback to notify of detection events.
      */
@@ -205,4 +261,14 @@
          */
         void onHotwordDetectionServiceRestarted();
     }
+
+    /**
+     * {@link HotwordDetector} specific exception thrown when the underlying state of the detector
+     * is invalid for the given action.
+     */
+    class IllegalDetectorStateException extends AndroidException {
+        IllegalDetectorStateException(String message) {
+            super(message);
+        }
+    }
 }
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index 2d662ea..36ea91e 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -30,6 +30,7 @@
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.SharedMemory;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.app.IHotwordRecognitionStatusCallback;
@@ -57,8 +58,6 @@
     SoftwareHotwordDetector(
             IVoiceInteractionManagerService managerService,
             AudioFormat audioFormat,
-            PersistableBundle options,
-            SharedMemory sharedMemory,
             HotwordDetector.Callback callback) {
         super(managerService, callback, DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE);
 
@@ -66,6 +65,12 @@
         mAudioFormat = audioFormat;
         mCallback = callback;
         mHandler = new Handler(Looper.getMainLooper());
+    }
+
+    @Override
+    void initialize(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory) {
+        // TODO: transition to use an API that is not updateState to provide
+        //  onHotwordDetectionServiceInitialized status to external callback
         updateStateLocked(options, sharedMemory,
                 new InitializationStateListener(mHandler, mCallback),
                 DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE);
@@ -73,7 +78,7 @@
 
     @RequiresPermission(RECORD_AUDIO)
     @Override
-    public boolean startRecognition() {
+    public boolean startRecognition() throws IllegalDetectorStateException {
         if (DEBUG) {
             Slog.i(TAG, "#startRecognition");
         }
@@ -96,7 +101,7 @@
     /** TODO: stopRecognition */
     @RequiresPermission(RECORD_AUDIO)
     @Override
-    public boolean stopRecognition() {
+    public boolean stopRecognition() throws IllegalDetectorStateException {
         if (DEBUG) {
             Slog.i(TAG, "#stopRecognition");
         }
@@ -113,17 +118,23 @@
 
     @Override
     public void destroy() {
-        stopRecognition();
-        maybeCloseExistingSession();
-
         try {
-            mManagerService.shutdownHotwordDetectionService();
-        } catch (RemoteException ex) {
-            ex.rethrowFromSystemServer();
+            stopRecognition();
+        } catch (Exception e) {
+            Log.i(TAG, "failed to stopRecognition in destroy", e);
         }
+        maybeCloseExistingSession();
         super.destroy();
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public boolean isUsingHotwordDetectionService() {
+        return true;
+    }
+
     private void maybeCloseExistingSession() {
         // TODO: needs to be synchronized.
         // TODO: implement this
@@ -231,6 +242,7 @@
     }
 
     /** @hide */
+    @Override
     public void dump(String prefix, PrintWriter pw) {
         // TODO: implement this
     }
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index bf0cfbe..1170237 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -24,12 +24,16 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.app.Service;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.hardware.soundtrigger.KeyphraseEnrollmentInfo;
 import android.media.voice.KeyphraseModelManager;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -89,6 +93,37 @@
      */
     public static final String SERVICE_META_DATA = "android.voice_interaction";
 
+    /**
+     * For apps targeting Build.VERSION_CODES.TRAMISU and above, implementors of this
+     * service can create multiple AlwaysOnHotwordDetector instances in parallel. They will
+     * also e ale to create a single SoftwareHotwordDetector in parallel with any other
+     * active AlwaysOnHotwordDetector instances.
+     *
+     * <p>Requirements when this change is enabled:
+     * <ul>
+     *     <li>
+     *         Any number of AlwaysOnHotwordDetector instances can be created in parallel
+     *         as long as they are unique to any other active AlwaysOnHotwordDetector.
+     *     </li>
+     *     <li>
+     *         Only a single instance of SoftwareHotwordDetector can be active at a given
+     *         time. It can be active at the same time as any number of
+     *         AlwaysOnHotwordDetector instances.
+     *     </li>
+     *     <li>
+     *         To release that reference and any resources associated with that reference,
+     *         HotwordDetector#destroy() must be called. An attempt to create an
+     *         HotwordDetector equal to an active HotwordDetector will be rejected
+     *         until HotwordDetector#destroy() is called on the active instance.
+     *     </li>
+     * </ul>
+     *
+     * @hide
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT)
+    static final long MULTIPLE_ACTIVE_HOTWORD_DETECTORS = 193232191L;
+
     IVoiceInteractionService mInterface = new IVoiceInteractionService.Stub() {
         @Override
         public void ready() {
@@ -133,8 +168,7 @@
 
     private KeyphraseEnrollmentInfo mKeyphraseEnrollmentInfo;
 
-    private AlwaysOnHotwordDetector mHotwordDetector;
-    private SoftwareHotwordDetector mSoftwareHotwordDetector;
+    private final Set<HotwordDetector> mActiveHotwordDetectors = new ArraySet<>();
 
     /**
      * Called when a user has activated an affordance to launch voice assist from the Keyguard.
@@ -284,10 +318,12 @@
 
     private void onSoundModelsChangedInternal() {
         synchronized (this) {
-            if (mHotwordDetector != null) {
-                // TODO: Stop recognition if a sound model that was being recognized gets deleted.
-                mHotwordDetector.onSoundModelsChanged();
-            }
+            // TODO: Stop recognition if a sound model that was being recognized gets deleted.
+            mActiveHotwordDetectors.forEach(detector -> {
+                if (detector instanceof AlwaysOnHotwordDetector) {
+                    ((AlwaysOnHotwordDetector) detector).onSoundModelsChanged();
+                }
+            });
         }
     }
 
@@ -379,16 +415,31 @@
             throw new IllegalStateException("Not available until onReady() is called");
         }
         synchronized (mLock) {
-            // Allow only one concurrent recognition via the APIs.
-            safelyShutdownAllHotwordDetectors();
-            mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
-                    mKeyphraseEnrollmentInfo, mSystemService,
+            if (!CompatChanges.isChangeEnabled(MULTIPLE_ACTIVE_HOTWORD_DETECTORS)) {
+                // Allow only one concurrent recognition via the APIs.
+                safelyShutdownAllHotwordDetectors();
+            }
+
+            AlwaysOnHotwordDetector dspDetector = new AlwaysOnHotwordDetector(keyphrase, locale,
+                    callback, mKeyphraseEnrollmentInfo, mSystemService,
                     getApplicationContext().getApplicationInfo().targetSdkVersion,
-                    supportHotwordDetectionService, options, sharedMemory);
-            mHotwordDetector.registerOnDestroyListener((detector) -> onDspHotwordDetectorDestroyed(
-                    (AlwaysOnHotwordDetector) detector));
+                    supportHotwordDetectionService);
+            if (!mActiveHotwordDetectors.add(dspDetector)) {
+                throw new IllegalArgumentException(
+                        "the keyphrase=" + keyphrase + " and locale=" + locale
+                                + " are already used by another always-on detector");
+            }
+
+            try {
+                dspDetector.registerOnDestroyListener(this::onHotwordDetectorDestroyed);
+                dspDetector.initialize(options, sharedMemory);
+            } catch (Exception e) {
+                mActiveHotwordDetectors.remove(dspDetector);
+                dspDetector.destroy();
+                throw e;
+            }
+            return dspDetector;
         }
-        return mHotwordDetector;
     }
 
     /**
@@ -434,16 +485,34 @@
             throw new IllegalStateException("Not available until onReady() is called");
         }
         synchronized (mLock) {
-            // Allow only one concurrent recognition via the APIs.
-            safelyShutdownAllHotwordDetectors();
-            mSoftwareHotwordDetector =
+            if (!CompatChanges.isChangeEnabled(MULTIPLE_ACTIVE_HOTWORD_DETECTORS)) {
+                // Allow only one concurrent recognition via the APIs.
+                safelyShutdownAllHotwordDetectors();
+            } else {
+                for (HotwordDetector detector : mActiveHotwordDetectors) {
+                    if (detector instanceof SoftwareHotwordDetector) {
+                        throw new IllegalArgumentException(
+                                "There is already an active SoftwareHotwordDetector. "
+                                        + "It must be destroyed to create a new one.");
+                    }
+                }
+            }
+
+            SoftwareHotwordDetector softwareHotwordDetector =
                     new SoftwareHotwordDetector(
-                            mSystemService, null, options, sharedMemory, callback);
-            mSoftwareHotwordDetector.registerOnDestroyListener(
-                    (detector) -> onMicrophoneHotwordDetectorDestroyed(
-                            (SoftwareHotwordDetector) detector));
+                            mSystemService, null, callback);
+
+            try {
+                softwareHotwordDetector.registerOnDestroyListener(
+                        this::onHotwordDetectorDestroyed);
+                softwareHotwordDetector.initialize(options, sharedMemory);
+            } catch (Exception e) {
+                mActiveHotwordDetectors.remove(softwareHotwordDetector);
+                softwareHotwordDetector.destroy();
+                throw e;
+            }
+            return softwareHotwordDetector;
         }
-        return mSoftwareHotwordDetector;
     }
 
     /**
@@ -489,33 +558,34 @@
 
     private void safelyShutdownAllHotwordDetectors() {
         synchronized (mLock) {
-            if (mHotwordDetector != null) {
+            mActiveHotwordDetectors.forEach(detector -> {
                 try {
-                    mHotwordDetector.destroy();
+                    detector.destroy();
                 } catch (Exception ex) {
-                    Log.i(TAG, "exception destroying AlwaysOnHotwordDetector", ex);
+                    Log.i(TAG, "exception destroying HotwordDetector", ex);
                 }
-            }
-
-            if (mSoftwareHotwordDetector != null) {
-                try {
-                    mSoftwareHotwordDetector.destroy();
-                } catch (Exception ex) {
-                    Log.i(TAG, "exception destroying SoftwareHotwordDetector", ex);
-                }
-            }
+            });
         }
     }
 
-    private void onDspHotwordDetectorDestroyed(@NonNull AlwaysOnHotwordDetector detector) {
+    private void onHotwordDetectorDestroyed(@NonNull HotwordDetector detector) {
         synchronized (mLock) {
-            mHotwordDetector = null;
+            mActiveHotwordDetectors.remove(detector);
+            shutdownHotwordDetectionServiceIfRequiredLocked();
         }
     }
 
-    private void onMicrophoneHotwordDetectorDestroyed(@NonNull SoftwareHotwordDetector detector) {
-        synchronized (mLock) {
-            mSoftwareHotwordDetector = null;
+    private void shutdownHotwordDetectionServiceIfRequiredLocked() {
+        for (HotwordDetector detector : mActiveHotwordDetectors) {
+            if (detector.isUsingHotwordDetectionService()) {
+                return;
+            }
+        }
+
+        try {
+            mSystemService.shutdownHotwordDetectionService();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
         }
     }
 
@@ -540,18 +610,14 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("VOICE INTERACTION");
         synchronized (mLock) {
-            pw.println("  AlwaysOnHotwordDetector");
-            if (mHotwordDetector == null) {
+            pw.println("  HotwordDetector(s)");
+            if (mActiveHotwordDetectors.size() == 0) {
                 pw.println("    NULL");
             } else {
-                mHotwordDetector.dump("    ", pw);
-            }
-
-            pw.println("  MicrophoneHotwordDetector");
-            if (mSoftwareHotwordDetector == null) {
-                pw.println("    NULL");
-            } else {
-                mSoftwareHotwordDetector.dump("    ", pw);
+                mActiveHotwordDetectors.forEach(detector -> {
+                    detector.dump("    ", pw);
+                    pw.println();
+                });
             }
         }
     }
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 2f85d2b6..520ceb2 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -25,6 +25,7 @@
 import android.graphics.text.LineBreakConfig;
 import android.graphics.text.LineBreaker;
 import android.os.Build;
+import android.os.SystemProperties;
 import android.text.style.LeadingMarginSpan;
 import android.text.style.LeadingMarginSpan.LeadingMarginSpan2;
 import android.text.style.LineHeightSpan;
@@ -32,6 +33,7 @@
 import android.util.Log;
 import android.util.Pools.SynchronizedPool;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.GrowingArrayUtils;
 
@@ -73,6 +75,13 @@
      * default values.
      */
     public final static class Builder {
+        // The content length threshold to enable LINE_BREAK_WORD_STYLE_PHRASE.
+        private static final int DEFAULT_LINECOUNT_THRESHOLD_FOR_PHRASE = 3;
+
+        // The property of content length threshold to enable LINE_BREAK_WORD_STYLE_PHRASE.
+        private static final String PROPERTY_LINECOUNT_THRESHOLD_FOR_PHRASE =
+                "android.phrase.linecount.threshold";
+
         private Builder() {}
 
         /**
@@ -431,11 +440,55 @@
          */
         @NonNull
         public StaticLayout build() {
+            reviseLineBreakConfig();
             StaticLayout result = new StaticLayout(this);
             Builder.recycle(this);
             return result;
         }
 
+        private void reviseLineBreakConfig() {
+            boolean autoPhraseBreaking = mLineBreakConfig.getAutoPhraseBreaking();
+            int wordStyle = mLineBreakConfig.getLineBreakWordStyle();
+            if (autoPhraseBreaking) {
+                if (wordStyle != LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE) {
+                    if (shouldEnablePhraseBreaking()) {
+                        mLineBreakConfig = LineBreakConfig.getLineBreakConfig(
+                                mLineBreakConfig.getLineBreakStyle(),
+                                LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE,
+                                mLineBreakConfig.getAutoPhraseBreaking());
+                    }
+                }
+            }
+        }
+
+        private boolean shouldEnablePhraseBreaking() {
+            if (TextUtils.isEmpty(mText) || mWidth <= 0) {
+                return false;
+            }
+            int lineLimit = SystemProperties.getInt(
+                    PROPERTY_LINECOUNT_THRESHOLD_FOR_PHRASE,
+                    DEFAULT_LINECOUNT_THRESHOLD_FOR_PHRASE);
+            double desiredWidth = (double) Layout.getDesiredWidth(mText, mStart,
+                    mEnd, mPaint, mTextDir);
+            int lineCount = (int) Math.ceil(desiredWidth / mWidth);
+            if (lineCount > 0 && lineCount <= lineLimit) {
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Get the line break word style.
+         *
+         * @return The current line break word style.
+         *
+         * @hide
+         */
+        @VisibleForTesting
+        public int getLineBreakWordStyle() {
+            return mLineBreakConfig.getLineBreakWordStyle();
+        }
+
         private CharSequence mText;
         private int mStart;
         private int mEnd;
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 7ac6ae1..51e3665 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -70,7 +70,6 @@
 import android.util.Printer;
 import android.view.View;
 
-import com.android.internal.R;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Preconditions;
 
@@ -1230,8 +1229,8 @@
 
     /**
      * Transforms a CharSequences to uppercase, copying the sources spans and keeping them spans as
-     * much as possible close to their relative original places. In the case the the uppercase
-     * string is identical to the sources, the source itself is returned instead of being copied.
+     * much as possible close to their relative original places. If uppercase string is identical
+     * to the sources, the source itself is returned instead of being copied.
      *
      * If copySpans is set, source must be an instance of Spanned.
      *
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 3be4c3ed..a173d80 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -74,6 +74,14 @@
     public static final String SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE =
             "settings_hide_second_layer_page_navigate_up_button_in_two_pane";
 
+    /** @hide */
+    public static final String SETTINGS_AUTO_TEXT_WRAPPING = "settings_auto_text_wrapping";
+
+    /** Flag to enable/disable guest mode UX changes as mentioned in b/214031645
+     *  @hide
+     */
+    public static  final String SETTINGS_GUEST_MODE_UX_CHANGES = "settings_guest_mode_ux_changes";
+
     private static final Map<String, String> DEFAULT_FLAGS;
 
     static {
@@ -100,6 +108,8 @@
         DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
         DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true");
         DEFAULT_FLAGS.put(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE, "true");
+        DEFAULT_FLAGS.put(SETTINGS_AUTO_TEXT_WRAPPING, "false");
+        DEFAULT_FLAGS.put(SETTINGS_GUEST_MODE_UX_CHANGES, "true");
     }
 
     private static final Set<String> PERSISTENT_FLAGS;
@@ -110,6 +120,7 @@
         PERSISTENT_FLAGS.add(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
         PERSISTENT_FLAGS.add(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME);
         PERSISTENT_FLAGS.add(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE);
+        PERSISTENT_FLAGS.add(SETTINGS_AUTO_TEXT_WRAPPING);
     }
 
     /**
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 0c4d9bf..3a68404 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -26,11 +26,9 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressLint;
 import android.annotation.TestApi;
-import android.app.ActivityThread;
 import android.app.KeyguardManager;
 import android.app.WindowConfiguration;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.content.ComponentName;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -52,14 +50,11 @@
 import android.util.DisplayMetrics;
 import android.util.Log;
 
-import com.android.internal.R;
-
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Optional;
 
 /**
  * Provides information about the size and density of a logical display.
@@ -116,12 +111,6 @@
     private int mCachedAppHeightCompat;
 
     /**
-     * Cache if the application is the recents component.
-     * TODO(b/179308296) Remove once Launcher addresses issue
-     */
-    private Optional<Boolean> mIsRecentsComponent = Optional.empty();
-
-    /**
      * The default Display id, which is the id of the primary display assuming there is one.
      */
     public static final int DEFAULT_DISPLAY = 0;
@@ -576,7 +565,8 @@
      * @see com.android.service.display.DisplayDevice#hasStableUniqueId().
      * @hide
      */
-    public String getUniqueId() {
+    @TestApi
+    public @Nullable String getUniqueId() {
         return mDisplayInfo.uniqueId;
     }
 
@@ -1584,36 +1574,7 @@
             return false;
         }
         final Configuration config = mResources.getConfiguration();
-        // TODO(b/179308296) Temporarily exclude Launcher from being given max bounds, by checking
-        // if the caller is the recents component.
-        return config != null && !config.windowConfiguration.getMaxBounds().isEmpty()
-                && !isRecentsComponent();
-    }
-
-    /**
-     * Returns {@code true} when the calling package is the recents component.
-     * TODO(b/179308296) Remove once Launcher addresses issue
-     */
-    boolean isRecentsComponent() {
-        if (mIsRecentsComponent.isPresent()) {
-            return mIsRecentsComponent.get();
-        }
-        if (mResources == null) {
-            return false;
-        }
-        try {
-            String recentsComponent = mResources.getString(R.string.config_recentsComponentName);
-            if (recentsComponent == null) {
-                return false;
-            }
-            String recentsPackage = ComponentName.unflattenFromString(recentsComponent)
-                    .getPackageName();
-            mIsRecentsComponent = Optional.of(recentsPackage != null
-                    && recentsPackage.equals(ActivityThread.currentPackageName()));
-            return mIsRecentsComponent.get();
-        } catch (Resources.NotFoundException e) {
-            return false;
-        }
+        return config != null && !config.windowConfiguration.getMaxBounds().isEmpty();
     }
 
     /**
@@ -1631,6 +1592,21 @@
     }
 
     /**
+     * Returns the committed state of the display.
+     *
+     * @return The latest committed display state, such as {@link #STATE_ON}. The display state
+     * {@link Display#getState()} is set as committed only after power state changes finish.
+     *
+     * @hide
+     */
+    public int getCommittedState() {
+        synchronized (mLock) {
+            updateDisplayInfoLocked();
+            return mIsValid ? mDisplayInfo.committedState : STATE_UNKNOWN;
+        }
+    }
+
+    /**
      * Returns true if the specified UID has access to this display.
      * @hide
      */
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 9264d2e..2aed319 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -253,6 +253,12 @@
     public int state;
 
     /**
+     * The current committed state of the display. For example, this becomes
+     * {@link android.view.Display#STATE_ON} only after the power state ON is fully committed.
+     */
+    public int committedState;
+
+    /**
      * The UID of the application that owns this display, or zero if it is owned by the system.
      * <p>
      * If the display is private, then only the owner can use it.
@@ -380,6 +386,7 @@
                 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
                 && presentationDeadlineNanos == other.presentationDeadlineNanos
                 && state == other.state
+                && committedState == other.committedState
                 && ownerUid == other.ownerUid
                 && Objects.equals(ownerPackageName, other.ownerPackageName)
                 && removeMode == other.removeMode
@@ -431,6 +438,7 @@
         appVsyncOffsetNanos = other.appVsyncOffsetNanos;
         presentationDeadlineNanos = other.presentationDeadlineNanos;
         state = other.state;
+        committedState = other.committedState;
         ownerUid = other.ownerUid;
         ownerPackageName = other.ownerPackageName;
         removeMode = other.removeMode;
@@ -482,6 +490,7 @@
         appVsyncOffsetNanos = source.readLong();
         presentationDeadlineNanos = source.readLong();
         state = source.readInt();
+        committedState = source.readInt();
         ownerUid = source.readInt();
         ownerPackageName = source.readString8();
         uniqueId = source.readString8();
@@ -538,6 +547,7 @@
         dest.writeLong(appVsyncOffsetNanos);
         dest.writeLong(presentationDeadlineNanos);
         dest.writeInt(state);
+        dest.writeInt(committedState);
         dest.writeInt(ownerUid);
         dest.writeString8(ownerPackageName);
         dest.writeString8(uniqueId);
@@ -761,6 +771,8 @@
         sb.append(rotation);
         sb.append(", state ");
         sb.append(Display.stateToString(state));
+        sb.append(", committedState ");
+        sb.append(Display.stateToString(committedState));
 
         if (Process.myUid() != Process.SYSTEM_UID) {
             sb.append("}");
diff --git a/core/java/android/view/HandwritingInitiator.java b/core/java/android/view/HandwritingInitiator.java
index 61098d6..3247bb7 100644
--- a/core/java/android/view/HandwritingInitiator.java
+++ b/core/java/android/view/HandwritingInitiator.java
@@ -19,6 +19,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
 import android.view.inputmethod.InputMethodManager;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -49,6 +51,12 @@
  * @hide
  */
 public class HandwritingInitiator {
+    /** The amount of extra space added to handwriting in dip. */
+    private static final int HANDWRITING_AREA_PADDING_DIP = 20;
+
+    /** The amount of extra space added to handwriting in px. */
+    private final float mHandwritingAreaPaddingPx;
+
     /**
      * The touchSlop from {@link ViewConfiguration} used to decide whether a pointer is considered
      * moving or stationary.
@@ -88,9 +96,13 @@
 
     @VisibleForTesting
     public HandwritingInitiator(@NonNull ViewConfiguration viewConfiguration,
-            @NonNull InputMethodManager inputMethodManager) {
+            @NonNull InputMethodManager inputMethodManager, DisplayMetrics displayMetrics) {
         mTouchSlop = viewConfiguration.getScaledTouchSlop();
         mHandwritingTimeoutInMillis = ViewConfiguration.getLongPressTimeout();
+        mHandwritingAreaPaddingPx = TypedValue.applyDimension(
+                TypedValue.COMPLEX_UNIT_DIP,
+                HANDWRITING_AREA_PADDING_DIP,
+                displayMetrics);
         mImm = inputMethodManager;
     }
 
@@ -250,7 +262,8 @@
         }
 
         final Rect handwritingArea = getViewHandwritingArea(connectedView);
-        if (contains(handwritingArea, mState.mStylusDownX, mState.mStylusDownY)) {
+        if (containsInExtendedHandwritingArea(handwritingArea,
+                mState.mStylusDownX, mState.mStylusDownY)) {
             startHandwriting(connectedView);
         } else {
             reset();
@@ -281,14 +294,21 @@
      */
     @Nullable
     private View findBestCandidateView(float x, float y) {
+        float minDistance = Float.MAX_VALUE;
+        View bestCandidate = null;
+
         // If the connectedView is not null and do not set any handwriting area, it will check
         // whether the connectedView's boundary contains the initial stylus position. If true,
         // directly return the connectedView.
         final View connectedView = getConnectedView();
         if (connectedView != null && connectedView.isAutoHandwritingEnabled()) {
-            final Rect handwritingArea = getViewHandwritingArea(connectedView);
-            if (contains(handwritingArea, x, y)) {
-                return connectedView;
+            Rect handwritingArea = getViewHandwritingArea(connectedView);
+            if (containsInExtendedHandwritingArea(handwritingArea, x, y)) {
+                final float distance = distance(handwritingArea, x, y);
+                if (distance == 0f) return connectedView;
+
+                bestCandidate = connectedView;
+                minDistance = distance;
             }
         }
 
@@ -297,18 +317,78 @@
                 mHandwritingAreasTracker.computeViewInfos();
         for (HandwritableViewInfo viewInfo : handwritableViewInfos) {
             final View view = viewInfo.getView();
-            if (!view.isAutoHandwritingEnabled()) continue;
-            if (contains(viewInfo.getHandwritingArea(), x, y)) {
-                return viewInfo.getView();
+            final Rect handwritingArea = viewInfo.getHandwritingArea();
+            if (!containsInExtendedHandwritingArea(handwritingArea, x, y)) continue;
+
+            final float distance = distance(handwritingArea, x, y);
+
+            if (distance == 0f) return view;
+            if (distance < minDistance) {
+                minDistance = distance;
+                bestCandidate = view;
             }
         }
-        return null;
+        return bestCandidate;
+    }
+
+    /**
+     *  Return the square of the distance from point (x, y) to the given rect, which is mainly used
+     *  for comparison. The distance is defined to be: the shortest distance between (x, y) to any
+     *  point on rect. When (x, y) is contained by the rect, return 0f.
+     */
+    private static float distance(@NonNull Rect rect, float x, float y) {
+        if (contains(rect, x, y, 0f, 0f, 0f, 0f)) {
+            return 0f;
+        }
+
+        /* The distance between point (x, y) and rect, there are 2 basic cases:
+         * a) The distance is the distance from (x, y) to the closest corner on rect.
+         *                    o |     |
+         *         ---+-----+---
+         *            |     |
+         *         ---+-----+---
+         *            |     |
+         * b) The distance is the distance from (x, y) to the closest edge on rect.
+         *                      |  o  |
+         *         ---+-----+---
+         *            |     |
+         *         ---+-----+---
+         *            |     |
+         * We define xDistance as following(similar for yDistance):
+         *   If x is in [left, right) 0, else min(abs(x - left), abs(x - y))
+         * For case a, sqrt(xDistance^2 + yDistance^2) is the final distance.
+         * For case b, distance should be yDistance, which is also equal to
+         * sqrt(xDistance^2 + yDistance^2) because xDistance is 0.
+         */
+        final float xDistance;
+        if (x >= rect.left && x < rect.right) {
+            xDistance = 0f;
+        } else if (x < rect.left) {
+            xDistance = rect.left - x;
+        } else {
+            xDistance = x - rect.right;
+        }
+
+        final float yDistance;
+        if (y >= rect.top && y < rect.bottom) {
+            yDistance = 0f;
+        } else if (y < rect.top) {
+            yDistance = rect.top - y;
+        } else {
+            yDistance = y - rect.bottom;
+        }
+        // We can omit sqrt here because we only need the distance for comparison.
+        return xDistance * xDistance + yDistance * yDistance;
     }
 
     /**
      * Return the handwriting area of the given view, represented in the window's coordinate.
      * If the view didn't set any handwriting area, it will return the view's boundary.
      * It will return null if the view or its handwriting area is not visible.
+     *
+     * The handwriting area is clipped to its visible part.
+     * Notice that the returned rectangle is the view's original handwriting area without the
+     * view's handwriting area extends.
      */
     @Nullable
     private static Rect getViewHandwritingArea(@NonNull View view) {
@@ -329,11 +409,24 @@
     }
 
     /**
-     * Return true if the (x, y) is inside by the given {@link Rect}.
+     * Return true if the (x, y) is inside by the given {@link Rect} extended by the View's
+     * handwriting extends settings.
      */
-    private boolean contains(@Nullable Rect rect, float x, float y) {
-        if (rect == null) return false;
-        return x >= rect.left && x < rect.right && y >= rect.top && y < rect.bottom;
+    private boolean containsInExtendedHandwritingArea(@Nullable Rect handwritingArea,
+            float x, float y) {
+        if (handwritingArea == null) return false;
+        return contains(handwritingArea, x, y, mHandwritingAreaPaddingPx, mHandwritingAreaPaddingPx,
+                mHandwritingAreaPaddingPx, mHandwritingAreaPaddingPx);
+    }
+
+    /**
+     * Return true if the (x, y) is inside by the given {@link Rect} extended by the given
+     * extendLeft, extendTop, extendRight and extendBottom.
+     */
+    private static boolean contains(@NonNull Rect rect, float x, float y,
+            float extendLeft, float extendTop, float extendRight, float extendBottom) {
+        return x >= rect.left - extendLeft && x < rect.right  + extendRight
+                && y >= rect.top - extendTop && y < rect.bottom + extendBottom;
     }
 
     private boolean largerThanTouchSlop(float x1, float y1, float x2, float y2) {
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 7d56039..addbab0 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -517,6 +518,7 @@
      * @param id The device id.
      * @return The input device or null if not found.
      */
+    @Nullable
     public static InputDevice getDevice(int id) {
         return InputManager.getInstance().getInputDevice(id);
     }
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 2b79bbf..f838d7f 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -17,9 +17,9 @@
 package android.view;
 
 import android.annotation.IntDef;
+import android.app.ActivityThread;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
-import android.sysprop.InputProperties;
 import android.util.ArrayMap;
 import android.util.Pools.SynchronizedPool;
 
@@ -278,8 +278,10 @@
     private VelocityTracker(@VelocityTrackerStrategy int strategy) {
         // If user has not selected a specific strategy
         if (strategy == VELOCITY_TRACKER_STRATEGY_DEFAULT) {
+            final String strategyProperty = ViewConfiguration.get(
+                    ActivityThread.currentActivityThread().getApplication())
+                    .getVelocityTrackerStrategy();
             // Check if user specified strategy by overriding system property.
-            String strategyProperty = InputProperties.velocitytracker_strategy().orElse(null);
             if (strategyProperty == null || strategyProperty.isEmpty()) {
                 mStrategy = strategy;
             } else {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8b9a86b9..88449f5 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -31408,6 +31408,10 @@
      * {@link android.view.inputmethod.InputMethodManager#startStylusHandwriting(View)} when there
      * is stylus movement detected.
      *
+     * Note that this attribute has no effect on the View's children. For example, if a
+     * {@link ViewGroup} disables auto handwriting but its children set auto handwriting to true,
+     * auto handwriting will still work for the children, and vice versa.
+     *
      * @see #onCreateInputConnection(EditorInfo)
      * @see android.view.inputmethod.InputMethodManager#startStylusHandwriting(View)
      * @param enabled whether auto handwriting initiation is enabled for this view.
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index ebc409e..30ae9c8 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -27,6 +27,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.hardware.input.InputManager;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -348,6 +349,7 @@
     private final int mSmartSelectionInitializedTimeout;
     private final int mSmartSelectionInitializingTimeout;
     private final int mPreferKeepClearForFocusDelay;
+    private final String mVelocityTrackerStrategy;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768915)
     private boolean sHasPermanentMenuKey;
@@ -394,6 +396,7 @@
         mSmartSelectionInitializedTimeout = SMART_SELECTION_INITIALIZED_TIMEOUT_IN_MILLISECOND;
         mSmartSelectionInitializingTimeout = SMART_SELECTION_INITIALIZING_TIMEOUT_IN_MILLISECOND;
         mPreferKeepClearForFocusDelay = -1;
+        mVelocityTrackerStrategy = InputManager.getInstance().getVelocityTrackerStrategy();
     }
 
     /**
@@ -510,6 +513,16 @@
                 com.android.internal.R.integer.config_smartSelectionInitializingTimeoutMillis);
         mPreferKeepClearForFocusDelay = res.getInteger(
                 com.android.internal.R.integer.config_preferKeepClearForFocusDelayMillis);
+
+        mVelocityTrackerStrategy = InputManager.getInstance().getVelocityTrackerStrategy();
+    }
+
+    /**
+     * Get the current VelocityTracker strategy
+     * @hide
+     */
+    public String getVelocityTrackerStrategy() {
+        return mVelocityTrackerStrategy;
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a3d0bf7..f310e7f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -890,8 +890,10 @@
         mChoreographer = Choreographer.getInstance();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
         mInsetsController = new InsetsController(new ViewRootInsetsControllerHost(this));
-        mHandwritingInitiator = new HandwritingInitiator(mViewConfiguration,
-                mContext.getSystemService(InputMethodManager.class));
+        mHandwritingInitiator = new HandwritingInitiator(
+                mViewConfiguration,
+                mContext.getSystemService(InputMethodManager.class),
+                context.getResources().getDisplayMetrics());
 
         String processorOverrideName = context.getResources().getString(
                                     R.string.config_inputEventCompatProcessorOverrideClassName);
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 0008aa6..af8a017 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3063,6 +3063,9 @@
             int spanToReplaceStart = spannable.getSpanStart(span);
             int spanToReplaceEnd = spannable.getSpanEnd(span);
             int spanToReplaceFlags = spannable.getSpanFlags(span);
+            if (spanToReplaceStart < 0) {
+                continue;
+            }
             spannable.removeSpan(span);
             ClickableSpan replacementSpan = (span instanceof URLSpan)
                     ? new AccessibilityURLSpan((URLSpan) span)
@@ -3100,6 +3103,9 @@
             int spanToReplaceStart = spannable.getSpanStart(span);
             int spanToReplaceEnd = spannable.getSpanEnd(span);
             int spanToReplaceFlags = spannable.getSpanFlags(span);
+            if (spanToReplaceStart < 0) {
+                continue;
+            }
             spannable.removeSpan(span);
             ReplacementSpan replacementSpan = new AccessibilityReplacementSpan(replacementText);
             spannable.setSpan(replacementSpan, spanToReplaceStart, spanToReplaceEnd,
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index b05b791..92cf745 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -27,6 +27,7 @@
 import static android.view.autofill.Helper.toList;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
+import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -47,17 +48,22 @@
 import android.content.pm.ResolveInfo;
 import android.graphics.Rect;
 import android.metrics.LogMaker;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.CancellationSignal;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.ICancellationSignal;
 import android.os.Looper;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.provider.DeviceConfig;
 import android.service.autofill.AutofillService;
+import android.service.autofill.FillCallback;
 import android.service.autofill.FillEventHistory;
+import android.service.autofill.IFillCallback;
 import android.service.autofill.UserData;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -78,6 +84,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeProvider;
 import android.view.accessibility.AccessibilityWindowInfo;
+import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.TextView;
@@ -102,6 +109,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.Executor;
 
 import sun.misc.Cleaner;
 
@@ -170,6 +178,12 @@
  * shows an autofill save UI if the value of savable views have changed. If the user selects the
  * option to Save, the current value of the views is then sent to the autofill service.
  *
+ * <p>There is another choice for the application to provide it's datasets to the Autofill framework
+ * by setting an {@link AutofillRequestCallback} through
+ * {@link #setAutofillRequestCallback(Executor, AutofillRequestCallback)}. The application can use
+ * its callback instead of the default {@link AutofillService}. See
+ * {@link AutofillRequestCallback} for more details.
+ *
  * <h3 id="additional-notes">Additional notes</h3>
  *
  * <p>It is safe to call <code>AutofillManager</code> methods from any thread.
@@ -295,6 +309,7 @@
     /** @hide */ public static final int FLAG_ADD_CLIENT_DEBUG = 0x2;
     /** @hide */ public static final int FLAG_ADD_CLIENT_VERBOSE = 0x4;
     /** @hide */ public static final int FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY = 0x8;
+    /** @hide */ public static final int FLAG_ENABLED_CLIENT_SUGGESTIONS = 0x20;
 
     // NOTE: flag below is used by the session start receiver only, hence it can have values above
     /** @hide */ public static final int RECEIVER_FLAG_SESSION_FOR_AUGMENTED_AUTOFILL_ONLY = 0x1;
@@ -624,6 +639,11 @@
     @GuardedBy("mLock")
     private boolean mEnabledForAugmentedAutofillOnly;
 
+    @GuardedBy("mLock")
+    @Nullable private AutofillRequestCallback mAutofillRequestCallback;
+    @GuardedBy("mLock")
+    @Nullable private Executor mRequestCallbackExecutor;
+
     /**
      * Indicates whether there are any fields that need to do a fill request
      * after the activity starts.
@@ -1952,6 +1972,32 @@
         return new AutofillId(parent.getAutofillViewId(), virtualId);
     }
 
+    /**
+     * Sets the client's suggestions callback for autofill.
+     *
+     * @see AutofillRequestCallback
+     *
+     * @param executor specifies the thread upon which the callbacks will be invoked.
+     * @param callback which handles autofill request to provide client's suggestions.
+     */
+    public void setAutofillRequestCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull AutofillRequestCallback callback) {
+        synchronized (mLock) {
+            mRequestCallbackExecutor = executor;
+            mAutofillRequestCallback = callback;
+        }
+    }
+
+    /**
+     * clears the client's suggestions callback for autofill.
+     */
+    public void clearAutofillRequestCallback() {
+        synchronized (mLock) {
+            mRequestCallbackExecutor = null;
+            mAutofillRequestCallback = null;
+        }
+    }
+
     @GuardedBy("mLock")
     private void startSessionLocked(@NonNull AutofillId id, @NonNull Rect bounds,
             @NonNull AutofillValue value, int flags) {
@@ -2012,6 +2058,13 @@
                 }
             }
 
+            if (mAutofillRequestCallback != null) {
+                if (sDebug) {
+                    Log.d(TAG, "startSession with the client suggestions provider");
+                }
+                flags |= FLAG_ENABLED_CLIENT_SUGGESTIONS;
+            }
+
             mService.startSession(client.autofillClientGetActivityToken(),
                     mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
                     mCallback != null, flags, clientActivity,
@@ -2365,6 +2418,28 @@
         }
     }
 
+    private void onFillRequest(InlineSuggestionsRequest request,
+            CancellationSignal cancellationSignal, FillCallback callback) {
+        final AutofillRequestCallback autofillRequestCallback;
+        final Executor executor;
+        synchronized (mLock) {
+            autofillRequestCallback = mAutofillRequestCallback;
+            executor = mRequestCallbackExecutor;
+        }
+        if (autofillRequestCallback != null && executor != null) {
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                executor.execute(() ->
+                        autofillRequestCallback.onFillRequest(
+                                request, cancellationSignal, callback));
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        } else {
+            callback.onSuccess(null);
+        }
+    }
+
     /** @hide */
     public static final int SET_STATE_FLAG_ENABLED = 0x01;
     /** @hide */
@@ -3852,6 +3927,23 @@
             }
         }
 
+        @Override
+        public void requestFillFromClient(int id, InlineSuggestionsRequest request,
+                IFillCallback callback) {
+            final AutofillManager afm = mAfm.get();
+            if (afm != null) {
+                ICancellationSignal transport = CancellationSignal.createTransport();
+                try {
+                    callback.onCancellable(transport);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Error requesting a cancellation", e);
+                }
+
+                afm.onFillRequest(request, CancellationSignal.fromTransport(transport),
+                        new FillCallback(callback, id));
+            }
+        }
+
         public void notifyFillDialogTriggerIds(List<AutofillId> ids) {
             final AutofillManager afm = mAfm.get();
             if (afm != null) {
diff --git a/core/java/android/view/autofill/AutofillRequestCallback.java b/core/java/android/view/autofill/AutofillRequestCallback.java
new file mode 100644
index 0000000..e632a58
--- /dev/null
+++ b/core/java/android/view/autofill/AutofillRequestCallback.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.autofill;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.CancellationSignal;
+import android.service.autofill.FillCallback;
+import android.view.inputmethod.InlineSuggestionsRequest;
+
+/**
+ * <p>This class is used to provide some input suggestions to the Autofill framework.
+ *
+ * <P>When the user is requested to input something, Autofill will try to query input suggestions
+ * for the user choosing. If the application want to provide some internal input suggestions,
+ * implements this callback and register via
+ * {@link AutofillManager#setAutofillRequestCallback(java.util.concurrent.Executor,
+ * AutofillRequestCallback)}. Autofill will callback the
+ * {@link #onFillRequest(InlineSuggestionsRequest, CancellationSignal, FillCallback)} to request
+ * input suggestions.
+ *
+ * <P>To make sure the callback to take effect, must register before the autofill session starts.
+ * If the autofill session is started, calls {@link AutofillManager#cancel()} to finish current
+ * session, and then the callback will be used at the next restarted session.
+ *
+ * <P>To create a {@link android.service.autofill.FillResponse}, application should fetch
+ * {@link AutofillId}s from its view structure. Below is an example:
+ * <pre class="prettyprint">
+ * AutofillId usernameId = findViewById(R.id.username).getAutofillId();
+ * AutofillId passwordId = findViewById(R.id.password).getAutofillId();
+ * </pre>
+ * To learn more about creating a {@link android.service.autofill.FillResponse}, read
+ * <a href="/guide/topics/text/autofill-services#fill">Fill out client views</a>.
+ *
+ * <P>To fallback to the default {@link android.service.autofill.AutofillService}, just respond
+ * a null of the {@link android.service.autofill.FillResponse}. And then Autofill will do a fill
+ * request with the default {@link android.service.autofill.AutofillService}. Or clear the callback
+ * from {@link AutofillManager} via {@link AutofillManager#clearAutofillRequestCallback()}. If the
+ * client would like to keep no suggestions for the field, respond with an empty
+ * {@link android.service.autofill.FillResponse} which has no dataset.
+ *
+ * <P>IMPORTANT: This should not be used for displaying anything other than input suggestions, or
+ * the keyboard may choose to block your app from the inline strip.
+ */
+public interface AutofillRequestCallback {
+    /**
+     * Called by the Android system to decide if a screen can be autofilled by the callback.
+     *
+     * @param inlineSuggestionsRequest the {@link InlineSuggestionsRequest request} to handle if
+     *     currently inline suggestions are supported and can be displayed.
+     * @param cancellationSignal signal for observing cancellation requests. The system will use
+     *     this to notify you that the fill result is no longer needed and you should stop
+     *     handling this fill request in order to save resources.
+     * @param callback object used to notify the result of the request.
+     */
+    void onFillRequest(@Nullable InlineSuggestionsRequest inlineSuggestionsRequest,
+            @NonNull CancellationSignal cancellationSignal, @NonNull FillCallback callback);
+}
diff --git a/core/java/android/view/autofill/IAutoFillManagerClient.aidl b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
index 51afe4c..2e5967c 100644
--- a/core/java/android/view/autofill/IAutoFillManagerClient.aidl
+++ b/core/java/android/view/autofill/IAutoFillManagerClient.aidl
@@ -24,9 +24,11 @@
 import android.content.IntentSender;
 import android.graphics.Rect;
 import android.os.IBinder;
+import android.service.autofill.IFillCallback;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutofillWindowPresenter;
+import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.KeyEvent;
 
 import com.android.internal.os.IResultReceiver;
@@ -142,6 +144,12 @@
    void requestShowSoftInput(in AutofillId id);
 
     /**
+     * Requests to determine if a screen can be autofilled by the client app.
+     */
+    void requestFillFromClient(int id, in InlineSuggestionsRequest request,
+            in IFillCallback callback);
+
+    /**
      * Notifies autofill ids that require to show the fill dialog.
      */
     void notifyFillDialogTriggerIds(in List<AutofillId> ids);
diff --git a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
index c78b810..70279cc 100644
--- a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
+++ b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
@@ -111,6 +111,22 @@
     private @Nullable InlinePresentationSpec mInlineTooltipPresentationSpec;
 
     /**
+     * Whether the IME supports inline suggestions from the default Autofill service that
+     * provides the input view.
+     *
+     * Note: The default value is {@code true}.
+     */
+    private boolean mServiceSupported;
+
+    /**
+     * Whether the IME supports inline suggestions from the application that provides the
+     * input view.
+     *
+     * Note: The default value is {@code true}.
+     */
+    private boolean mClientSupported;
+
+    /**
      * @hide
      * @see {@link #mHostInputToken}.
      */
@@ -204,6 +220,14 @@
         return Bundle.EMPTY;
     }
 
+    private static boolean defaultServiceSupported() {
+        return true;
+    }
+
+    private static boolean defaultClientSupported() {
+        return true;
+    }
+
     /** @hide */
     abstract static class BaseBuilder {
         abstract Builder setInlinePresentationSpecs(
@@ -216,15 +240,25 @@
         abstract Builder setHostDisplayId(int value);
     }
 
+    /** @hide */
+    public boolean isServiceSupported() {
+        return mServiceSupported;
+    }
+
+    /** @hide */
+    public boolean isClientSupported() {
+        return mClientSupported;
+    }
 
 
-    // Code below generated by codegen v1.0.23.
+
+    // Code below generated by codegen v1.0.22.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
     //
     // To regenerate run:
-    // $ codegen $ANDROID_BUILD_TOP/./frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java
     //
     // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
     //   Settings > Editor > Code Style > Formatter Control
@@ -240,7 +274,9 @@
             @NonNull Bundle extras,
             @Nullable IBinder hostInputToken,
             int hostDisplayId,
-            @Nullable InlinePresentationSpec inlineTooltipPresentationSpec) {
+            @Nullable InlinePresentationSpec inlineTooltipPresentationSpec,
+            boolean serviceSupported,
+            boolean clientSupported) {
         this.mMaxSuggestionCount = maxSuggestionCount;
         this.mInlinePresentationSpecs = inlinePresentationSpecs;
         com.android.internal.util.AnnotationValidations.validate(
@@ -257,6 +293,8 @@
         this.mHostInputToken = hostInputToken;
         this.mHostDisplayId = hostDisplayId;
         this.mInlineTooltipPresentationSpec = inlineTooltipPresentationSpec;
+        this.mServiceSupported = serviceSupported;
+        this.mClientSupported = clientSupported;
 
         onConstructed();
     }
@@ -340,7 +378,9 @@
     }
 
     /**
-     * Specifies the UI specification for the inline suggestion tooltip in the response.
+     * The {@link InlinePresentationSpec} for the inline suggestion tooltip in the response.
+     *
+     * @see android.service.autofill.InlinePresentation#createTooltipPresentation(Slice, InlinePresentationSpec)
      */
     @DataClass.Generated.Member
     public @Nullable InlinePresentationSpec getInlineTooltipPresentationSpec() {
@@ -361,7 +401,9 @@
                 "extras = " + mExtras + ", " +
                 "hostInputToken = " + mHostInputToken + ", " +
                 "hostDisplayId = " + mHostDisplayId + ", " +
-                "inlineTooltipPresentationSpec = " + mInlineTooltipPresentationSpec +
+                "inlineTooltipPresentationSpec = " + mInlineTooltipPresentationSpec + ", " +
+                "serviceSupported = " + mServiceSupported + ", " +
+                "clientSupported = " + mClientSupported +
         " }";
     }
 
@@ -385,7 +427,9 @@
                 && extrasEquals(that.mExtras)
                 && java.util.Objects.equals(mHostInputToken, that.mHostInputToken)
                 && mHostDisplayId == that.mHostDisplayId
-                && java.util.Objects.equals(mInlineTooltipPresentationSpec, that.mInlineTooltipPresentationSpec);
+                && java.util.Objects.equals(mInlineTooltipPresentationSpec, that.mInlineTooltipPresentationSpec)
+                && mServiceSupported == that.mServiceSupported
+                && mClientSupported == that.mClientSupported;
     }
 
     @Override
@@ -403,6 +447,8 @@
         _hash = 31 * _hash + java.util.Objects.hashCode(mHostInputToken);
         _hash = 31 * _hash + mHostDisplayId;
         _hash = 31 * _hash + java.util.Objects.hashCode(mInlineTooltipPresentationSpec);
+        _hash = 31 * _hash + Boolean.hashCode(mServiceSupported);
+        _hash = 31 * _hash + Boolean.hashCode(mClientSupported);
         return _hash;
     }
 
@@ -413,6 +459,8 @@
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
         int flg = 0;
+        if (mServiceSupported) flg |= 0x100;
+        if (mClientSupported) flg |= 0x200;
         if (mHostInputToken != null) flg |= 0x20;
         if (mInlineTooltipPresentationSpec != null) flg |= 0x80;
         dest.writeInt(flg);
@@ -438,6 +486,8 @@
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
         int flg = in.readInt();
+        boolean serviceSupported = (flg & 0x100) != 0;
+        boolean clientSupported = (flg & 0x200) != 0;
         int maxSuggestionCount = in.readInt();
         List<InlinePresentationSpec> inlinePresentationSpecs = new ArrayList<>();
         in.readParcelableList(inlinePresentationSpecs, InlinePresentationSpec.class.getClassLoader(), android.widget.inline.InlinePresentationSpec.class);
@@ -464,6 +514,8 @@
         this.mHostInputToken = hostInputToken;
         this.mHostDisplayId = hostDisplayId;
         this.mInlineTooltipPresentationSpec = inlineTooltipPresentationSpec;
+        this.mServiceSupported = serviceSupported;
+        this.mClientSupported = clientSupported;
 
         onConstructed();
     }
@@ -497,6 +549,8 @@
         private @Nullable IBinder mHostInputToken;
         private int mHostDisplayId;
         private @Nullable InlinePresentationSpec mInlineTooltipPresentationSpec;
+        private boolean mServiceSupported;
+        private boolean mClientSupported;
 
         private long mBuilderFieldsSet = 0L;
 
@@ -629,7 +683,9 @@
         }
 
         /**
-         * Specifies the UI specification for the inline suggestion tooltip in the response.
+         * The {@link InlinePresentationSpec} for the inline suggestion tooltip in the response.
+         *
+         * @see android.service.autofill.InlinePresentation#createTooltipPresentation(Slice, InlinePresentationSpec)s
          */
         @DataClass.Generated.Member
         public @NonNull Builder setInlineTooltipPresentationSpec(@NonNull InlinePresentationSpec value) {
@@ -639,10 +695,38 @@
             return this;
         }
 
+        /**
+         * Whether the IME supports inline suggestions from the default Autofill service that
+         * provides the input view.
+         *
+         * Note: The default value is {@code true}.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setServiceSupported(boolean value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x100;
+            mServiceSupported = value;
+            return this;
+        }
+
+        /**
+         * Whether the IME supports inline suggestions from the application that provides the
+         * input view.
+         *
+         * Note: The default value is {@code true}.
+         */
+        @DataClass.Generated.Member
+        public @NonNull Builder setClientSupported(boolean value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x200;
+            mClientSupported = value;
+            return this;
+        }
+
         /** Builds the instance. This builder should not be touched after calling this! */
         public @NonNull InlineSuggestionsRequest build() {
             checkNotUsed();
-            mBuilderFieldsSet |= 0x100; // Mark builder used
+            mBuilderFieldsSet |= 0x400; // Mark builder used
 
             if ((mBuilderFieldsSet & 0x1) == 0) {
                 mMaxSuggestionCount = defaultMaxSuggestionCount();
@@ -665,6 +749,12 @@
             if ((mBuilderFieldsSet & 0x80) == 0) {
                 mInlineTooltipPresentationSpec = defaultInlineTooltipPresentationSpec();
             }
+            if ((mBuilderFieldsSet & 0x100) == 0) {
+                mServiceSupported = defaultServiceSupported();
+            }
+            if ((mBuilderFieldsSet & 0x200) == 0) {
+                mClientSupported = defaultClientSupported();
+            }
             InlineSuggestionsRequest o = new InlineSuggestionsRequest(
                     mMaxSuggestionCount,
                     mInlinePresentationSpecs,
@@ -673,12 +763,14 @@
                     mExtras,
                     mHostInputToken,
                     mHostDisplayId,
-                    mInlineTooltipPresentationSpec);
+                    mInlineTooltipPresentationSpec,
+                    mServiceSupported,
+                    mClientSupported);
             return o;
         }
 
         private void checkNotUsed() {
-            if ((mBuilderFieldsSet & 0x100) != 0) {
+            if ((mBuilderFieldsSet & 0x400) != 0) {
                 throw new IllegalStateException(
                         "This Builder should not be reused. Use a new Builder instance instead");
             }
@@ -686,10 +778,10 @@
     }
 
     @DataClass.Generated(
-            time = 1621415989607L,
-            codegenVersion = "1.0.23",
+            time = 1615798784918L,
+            codegenVersion = "1.0.22",
             sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestionsRequest.java",
-            inputSignatures = "public static final  int SUGGESTION_COUNT_UNLIMITED\nprivate final  int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.widget.inline.InlinePresentationSpec> mInlinePresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @android.annotation.NonNull android.os.Bundle mExtras\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate  int mHostDisplayId\nprivate @android.annotation.Nullable android.widget.inline.InlinePresentationSpec mInlineTooltipPresentationSpec\nprivate static final @android.compat.annotation.ChangeId @android.compat.annotation.EnabledSince long IME_AUTOFILL_DEFAULT_SUPPORTED_LOCALES_IS_EMPTY\npublic  void setHostInputToken(android.os.IBinder)\nprivate  boolean extrasEquals(android.os.Bundle)\nprivate  void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic  void setHostDisplayId(int)\nprivate  void onConstructed()\npublic  void filterContentTypes()\nprivate static  int defaultMaxSuggestionCount()\nprivate static  java.lang.String defaultHostPackageName()\nprivate static  android.widget.inline.InlinePresentationSpec defaultInlineTooltipPresentationSpec()\nprivate static  android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.NonNull android.os.Bundle defaultExtras()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []")
+            inputSignatures = "public static final  int SUGGESTION_COUNT_UNLIMITED\nprivate final  int mMaxSuggestionCount\nprivate final @android.annotation.NonNull java.util.List<android.widget.inline.InlinePresentationSpec> mInlinePresentationSpecs\nprivate @android.annotation.NonNull java.lang.String mHostPackageName\nprivate @android.annotation.NonNull android.os.LocaleList mSupportedLocales\nprivate @android.annotation.NonNull android.os.Bundle mExtras\nprivate @android.annotation.Nullable android.os.IBinder mHostInputToken\nprivate  int mHostDisplayId\nprivate @android.annotation.Nullable android.widget.inline.InlinePresentationSpec mInlineTooltipPresentationSpec\nprivate  boolean mServiceSupported\nprivate  boolean mClientSupported\nprivate static final @android.compat.annotation.ChangeId @android.compat.annotation.EnabledSince long IME_AUTOFILL_DEFAULT_SUPPORTED_LOCALES_IS_EMPTY\npublic  void setHostInputToken(android.os.IBinder)\nprivate  boolean extrasEquals(android.os.Bundle)\nprivate  void parcelHostInputToken(android.os.Parcel,int)\nprivate @android.annotation.Nullable android.os.IBinder unparcelHostInputToken(android.os.Parcel)\npublic  void setHostDisplayId(int)\nprivate  void onConstructed()\npublic  void filterContentTypes()\nprivate static  int defaultMaxSuggestionCount()\nprivate static  java.lang.String defaultHostPackageName()\nprivate static  android.widget.inline.InlinePresentationSpec defaultInlineTooltipPresentationSpec()\nprivate static  android.os.LocaleList defaultSupportedLocales()\nprivate static @android.annotation.Nullable android.os.IBinder defaultHostInputToken()\nprivate static @android.annotation.Nullable int defaultHostDisplayId()\nprivate static @android.annotation.NonNull android.os.Bundle defaultExtras()\nprivate static  boolean defaultServiceSupported()\nprivate static  boolean defaultClientSupported()\npublic  boolean isServiceSupported()\npublic  boolean isClientSupported()\nclass InlineSuggestionsRequest extends java.lang.Object implements [android.os.Parcelable]\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setInlinePresentationSpecs(java.util.List<android.widget.inline.InlinePresentationSpec>)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostPackageName(java.lang.String)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostInputToken(android.os.IBinder)\nabstract  android.view.inputmethod.InlineSuggestionsRequest.Builder setHostDisplayId(int)\nclass BaseBuilder extends java.lang.Object implements []")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 805f8e7..52d88d6 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2918,7 +2918,8 @@
      */
     @Deprecated
     public void hideSoftInputFromInputMethod(IBinder token, int flags) {
-        InputMethodPrivilegedOperationsRegistry.get(token).hideMySoftInput(flags);
+        InputMethodPrivilegedOperationsRegistry.get(token).hideMySoftInput(
+                flags, SoftInputShowHideReason.HIDE_SOFT_INPUT_IMM_DEPRECATION);
     }
 
     /**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 231ae08..184e7bc 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4363,8 +4363,35 @@
 
                 final int delta = Math.round(axisValue * mVerticalScrollFactor);
                 if (delta != 0) {
+                    // If we're moving down, we want the top item. If we're moving up, bottom item.
+                    final int motionIndex = delta > 0 ? 0 : getChildCount() - 1;
+
+                    int motionViewPrevTop = 0;
+                    View motionView = this.getChildAt(motionIndex);
+                    if (motionView != null) {
+                        motionViewPrevTop = motionView.getTop();
+                    }
+
+                    final int overscrollMode = getOverScrollMode();
+
                     if (!trackMotionScroll(delta, delta)) {
                         return true;
+                    } else if (!event.isFromSource(InputDevice.SOURCE_MOUSE) && motionView != null
+                            && (overscrollMode == OVER_SCROLL_ALWAYS
+                            || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS
+                            && !contentFits()))) {
+                        int motionViewRealTop = motionView.getTop();
+                        float overscroll = (delta - (motionViewRealTop - motionViewPrevTop))
+                                / ((float) getHeight());
+                        if (delta > 0) {
+                            mEdgeGlowTop.onPullDistance(overscroll, 0.5f);
+                            mEdgeGlowTop.onRelease();
+                        } else {
+                            mEdgeGlowBottom.onPullDistance(-overscroll, 0.5f);
+                            mEdgeGlowBottom.onRelease();
+                        }
+                        invalidate();
+                        return true;
                     }
                 }
                 break;
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 018cba7..2dbfd7e 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -872,15 +872,39 @@
                         final int range = getScrollRange();
                         int oldScrollX = mScrollX;
                         int newScrollX = oldScrollX + delta;
+
+                        final int overscrollMode = getOverScrollMode();
+                        boolean canOverscroll = !event.isFromSource(InputDevice.SOURCE_MOUSE)
+                                && (overscrollMode == OVER_SCROLL_ALWAYS
+                                || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0));
+                        boolean absorbed = false;
+
                         if (newScrollX < 0) {
+                            if (canOverscroll) {
+                                mEdgeGlowLeft.onPullDistance(-(float) newScrollX / getWidth(),
+                                        0.5f);
+                                mEdgeGlowLeft.onRelease();
+                                invalidate();
+                                absorbed = true;
+                            }
                             newScrollX = 0;
                         } else if (newScrollX > range) {
+                            if (canOverscroll) {
+                                mEdgeGlowRight.onPullDistance(
+                                        (float) (newScrollX - range) / getWidth(), 0.5f);
+                                mEdgeGlowRight.onRelease();
+                                invalidate();
+                                absorbed = true;
+                            }
                             newScrollX = range;
                         }
                         if (newScrollX != oldScrollX) {
                             super.scrollTo(newScrollX, mScrollY);
                             return true;
                         }
+                        if (absorbed) {
+                            return true;
+                        }
                     }
                 }
             }
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 8e293f4..61a7599 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -52,9 +52,9 @@
 import com.android.internal.widget.IRemoteViewsFactory;
 
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.concurrent.Executor;
 
 /**
@@ -424,17 +424,17 @@
      * adapter that have not yet had their RemoteViews loaded.
      */
     private class RemoteViewsFrameLayoutRefSet
-            extends SparseArray<LinkedList<RemoteViewsFrameLayout>> {
+            extends SparseArray<ArrayList<RemoteViewsFrameLayout>> {
 
         /**
          * Adds a new reference to a RemoteViewsFrameLayout returned by the adapter.
          */
         public void add(int position, RemoteViewsFrameLayout layout) {
-            LinkedList<RemoteViewsFrameLayout> refs = get(position);
+            ArrayList<RemoteViewsFrameLayout> refs = get(position);
 
             // Create the list if necessary
             if (refs == null) {
-                refs = new LinkedList<>();
+                refs = new ArrayList<>();
                 put(position, refs);
             }
 
@@ -451,7 +451,7 @@
             if (view == null) return;
 
             // Remove this set from the original mapping
-            final LinkedList<RemoteViewsFrameLayout> refs = removeReturnOld(position);
+            final ArrayList<RemoteViewsFrameLayout> refs = removeReturnOld(position);
             if (refs != null) {
                 // Notify all the references for that position of the newly loaded RemoteViews
                 for (final RemoteViewsFrameLayout ref : refs) {
@@ -467,7 +467,7 @@
             if (rvfl.cacheIndex < 0) {
                 return;
             }
-            final LinkedList<RemoteViewsFrameLayout> refs = get(rvfl.cacheIndex);
+            final ArrayList<RemoteViewsFrameLayout> refs = get(rvfl.cacheIndex);
             if (refs != null) {
                 refs.remove(rvfl);
             }
@@ -933,12 +933,8 @@
 
             Runnable r = () -> {
                 synchronized (sCachedRemoteViewsCaches) {
-                    if (sCachedRemoteViewsCaches.containsKey(key)) {
-                        sCachedRemoteViewsCaches.remove(key);
-                    }
-                    if (sRemoteViewsCacheRemoveRunnables.containsKey(key)) {
-                        sRemoteViewsCacheRemoveRunnables.remove(key);
-                    }
+                    sCachedRemoteViewsCaches.remove(key);
+                    sRemoteViewsCacheRemoveRunnables.remove(key);
                 }
             };
             sRemoteViewsCacheRemoveRunnables.put(key, r);
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 15cd17b..2acd50c 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -939,15 +939,38 @@
                     final int range = getScrollRange();
                     int oldScrollY = mScrollY;
                     int newScrollY = oldScrollY - delta;
+
+                    final int overscrollMode = getOverScrollMode();
+                    boolean canOverscroll = !event.isFromSource(InputDevice.SOURCE_MOUSE)
+                            && (overscrollMode == OVER_SCROLL_ALWAYS
+                            || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0));
+                    boolean absorbed = false;
+
                     if (newScrollY < 0) {
+                        if (canOverscroll) {
+                            mEdgeGlowTop.onPullDistance(-(float) newScrollY / getHeight(), 0.5f);
+                            mEdgeGlowTop.onRelease();
+                            invalidate();
+                            absorbed = true;
+                        }
                         newScrollY = 0;
                     } else if (newScrollY > range) {
+                        if (canOverscroll) {
+                            mEdgeGlowBottom.onPullDistance(
+                                    (float) (newScrollY - range) / getHeight(), 0.5f);
+                            mEdgeGlowBottom.onRelease();
+                            invalidate();
+                            absorbed = true;
+                        }
                         newScrollY = range;
                     }
                     if (newScrollY != oldScrollY) {
                         super.scrollTo(mScrollX, newScrollY);
                         return true;
                     }
+                    if (absorbed) {
+                        return true;
+                    }
                 }
                 break;
         }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 54c0d7c..9e1bc8f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -144,6 +144,7 @@
 import android.text.util.Linkify;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.FeatureFlagUtils;
 import android.util.IntArray;
 import android.util.Log;
 import android.util.SparseIntArray;
@@ -791,6 +792,11 @@
     private int mLineBreakStyle = DEFAULT_LINE_BREAK_STYLE;
     private int mLineBreakWordStyle = DEFAULT_LINE_BREAK_WORD_STYLE;
 
+    // The auto option for LINE_BREAK_WORD_STYLE_PHRASE may not be applied in recycled view due to
+    // one-way flag flipping. This is a tentative limitation during experiment and will not have the
+    // issue once this is finalized to LINE_BREAK_WORD_STYLE_PHRASE_AUTO option.
+    private boolean mUserSpeficiedLineBreakwordStyle = false;
+
     // This is used to reflect the current user preference for changing font weight and making text
     // more bold.
     private int mFontWeightAdjustment;
@@ -1462,6 +1468,9 @@
                     break;
 
                 case com.android.internal.R.styleable.TextView_lineBreakWordStyle:
+                    if (a.hasValue(attr)) {
+                        mUserSpeficiedLineBreakwordStyle = true;
+                    }
                     mLineBreakWordStyle = a.getInt(attr,
                             LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE);
                     break;
@@ -4209,6 +4218,7 @@
                     break;
                 case com.android.internal.R.styleable.TextAppearance_lineBreakWordStyle:
                     attributes.mHasLineBreakWordStyle = true;
+                    mUserSpeficiedLineBreakwordStyle = true;
                     attributes.mLineBreakWordStyle =
                             appearance.getInt(attr, attributes.mLineBreakWordStyle);
                     break;
@@ -4910,6 +4920,7 @@
      * @param lineBreakWordStyle the line break word style for the tet
      */
     public void setLineBreakWordStyle(@LineBreakConfig.LineBreakWordStyle int lineBreakWordStyle) {
+        mUserSpeficiedLineBreakwordStyle = true;
         if (mLineBreakWordStyle != lineBreakWordStyle) {
             mLineBreakWordStyle = lineBreakWordStyle;
             if (mLayout != null) {
@@ -4945,8 +4956,12 @@
      * @see PrecomputedText
      */
     public @NonNull PrecomputedText.Params getTextMetricsParams() {
+        final boolean autoPhraseBreaking =
+                !mUserSpeficiedLineBreakwordStyle && FeatureFlagUtils.isEnabled(mContext,
+                        FeatureFlagUtils.SETTINGS_AUTO_TEXT_WRAPPING);
         return new PrecomputedText.Params(new TextPaint(mTextPaint),
-                LineBreakConfig.getLineBreakConfig(mLineBreakStyle, mLineBreakWordStyle),
+                LineBreakConfig.getLineBreakConfig(mLineBreakStyle, mLineBreakWordStyle,
+                        autoPhraseBreaking),
                 getTextDirectionHeuristic(),
                 mBreakStrategy, mHyphenationFrequency);
     }
@@ -4966,6 +4981,7 @@
         LineBreakConfig lineBreakConfig = params.getLineBreakConfig();
         mLineBreakStyle = lineBreakConfig.getLineBreakStyle();
         mLineBreakWordStyle = lineBreakConfig.getLineBreakWordStyle();
+        mUserSpeficiedLineBreakwordStyle = true;
         if (mLayout != null) {
             nullLayouts();
             requestLayout();
@@ -6502,10 +6518,13 @@
             if (mTextDir == null) {
                 mTextDir = getTextDirectionHeuristic();
             }
+            final boolean autoPhraseBreaking =
+                    !mUserSpeficiedLineBreakwordStyle && FeatureFlagUtils.isEnabled(mContext,
+                            FeatureFlagUtils.SETTINGS_AUTO_TEXT_WRAPPING);
             final @PrecomputedText.Params.CheckResultUsableResult int checkResult =
                     precomputed.getParams().checkResultUsable(getPaint(), mTextDir, mBreakStrategy,
                             mHyphenationFrequency, LineBreakConfig.getLineBreakConfig(
-                                    mLineBreakStyle, mLineBreakWordStyle));
+                                    mLineBreakStyle, mLineBreakWordStyle, autoPhraseBreaking));
             switch (checkResult) {
                 case PrecomputedText.Params.UNUSABLE:
                     throw new IllegalArgumentException(
@@ -9391,6 +9410,9 @@
             }
             // TODO: code duplication with makeSingleLayout()
             if (mHintLayout == null) {
+                final boolean autoPhraseBreaking =
+                        !mUserSpeficiedLineBreakwordStyle && FeatureFlagUtils.isEnabled(mContext,
+                                FeatureFlagUtils.SETTINGS_AUTO_TEXT_WRAPPING);
                 StaticLayout.Builder builder = StaticLayout.Builder.obtain(mHint, 0,
                         mHint.length(), mTextPaint, hintWidth)
                         .setAlignment(alignment)
@@ -9403,7 +9425,7 @@
                         .setJustificationMode(mJustificationMode)
                         .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
                         .setLineBreakConfig(LineBreakConfig.getLineBreakConfig(
-                                mLineBreakStyle, mLineBreakWordStyle));
+                                mLineBreakStyle, mLineBreakWordStyle, autoPhraseBreaking));
                 if (shouldEllipsize) {
                     builder.setEllipsize(mEllipsize)
                             .setEllipsizedWidth(ellipsisWidth);
@@ -9507,6 +9529,9 @@
             }
         }
         if (result == null) {
+            final boolean autoPhraseBreaking =
+                    !mUserSpeficiedLineBreakwordStyle && FeatureFlagUtils.isEnabled(mContext,
+                            FeatureFlagUtils.SETTINGS_AUTO_TEXT_WRAPPING);
             StaticLayout.Builder builder = StaticLayout.Builder.obtain(mTransformed,
                     0, mTransformed.length(), mTextPaint, wantWidth)
                     .setAlignment(alignment)
@@ -9519,7 +9544,7 @@
                     .setJustificationMode(mJustificationMode)
                     .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
                     .setLineBreakConfig(LineBreakConfig.getLineBreakConfig(
-                            mLineBreakStyle, mLineBreakWordStyle));
+                            mLineBreakStyle, mLineBreakWordStyle, autoPhraseBreaking));
             if (shouldEllipsize) {
                 builder.setEllipsize(effectiveEllipsize)
                         .setEllipsizedWidth(ellipsisWidth);
@@ -9877,7 +9902,9 @@
 
         final StaticLayout.Builder layoutBuilder = StaticLayout.Builder.obtain(
                 text, 0, text.length(),  mTempTextPaint, Math.round(availableSpace.right));
-
+        final boolean autoPhraseBreaking =
+                !mUserSpeficiedLineBreakwordStyle && FeatureFlagUtils.isEnabled(mContext,
+                        FeatureFlagUtils.SETTINGS_AUTO_TEXT_WRAPPING);
         layoutBuilder.setAlignment(getLayoutAlignment())
                 .setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier())
                 .setIncludePad(getIncludeFontPadding())
@@ -9888,7 +9915,7 @@
                 .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
                 .setTextDirection(getTextDirectionHeuristic())
                 .setLineBreakConfig(LineBreakConfig.getLineBreakConfig(
-                        mLineBreakStyle, mLineBreakWordStyle));
+                        mLineBreakStyle, mLineBreakWordStyle, autoPhraseBreaking));
 
         final StaticLayout layout = layoutBuilder.build();
 
diff --git a/core/java/com/android/internal/app/AbstractResolverComparator.java b/core/java/com/android/internal/app/AbstractResolverComparator.java
index 42fc7bd..9759540 100644
--- a/core/java/com/android/internal/app/AbstractResolverComparator.java
+++ b/core/java/com/android/internal/app/AbstractResolverComparator.java
@@ -228,12 +228,6 @@
      */
     abstract float getScore(ComponentName name);
 
-    /**
-     * Returns the list of top K component names which have highest
-     * {@link #getScore(ComponentName)}
-     */
-    abstract List<ComponentName> getTopComponentNames(int topK);
-
     /** Handles result message sent to mHandler. */
     abstract void handleResultMessage(Message message);
 
diff --git a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
index bc9eff0..b19ac2f 100644
--- a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
@@ -18,6 +18,7 @@
 
 import static android.app.prediction.AppTargetEvent.ACTION_LAUNCH;
 
+import android.annotation.Nullable;
 import android.app.prediction.AppPredictor;
 import android.app.prediction.AppTarget;
 import android.app.prediction.AppTargetEvent;
@@ -33,12 +34,11 @@
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
 
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 import java.util.concurrent.Executors;
-import java.util.stream.Collectors;
 
 /**
  * Uses an {@link AppPredictor} to sort Resolver targets. If the AppPredictionService appears to be
@@ -58,7 +58,9 @@
     private final String mReferrerPackage;
     // If this is non-null (and this is not destroyed), it means APS is disabled and we should fall
     // back to using the ResolverRankerService.
+    // TODO: responsibility for this fallback behavior can live outside of the AppPrediction client.
     private ResolverRankerServiceResolverComparator mResolverRankerService;
+    private AppPredictionServiceComparatorModel mComparatorModel;
 
     AppPredictionServiceResolverComparator(
             Context context,
@@ -74,25 +76,12 @@
         mUser = user;
         mReferrerPackage = referrerPackage;
         setChooserActivityLogger(chooserActivityLogger);
+        mComparatorModel = buildUpdatedModel();
     }
 
     @Override
     int compare(ResolveInfo lhs, ResolveInfo rhs) {
-        if (mResolverRankerService != null) {
-            return mResolverRankerService.compare(lhs, rhs);
-        }
-        Integer lhsRank = mTargetRanks.get(new ComponentName(lhs.activityInfo.packageName,
-                lhs.activityInfo.name));
-        Integer rhsRank = mTargetRanks.get(new ComponentName(rhs.activityInfo.packageName,
-                rhs.activityInfo.name));
-        if (lhsRank == null && rhsRank == null) {
-            return 0;
-        } else if (lhsRank == null) {
-            return -1;
-        } else if (rhsRank == null) {
-            return 1;
-        }
-        return lhsRank - rhsRank;
+        return mComparatorModel.getComparator().compare(lhs, rhs);
     }
 
     @Override
@@ -121,6 +110,7 @@
                                         mContext, mIntent, mReferrerPackage,
                                         () -> mHandler.sendEmptyMessage(RANKER_SERVICE_RESULT),
                                         getChooserActivityLogger());
+                        mComparatorModel = buildUpdatedModel();
                         mResolverRankerService.compute(targets);
                     } else {
                         Log.i(TAG, "AppPredictionService response received");
@@ -163,6 +153,7 @@
             mTargetRanks.put(componentName, i);
             Log.i(TAG, "handleSortedAppTargets, sortedAppTargets #" + i + ": " + componentName);
         }
+        mComparatorModel = buildUpdatedModel();
     }
 
     private boolean checkAppTargetRankValid(List<AppTarget> sortedAppTargets) {
@@ -176,43 +167,12 @@
 
     @Override
     float getScore(ComponentName name) {
-        if (mResolverRankerService != null) {
-            return mResolverRankerService.getScore(name);
-        }
-        Integer rank = mTargetRanks.get(name);
-        if (rank == null) {
-            Log.w(TAG, "Score requested for unknown component. Did you call compute yet?");
-            return 0f;
-        }
-        int consecutiveSumOfRanks = (mTargetRanks.size() - 1) * (mTargetRanks.size()) / 2;
-        return 1.0f - (((float) rank) / consecutiveSumOfRanks);
-    }
-
-    @Override
-    List<ComponentName> getTopComponentNames(int topK) {
-        if (mResolverRankerService != null) {
-            return mResolverRankerService.getTopComponentNames(topK);
-        }
-        return mTargetRanks.entrySet().stream()
-                .sorted(Entry.comparingByValue())
-                .limit(topK)
-                .map(Entry::getKey)
-                .collect(Collectors.toList());
+        return mComparatorModel.getScore(name);
     }
 
     @Override
     void updateModel(ComponentName componentName) {
-        if (mResolverRankerService != null) {
-            mResolverRankerService.updateModel(componentName);
-            return;
-        }
-        mAppPredictor.notifyAppTargetEvent(
-                new AppTargetEvent.Builder(
-                    new AppTarget.Builder(
-                        new AppTargetId(componentName.toString()),
-                        componentName.getPackageName(), mUser)
-                        .setClassName(componentName.getClassName()).build(),
-                    ACTION_LAUNCH).build());
+        mComparatorModel.notifyOnTargetSelected(componentName);
     }
 
     @Override
@@ -220,6 +180,97 @@
         if (mResolverRankerService != null) {
             mResolverRankerService.destroy();
             mResolverRankerService = null;
+            mComparatorModel = buildUpdatedModel();
+        }
+    }
+
+    /**
+     * Re-construct an {@code AppPredictionServiceComparatorModel} to replace the current model
+     * instance (if any) using the up-to-date {@code AppPredictionServiceResolverComparator} ivar
+     * values.
+     *
+     * TODO: each time we replace the model instance, we're either updating the model to use
+     * adjusted data (which is appropriate), or we're providing a (late) value for one of our ivars
+     * that wasn't available the last time the model was updated. For those latter cases, we should
+     * just avoid creating the model altogether until we have all the prerequisites we'll need. Then
+     * we can probably simplify the logic in {@code AppPredictionServiceComparatorModel} since we
+     * won't need to handle edge cases when the model data isn't fully prepared.
+     * (In some cases, these kinds of "updates" might interleave -- e.g., we might have finished
+     * initializing the first time and now want to adjust some data, but still need to wait for
+     * changes to propagate to the other ivars before rebuilding the model.)
+     */
+    private AppPredictionServiceComparatorModel buildUpdatedModel() {
+        return new AppPredictionServiceComparatorModel(
+                mAppPredictor, mResolverRankerService, mUser, mTargetRanks);
+    }
+
+    // TODO: Finish separating behaviors of AbstractResolverComparator, then (probably) make this a
+    // standalone class once clients are written in terms of ResolverComparatorModel.
+    static class AppPredictionServiceComparatorModel implements ResolverComparatorModel {
+        private final AppPredictor mAppPredictor;
+        private final ResolverRankerServiceResolverComparator mResolverRankerService;
+        private final UserHandle mUser;
+        private final Map<ComponentName, Integer> mTargetRanks;  // Treat as immutable.
+
+        AppPredictionServiceComparatorModel(
+                AppPredictor appPredictor,
+                @Nullable ResolverRankerServiceResolverComparator resolverRankerService,
+                UserHandle user,
+                Map<ComponentName, Integer> targetRanks) {
+            mAppPredictor = appPredictor;
+            mResolverRankerService = resolverRankerService;
+            mUser = user;
+            mTargetRanks = targetRanks;
+        }
+
+        @Override
+        public Comparator<ResolveInfo> getComparator() {
+            return (lhs, rhs) -> {
+                if (mResolverRankerService != null) {
+                    return mResolverRankerService.compare(lhs, rhs);
+                }
+                Integer lhsRank = mTargetRanks.get(new ComponentName(lhs.activityInfo.packageName,
+                        lhs.activityInfo.name));
+                Integer rhsRank = mTargetRanks.get(new ComponentName(rhs.activityInfo.packageName,
+                        rhs.activityInfo.name));
+                if (lhsRank == null && rhsRank == null) {
+                    return 0;
+                } else if (lhsRank == null) {
+                    return -1;
+                } else if (rhsRank == null) {
+                    return 1;
+                }
+                return lhsRank - rhsRank;
+            };
+        }
+
+        @Override
+        public float getScore(ComponentName name) {
+            if (mResolverRankerService != null) {
+                return mResolverRankerService.getScore(name);
+            }
+            Integer rank = mTargetRanks.get(name);
+            if (rank == null) {
+                Log.w(TAG, "Score requested for unknown component. Did you call compute yet?");
+                return 0f;
+            }
+            int consecutiveSumOfRanks = (mTargetRanks.size() - 1) * (mTargetRanks.size()) / 2;
+            return 1.0f - (((float) rank) / consecutiveSumOfRanks);
+        }
+
+        @Override
+        public void notifyOnTargetSelected(ComponentName componentName) {
+            if (mResolverRankerService != null) {
+                mResolverRankerService.updateModel(componentName);
+                return;
+            }
+            mAppPredictor.notifyAppTargetEvent(
+                    new AppTargetEvent.Builder(
+                        new AppTarget.Builder(
+                            new AppTargetId(componentName.toString()),
+                            componentName.getPackageName(), mUser)
+                            .setClassName(componentName.getClassName()).build(),
+                        ACTION_LAUNCH).build());
         }
     }
 }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index d4a8a16..595c963 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -194,9 +194,6 @@
     private static final String PLURALS_COUNT = "count";
     private static final String PLURALS_FILE_NAME = "file_name";
 
-    @VisibleForTesting
-    public static final int LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS = 250;
-
     private boolean mIsAppPredictorComponentAvailable;
     private Map<ChooserTarget, AppTarget> mDirectShareAppTargetCache;
     private Map<ChooserTarget, ShortcutInfo> mDirectShareShortcutInfoCache;
@@ -248,6 +245,13 @@
                     SystemUiDeviceConfigFlags.IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP,
                     DEFAULT_IS_NEARBY_SHARE_FIRST_TARGET_IN_RANKED_APP);
 
+    private static final int DEFAULT_LIST_VIEW_UPDATE_DELAY_MS = 250;
+
+    @VisibleForTesting
+    int mListViewUpdateDelayMs = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
+            SystemUiDeviceConfigFlags.SHARESHEET_LIST_VIEW_UPDATE_DELAY,
+            DEFAULT_LIST_VIEW_UPDATE_DELAY_MS);
+
     private Bundle mReplacementExtras;
     private IntentSender mChosenComponentSender;
     private IntentSender mRefinementIntentSender;
@@ -2605,7 +2609,7 @@
         Message msg = Message.obtain();
         msg.what = ChooserHandler.LIST_VIEW_UPDATE_MESSAGE;
         msg.obj = userHandle;
-        mChooserHandler.sendMessageDelayed(msg, LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        mChooserHandler.sendMessageDelayed(msg, mListViewUpdateDelayMs);
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/ChooserUtil.java b/core/java/com/android/internal/app/ChooserUtil.java
deleted file mode 100644
index 3f8788c..0000000
--- a/core/java/com/android/internal/app/ChooserUtil.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.app;
-
-import java.nio.charset.Charset;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * Utility method for common computation operations for Share sheet.
- */
-public class ChooserUtil {
-
-    private static final Charset UTF_8 = Charset.forName("UTF-8");
-
-    /**
-     * Hashes the given input based on MD5 algorithm.
-     *
-     * @return a string representation of the hash computation.
-     */
-    public static String md5(String input) {
-        try {
-            MessageDigest md = MessageDigest.getInstance("MD5");
-            md.update(input.getBytes(UTF_8));
-            return convertBytesToHexString(md.digest());
-        } catch (NoSuchAlgorithmException e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    /** Converts byte array input into an hex string. */
-    private static String convertBytesToHexString(byte[] input) {
-        char[] chars = new char[input.length * 2];
-        for (int i = 0; i < input.length; i++) {
-            byte b = input[i];
-            chars[i * 2] = Character.forDigit((b >> 4) & 0xF, 16 /* radix */);
-            chars[i * 2 + 1] = Character.forDigit(b & 0xF, 16 /* radix */);
-        }
-        return new String(chars);
-    }
-
-    private ChooserUtil() {}
-}
diff --git a/core/java/com/android/internal/app/ResolverComparatorModel.java b/core/java/com/android/internal/app/ResolverComparatorModel.java
new file mode 100644
index 0000000..3e8f64b
--- /dev/null
+++ b/core/java/com/android/internal/app/ResolverComparatorModel.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.ComponentName;
+import android.content.pm.ResolveInfo;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * A ranking model for resolver targets, providing ordering and (optionally) numerical scoring.
+ *
+ * As required by the {@link Comparator} contract, objects returned by {@code getComparator()} must
+ * apply a total ordering on its inputs consistent across all calls to {@code Comparator#compare()}.
+ * Other query methods and ranking feedback should refer to that same ordering, so implementors are
+ * generally advised to "lock in" an immutable snapshot of their model data when this object is
+ * initialized (preferring to replace the entire {@code ResolverComparatorModel} instance if the
+ * backing data needs to be updated in the future).
+ */
+interface ResolverComparatorModel {
+    /**
+     * Get a {@code Comparator} that can be used to sort {@code ResolveInfo} targets according to
+     * the model ranking.
+     */
+    Comparator<ResolveInfo> getComparator();
+
+    /**
+     * Get the numerical score, if any, that the model assigns to the component with the specified
+     * {@code name}. Scores range from zero to one, with one representing the highest possible
+     * likelihood that the user will select that component as the target. Implementations that don't
+     * assign numerical scores are <em>recommended</em> to return a value of 0 for all components.
+     */
+    float getScore(ComponentName name);
+
+    /**
+     * Notify the model that the user selected a target. (Models may log this information, use it as
+     * a feedback signal for their ranking, etc.) Because the data in this
+     * {@code ResolverComparatorModel} instance is immutable, clients will need to get an up-to-date
+     * instance in order to see any changes in the ranking that might result from this feedback.
+     */
+    void notifyOnTargetSelected(ComponentName componentName);
+}
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index ac9b2d8..351ac45 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -155,14 +155,6 @@
         return mResolverListController.getScore(componentName);
     }
 
-    /**
-     * Returns the list of top K component names which have highest
-     * {@link #getScore(DisplayResolveInfo)}
-     */
-    public List<ComponentName> getTopComponentNames(int topK) {
-        return mResolverListController.getTopComponentNames(topK);
-    }
-
     public void updateModel(ComponentName componentName) {
         mResolverListController.updateModel(componentName);
     }
@@ -177,107 +169,206 @@
     }
 
     /**
-     * Rebuild the list of resolvers. In some cases some parts will need some asynchronous work
-     * to complete.
+     * Rebuild the list of resolvers. When rebuilding is complete, queue the {@code onPostListReady}
+     * callback on the main handler with {@code rebuildCompleted} true.
      *
-     * The {@code doPostProcessing } parameter is used to specify whether to update the UI and
-     * load additional targets (e.g. direct share) after the list has been rebuilt. This is used
-     * in the case where we want to load the inactive profile's resolved apps to know the
+     * In some cases some parts will need some asynchronous work to complete. Then this will first
+     * immediately queue {@code onPostListReady} (on the main handler) with {@code rebuildCompleted}
+     * false; only when the asynchronous work completes will this then go on to queue another
+     * {@code onPostListReady} callback with {@code rebuildCompleted} true.
+     *
+     * The {@code doPostProcessing} parameter is used to specify whether to update the UI and
+     * load additional targets (e.g. direct share) after the list has been rebuilt. We may choose
+     * to skip that step if we're only loading the inactive profile's resolved apps to know the
      * number of targets.
      *
-     * @return Whether or not the list building is completed.
+     * @return Whether the list building was completed synchronously. If not, we'll queue the
+     * {@code onPostListReady} callback first with {@code rebuildCompleted} false, and then again
+     * with {@code rebuildCompleted} true at the end of some newly-launched asynchronous work.
+     * Otherwise the callback is only queued once, with {@code rebuildCompleted} true.
      */
     protected boolean rebuildList(boolean doPostProcessing) {
-        List<ResolvedComponentInfo> currentResolveList = null;
-        // Clear the value of mOtherProfile from previous call.
-        mOtherProfile = null;
-        mLastChosen = null;
-        mLastChosenPosition = -1;
         mDisplayList.clear();
         mIsTabLoaded = false;
+        mLastChosenPosition = -1;
 
-        if (mBaseResolveList != null) {
-            currentResolveList = mUnfilteredResolveList = new ArrayList<>();
-            mResolverListController.addResolveListDedupe(currentResolveList,
-                    mResolverListCommunicator.getTargetIntent(),
-                    mBaseResolveList);
-        } else {
-            currentResolveList = mUnfilteredResolveList =
-                    mResolverListController.getResolversForIntent(
-                            /* shouldGetResolvedFilter= */ true,
-                            mResolverListCommunicator.shouldGetActivityMetadata(),
-                            mIntents);
-            if (currentResolveList == null) {
-                processSortedList(currentResolveList, doPostProcessing);
-                return true;
-            }
-            List<ResolvedComponentInfo> originalList =
-                    mResolverListController.filterIneligibleActivities(currentResolveList,
-                            true);
-            if (originalList != null) {
-                mUnfilteredResolveList = originalList;
-            }
-        }
+        List<ResolvedComponentInfo> currentResolveList = getInitialRebuiltResolveList();
+
+        /* TODO: this seems like unnecessary extra complexity; why do we need to do this "primary"
+         * (i.e. "eligibility") filtering before evaluating the "other profile" special-treatment,
+         * but the "secondary" (i.e. "priority") filtering after? Are there in fact cases where the
+         * eligibility conditions will filter out a result that would've otherwise gotten the "other
+         * profile" treatment? Or, are there cases where the priority conditions *would* filter out
+         * a result, but we *want* that result to get the "other profile" treatment, so we only
+         * filter *after* evaluating the special-treatment conditions? If the answer to either is
+         * "no," then the filtering steps can be consolidated. (And that also makes the "unfiltered
+         * list" bookkeeping a little cleaner.)
+         */
+        mUnfilteredResolveList = performPrimaryResolveListFiltering(currentResolveList);
 
         // So far we only support a single other profile at a time.
         // The first one we see gets special treatment.
-        for (ResolvedComponentInfo info : currentResolveList) {
-            ResolveInfo resolveInfo = info.getResolveInfoAt(0);
-            if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) {
-                Intent pOrigIntent = mResolverListCommunicator.getReplacementIntent(
-                        resolveInfo.activityInfo,
-                        info.getIntentAt(0));
-                Intent replacementIntent = mResolverListCommunicator.getReplacementIntent(
-                        resolveInfo.activityInfo,
-                        mResolverListCommunicator.getTargetIntent());
-                mOtherProfile = new DisplayResolveInfo(info.getIntentAt(0),
-                        resolveInfo,
-                        resolveInfo.loadLabel(mPm),
-                        resolveInfo.loadLabel(mPm),
-                        pOrigIntent != null ? pOrigIntent : replacementIntent,
-                        makePresentationGetter(resolveInfo));
-                currentResolveList.remove(info);
-                break;
-            }
+        ResolvedComponentInfo otherProfileInfo =
+                getFirstNonCurrentUserResolvedComponentInfo(currentResolveList);
+        updateOtherProfileTreatment(otherProfileInfo);
+        if (otherProfileInfo != null) {
+            currentResolveList.remove(otherProfileInfo);
+            /* TODO: the previous line removed the "other profile info" item from
+             * mUnfilteredResolveList *ONLY IF* that variable is an alias for the same List instance
+             * as currentResolveList (i.e., if no items were filtered out as the result of the
+             * earlier "primary" filtering). It seems wrong for our behavior to depend on that.
+             * Should we:
+             *  A. replicate the above removal to mUnfilteredResolveList (which is idempotent, so we
+             *     don't even have to check whether they're aliases); or
+             *  B. break the alias relationship by copying currentResolveList to a new
+             *  mUnfilteredResolveList instance if necessary before removing otherProfileInfo?
+             * In other words: do we *want* otherProfileInfo in the "unfiltered" results? Either
+             * way, we'll need one of the changes suggested above.
+             */
         }
 
-        if (mOtherProfile == null) {
+        // If no results have yet been filtered, mUnfilteredResolveList is an alias for the same
+        // List instance as currentResolveList. Then we need to make a copy to store as the
+        // mUnfilteredResolveList if we go on to filter any more items. Otherwise we've already
+        // copied the original unfiltered items to a separate List instance and can now filter
+        // the remainder in-place without any further bookkeeping.
+        boolean needsCopyOfUnfiltered = (mUnfilteredResolveList == currentResolveList);
+        mUnfilteredResolveList = performSecondaryResolveListFiltering(
+                currentResolveList, needsCopyOfUnfiltered);
+
+        return finishRebuildingListWithFilteredResults(currentResolveList, doPostProcessing);
+    }
+
+    /**
+     * Get the full (unfiltered) set of {@code ResolvedComponentInfo} records for all resolvers
+     * to be considered in a newly-rebuilt list. This list will be filtered and ranked before the
+     * rebuild is complete.
+     */
+    List<ResolvedComponentInfo> getInitialRebuiltResolveList() {
+        if (mBaseResolveList != null) {
+            List<ResolvedComponentInfo> currentResolveList = new ArrayList<>();
+            mResolverListController.addResolveListDedupe(currentResolveList,
+                    mResolverListCommunicator.getTargetIntent(),
+                    mBaseResolveList);
+            return currentResolveList;
+        } else {
+            return mResolverListController.getResolversForIntent(
+                            /* shouldGetResolvedFilter= */ true,
+                            mResolverListCommunicator.shouldGetActivityMetadata(),
+                            mIntents);
+        }
+    }
+
+    /**
+     * Remove ineligible activities from {@code currentResolveList} (if non-null), in-place. More
+     * broadly, filtering logic should apply in the "primary" stage if it should preclude items from
+     * receiving the "other profile" special-treatment described in {@code rebuildList()}.
+     *
+     * @return A copy of the original {@code currentResolveList}, if any items were removed, or a
+     * (possibly null) reference to the original list otherwise. (That is, this always returns a
+     * list of all the unfiltered items, but if no items were filtered, it's just an alias for the
+     * same list that was passed in).
+     */
+    @Nullable
+    List<ResolvedComponentInfo> performPrimaryResolveListFiltering(
+            @Nullable List<ResolvedComponentInfo> currentResolveList) {
+        /* TODO: mBaseResolveList appears to be(?) some kind of configured mode. Why is it not
+         * subject to filterIneligibleActivities, even though all the other logic still applies
+         * (including "secondary" filtering)? (This also relates to the earlier question; do we
+         * believe there's an item that would be eligible for "other profile" special treatment,
+         * except we want to filter it out as ineligible... but only if we're not in
+         * "mBaseResolveList mode"? */
+        if ((mBaseResolveList != null) || (currentResolveList == null)) {
+            return currentResolveList;
+        }
+
+        List<ResolvedComponentInfo> originalList =
+                mResolverListController.filterIneligibleActivities(currentResolveList, true);
+        return (originalList == null) ? currentResolveList : originalList;
+    }
+
+    /**
+     * Remove low-priority activities from {@code currentResolveList} (if non-null), in place. More
+     * broadly, filtering logic should apply in the "secondary" stage to prevent items from
+     * appearing in the rebuilt-list results, while still considering those items for the "other
+     * profile" special-treatment described in {@code rebuildList()}.
+     *
+     * @return the same (possibly null) List reference as {@code currentResolveList}, if the list is
+     * unmodified as a result of filtering; or, if some item(s) were removed, then either a copy of
+     * the original {@code currentResolveList} (if {@code returnCopyOfOriginalListIfModified} is
+     * true), or null (otherwise).
+     */
+    @Nullable
+    List<ResolvedComponentInfo> performSecondaryResolveListFiltering(
+            @Nullable List<ResolvedComponentInfo> currentResolveList,
+            boolean returnCopyOfOriginalListIfModified) {
+        if ((currentResolveList == null) || currentResolveList.isEmpty()) {
+            return currentResolveList;
+        }
+        return mResolverListController.filterLowPriority(
+                currentResolveList, returnCopyOfOriginalListIfModified);
+    }
+
+    /**
+     * Update the special "other profile" UI treatment based on the components resolved for a
+     * newly-built list.
+     *
+     * @param otherProfileInfo the first {@code ResolvedComponentInfo} specifying a
+     * {@code targetUserId} other than {@code USER_CURRENT}, or null if no such component info was
+     * found in the process of rebuilding the list (or if any such candidates were already removed
+     * due to "primary filtering").
+     */
+    void updateOtherProfileTreatment(@Nullable ResolvedComponentInfo otherProfileInfo) {
+        mLastChosen = null;
+
+        if (otherProfileInfo != null) {
+            mOtherProfile = makeOtherProfileDisplayResolveInfo(
+                    mContext, otherProfileInfo, mPm, mResolverListCommunicator, mIconDpi);
+        } else {
+            mOtherProfile = null;
             try {
                 mLastChosen = mResolverListController.getLastChosen();
+                // TODO: does this also somehow need to update mLastChosenPosition? If so, maybe
+                // the current method should also take responsibility for re-initializing
+                // mLastChosenPosition, where it's currently done at the start of rebuildList()?
+                // (Why is this related to the presence of mOtherProfile in fhe first place?)
             } catch (RemoteException re) {
                 Log.d(TAG, "Error calling getLastChosenActivity\n" + re);
             }
         }
+    }
 
-        setPlaceholderCount(0);
-        int n;
-        if ((currentResolveList != null) && ((n = currentResolveList.size()) > 0)) {
-            // We only care about fixing the unfilteredList if the current resolve list and
-            // current resolve list are currently the same.
-            List<ResolvedComponentInfo> originalList =
-                    mResolverListController.filterLowPriority(currentResolveList,
-                            mUnfilteredResolveList == currentResolveList);
-            if (originalList != null) {
-                mUnfilteredResolveList = originalList;
-            }
-
-            if (currentResolveList.size() > 1) {
-                int placeholderCount = currentResolveList.size();
-                if (mResolverListCommunicator.useLayoutWithDefault()) {
-                    --placeholderCount;
-                }
-                setPlaceholderCount(placeholderCount);
-                createSortingTask(doPostProcessing).execute(currentResolveList);
-                postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ false);
-                return false;
-            } else {
-                processSortedList(currentResolveList, doPostProcessing);
-                return true;
-            }
-        } else {
-            processSortedList(currentResolveList, doPostProcessing);
+    /**
+     * Prepare the appropriate placeholders to eventually display the final set of resolved
+     * components in a newly-rebuilt list, and spawn an asynchronous sorting task if necessary.
+     * This eventually results in a {@code onPostListReady} callback with {@code rebuildCompleted}
+     * true; if any asynchronous work is required, that will first be preceded by a separate
+     * occurrence of the callback with {@code rebuildCompleted} false (once there are placeholders
+     * set up to represent the pending asynchronous results).
+     * @return Whether we were able to do all the work to prepare the list for display
+     * synchronously; if false, there will eventually be two separate {@code onPostListReady}
+     * callbacks, first with placeholders to represent pending asynchronous results, then later when
+     * the results are ready for presentation.
+     */
+    boolean finishRebuildingListWithFilteredResults(
+            @Nullable List<ResolvedComponentInfo> filteredResolveList, boolean doPostProcessing) {
+        if (filteredResolveList == null || filteredResolveList.size() < 2) {
+            // No asynchronous work to do.
+            setPlaceholderCount(0);
+            processSortedList(filteredResolveList, doPostProcessing);
             return true;
         }
+
+        int placeholderCount = filteredResolveList.size();
+        if (mResolverListCommunicator.useLayoutWithDefault()) {
+            --placeholderCount;
+        }
+        setPlaceholderCount(placeholderCount);
+
+        // Send an "incomplete" list-ready while the async task is running.
+        postListReadyRunnable(doPostProcessing, /* rebuildCompleted */ false);
+        createSortingTask(doPostProcessing).execute(filteredResolveList);
+        return false;
     }
 
     AsyncTask<List<ResolvedComponentInfo>,
@@ -644,6 +735,59 @@
     }
 
     /**
+     * Find the first element in a list of {@code ResolvedComponentInfo} objects whose
+     * {@code ResolveInfo} specifies a {@code targetUserId} other than the current user.
+     * @return the first ResolvedComponentInfo targeting a non-current user, or null if there are
+     * none (or if the list itself is null).
+     */
+    private static ResolvedComponentInfo getFirstNonCurrentUserResolvedComponentInfo(
+            @Nullable List<ResolvedComponentInfo> resolveList) {
+        if (resolveList == null) {
+            return null;
+        }
+
+        for (ResolvedComponentInfo info : resolveList) {
+            ResolveInfo resolveInfo = info.getResolveInfoAt(0);
+            if (resolveInfo.targetUserId != UserHandle.USER_CURRENT) {
+                return info;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Set up a {@code DisplayResolveInfo} to provide "special treatment" for the first "other"
+     * profile in the resolve list (i.e., the first non-current profile to appear as the target user
+     * of an element in the resolve list).
+     */
+    private static DisplayResolveInfo makeOtherProfileDisplayResolveInfo(
+            Context context,
+            ResolvedComponentInfo resolvedComponentInfo,
+            PackageManager pm,
+            ResolverListCommunicator resolverListCommunicator,
+            int iconDpi) {
+        ResolveInfo resolveInfo = resolvedComponentInfo.getResolveInfoAt(0);
+
+        Intent pOrigIntent = resolverListCommunicator.getReplacementIntent(
+                resolveInfo.activityInfo,
+                resolvedComponentInfo.getIntentAt(0));
+        Intent replacementIntent = resolverListCommunicator.getReplacementIntent(
+                resolveInfo.activityInfo,
+                resolverListCommunicator.getTargetIntent());
+
+        ResolveInfoPresentationGetter presentationGetter =
+                new ResolveInfoPresentationGetter(context, iconDpi, resolveInfo);
+
+        return new DisplayResolveInfo(
+                resolvedComponentInfo.getIntentAt(0),
+                resolveInfo,
+                resolveInfo.loadLabel(pm),
+                resolveInfo.loadLabel(pm),
+                pOrigIntent != null ? pOrigIntent : replacementIntent,
+                presentationGetter);
+    }
+
+    /**
      * Necessary methods to communicate between {@link ResolverListAdapter}
      * and {@link ResolverActivity}.
      */
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 9a95e64..2757363 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -393,14 +393,6 @@
         return mResolverComparator.getScore(componentName);
     }
 
-    /**
-     * Returns the list of top K component names which have highest
-     * {@link #getScore(DisplayResolveInfo)}
-     */
-    public List<ComponentName> getTopComponentNames(int topK) {
-        return mResolverComparator.getTopComponentNames(topK);
-    }
-
     public void updateModel(ComponentName componentName) {
         mResolverComparator.updateModel(componentName);
     }
diff --git a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
index cb946c0..c5b21ac 100644
--- a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
@@ -43,12 +43,12 @@
 
 import java.text.Collator;
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 /**
  * Ranks and compares packages based on usage stats and uses the {@link ResolverRankerService}.
@@ -83,6 +83,7 @@
     private ResolverRankerServiceConnection mConnection;
     private Context mContext;
     private CountDownLatch mConnectSignal;
+    private ResolverRankerServiceComparatorModel mComparatorModel;
 
     public ResolverRankerServiceResolverComparator(Context context, Intent intent,
                 String referrerPackage, AfterCompute afterCompute,
@@ -99,6 +100,8 @@
         mRankerServiceName = new ComponentName(mContext, this.getClass());
         setCallBack(afterCompute);
         setChooserActivityLogger(chooserActivityLogger);
+
+        mComparatorModel = buildUpdatedModel();
     }
 
     @Override
@@ -125,6 +128,7 @@
             }
             if (isUpdated) {
                 mRankerServiceName = mResolvedRankerName;
+                mComparatorModel = buildUpdatedModel();
             }
         } else {
             Log.e(TAG, "Sizes of sent and received ResolverTargets diff.");
@@ -218,83 +222,25 @@
             }
         }
         predictSelectProbabilities(mTargets);
+
+        mComparatorModel = buildUpdatedModel();
     }
 
     @Override
     public int compare(ResolveInfo lhs, ResolveInfo rhs) {
-        if (mStats != null) {
-            final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
-                    lhs.activityInfo.packageName, lhs.activityInfo.name));
-            final ResolverTarget rhsTarget = mTargetsDict.get(new ComponentName(
-                    rhs.activityInfo.packageName, rhs.activityInfo.name));
-
-            if (lhsTarget != null && rhsTarget != null) {
-                final int selectProbabilityDiff = Float.compare(
-                        rhsTarget.getSelectProbability(), lhsTarget.getSelectProbability());
-
-                if (selectProbabilityDiff != 0) {
-                    return selectProbabilityDiff > 0 ? 1 : -1;
-                }
-            }
-        }
-
-        CharSequence  sa = lhs.loadLabel(mPm);
-        if (sa == null) sa = lhs.activityInfo.name;
-        CharSequence  sb = rhs.loadLabel(mPm);
-        if (sb == null) sb = rhs.activityInfo.name;
-
-        return mCollator.compare(sa.toString().trim(), sb.toString().trim());
+        return mComparatorModel.getComparator().compare(lhs, rhs);
     }
 
     @Override
     public float getScore(ComponentName name) {
-        final ResolverTarget target = mTargetsDict.get(name);
-        if (target != null) {
-            return target.getSelectProbability();
-        }
-        return 0;
-    }
-
-    @Override
-    List<ComponentName> getTopComponentNames(int topK) {
-        return mTargetsDict.entrySet().stream()
-                .sorted((o1, o2) -> -Float.compare(getScore(o1.getKey()), getScore(o2.getKey())))
-                .limit(topK)
-                .map(Map.Entry::getKey)
-                .collect(Collectors.toList());
+        return mComparatorModel.getScore(name);
     }
 
     // update ranking model when the connection to it is valid.
     @Override
     public void updateModel(ComponentName componentName) {
         synchronized (mLock) {
-            if (mRanker != null) {
-                try {
-                    int selectedPos = new ArrayList<ComponentName>(mTargetsDict.keySet())
-                            .indexOf(componentName);
-                    if (selectedPos >= 0 && mTargets != null) {
-                        final float selectedProbability = getScore(componentName);
-                        int order = 0;
-                        for (ResolverTarget target : mTargets) {
-                            if (target.getSelectProbability() > selectedProbability) {
-                                order++;
-                            }
-                        }
-                        logMetrics(order);
-                        mRanker.train(mTargets, selectedPos);
-                    } else {
-                        if (DEBUG) {
-                            Log.d(TAG, "Selected a unknown component: " + componentName);
-                        }
-                    }
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Error in Train: " + e);
-                }
-            } else {
-                if (DEBUG) {
-                    Log.d(TAG, "Ranker is null; skip updateModel.");
-                }
-            }
+            mComparatorModel.notifyOnTargetSelected(componentName);
         }
     }
 
@@ -313,19 +259,6 @@
         }
     }
 
-    // records metrics for evaluation.
-    private void logMetrics(int selectedPos) {
-        if (mRankerServiceName != null) {
-            MetricsLogger metricsLogger = new MetricsLogger();
-            LogMaker log = new LogMaker(MetricsEvent.ACTION_TARGET_SELECTED);
-            log.setComponentName(mRankerServiceName);
-            int isCategoryUsed = (mAnnotations == null) ? 0 : 1;
-            log.addTaggedData(MetricsEvent.FIELD_IS_CATEGORY_USED, isCategoryUsed);
-            log.addTaggedData(MetricsEvent.FIELD_RANKED_POSITION, selectedPos);
-            metricsLogger.write(log);
-        }
-    }
-
     // connect to a ranking service.
     private void initRanker(Context context) {
         synchronized (mLock) {
@@ -426,6 +359,7 @@
             }
             synchronized (mLock) {
                 mRanker = IResolverRankerService.Stub.asInterface(service);
+                mComparatorModel = buildUpdatedModel();
                 mConnectSignal.countDown();
             }
         }
@@ -443,6 +377,7 @@
         public void destroy() {
             synchronized (mLock) {
                 mRanker = null;
+                mComparatorModel = buildUpdatedModel();
             }
         }
     }
@@ -453,6 +388,7 @@
         mTargetsDict.clear();
         mTargets = null;
         mRankerServiceName = new ComponentName(mContext, this.getClass());
+        mComparatorModel = buildUpdatedModel();
         mResolvedRankerName = null;
         initRanker(mContext);
     }
@@ -508,4 +444,155 @@
         }
         return false;
     }
+
+    /**
+     * Re-construct a {@code ResolverRankerServiceComparatorModel} to replace the current model
+     * instance (if any) using the up-to-date {@code ResolverRankerServiceResolverComparator} ivar
+     * values.
+     *
+     * TODO: each time we replace the model instance, we're either updating the model to use
+     * adjusted data (which is appropriate), or we're providing a (late) value for one of our ivars
+     * that wasn't available the last time the model was updated. For those latter cases, we should
+     * just avoid creating the model altogether until we have all the prerequisites we'll need. Then
+     * we can probably simplify the logic in {@code ResolverRankerServiceComparatorModel} since we
+     * won't need to handle edge cases when the model data isn't fully prepared.
+     * (In some cases, these kinds of "updates" might interleave -- e.g., we might have finished
+     * initializing the first time and now want to adjust some data, but still need to wait for
+     * changes to propagate to the other ivars before rebuilding the model.)
+     */
+    private ResolverRankerServiceComparatorModel buildUpdatedModel() {
+        // TODO: we don't currently guarantee that the underlying target list/map won't be mutated,
+        // so the ResolverComparatorModel may provide inconsistent results. We should make immutable
+        // copies of the data (waiting for any necessary remaining data before creating the model).
+        return new ResolverRankerServiceComparatorModel(
+                mStats,
+                mTargetsDict,
+                mTargets,
+                mCollator,
+                mRanker,
+                mRankerServiceName,
+                (mAnnotations != null),
+                mPm);
+    }
+
+    /**
+     * Implementation of a {@code ResolverComparatorModel} that provides the same ranking logic as
+     * the legacy {@code ResolverRankerServiceResolverComparator}, as a refactoring step toward
+     * removing the complex legacy API.
+     */
+    static class ResolverRankerServiceComparatorModel implements ResolverComparatorModel {
+        private final Map<String, UsageStats> mStats;  // Treat as immutable.
+        private final Map<ComponentName, ResolverTarget> mTargetsDict;  // Treat as immutable.
+        private final List<ResolverTarget> mTargets;  // Treat as immutable.
+        private final Collator mCollator;
+        private final IResolverRankerService mRanker;
+        private final ComponentName mRankerServiceName;
+        private final boolean mAnnotationsUsed;
+        private final PackageManager mPm;
+
+        // TODO: it doesn't look like we should have to pass both targets and targetsDict, but it's
+        // not written in a way that makes it clear whether we can derive one from the other (at
+        // least in this constructor).
+        ResolverRankerServiceComparatorModel(
+                Map<String, UsageStats> stats,
+                Map<ComponentName, ResolverTarget> targetsDict,
+                List<ResolverTarget> targets,
+                Collator collator,
+                IResolverRankerService ranker,
+                ComponentName rankerServiceName,
+                boolean annotationsUsed,
+                PackageManager pm) {
+            mStats = stats;
+            mTargetsDict = targetsDict;
+            mTargets = targets;
+            mCollator = collator;
+            mRanker = ranker;
+            mRankerServiceName = rankerServiceName;
+            mAnnotationsUsed = annotationsUsed;
+            mPm = pm;
+        }
+
+        @Override
+        public Comparator<ResolveInfo> getComparator() {
+            // TODO: doCompute() doesn't seem to be concerned about null-checking mStats. Is that
+            // a bug there, or do we have a way of knowing it will be non-null under certain
+            // conditions?
+            return (lhs, rhs) -> {
+                if (mStats != null) {
+                    final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
+                            lhs.activityInfo.packageName, lhs.activityInfo.name));
+                    final ResolverTarget rhsTarget = mTargetsDict.get(new ComponentName(
+                            rhs.activityInfo.packageName, rhs.activityInfo.name));
+
+                    if (lhsTarget != null && rhsTarget != null) {
+                        final int selectProbabilityDiff = Float.compare(
+                                rhsTarget.getSelectProbability(), lhsTarget.getSelectProbability());
+
+                        if (selectProbabilityDiff != 0) {
+                            return selectProbabilityDiff > 0 ? 1 : -1;
+                        }
+                    }
+                }
+
+                CharSequence  sa = lhs.loadLabel(mPm);
+                if (sa == null) sa = lhs.activityInfo.name;
+                CharSequence  sb = rhs.loadLabel(mPm);
+                if (sb == null) sb = rhs.activityInfo.name;
+
+                return mCollator.compare(sa.toString().trim(), sb.toString().trim());
+            };
+        }
+
+        @Override
+        public float getScore(ComponentName name) {
+            final ResolverTarget target = mTargetsDict.get(name);
+            if (target != null) {
+                return target.getSelectProbability();
+            }
+            return 0;
+        }
+
+        @Override
+        public void notifyOnTargetSelected(ComponentName componentName) {
+            if (mRanker != null) {
+                try {
+                    int selectedPos = new ArrayList<ComponentName>(mTargetsDict.keySet())
+                            .indexOf(componentName);
+                    if (selectedPos >= 0 && mTargets != null) {
+                        final float selectedProbability = getScore(componentName);
+                        int order = 0;
+                        for (ResolverTarget target : mTargets) {
+                            if (target.getSelectProbability() > selectedProbability) {
+                                order++;
+                            }
+                        }
+                        logMetrics(order);
+                        mRanker.train(mTargets, selectedPos);
+                    } else {
+                        if (DEBUG) {
+                            Log.d(TAG, "Selected a unknown component: " + componentName);
+                        }
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error in Train: " + e);
+                }
+            } else {
+                if (DEBUG) {
+                    Log.d(TAG, "Ranker is null; skip updateModel.");
+                }
+            }
+        }
+
+        /** Records metrics for evaluation. */
+        private void logMetrics(int selectedPos) {
+            if (mRankerServiceName != null) {
+                MetricsLogger metricsLogger = new MetricsLogger();
+                LogMaker log = new LogMaker(MetricsEvent.ACTION_TARGET_SELECTED);
+                log.setComponentName(mRankerServiceName);
+                log.addTaggedData(MetricsEvent.FIELD_IS_CATEGORY_USED, mAnnotationsUsed);
+                log.addTaggedData(MetricsEvent.FIELD_RANKED_POSITION, selectedPos);
+                metricsLogger.write(log);
+            }
+        }
+    }
 }
diff --git a/core/java/com/android/internal/app/SimpleIconFactory.java b/core/java/com/android/internal/app/SimpleIconFactory.java
index 43dacd7..354eb62 100644
--- a/core/java/com/android/internal/app/SimpleIconFactory.java
+++ b/core/java/com/android/internal/app/SimpleIconFactory.java
@@ -71,7 +71,7 @@
             new SynchronizedPool<>(Runtime.getRuntime().availableProcessors());
 
     private static final int DEFAULT_WRAPPER_BACKGROUND = Color.WHITE;
-    private static final float BLUR_FACTOR = 0.5f / 48;
+    private static final float BLUR_FACTOR = 1.5f / 48;
 
     private Context mContext;
     private Canvas mCanvas;
@@ -650,8 +650,8 @@
     /* Shadow generator block */
 
     private static final float KEY_SHADOW_DISTANCE = 1f / 48;
-    private static final int KEY_SHADOW_ALPHA = 61;
-    private static final int AMBIENT_SHADOW_ALPHA = 30;
+    private static final int KEY_SHADOW_ALPHA = 10;
+    private static final int AMBIENT_SHADOW_ALPHA = 7;
 
     private Paint mBlurPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
     private Paint mDrawPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 8847a49..5541558 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -47,6 +47,7 @@
      * @param appInfo  representing the affected app
      * @throws SecurityException if logging is not allowed
      */
+    @EnforcePermission("LOG_COMPAT_CHANGE")
     void reportChange(long changeId, in ApplicationInfo appInfo);
 
     /**
@@ -60,6 +61,7 @@
      * @param packageName the package name of the app in question
      * @throws SecurityException if logging is not allowed
      */
+    @EnforcePermission("LOG_COMPAT_CHANGE")
     void reportChangeByPackageName(long changeId, in String packageName, int userId);
 
     /**
@@ -72,6 +74,7 @@
      * @param uid      the UID of the app in question
      * @throws SecurityException if logging is not allowed
      */
+    @EnforcePermission("LOG_COMPAT_CHANGE")
     void reportChangeByUid(long changeId, int uid);
 
     /**
@@ -90,6 +93,7 @@
      * @return {@code true} if the change is enabled for the current app
      * @throws SecurityException if logging or reading compat confis is not allowed
      */
+    @EnforcePermission(allOf={"LOG_COMPAT_CHANGE", "READ_COMPAT_CHANGE_CONFIG"})
     boolean isChangeEnabled(long changeId, in ApplicationInfo appInfo);
 
     /**
@@ -115,6 +119,7 @@
      * @return {@code true} if the change is enabled for the current app
      * @throws SecurityException if logging or reading compat confis is not allowed
      */
+    @EnforcePermission(allOf={"LOG_COMPAT_CHANGE", "READ_COMPAT_CHANGE_CONFIG"})
     boolean isChangeEnabledByPackageName(long changeId, in String packageName, int userId);
 
     /**
@@ -140,6 +145,7 @@
      * @return {@code true} if the change is enabled for the current app
      * @throws SecurityException if logging or reading compat confis is not allowed
      */
+    @EnforcePermission(allOf={"LOG_COMPAT_CHANGE", "READ_COMPAT_CHANGE_CONFIG"})
     boolean isChangeEnabledByUid(long changeId, int uid);
 
     /**
@@ -151,6 +157,7 @@
      * @param packageName the package name of the app whose changes will be overridden
      * @throws SecurityException if overriding changes is not permitted
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
     void setOverrides(in CompatibilityChangeConfig overrides, in String packageName);
 
     /**
@@ -171,6 +178,7 @@
      *                           on specific apps by their package name
      * @throws SecurityException if overriding changes is not permitted
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD")
     void putAllOverridesOnReleaseBuilds(in CompatibilityOverridesByPackageConfig overridesByPackage);
 
     /**
@@ -190,6 +198,7 @@
      * @param packageName the package name of the app whose changes will be overridden
      * @throws SecurityException if overriding changes is not permitted
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD")
     void putOverridesOnReleaseBuilds(in CompatibilityOverrideConfig overrides, in String packageName);
 
     /**
@@ -201,6 +210,7 @@
      * @param packageName the package name of the app whose changes will be overridden
      * @throws SecurityException if overriding changes is not permitted.
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
     void setOverridesForTest(in CompatibilityChangeConfig overrides, in String packageName);
 
     /**
@@ -213,6 +223,7 @@
      * @return {@code true} if an override existed
      * @throws SecurityException if overriding changes is not permitted
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
     boolean clearOverride(long changeId, String packageName);
 
     /**
@@ -225,6 +236,7 @@
      * @return {@code true} if an override existed
      * @throws SecurityException if overriding changes is not permitted
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
     boolean clearOverrideForTest(long changeId, String packageName);
 
     /**
@@ -245,6 +257,7 @@
      *                                   removed for specific apps by their package name
      * @throws SecurityException if overriding changes is not permitted
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD")
     void removeAllOverridesOnReleaseBuilds(in CompatibilityOverridesToRemoveByPackageConfig overridesToRemoveByPackage);
 
     /**
@@ -266,6 +279,7 @@
      *                            default behaviour
      * @throws SecurityException if overriding changes is not permitted
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD")
     void removeOverridesOnReleaseBuilds(in CompatibilityOverridesToRemoveConfig overridesToRemove, in String packageName);
 
     /**
@@ -280,6 +294,7 @@
      * @return The number of changes that were enabled.
      * @throws SecurityException if overriding changes is not permitted.
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
     int enableTargetSdkChanges(in String packageName, int targetSdkVersion);
 
     /**
@@ -294,6 +309,7 @@
      * @return the number of changes that were disabled
      * @throws SecurityException if overriding changes is not permitted.
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
     int disableTargetSdkChanges(in String packageName, int targetSdkVersion);
 
     /**
@@ -304,6 +320,7 @@
      * @param packageName the package name of the app whose overrides will be cleared
      * @throws SecurityException if overriding changes is not permitted
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
     void clearOverrides(in String packageName);
 
     /**
@@ -314,6 +331,7 @@
      * @param packageName the package name of the app whose overrides will be cleared
      * @throws SecurityException if overriding changes is not permitted
      */
+    @EnforcePermission("OVERRIDE_COMPAT_CHANGE_CONFIG")
     void clearOverridesForTest(in String packageName);
 
     /**
@@ -323,6 +341,7 @@
      * @return a {@link CompatibilityChangeConfig}, representing whether a change is enabled for
      * the given app or not
      */
+    @EnforcePermission(allOf={"LOG_COMPAT_CHANGE", "READ_COMPAT_CHANGE_CONFIG"})
     CompatibilityChangeConfig getAppConfig(in ApplicationInfo appInfo);
 
     /**
@@ -330,6 +349,7 @@
      *
      * @return an array of {@link CompatibilityChangeInfo} known to the service
      */
+    @EnforcePermission("READ_COMPAT_CHANGE_CONFIG")
     CompatibilityChangeInfo[] listAllChanges();
 
     /**
@@ -338,10 +358,12 @@
      *
      * @return an array of {@link CompatibilityChangeInfo}
      */
+    @RequiresNoPermission
     CompatibilityChangeInfo[] listUIChanges();
 
     /**
      * Gets an instance that can determine whether a changeid can be overridden for a package name.
      */
+    @RequiresNoPermission
     IOverrideValidator getOverrideValidator();
 }
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index c94438e..ffb3752 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -520,6 +520,13 @@
     public static final String USE_UNBUNDLED_SHARESHEET = "use_unbundled_sharesheet";
 
     /**
+     * (int) The delay (in ms) before refreshing the Sharesheet UI after a change to the share
+     * target data model. For more info see go/sharesheet-list-view-update-delay.
+     */
+    public static final String SHARESHEET_LIST_VIEW_UPDATE_DELAY =
+            "sharesheet_list_view_update_delay";
+
+    /**
      * (string) Name of the default QR code scanner activity. On the eligible devices this activity
      * is provided by GMS core.
      */
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index a60b310..73a4f1c 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -62,7 +62,9 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Deque;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
@@ -232,9 +234,9 @@
             throw new FileNotFoundException(doc + " is not found under " + parent);
         }
 
-        LinkedList<String> path = new LinkedList<>();
+        List<String> path = new ArrayList<>();
         while (doc != null && FileUtils.contains(parent, doc)) {
-            path.addFirst(getDocIdForFile(doc));
+            path.add(0, getDocIdForFile(doc));
 
             doc = doc.getParentFile();
         }
@@ -448,10 +450,10 @@
             File folder, String[] projection, Set<String> exclusion, Bundle queryArgs)
             throws FileNotFoundException {
         final MatrixCursor result = new MatrixCursor(resolveProjection(projection));
-        final LinkedList<File> pending = new LinkedList<>();
+        final List<File> pending = new ArrayList<>();
         pending.add(folder);
         while (!pending.isEmpty() && result.getCount() < 24) {
-            final File file = pending.removeFirst();
+            final File file = pending.remove(0);
             if (shouldHide(file)) continue;
 
             if (file.isDirectory()) {
diff --git a/core/java/com/android/internal/content/om/OverlayConfig.java b/core/java/com/android/internal/content/om/OverlayConfig.java
index b786526..828e5cf 100644
--- a/core/java/com/android/internal/content/om/OverlayConfig.java
+++ b/core/java/com/android/internal/content/om/OverlayConfig.java
@@ -183,7 +183,7 @@
                 final ParsedOverlayInfo p = partitionOverlayInfos.get(j);
                 if (p.isStatic) {
                     partitionConfigs.add(new ParsedConfiguration(p.packageName,
-                            true /* enabled */, false /* mutable */, partition.policy, p));
+                            true /* enabled */, false /* mutable */, partition.policy, p, null));
                 }
             }
 
diff --git a/core/java/com/android/internal/content/om/OverlayConfigParser.java b/core/java/com/android/internal/content/om/OverlayConfigParser.java
index 0ab7b3d..5ab77d8 100644
--- a/core/java/com/android/internal/content/om/OverlayConfigParser.java
+++ b/core/java/com/android/internal/content/om/OverlayConfigParser.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.content.pm.PackagePartitions;
 import android.content.pm.PackagePartitions.SystemPartition;
+import android.os.Build;
 import android.os.FileUtils;
 import android.util.ArraySet;
 import android.util.Log;
@@ -56,6 +57,34 @@
  **/
 final class OverlayConfigParser {
 
+    /** Represents a part of a parsed overlay configuration XML file. */
+    public static class ParsedConfigFile {
+        @NonNull public final String path;
+        @NonNull public final int line;
+        @Nullable public final String xml;
+
+        ParsedConfigFile(@NonNull String path, int line, @Nullable String xml) {
+            this.path = path;
+            this.line = line;
+            this.xml = xml;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder(getClass().getSimpleName());
+            sb.append("{path=");
+            sb.append(path);
+            sb.append(", line=");
+            sb.append(line);
+            if (xml != null) {
+                sb.append(", xml=");
+                sb.append(xml);
+            }
+            sb.append("}");
+            return sb.toString();
+        }
+    }
+
     // Default values for overlay configurations.
     static final boolean DEFAULT_ENABLED_STATE = false;
     static final boolean DEFAULT_MUTABILITY = true;
@@ -94,24 +123,40 @@
         @NonNull
         public final String policy;
 
-        /** Information extracted from the manifest of the overlay. */
-        @NonNull
+        /**
+         * Information extracted from the manifest of the overlay.
+         * Null if the information was read from a config file instead of a manifest.
+         *
+         * @see parsedConfigFile
+         **/
+        @Nullable
         public final ParsedOverlayInfo parsedInfo;
 
+        /**
+         * The config file used to configure this overlay.
+         * Null if no config file was used, in which case the overlay's manifest was used instead.
+         *
+         * @see parsedInfo
+         **/
+        @Nullable
+        public final ParsedConfigFile parsedConfigFile;
+
         ParsedConfiguration(@NonNull String packageName, boolean enabled, boolean mutable,
-                @NonNull String policy, @NonNull ParsedOverlayInfo parsedInfo) {
+                @NonNull String policy, @Nullable ParsedOverlayInfo parsedInfo,
+                @Nullable ParsedConfigFile parsedConfigFile) {
             this.packageName = packageName;
             this.enabled = enabled;
             this.mutable = mutable;
             this.policy = policy;
             this.parsedInfo = parsedInfo;
+            this.parsedConfigFile = parsedConfigFile;
         }
 
         @Override
         public String toString() {
             return getClass().getSimpleName() + String.format("{packageName=%s, enabled=%s"
-                            + ", mutable=%s, policy=%s, parsedInfo=%s}", packageName, enabled,
-                    mutable, policy, parsedInfo);
+                            + ", mutable=%s, policy=%s, parsedInfo=%s, parsedConfigFile=%s}",
+                    packageName, enabled, mutable, policy, parsedInfo, parsedConfigFile);
         }
     }
 
@@ -417,9 +462,26 @@
             Log.w(TAG, "found default-disabled immutable overlay " + packageName);
         }
 
-        final ParsedConfiguration Config = new ParsedConfiguration(packageName, isEnabled,
-                isMutable, parsingContext.mPartition.policy, info);
+        final ParsedConfigFile parsedConfigFile = new ParsedConfigFile(
+                configFile.getPath().intern(), parser.getLineNumber(),
+                (Build.IS_ENG || Build.IS_USERDEBUG) ? currentParserContextToString(parser) : null);
+        final ParsedConfiguration config = new ParsedConfiguration(packageName, isEnabled,
+                isMutable, parsingContext.mPartition.policy, info, parsedConfigFile);
         parsingContext.mConfiguredOverlays.add(packageName);
-        parsingContext.mOrderedConfigurations.add(Config);
+        parsingContext.mOrderedConfigurations.add(config);
+    }
+
+    private static String currentParserContextToString(@NonNull XmlPullParser parser) {
+        StringBuilder sb = new StringBuilder("<");
+        sb.append(parser.getName());
+        sb.append(" ");
+        for (int i = 0; i < parser.getAttributeCount(); i++) {
+            sb.append(parser.getAttributeName(i));
+            sb.append("=\"");
+            sb.append(parser.getAttributeValue(i));
+            sb.append("\" ");
+        }
+        sb.append("/>");
+        return sb.toString();
     }
 }
diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
index 2ee47b6..4babb70 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
@@ -34,7 +34,7 @@
     void setInputMethod(String id, in AndroidFuture future /* T=Void */);
     void setInputMethodAndSubtype(String id, in InputMethodSubtype subtype,
             in AndroidFuture future /* T=Void */);
-    void hideMySoftInput(int flags, in AndroidFuture future /* T=Void */);
+    void hideMySoftInput(int flags, int reason, in AndroidFuture future /* T=Void */);
     void showMySoftInput(int flags, in AndroidFuture future /* T=Void */);
     void updateStatusIconAsync(String packageName, int iconId);
     void switchToPreviousInputMethod(in AndroidFuture future /* T=Boolean */);
diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
index d669768..97ad084 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodDebug.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
@@ -194,12 +194,12 @@
                 return "SHOW_SOFT_INPUT";
             case SoftInputShowHideReason.ATTACH_NEW_INPUT:
                 return "ATTACH_NEW_INPUT";
-            case SoftInputShowHideReason.SHOW_MY_SOFT_INPUT:
-                return "SHOW_MY_SOFT_INPUT";
+            case SoftInputShowHideReason.SHOW_SOFT_INPUT_FROM_IME:
+                return "SHOW_SOFT_INPUT_FROM_IME";
             case SoftInputShowHideReason.HIDE_SOFT_INPUT:
                 return "HIDE_SOFT_INPUT";
-            case SoftInputShowHideReason.HIDE_MY_SOFT_INPUT:
-                return "HIDE_MY_SOFT_INPUT";
+            case SoftInputShowHideReason.HIDE_SOFT_INPUT_FROM_IME:
+                return "HIDE_SOFT_INPUT_FROM_IME";
             case SoftInputShowHideReason.SHOW_AUTO_EDITOR_FORWARD_NAV:
                 return "SHOW_AUTO_EDITOR_FORWARD_NAV";
             case SoftInputShowHideReason.SHOW_STATE_VISIBLE_FORWARD_NAV:
@@ -242,6 +242,16 @@
                 return "SHOW_SOFT_INPUT_BY_INSETS_API";
             case SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE:
                 return "HIDE_DISPLAY_IME_POLICY_HIDE";
+            case SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API:
+                return "HIDE_SOFT_INPUT_BY_INSETS_API";
+            case SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_BACK_KEY:
+                return "HIDE_SOFT_INPUT_BY_BACK_KEY";
+            case SoftInputShowHideReason.HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT:
+                return "HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT";
+            case SoftInputShowHideReason.HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED:
+                return "HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED";
+            case SoftInputShowHideReason.HIDE_SOFT_INPUT_IMM_DEPRECATION:
+                return "HIDE_SOFT_INPUT_IMM_DEPRECATION";
             default:
                 return "Unknown=" + reason;
         }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index 15d7acf..67c2103 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -253,18 +253,19 @@
      * Calls {@link IInputMethodPrivilegedOperations#hideMySoftInput(int, IVoidResultCallback)}
      *
      * @param flags additional operating flags
+     * @param reason the reason to hide soft input
      * @see android.view.inputmethod.InputMethodManager#HIDE_IMPLICIT_ONLY
      * @see android.view.inputmethod.InputMethodManager#HIDE_NOT_ALWAYS
      */
     @AnyThread
-    public void hideMySoftInput(int flags) {
+    public void hideMySoftInput(int flags, @SoftInputShowHideReason int reason) {
         final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
         if (ops == null) {
             return;
         }
         try {
             final AndroidFuture<Void> future = new AndroidFuture<>();
-            ops.hideMySoftInput(flags, future);
+            ops.hideMySoftInput(flags, reason, future);
             CompletableFutureUtil.getResult(future);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
diff --git a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
index 9e57762..97ad5cb 100644
--- a/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
+++ b/core/java/com/android/internal/inputmethod/SoftInputShowHideReason.java
@@ -19,8 +19,11 @@
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.annotation.IntDef;
+import android.os.IBinder;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
 
 import java.lang.annotation.Retention;
 
@@ -31,9 +34,9 @@
 @IntDef(value = {
         SoftInputShowHideReason.SHOW_SOFT_INPUT,
         SoftInputShowHideReason.ATTACH_NEW_INPUT,
-        SoftInputShowHideReason.SHOW_MY_SOFT_INPUT,
+        SoftInputShowHideReason.SHOW_SOFT_INPUT_FROM_IME,
         SoftInputShowHideReason.HIDE_SOFT_INPUT,
-        SoftInputShowHideReason.HIDE_MY_SOFT_INPUT,
+        SoftInputShowHideReason.HIDE_SOFT_INPUT_FROM_IME,
         SoftInputShowHideReason.SHOW_AUTO_EDITOR_FORWARD_NAV,
         SoftInputShowHideReason.SHOW_STATE_VISIBLE_FORWARD_NAV,
         SoftInputShowHideReason.SHOW_STATE_ALWAYS_VISIBLE,
@@ -55,7 +58,12 @@
         SoftInputShowHideReason.SHOW_TOGGLE_SOFT_INPUT,
         SoftInputShowHideReason.HIDE_TOGGLE_SOFT_INPUT,
         SoftInputShowHideReason.SHOW_SOFT_INPUT_BY_INSETS_API,
-        SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE})
+        SoftInputShowHideReason.HIDE_DISPLAY_IME_POLICY_HIDE,
+        SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_INSETS_API,
+        SoftInputShowHideReason.HIDE_SOFT_INPUT_BY_BACK_KEY,
+        SoftInputShowHideReason.HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT,
+        SoftInputShowHideReason.HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED,
+        SoftInputShowHideReason.HIDE_SOFT_INPUT_IMM_DEPRECATION})
 public @interface SoftInputShowHideReason {
     /** Show soft input by {@link android.view.inputmethod.InputMethodManager#showSoftInput}. */
     int SHOW_SOFT_INPUT = 0;
@@ -63,8 +71,12 @@
     /** Show soft input when {@code InputMethodManagerService#attachNewInputLocked} called. */
     int ATTACH_NEW_INPUT = 1;
 
-    /** Show soft input by {@code InputMethodManagerService#showMySoftInput}. */
-    int SHOW_MY_SOFT_INPUT = 2;
+    /** Show soft input by {@code InputMethodManagerService#showMySoftInput}. This is triggered when
+     *  the IME process try to show the keyboard.
+     *
+     * @see android.inputmethodservice.InputMethodService#requestShowSelf(int)
+     */
+    int SHOW_SOFT_INPUT_FROM_IME = 2;
 
     /**
      * Hide soft input by
@@ -72,8 +84,11 @@
      */
     int HIDE_SOFT_INPUT = 3;
 
-    /** Hide soft input by {@code InputMethodManagerService#hideMySoftInput}. */
-    int HIDE_MY_SOFT_INPUT = 4;
+    /**
+     * Hide soft input by
+     * {@link android.inputmethodservice.InputMethodService#requestHideSelf(int)}.
+     */
+    int HIDE_SOFT_INPUT_FROM_IME = 4;
 
     /**
      * Show soft input when navigated forward to the window (with
@@ -203,4 +218,32 @@
      * See also {@code InputMethodManagerService#mImeHiddenByDisplayPolicy}.
      */
     int HIDE_DISPLAY_IME_POLICY_HIDE = 26;
+
+    /**
+     * Hide soft input by {@link android.view.InsetsController#hide(int)}.
+     */
+    int HIDE_SOFT_INPUT_BY_INSETS_API = 27;
+
+    /**
+     * Hide soft input by {@link android.inputmethodservice.InputMethodService#handleBack(boolean)}.
+     */
+    int HIDE_SOFT_INPUT_BY_BACK_KEY = 28;
+
+    /**
+     * Hide soft input by
+     * {@link android.inputmethodservice.InputMethodService#onToggleSoftInput(int, int)}.
+     */
+    int HIDE_SOFT_INPUT_IME_TOGGLE_SOFT_INPUT = 29;
+
+    /**
+     * Hide soft input by
+     * {@link android.inputmethodservice.InputMethodService#onExtractingInputChanged(EditorInfo)})}.
+     */
+    int HIDE_SOFT_INPUT_EXTRACT_INPUT_CHANGED = 30;
+
+    /**
+     * Hide soft input by the deprecated
+     * {@link InputMethodManager#hideSoftInputFromInputMethod(IBinder, int)}.
+     */
+    int HIDE_SOFT_INPUT_IMM_DEPRECATION = 31;
 }
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 488fb180..12571b1 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -912,6 +912,12 @@
             }
         }
 
+        if (!st.hasPanelItems()) {
+            // Ensure that |st.decorView| has its actual content. Otherwise, an empty window can be
+            // created and cause ANR.
+            return;
+        }
+
         st.isHandled = false;
 
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
diff --git a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
index bf3e8d5..a0f7905 100644
--- a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
@@ -1,11 +1,5 @@
 package com.android.internal.view.menu;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
 import android.annotation.AttrRes;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -22,16 +16,16 @@
 import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewTreeObserver;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.View.OnKeyListener;
+import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.widget.AbsListView;
 import android.widget.FrameLayout;
 import android.widget.HeaderViewListAdapter;
 import android.widget.ListAdapter;
-import android.widget.MenuItemHoverListener;
 import android.widget.ListView;
+import android.widget.MenuItemHoverListener;
 import android.widget.MenuPopupWindow;
 import android.widget.PopupWindow;
 import android.widget.PopupWindow.OnDismissListener;
@@ -40,6 +34,11 @@
 import com.android.internal.R;
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * A popup for a menu which will allow multiple submenus to appear in a cascading fashion, side by
  * side.
@@ -70,7 +69,7 @@
     private final Handler mSubMenuHoverHandler;
 
     /** List of menus that were added before this popup was shown. */
-    private final List<MenuBuilder> mPendingMenus = new LinkedList<>();
+    private final List<MenuBuilder> mPendingMenus = new ArrayList<>();
 
     /**
      * List of open menus. The first item is the root menu and each
diff --git a/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java b/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java
index 481183e..c1e2840 100644
--- a/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java
+++ b/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java
@@ -23,6 +23,7 @@
 import android.widget.LinearLayout;
 import android.widget.RemoteViews;
 
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -96,7 +97,7 @@
                 continue;
             }
             if (visibleChildrenToShorten == null) {
-                visibleChildrenToShorten = new LinkedList<>();
+                visibleChildrenToShorten = new ArrayList<>(count);
             }
             visibleChildrenToShorten.add(new ViewInfo(child));
             remainingWeight += Math.max(0, weight);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index a94b307..6771cdf 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -39,7 +39,6 @@
 import android.content.pm.UserInfo;
 import android.os.Build;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
@@ -47,7 +46,6 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.text.TextUtils;
diff --git a/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
index 8c61a12..95a4e12 100644
--- a/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
+++ b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
@@ -61,10 +61,10 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -950,9 +950,9 @@
 
         int availableWidth = toolbarWidth;
 
-        final LinkedList<MenuItem> remainingMenuItems = new LinkedList<>();
+        final ArrayList<MenuItem> remainingMenuItems = new ArrayList<>();
         // add the overflow menu items to the end of the remainingMenuItems list.
-        final LinkedList<MenuItem> overflowMenuItems = new LinkedList();
+        final ArrayList<MenuItem> overflowMenuItems = new ArrayList<>();
         for (MenuItem menuItem : menuItems) {
             if (menuItem.getItemId() != android.R.id.textAssist
                     && menuItem.requiresOverflow()) {
@@ -969,7 +969,7 @@
         int lastGroupId = -1;
         boolean isFirstItem = true;
         while (!remainingMenuItems.isEmpty()) {
-            final MenuItem menuItem = remainingMenuItems.peek();
+            final MenuItem menuItem = remainingMenuItems.get(0);
 
             // if this is the first item, regardless of requiresOverflow(), it should be
             // displayed on the main panel. Otherwise all items including this one will be
@@ -1022,7 +1022,7 @@
                 params.width = menuItemButtonWidth;
                 menuItemButton.setLayoutParams(params);
                 availableWidth -= menuItemButtonWidth;
-                remainingMenuItems.pop();
+                remainingMenuItems.remove(0);
             } else {
                 break;
             }
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 518fc09..4d8ca1b 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -1950,8 +1950,10 @@
                                         jlong frameTimelineVsyncId) {
     auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
 
-    transaction->setFrameTimelineInfo(
-            {frameTimelineVsyncId, android::os::IInputConstants::INVALID_INPUT_EVENT_ID});
+    FrameTimelineInfo ftInfo;
+    ftInfo.vsyncId = frameTimelineVsyncId;
+    ftInfo.inputEventId = android::os::IInputConstants::INVALID_INPUT_EVENT_ID;
+    transaction->setFrameTimelineInfo(ftInfo);
 }
 
 static void nativeAddTransactionCommittedListener(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -2036,7 +2038,7 @@
 }
 
 static jint nativeGetGPUContextPriority(JNIEnv* env, jclass clazz) {
-    return static_cast<jint>(SurfaceComposerClient::getGPUContextPriority());
+    return static_cast<jint>(SurfaceComposerClient::getGpuContextPriority());
 }
 
 static void nativeSetTransformHint(JNIEnv* env, jclass clazz, jlong nativeSurfaceControl,
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index a4463e4..9070933 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -16,6 +16,7 @@
 per-file package_item_info.proto = toddke@google.com,patb@google.com
 per-file usagestatsservice.proto, usagestatsservice_v2.proto = file:/core/java/android/app/usage/OWNERS
 per-file apphibernationservice.proto = file:/core/java/android/apphibernation/OWNERS
+per-file android/hardware/sensorprivacy.proto = ntmyren@google.com,evanseverson@google.com,ewol@google.com
 
 # Biometrics
 jaggies@google.com
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4075c5f..fc7b634 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2278,7 +2278,8 @@
         android:protectionLevel="signature|role" />
 
     <!-- Allows bluetooth stack to access files
-         @hide This should only be used by Bluetooth apk.
+         This should only be granted to the Bluetooth apk.
+         @hide @SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES)
     -->
     <permission android:name="android.permission.BLUETOOTH_STACK"
         android:protectionLevel="signature|role" />
@@ -3735,12 +3736,6 @@
     <permission android:name="android.permission.BIND_ATTESTATION_VERIFICATION_SERVICE"
                 android:protectionLevel="signature" />
 
-    <!-- Allows the caller to generate keymint keys with the INCLUDE_UNIQUE_ID tag, which
-         uniquely identifies the device via the attestation certificate.
-         @hide @TestApi -->
-    <permission android:name="android.permission.REQUEST_UNIQUE_ID_ATTESTATION"
-         android:protectionLevel="signature" />
-
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
     <!-- ========================================= -->
@@ -4407,13 +4402,13 @@
     <permission android:name="android.permission.TUNER_RESOURCE_ACCESS"
          android:protectionLevel="signature|privileged|vendorPrivileged" />
 
-    <!-- This permission is required by Media Resource Manager Service when
-         accessing its overridePid Api.
-         <p>Protection level: signature
+    <!-- @SystemApi This permission is required by Media Resource Manager Service when
+         system services create MediaCodecs on behalf of other processes and apps.
+         <p>Protection level: signature|privileged|vendorPrivileged
          <p>Not for use by third-party applications.
          @hide -->
     <permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID"
-         android:protectionLevel="signature" />
+         android:protectionLevel="signature|privileged|vendorPrivileged" />
     <uses-permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID" />
 
     <!-- This permission is required by Media Resource Observer Service when
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 35bed2d..30fb45e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3736,6 +3736,9 @@
          "Guest" and "Reset guest". -->
     <bool name="config_guestUserAutoCreated">false</bool>
 
+    <!-- If true, owner can change guest user ephemeral state via UI option -->
+    <bool name="config_guestUserAllowEphemeralStateChange">true</bool>
+
     <!-- Enforce strong auth on boot. Setting this to false represents a security risk and should
          not be ordinarily done. The only case in which this might be permissible is in a car head
          unit where there are hardware mechanisms to protect the device (physical keys) and not
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f177226..61ca18c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -393,6 +393,7 @@
   <java-symbol type="bool" name="config_supportsInsecureLockScreen" />
   <java-symbol type="bool" name="config_guestUserEphemeral" />
   <java-symbol type="bool" name="config_guestUserAutoCreated" />
+  <java-symbol type="bool" name="config_guestUserAllowEphemeralStateChange" />
   <java-symbol type="bool" name="config_localDisplaysMirrorContent" />
   <java-symbol type="array" name="config_localPrivateDisplayPorts" />
   <java-symbol type="integer" name="config_defaultDisplayDefaultColorMode" />
diff --git a/core/res/res/xml-watch/default_zen_mode_config.xml b/core/res/res/xml-watch/default_zen_mode_config.xml
deleted file mode 100644
index 938cc0c..0000000
--- a/core/res/res/xml-watch/default_zen_mode_config.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright 2016, The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<!-- Default configuration for zen mode.  See android.service.notification.ZenModeConfig. -->
-<zen version="2">
-    <!-- Allow starred contacts to go through only.
-    Repeated calls, calls, messages, reminders, events off. -->
-    <allow from="2" repeatCallers="false" calls="false" messages="false" reminders="false"
-           events="false"/>
-</zen>
diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java
index e083b0d..3733bfa 100644
--- a/core/tests/coretests/src/android/net/UriTest.java
+++ b/core/tests/coretests/src/android/net/UriTest.java
@@ -48,6 +48,7 @@
     public void testParcelling() {
         parcelAndUnparcel(Uri.parse("foo:bob%20lee"));
         parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment"));
+        parcelAndUnparcel(Uri.fromParts("https", "www.google.com", null));
         parcelAndUnparcel(new Uri.Builder()
             .scheme("http")
             .authority("crazybob.org")
@@ -890,9 +891,62 @@
             Throwable targetException = expected.getTargetException();
             // Check that the exception was thrown for the correct reason.
             assertEquals("Unknown representation: 0", targetException.getMessage());
+        } finally {
+            parcel.recycle();
         }
     }
 
+    private Uri buildUriFromRawParcel(boolean argumentsEncoded,
+                                      String scheme,
+                                      String authority,
+                                      String path,
+                                      String query,
+                                      String fragment) {
+        // Representation value (from AbstractPart.REPRESENTATION_{ENCODED,DECODED}).
+        final int representation = argumentsEncoded ? 1 : 2;
+        Parcel parcel = Parcel.obtain();
+        try {
+            parcel.writeInt(3);  // hierarchical
+            parcel.writeString8(scheme);
+            parcel.writeInt(representation);
+            parcel.writeString8(authority);
+            parcel.writeInt(representation);
+            parcel.writeString8(path);
+            parcel.writeInt(representation);
+            parcel.writeString8(query);
+            parcel.writeInt(representation);
+            parcel.writeString8(fragment);
+            parcel.setDataPosition(0);
+            return Uri.CREATOR.createFromParcel(parcel);
+        } finally {
+            parcel.recycle();
+        }
+    }
+
+    public void testUnparcelMalformedPath() {
+        // Regression tests for b/171966843.
+
+        // Test cases with arguments encoded (covering testing `scheme` * `authority` options).
+        Uri uri0 = buildUriFromRawParcel(true, "https", "google.com", "@evil.com", null, null);
+        assertEquals("https://google.com/@evil.com", uri0.toString());
+        Uri uri1 = buildUriFromRawParcel(true, null, "google.com", "@evil.com", "name=spark", "x");
+        assertEquals("//google.com/@evil.com?name=spark#x", uri1.toString());
+        Uri uri2 = buildUriFromRawParcel(true, "http:", null, "@evil.com", null, null);
+        assertEquals("http::/@evil.com", uri2.toString());
+        Uri uri3 = buildUriFromRawParcel(true, null, null, "@evil.com", null, null);
+        assertEquals("@evil.com", uri3.toString());
+
+        // Test cases with arguments not encoded (covering testing `scheme` * `authority` options).
+        Uri uriA = buildUriFromRawParcel(false, "https", "google.com", "@evil.com", null, null);
+        assertEquals("https://google.com/%40evil.com", uriA.toString());
+        Uri uriB = buildUriFromRawParcel(false, null, "google.com", "@evil.com", null, null);
+        assertEquals("//google.com/%40evil.com", uriB.toString());
+        Uri uriC = buildUriFromRawParcel(false, "http:", null, "@evil.com", null, null);
+        assertEquals("http::/%40evil.com", uriC.toString());
+        Uri uriD = buildUriFromRawParcel(false, null, null, "@evil.com", "name=spark", "y");
+        assertEquals("%40evil.com?name%3Dspark#y", uriD.toString());
+    }
+
     public void testToSafeString() {
         checkToSafeString("tel:xxxxxx", "tel:Google");
         checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890");
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTest.java b/core/tests/coretests/src/android/text/StaticLayoutTest.java
index 0ebf03f..925da49 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutTest.java
@@ -24,6 +24,7 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Paint.FontMetricsInt;
+import android.graphics.text.LineBreakConfig;
 import android.os.LocaleList;
 import android.platform.test.annotations.Presubmit;
 import android.text.Layout.Alignment;
@@ -925,4 +926,24 @@
         assertEquals(0, layout.getHeight(true));
         assertEquals(2, layout.getLineCount());
     }
+
+    @Test
+    public void testBuilder_autoPhraseBreaking() {
+        {
+            // setAutoPhraseBreaking true
+            LineBreakConfig lineBreakConfig = new LineBreakConfig.Builder()
+                    .setLineBreakWordStyle(LineBreakConfig.LINE_BREAK_STYLE_NONE)
+                    .setLineBreakWordStyle(LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE)
+                    .setAutoPhraseBreaking(true)
+                    .build();
+            final String text = "これが正解。";
+            // Obtain.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(text, 0,
+                    text.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setLineBreakConfig(lineBreakConfig);
+            builder.build();
+            assertEquals(LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE,
+                    builder.getLineBreakWordStyle());
+        }
+    }
 }
diff --git a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
index e303934..b3b19ce 100644
--- a/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
+++ b/core/tests/coretests/src/android/view/stylus/HandwritingInitiatorTest.java
@@ -34,6 +34,8 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
 import android.view.HandwritingInitiator;
 import android.view.InputDevice;
 import android.view.MotionEvent;
@@ -61,23 +63,32 @@
 public class HandwritingInitiatorTest {
     private static final int TOUCH_SLOP = 8;
     private static final long TIMEOUT = ViewConfiguration.getLongPressTimeout();
+    private static final int HANDWRITING_AREA_PADDING_DIP = 20;
+
     private static final Rect sHwArea = new Rect(100, 200, 500, 500);
 
     private HandwritingInitiator mHandwritingInitiator;
     private View mTestView;
-    private  Context mContext;
+    private Context mContext;
+    private int mHandwritingAreaPaddingPx;
 
     @Before
     public void setup() {
         final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mContext = mInstrumentation.getTargetContext();
-        ViewConfiguration viewConfiguration = mock(ViewConfiguration.class);
+        final ViewConfiguration viewConfiguration = mock(ViewConfiguration.class);
         when(viewConfiguration.getScaledTouchSlop()).thenReturn(TOUCH_SLOP);
 
-        InputMethodManager inputMethodManager = mContext.getSystemService(InputMethodManager.class);
-        mHandwritingInitiator =
-                spy(new HandwritingInitiator(viewConfiguration, inputMethodManager));
 
+        final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+        InputMethodManager inputMethodManager = mContext.getSystemService(InputMethodManager.class);
+        mHandwritingInitiator = spy(new HandwritingInitiator(viewConfiguration, inputMethodManager,
+                displayMetrics));
+
+        mHandwritingAreaPaddingPx = Math.round(TypedValue.applyDimension(
+                TypedValue.COMPLEX_UNIT_DIP,
+                HANDWRITING_AREA_PADDING_DIP,
+                displayMetrics));
         mTestView = createView(sHwArea, true);
         mHandwritingInitiator.updateHandwritingAreasForView(mTestView);
     }
@@ -127,6 +138,24 @@
     }
 
     @Test
+    public void onTouchEvent_startHandwriting_when_stylusMove_withinExtendedHWArea() {
+        mHandwritingInitiator.onInputConnectionCreated(mTestView);
+        final int x1 = sHwArea.left - mHandwritingAreaPaddingPx / 2;
+        final int y1 = sHwArea.top - mHandwritingAreaPaddingPx / 2;
+        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
+        mHandwritingInitiator.onTouchEvent(stylusEvent1);
+
+        final int x2 = x1 + TOUCH_SLOP * 2;
+        final int y2 = y1;
+
+        MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
+        mHandwritingInitiator.onTouchEvent(stylusEvent2);
+
+        // Stylus movement within extended HandwritingArea should trigger IMM.startHandwriting once.
+        verify(mHandwritingInitiator, times(1)).startHandwriting(mTestView);
+    }
+
+    @Test
     public void onTouchEvent_startHandwriting_inputConnectionBuiltAfterStylusMove() {
         final int x1 = (sHwArea.left + sHwArea.right) / 2;
         final int y1 = (sHwArea.top + sHwArea.bottom) / 2;
@@ -145,6 +174,24 @@
     }
 
     @Test
+    public void onTouchEvent_startHandwriting_inputConnectionBuilt_stylusMoveInExtendedHWArea() {
+        final int x1 = sHwArea.right + mHandwritingAreaPaddingPx / 2;
+        final int y1 = sHwArea.bottom + mHandwritingAreaPaddingPx / 2;
+        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
+        mHandwritingInitiator.onTouchEvent(stylusEvent1);
+
+        final int x2 = x1 + TOUCH_SLOP * 2;
+        final int y2 = y1;
+        MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
+        mHandwritingInitiator.onTouchEvent(stylusEvent2);
+
+        // InputConnection is created after stylus movement.
+        mHandwritingInitiator.onInputConnectionCreated(mTestView);
+
+        verify(mHandwritingInitiator, times(1)).startHandwriting(mTestView);
+    }
+
+    @Test
     public void onTouchEvent_notStartHandwriting_when_stylusTap_withinHWArea() {
         mHandwritingInitiator.onInputConnectionCreated(mTestView);
         final int x1 = 200;
@@ -213,6 +260,23 @@
     }
 
     @Test
+    public void onTouchEvent_focusView_stylusMoveOnce_withinExtendedHWArea() {
+        final int x1 = sHwArea.left - mHandwritingAreaPaddingPx / 2;
+        final int y1 = sHwArea.top - mHandwritingAreaPaddingPx / 2;
+        MotionEvent stylusEvent1 = createStylusEvent(ACTION_DOWN, x1, y1, 0);
+        mHandwritingInitiator.onTouchEvent(stylusEvent1);
+
+        final int x2 = x1 + TOUCH_SLOP * 2;
+        final int y2 = y1;
+
+        MotionEvent stylusEvent2 = createStylusEvent(ACTION_MOVE, x2, y2, 0);
+        mHandwritingInitiator.onTouchEvent(stylusEvent2);
+
+        // HandwritingInitiator will request focus for the registered view.
+        verify(mTestView, times(1)).requestFocus();
+    }
+
+    @Test
     public void autoHandwriting_whenDisabled_wontStartHW() {
         View mockView = createView(sHwArea, false);
         mHandwritingInitiator.onInputConnectionCreated(mockView);
diff --git a/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java b/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java
index 04b8886..3e640c1 100644
--- a/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/AbstractResolverComparatorTest.java
@@ -115,11 +115,6 @@
 
             @Override
             void handleResultMessage(Message message) {}
-
-            @Override
-            List<ComponentName> getTopComponentNames(int topK) {
-                return null;
-            }
         };
         return testComparator;
     }
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 cf78646..b38e1c2 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -81,7 +81,6 @@
 import android.os.UserHandle;
 import android.provider.DeviceConfig;
 import android.service.chooser.ChooserTarget;
-import android.util.Log;
 import android.view.View;
 
 import androidx.annotation.CallSuper;
@@ -623,7 +622,7 @@
         List<ResolvedComponentInfo> stableCopy =
                 createResolvedComponentsForTestWithOtherProfile(2, /* userId= */ 10);
         waitForIdle();
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         onView(first(withText(stableCopy.get(1).getResolveInfoAt(0).activityInfo.name)))
                 .perform(click());
@@ -1437,7 +1436,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
                 activity.getAdapter().getCount(), is(3));
@@ -1513,7 +1512,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
                 activity.getAdapter().getCount(), is(3));
@@ -1595,7 +1594,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
                 wrapper.getAdapter().getCount(), is(3));
@@ -1667,7 +1666,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 4 targets (2 apps, 2 direct)",
                 wrapper.getAdapter().getCount(), is(4));
@@ -1754,7 +1753,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat(
                 String.format("Chooser should have %d targets (%d apps, 1 direct, 15 A-Z)",
@@ -1879,12 +1878,13 @@
             return true;
         };
 
-        mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
+        final IChooserWrapper activity = (IChooserWrapper)
+                mActivityRule.launchActivity(Intent.createChooser(sendIntent, "work tab test"));
         waitForIdle();
         onView(withTextFromRuntimeResource("resolver_work_tab")).perform(click());
         waitForIdle();
         // wait for the share sheet to expand
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         onView(first(allOf(
                 withText(workResolvedComponentInfos.get(0)
@@ -2023,7 +2023,7 @@
                 .check(matches(isDisplayed()));
     }
 
-    @Test
+    @Test @Ignore("b/222124533")
     public void testAppTargetLogging() throws InterruptedException {
         Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -2042,6 +2042,10 @@
                 mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
         waitForIdle();
 
+        // TODO(b/222124533): other test cases use a timeout to make sure that the UI is fully
+        // populated; without one, this test flakes. Ideally we should address the need for a
+        // timeout everywhere instead of introducing one to fix this particular test.
+
         assertThat(activity.getAdapter().getCount(), is(2));
         onView(withIdFromRuntimeResource("profile_button")).check(doesNotExist());
 
@@ -2143,7 +2147,7 @@
         // Thread.sleep shouldn't be a thing in an integration test but it's
         // necessary here because of the way the code is structured
         // TODO: restructure the tests b/129870719
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
+        Thread.sleep(((ChooserActivity) activity).mListViewUpdateDelayMs);
 
         assertThat("Chooser should have 3 targets (2 apps, 1 direct)",
                 activity.getAdapter().getCount(), is(3));
@@ -2324,7 +2328,7 @@
         assertThat(logger.numCalls(), is(6));
     }
 
-    @Test
+    @Test @Ignore("b/222124533")
     public void testSwitchProfileLogging() throws InterruptedException {
         // enable the work tab feature flag
         ResolverActivity.ENABLE_TABBED_VIEW = true;
@@ -3069,8 +3073,15 @@
     // framework code on the device is up-to-date.
     // TODO: is there a better way to do this? (Other than abandoning inheritance-based DI wrapper?)
     private int getRuntimeResourceId(String name, String defType) {
-        int id = mActivityRule.getActivity().getResources().getIdentifier(name, defType, "android");
+        int id = -1;
+        if (ChooserActivityOverrideData.getInstance().resources != null) {
+            id = ChooserActivityOverrideData.getInstance().resources.getIdentifier(
+                  name, defType, "android");
+        } else {
+            id = mActivityRule.getActivity().getResources().getIdentifier(name, defType, "android");
+        }
         assertThat(id, greaterThan(0));
+
         return id;
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/app/FakeResolverComparatorModel.java b/core/tests/coretests/src/com/android/internal/app/FakeResolverComparatorModel.java
new file mode 100644
index 0000000..fbbe57c
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/FakeResolverComparatorModel.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.ComponentName;
+import android.content.pm.ResolveInfo;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Basic {@link ResolverComparatorModel} implementation that sorts according to a pre-defined (or
+ * default) {@link java.util.Comparator}.
+ */
+public class FakeResolverComparatorModel implements ResolverComparatorModel {
+    private final Comparator<ResolveInfo> mComparator;
+
+    public static FakeResolverComparatorModel makeModelFromComparator(
+            Comparator<ResolveInfo> comparator) {
+        return new FakeResolverComparatorModel(comparator);
+    }
+
+    public static FakeResolverComparatorModel makeDefaultModel() {
+       return makeModelFromComparator(Comparator.comparing(ri -> ri.activityInfo.name));
+    }
+
+    @Override
+    public Comparator<ResolveInfo> getComparator() {
+        return mComparator;
+    }
+
+    @Override
+    public float getScore(ComponentName name) {
+        return 0.0f;  // Models are not required to provide numerical scores.
+    }
+
+    @Override
+    public void notifyOnTargetSelected(ComponentName componentName) {
+        System.out.println(
+                "User selected " + componentName + " under model " + System.identityHashCode(this));
+    }
+
+    private FakeResolverComparatorModel(Comparator<ResolveInfo> comparator) {
+        mComparator = comparator;
+    }
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index e7a23f2..43fba52 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -516,8 +516,6 @@
         onView(withText(R.string.resolver_work_tab))
                 .perform(click());
         waitForIdle();
-        // wait for the share sheet to expand
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
         onView(first(allOf(withText(workResolvedComponentInfos.get(0)
                 .getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed())))
                 .perform(click());
@@ -616,8 +614,6 @@
         onView(withText(R.string.resolver_work_tab))
                 .perform(click());
         waitForIdle();
-        // wait for the share sheet to expand
-        Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
         onView(first(allOf(
                 withText(workResolvedComponentInfos.get(0)
                         .getResolveInfoAt(0).activityInfo.applicationInfo.name),
diff --git a/errorprone/Android.bp b/errorprone/Android.bp
index a927f53..8f32f0e 100644
--- a/errorprone/Android.bp
+++ b/errorprone/Android.bp
@@ -1,4 +1,3 @@
-
 package {
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
@@ -42,8 +41,10 @@
     static_libs: [
         "truth-prebuilt",
         "kxml2-2.3.0",
+        "compile-testing-prebuilt",
         "error_prone_android_framework_lib",
         "error_prone_test_helpers",
+        "google_java_format",
         "hamcrest-library",
         "hamcrest",
         "platform-test-annotations",
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/HideInCommentsChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/HideInCommentsChecker.java
new file mode 100644
index 0000000..07f1d4a
--- /dev/null
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/HideInCommentsChecker.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2022 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.google.errorprone.bugpatterns.android;
+
+import static com.google.errorprone.BugPattern.LinkType.NONE;
+import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
+import static com.google.errorprone.matchers.Description.NO_MATCH;
+import static com.google.errorprone.util.ASTHelpers.getStartPosition;
+import static com.google.errorprone.util.ASTHelpers.getSymbol;
+
+import com.google.auto.service.AutoService;
+import com.google.errorprone.BugPattern;
+import com.google.errorprone.VisitorState;
+import com.google.errorprone.bugpatterns.BugChecker;
+import com.google.errorprone.fixes.SuggestedFix;
+import com.google.errorprone.matchers.Description;
+import com.google.errorprone.util.ASTHelpers;
+import com.google.errorprone.util.ErrorProneToken;
+import com.google.errorprone.util.ErrorProneTokens;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.NewClassTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.tools.javac.parser.Tokens;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.lang.model.element.ElementKind;
+
+/**
+ * Bug checker to warn about {@code @hide} directives in comments.
+ *
+ * {@code @hide} tags are only meaningful inside of Javadoc comments. Errorprone has checks for
+ * standard Javadoc tags but doesn't know anything about {@code @hide} since it's an Android
+ * specific tag.
+ */
+@AutoService(BugChecker.class)
+@BugPattern(
+        name = "AndroidHideInComments",
+        summary = "Warns when there are @hide declarations in comments rather than javadoc",
+        linkType = NONE,
+        severity = WARNING)
+public class HideInCommentsChecker extends BugChecker implements
+        BugChecker.CompilationUnitTreeMatcher {
+
+    @Override
+    public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
+        final Map<Integer, Tree> javadocableTrees = findJavadocableTrees(tree);
+        final String sourceCode = state.getSourceCode().toString();
+        for (ErrorProneToken token : ErrorProneTokens.getTokens(sourceCode, state.context)) {
+            for (Tokens.Comment comment : token.comments()) {
+                if (!javadocableTrees.containsKey(token.pos())) {
+                    continue;
+                }
+                generateFix(comment).ifPresent(fix -> {
+                    final Tree javadocableTree = javadocableTrees.get(token.pos());
+                    state.reportMatch(describeMatch(javadocableTree, fix));
+                });
+            }
+        }
+        // We might have multiple matches, so report them via VisitorState rather than the return
+        // value from the match function.
+        return NO_MATCH;
+    }
+
+    private static Optional<SuggestedFix> generateFix(Tokens.Comment comment) {
+        final String text = comment.getText();
+        if (text.startsWith("/**")) {
+            return Optional.empty();
+        }
+
+        if (!text.contains("@hide")) {
+            return Optional.empty();
+        }
+
+        if (text.startsWith("/*")) {
+            final int pos = comment.getSourcePos(1);
+            return Optional.of(SuggestedFix.replace(pos, pos, "*"));
+        } else if (text.startsWith("//")) {
+            final int endPos = comment.getSourcePos(text.length() - 1);
+            final char endChar = text.charAt(text.length() - 1);
+            String javadocClose = " */";
+            if (endChar != ' ') {
+                javadocClose = endChar + javadocClose;
+            }
+            final SuggestedFix fix = SuggestedFix.builder()
+                    .replace(comment.getSourcePos(1), comment.getSourcePos(2), "**")
+                    .replace(endPos, endPos + 1, javadocClose)
+                    .build();
+            return Optional.of(fix);
+        }
+
+        return Optional.empty();
+    }
+
+
+    private Map<Integer, Tree> findJavadocableTrees(CompilationUnitTree tree) {
+        Map<Integer, Tree> javadoccableTrees = new HashMap<>();
+        new SuppressibleTreePathScanner<Void, Void>() {
+            @Override
+            public Void visitClass(ClassTree classTree, Void unused) {
+                javadoccableTrees.put(getStartPosition(classTree), classTree);
+                return super.visitClass(classTree, null);
+            }
+
+            @Override
+            public Void visitMethod(MethodTree methodTree, Void unused) {
+                // Generated constructors never have comments
+                if (!ASTHelpers.isGeneratedConstructor(methodTree)) {
+                    javadoccableTrees.put(getStartPosition(methodTree), methodTree);
+                }
+                return super.visitMethod(methodTree, null);
+            }
+
+            @Override
+            public Void visitVariable(VariableTree variableTree, Void unused) {
+                ElementKind kind = getSymbol(variableTree).getKind();
+                if (kind == ElementKind.FIELD) {
+                    javadoccableTrees.put(getStartPosition(variableTree), variableTree);
+                }
+                if (kind == ElementKind.ENUM_CONSTANT) {
+                    javadoccableTrees.put(getStartPosition(variableTree), variableTree);
+                    if (variableTree.getInitializer() instanceof NewClassTree) {
+                        // Skip the generated class definition
+                        ClassTree classBody =
+                                ((NewClassTree) variableTree.getInitializer()).getClassBody();
+                        if (classBody != null) {
+                            scan(classBody.getMembers(), null);
+                        }
+                        return null;
+                    }
+                }
+                return super.visitVariable(variableTree, null);
+            }
+
+        }.scan(tree, null);
+        return javadoccableTrees;
+    }
+
+}
diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/HideInCommentsCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/HideInCommentsCheckerTest.java
new file mode 100644
index 0000000..f3e6c727
--- /dev/null
+++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/HideInCommentsCheckerTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2022 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.google.errorprone.bugpatterns.android;
+
+import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH;
+
+import com.google.errorprone.BugCheckerRefactoringTestHelper;
+import com.google.errorprone.CompilationTestHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class HideInCommentsCheckerTest {
+    private static final String REFACTORING_FILE = "Test.java";
+
+    private BugCheckerRefactoringTestHelper mRefactoringHelper;
+    private CompilationTestHelper mCompilationHelper;
+
+    @Before
+    public void setUp() {
+        mRefactoringHelper = BugCheckerRefactoringTestHelper.newInstance(
+                HideInCommentsChecker.class, HideInCommentsCheckerTest.class);
+        mCompilationHelper = CompilationTestHelper.newInstance(
+                HideInCommentsChecker.class, HideInCommentsCheckerTest.class);
+    }
+
+
+    @Test
+    public void refactorSingleLineComment() {
+        mRefactoringHelper
+                .addInputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  // Foo @hide",
+                        "  void foo() {}",
+                        "}")
+                .addOutputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /** Foo @hide */",
+                        "  void foo() {}",
+                        "}")
+                .doTest(TEXT_MATCH);
+    }
+
+    @Test
+    public void refactorSingleLineComment_doesntAddUnnecessarySpace() {
+        mRefactoringHelper
+                .addInputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  // Foo @hide ",
+                        "  void foo() {}",
+                        "}")
+                .addOutputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /** Foo @hide */",
+                        "  void foo() {}",
+                        "}")
+                .doTest(TEXT_MATCH);
+    }
+
+    @Test
+    public void refactorSingleLineBlockComment() {
+        mRefactoringHelper
+                .addInputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /* Foo @hide */",
+                        "  void foo() {}",
+                        "}")
+                .addOutputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /** Foo @hide */",
+                        "  void foo() {}",
+                        "}")
+                .doTest(TEXT_MATCH);
+    }
+
+    @Test
+    public void refactorMultiLineBlockComment() {
+        mRefactoringHelper
+                .addInputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /*",
+                        "   * Foo.",
+                        "   *",
+                        "   * @hide",
+                        "   */",
+                        "  void foo(int foo) {}",
+                        "}")
+                .addOutputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /**",
+                        "   * Foo.",
+                        "   *",
+                        "   * @hide",
+                        "   */",
+                        "  void foo(int foo) {}",
+                        "}")
+                .doTest(TEXT_MATCH);
+    }
+
+    @Test
+    public void refactorFieldComment() {
+        mRefactoringHelper
+                .addInputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /* Foo @hide */",
+                        "  public int foo = 0;",
+                        "}")
+                .addOutputLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /** Foo @hide */",
+                        "  public int foo = 0;",
+                        "}")
+                .doTest(TEXT_MATCH);
+    }
+
+    @Test
+    public void refactorClassComment() {
+        mRefactoringHelper
+                .addInputLines(
+                        REFACTORING_FILE,
+                        "/* Foo @hide */",
+                        "public class Test {}")
+                .addOutputLines(
+                        REFACTORING_FILE,
+                        "/** Foo @hide */",
+                        "public class Test {}")
+                .doTest(TEXT_MATCH);
+    }
+
+    @Test
+    public void refactorEnumComment() {
+        mRefactoringHelper
+                .addInputLines(
+                        REFACTORING_FILE,
+                        "public enum Test {",
+                        "  /* Foo @hide */",
+                        "  FOO",
+                        "}")
+                .addOutputLines(
+                        REFACTORING_FILE,
+                        "public enum Test {",
+                        "  /** Foo @hide */",
+                        "  FOO",
+                        "}")
+                .doTest(TEXT_MATCH);
+    }
+
+    @Test
+    public void canBeSuppressed() {
+        mCompilationHelper
+                .addSourceLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /* Foo @hide */",
+                        "  @SuppressWarnings(\"AndroidHideInComments\")",
+                        "  void foo() {}",
+                        "}")
+                .doTest();
+    }
+
+    @Test
+    public void isInJavadoc() {
+        mCompilationHelper
+                .addSourceLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /** Foo @hide */",
+                        "  void foo() {}",
+                        "}")
+                .doTest();
+    }
+
+    @Test
+    public void isInMultilineJavadoc() {
+        mCompilationHelper
+                .addSourceLines(
+                        REFACTORING_FILE,
+                        "public class Test {",
+                        "  /**",
+                        "   * Foo.",
+                        "   *",
+                        "   * @hide",
+                        "   */",
+                        "  void foo(int foo) {}",
+                        "}")
+                .doTest();
+    }
+
+    @Test
+    public void noHidePresent() {
+        mCompilationHelper
+                .addSourceLines(
+                        "test/" + REFACTORING_FILE,
+                        "package test;",
+                        "// Foo.",
+                        "public class Test {",
+                        "  // Foo.",
+                        "  public int a;",
+                        "  /*",
+                        "   * Foo.",
+                        "   *",
+                        "   */",
+                        "  void foo(int foo) {}",
+                        "}")
+                .doTest();
+    }
+
+}
diff --git a/graphics/java/android/graphics/text/LineBreakConfig.java b/graphics/java/android/graphics/text/LineBreakConfig.java
index d083e44..7ad9aec 100644
--- a/graphics/java/android/graphics/text/LineBreakConfig.java
+++ b/graphics/java/android/graphics/text/LineBreakConfig.java
@@ -89,6 +89,11 @@
         private @LineBreakWordStyle int mLineBreakWordStyle =
                 LineBreakConfig.LINE_BREAK_WORD_STYLE_NONE;
 
+        // Whether or not enabling phrase breaking automatically.
+        // TODO(b/226012260): Remove this and add LINE_BREAK_WORD_STYLE_PHRASE_AUTO after
+        // the experiment.
+        private boolean mAutoPhraseBreaking = false;
+
         /**
          * Builder constructor with line break parameters.
          */
@@ -118,12 +123,22 @@
         }
 
         /**
+         * Enable or disable the automation of {@link LINE_BREAK_WORD_STYLE_PHRASE}.
+         *
+         * @hide
+         */
+        public @NonNull Builder setAutoPhraseBreaking(boolean autoPhraseBreaking) {
+            mAutoPhraseBreaking = autoPhraseBreaking;
+            return this;
+        }
+
+        /**
          * Build the {@link LineBreakConfig}
          *
          * @return the LineBreakConfig instance.
          */
         public @NonNull LineBreakConfig build() {
-            return new LineBreakConfig(mLineBreakStyle, mLineBreakWordStyle);
+            return new LineBreakConfig(mLineBreakStyle, mLineBreakWordStyle, mAutoPhraseBreaking);
         }
     }
 
@@ -143,6 +158,23 @@
                 .build();
     }
 
+    /**
+     * Create the LineBreakConfig instance.
+     *
+     * @param lineBreakStyle the line break style for text wrapping.
+     * @param lineBreakWordStyle the line break word style for text wrapping.
+     * @return the {@link LineBreakConfig} instance.     *
+     * @hide
+     */
+    public static @NonNull LineBreakConfig getLineBreakConfig(@LineBreakStyle int lineBreakStyle,
+            @LineBreakWordStyle int lineBreakWordStyle, boolean autoPhraseBreaking) {
+        LineBreakConfig.Builder builder = new LineBreakConfig.Builder();
+        return builder.setLineBreakStyle(lineBreakStyle)
+                .setLineBreakWordStyle(lineBreakWordStyle)
+                .setAutoPhraseBreaking(autoPhraseBreaking)
+                .build();
+    }
+
     /** @hide */
     public static final LineBreakConfig NONE =
             new Builder().setLineBreakStyle(LINE_BREAK_STYLE_NONE)
@@ -150,15 +182,17 @@
 
     private final @LineBreakStyle int mLineBreakStyle;
     private final @LineBreakWordStyle int mLineBreakWordStyle;
+    private final boolean mAutoPhraseBreaking;
 
     /**
      * Constructor with the line break parameters.
      * Use the {@link LineBreakConfig.Builder} to create the LineBreakConfig instance.
      */
     private LineBreakConfig(@LineBreakStyle int lineBreakStyle,
-            @LineBreakWordStyle int lineBreakWordStyle) {
+            @LineBreakWordStyle int lineBreakWordStyle, boolean autoPhraseBreaking) {
         mLineBreakStyle = lineBreakStyle;
         mLineBreakWordStyle = lineBreakWordStyle;
+        mAutoPhraseBreaking = autoPhraseBreaking;
     }
 
     /**
@@ -179,6 +213,17 @@
         return mLineBreakWordStyle;
     }
 
+    /**
+     * Used to identify if the automation of {@link LINE_BREAK_WORD_STYLE_PHRASE} is enabled.
+     *
+     * @return The result that records whether or not the automation of
+     * {@link LINE_BREAK_WORD_STYLE_PHRASE} is enabled.
+     * @hide
+     */
+    public boolean getAutoPhraseBreaking() {
+        return mAutoPhraseBreaking;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (o == null) return false;
@@ -186,7 +231,8 @@
         if (!(o instanceof LineBreakConfig)) return false;
         LineBreakConfig that = (LineBreakConfig) o;
         return (mLineBreakStyle == that.mLineBreakStyle)
-                && (mLineBreakWordStyle == that.mLineBreakWordStyle);
+                && (mLineBreakWordStyle == that.mLineBreakWordStyle)
+                && (mAutoPhraseBreaking == that.mAutoPhraseBreaking);
     }
 
     @Override
diff --git a/identity/java/android/security/identity/CredstoreIdentityCredential.java b/identity/java/android/security/identity/CredstoreIdentityCredential.java
index 8e01105..c591c87 100644
--- a/identity/java/android/security/identity/CredstoreIdentityCredential.java
+++ b/identity/java/android/security/identity/CredstoreIdentityCredential.java
@@ -38,8 +38,9 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.time.Instant;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 
 import javax.crypto.BadPaddingException;
@@ -227,7 +228,7 @@
                 throw new RuntimeException("Error decoding certificates", e);
             }
 
-            LinkedList<X509Certificate> x509Certs = new LinkedList<>();
+            ArrayList<X509Certificate> x509Certs = new ArrayList<>();
             for (Certificate cert : certs) {
                 x509Certs.add((X509Certificate) cert);
             }
@@ -384,7 +385,7 @@
     public @NonNull Collection<X509Certificate> getAuthKeysNeedingCertification() {
         try {
             AuthKeyParcel[] authKeyParcels = mBinder.getAuthKeysNeedingCertification();
-            LinkedList<X509Certificate> x509Certs = new LinkedList<>();
+            ArrayList<X509Certificate> x509Certs = new ArrayList<>();
             CertificateFactory factory = CertificateFactory.getInstance("X.509");
             for (AuthKeyParcel authKeyParcel : authKeyParcels) {
                 Collection<? extends Certificate> certs = null;
diff --git a/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java b/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java
index d2e7984..1ad70ed 100644
--- a/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java
+++ b/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java
@@ -25,8 +25,9 @@
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedList;
+import java.util.List;
 
 class CredstoreWritableIdentityCredential extends WritableIdentityCredential {
 
@@ -61,7 +62,7 @@
                 throw new RuntimeException("Error decoding certificates", e);
             }
 
-            LinkedList<X509Certificate> x509Certs = new LinkedList<>();
+            ArrayList<X509Certificate> x509Certs = new ArrayList<>();
             for (Certificate cert : certs) {
                 x509Certs.add((X509Certificate) cert);
             }
diff --git a/identity/java/android/security/identity/PersonalizationData.java b/identity/java/android/security/identity/PersonalizationData.java
index b34f250..bdb00fdf 100644
--- a/identity/java/android/security/identity/PersonalizationData.java
+++ b/identity/java/android/security/identity/PersonalizationData.java
@@ -18,10 +18,11 @@
 
 import android.annotation.NonNull;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
-import java.util.LinkedList;
+import java.util.List;
 
 /**
  * An object that holds personalization data.
@@ -38,7 +39,7 @@
     private PersonalizationData() {
     }
 
-    private LinkedList<AccessControlProfile> mProfiles = new LinkedList<>();
+    private ArrayList<AccessControlProfile> mProfiles = new ArrayList<>();
 
     private LinkedHashMap<String, NamespaceData> mNamespaces = new LinkedHashMap<>();
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 31f0ef0..b20caf4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -439,6 +439,7 @@
         }
         notifyLocusVisibilityIfNeeded(info.getTaskInfo());
         notifyCompatUI(info.getTaskInfo(), listener);
+        mRecentTasks.ifPresent(recentTasks -> recentTasks.onTaskAdded(info.getTaskInfo()));
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
index 6e78fcb..b71cc32 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.recents;
 
+import android.app.ActivityManager;
+
 import com.android.wm.shell.recents.IRecentTasksListener;
 import com.android.wm.shell.util.GroupedRecentTaskInfo;
 
@@ -38,4 +40,9 @@
      * Gets the set of recent tasks.
      */
     GroupedRecentTaskInfo[] getRecentTasks(int maxNum, int flags, int userId) = 3;
+
+    /**
+     * Gets the set of running tasks.
+     */
+    ActivityManager.RunningTaskInfo[] getRunningTasks(int maxNum) = 4;
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
index 8efa428..59f7233 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
@@ -16,6 +16,8 @@
 
 package com.android.wm.shell.recents;
 
+import android.app.ActivityManager;
+
 /**
  * Listener interface that Launcher attaches to SystemUI to get split-screen callbacks.
  */
@@ -25,4 +27,14 @@
      * Called when the set of recent tasks change.
      */
     void onRecentTasksChanged();
+
+    /**
+     * Called when a running task appears.
+     */
+    void onRunningTaskAppeared(in ActivityManager.RunningTaskInfo taskInfo);
+
+    /**
+     * Called when a running task vanishes.
+     */
+    void onRunningTaskVanished(in ActivityManager.RunningTaskInfo taskInfo);
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index c166178..d903d5b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -17,6 +17,7 @@
 package com.android.wm.shell.recents;
 
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.content.pm.PackageManager.FEATURE_PC;
 
 import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
 
@@ -63,8 +64,9 @@
     private final ShellExecutor mMainExecutor;
     private final TaskStackListenerImpl mTaskStackListener;
     private final RecentTasks mImpl = new RecentTasksImpl();
+    private IRecentTasksListener mListener;
+    private final boolean mIsDesktopMode;
 
-    private final ArrayList<Runnable> mCallbacks = new ArrayList<>();
     // Mapping of split task ids, mappings are symmetrical (ie. if t1 is the taskid of a task in a
     // pair, then mSplitTasks[t1] = t2, and mSplitTasks[t2] = t1)
     private final SparseIntArray mSplitTasks = new SparseIntArray();
@@ -95,6 +97,7 @@
     RecentTasksController(Context context, TaskStackListenerImpl taskStackListener,
             ShellExecutor mainExecutor) {
         mContext = context;
+        mIsDesktopMode = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
         mTaskStackListener = taskStackListener;
         mMainExecutor = mainExecutor;
     }
@@ -176,10 +179,15 @@
         notifyRecentTasksChanged();
     }
 
-    public void onTaskRemoved(TaskInfo taskInfo) {
+    public void onTaskAdded(ActivityManager.RunningTaskInfo taskInfo) {
+        notifyRunningTaskAppeared(taskInfo);
+    }
+
+    public void onTaskRemoved(ActivityManager.RunningTaskInfo taskInfo) {
         // Remove any split pairs associated with this task
         removeSplitPair(taskInfo.taskId);
         notifyRecentTasksChanged();
+        notifyRunningTaskVanished(taskInfo);
     }
 
     public void onTaskWindowingModeChanged(TaskInfo taskInfo) {
@@ -189,19 +197,50 @@
     @VisibleForTesting
     void notifyRecentTasksChanged() {
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENT_TASKS, "Notify recent tasks changed");
-        for (int i = 0; i < mCallbacks.size(); i++) {
-            mCallbacks.get(i).run();
+        if (mListener == null) {
+            return;
+        }
+        try {
+            mListener.onRecentTasksChanged();
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed call notifyRecentTasksChanged", e);
         }
     }
 
-    private void registerRecentTasksListener(Runnable listener) {
-        if (!mCallbacks.contains(listener)) {
-            mCallbacks.add(listener);
+    /**
+     * Notify the running task listener that a task appeared on desktop environment.
+     */
+    private void notifyRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+        if (mListener == null || !mIsDesktopMode || taskInfo.realActivity == null) {
+            return;
+        }
+        try {
+            mListener.onRunningTaskAppeared(taskInfo);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed call onRunningTaskAppeared", e);
         }
     }
 
-    private void unregisterRecentTasksListener(Runnable listener) {
-        mCallbacks.remove(listener);
+    /**
+     * Notify the running task listener that a task was removed on desktop environment.
+     */
+    private void notifyRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+        if (mListener == null || !mIsDesktopMode || taskInfo.realActivity == null) {
+            return;
+        }
+        try {
+            mListener.onRunningTaskVanished(taskInfo);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "Failed call onRunningTaskVanished", e);
+        }
+    }
+
+    private void registerRecentTasksListener(IRecentTasksListener listener) {
+        mListener = listener;
+    }
+
+    private void unregisterRecentTasksListener() {
+        mListener = null;
     }
 
     @VisibleForTesting
@@ -280,19 +319,28 @@
         private RecentTasksController mController;
         private final SingleInstanceRemoteListener<RecentTasksController,
                 IRecentTasksListener> mListener;
-        private final Runnable mRecentTasksListener =
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        mListener.call(l -> l.onRecentTasksChanged());
-                    }
-                };
+        private final IRecentTasksListener mRecentTasksListener = new IRecentTasksListener.Stub() {
+            @Override
+            public void onRecentTasksChanged() throws RemoteException {
+                mListener.call(l -> l.onRecentTasksChanged());
+            }
+
+            @Override
+            public void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+                mListener.call(l -> l.onRunningTaskAppeared(taskInfo));
+            }
+
+            @Override
+            public void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+                mListener.call(l -> l.onRunningTaskVanished(taskInfo));
+            }
+        };
 
         public IRecentTasksImpl(RecentTasksController controller) {
             mController = controller;
             mListener = new SingleInstanceRemoteListener<>(controller,
                     c -> c.registerRecentTasksListener(mRecentTasksListener),
-                    c -> c.unregisterRecentTasksListener(mRecentTasksListener));
+                    c -> c.unregisterRecentTasksListener());
         }
 
         /**
@@ -331,5 +379,16 @@
                     true /* blocking */);
             return out[0];
         }
+
+        @Override
+        public ActivityManager.RunningTaskInfo[] getRunningTasks(int maxNum) {
+            final ActivityManager.RunningTaskInfo[][] tasks =
+                    new ActivityManager.RunningTaskInfo[][] {null};
+            executeRemoteCallWithTaskPermission(mController, "getRunningTasks",
+                    (controller) -> tasks[0] = ActivityTaskManager.getInstance().getTasks(maxNum)
+                            .toArray(new ActivityManager.RunningTaskInfo[0]),
+                    true /* blocking */);
+            return tasks[0];
+        }
     }
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 50f6bd7..9ef8c32 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -30,11 +30,13 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import static java.lang.Integer.MAX_VALUE;
 
 import android.app.ActivityManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.view.SurfaceControl;
 
@@ -77,6 +79,7 @@
     @Before
     public void setUp() {
         mMainExecutor = new TestShellExecutor();
+        when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
         mRecentTasksController = spy(new RecentTasksController(mContext, mTaskStackListener,
                 mMainExecutor));
         mShellTaskOrganizer = new ShellTaskOrganizer(mMainExecutor, mContext,
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index c80fb18..8a379d5 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -33,6 +33,7 @@
 
 cc_defaults {
     name: "libandroidfw_defaults",
+    cpp_std: "gnu++2b",
     cflags: [
         "-Werror",
         "-Wunreachable-code",
diff --git a/libs/androidfw/include/androidfw/StringPiece.h b/libs/androidfw/include/androidfw/StringPiece.h
index 921877dc..fac2fa4 100644
--- a/libs/androidfw/include/androidfw/StringPiece.h
+++ b/libs/androidfw/include/androidfw/StringPiece.h
@@ -288,12 +288,12 @@
 
 template <typename TChar>
 inline bool operator==(const ::std::basic_string<TChar>& lhs, const BasicStringPiece<TChar>& rhs) {
-  return rhs == lhs;
+  return BasicStringPiece<TChar>(lhs) == rhs;
 }
 
 template <typename TChar>
 inline bool operator!=(const ::std::basic_string<TChar>& lhs, const BasicStringPiece<TChar>& rhs) {
-  return rhs != lhs;
+  return BasicStringPiece<TChar>(lhs) != rhs;
 }
 
 }  // namespace android
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index d5fee3f..2e6e36a 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -16,7 +16,9 @@
 #ifndef DEVICEINFO_H
 #define DEVICEINFO_H
 
+#include <SkColorSpace.h>
 #include <SkImageInfo.h>
+#include <SkRefCnt.h>
 #include <android/data_space.h>
 
 #include <mutex>
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index c24cabb..7291cab 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -22,8 +22,11 @@
 #include <GLES2/gl2ext.h>
 #include <GLES3/gl3.h>
 #include <GrDirectContext.h>
+#include <SkBitmap.h>
 #include <SkCanvas.h>
 #include <SkImage.h>
+#include <SkImageInfo.h>
+#include <SkRefCnt.h>
 #include <gui/TraceUtils.h>
 #include <utils/GLUtils.h>
 #include <utils/NdkUtils.h>
diff --git a/libs/hwui/HardwareBitmapUploader.h b/libs/hwui/HardwareBitmapUploader.h
index 81057a2..00ee996 100644
--- a/libs/hwui/HardwareBitmapUploader.h
+++ b/libs/hwui/HardwareBitmapUploader.h
@@ -17,6 +17,9 @@
 #pragma once
 
 #include <hwui/Bitmap.h>
+#include <SkRefCnt.h>
+
+class SkBitmap;
 
 namespace android::uirenderer {
 
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 4cce87a..79953aa 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -26,6 +26,18 @@
 #include "pipeline/skia/LayerDrawable.h"
 #include "renderthread/EglManager.h"
 #include "renderthread/VulkanManager.h"
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkCanvas.h>
+#include <SkColorSpace.h>
+#include <SkImage.h>
+#include <SkImageInfo.h>
+#include <SkMatrix.h>
+#include <SkPaint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+#include <SkSamplingOptions.h>
+#include <SkSurface.h>
 #include "utils/Color.h"
 #include "utils/MathUtils.h"
 #include "utils/NdkUtils.h"
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index d0d748f..aa6e43c 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -20,7 +20,11 @@
 #include "Rect.h"
 #include "renderthread/RenderThread.h"
 
-#include <SkBitmap.h>
+#include <SkRefCnt.h>
+
+class SkBitmap;
+class SkImage;
+struct SkRect;
 
 namespace android {
 class Bitmap;
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index a285462..f5ebfd5 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -29,10 +29,14 @@
 #include "SkDrawShadowInfo.h"
 #include "SkImage.h"
 #include "SkImageFilter.h"
+#include "SkImageInfo.h"
 #include "SkLatticeIter.h"
 #include "SkMath.h"
+#include "SkPaint.h"
 #include "SkPicture.h"
+#include "SkRRect.h"
 #include "SkRSXform.h"
+#include "SkRect.h"
 #include "SkRegion.h"
 #include "SkTextBlob.h"
 #include "SkVertices.h"
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 212b4e7..35bec93 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -34,6 +34,8 @@
 #include <SkRuntimeEffect.h>
 #include <vector>
 
+class SkRRect;
+
 namespace android {
 namespace uirenderer {
 
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 53c6db0..023d6bf 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -27,6 +27,7 @@
 
 #include <SkAndroidFrameworkUtils.h>
 #include <SkAnimatedImage.h>
+#include <SkBitmap.h>
 #include <SkCanvasPriv.h>
 #include <SkCanvasStateUtils.h>
 #include <SkColorFilter.h>
@@ -36,8 +37,13 @@
 #include <SkGraphics.h>
 #include <SkImage.h>
 #include <SkImagePriv.h>
+#include <SkMatrix.h>
+#include <SkPaint.h>
 #include <SkPicture.h>
 #include <SkRSXform.h>
+#include <SkRRect.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
 #include <SkShader.h>
 #include <SkTemplates.h>
 #include <SkTextBlob.h>
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 715007c..c6313f6 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -33,6 +33,8 @@
 #include <cassert>
 #include <optional>
 
+class SkRRect;
+
 namespace android {
 
 // Holds an SkCanvas reference plus additional native data.
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 983c776..536ff78 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -21,9 +21,10 @@
 #include <utils/Log.h>
 
 #include "PathParser.h"
-#include "SkColorFilter.h"
+#include "SkImage.h"
 #include "SkImageInfo.h"
-#include "SkShader.h"
+#include "SkSamplingOptions.h"
+#include "SkScalar.h"
 #include "hwui/Paint.h"
 
 #ifdef __ANDROID__
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index 30bb04a..c92654c 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -31,6 +31,7 @@
 #include <SkPath.h>
 #include <SkPathMeasure.h>
 #include <SkRect.h>
+#include <SkRefCnt.h>
 #include <SkShader.h>
 #include <SkSurface.h>
 
diff --git a/libs/hwui/apex/android_bitmap.cpp b/libs/hwui/apex/android_bitmap.cpp
index bc6bc45..c442a7b 100644
--- a/libs/hwui/apex/android_bitmap.cpp
+++ b/libs/hwui/apex/android_bitmap.cpp
@@ -24,6 +24,11 @@
 
 #include <GraphicsJNI.h>
 #include <hwui/Bitmap.h>
+#include <SkBitmap.h>
+#include <SkColorSpace.h>
+#include <SkImageInfo.h>
+#include <SkRefCnt.h>
+#include <SkStream.h>
 #include <utils/Color.h>
 
 using namespace android;
diff --git a/libs/hwui/apex/android_canvas.cpp b/libs/hwui/apex/android_canvas.cpp
index 2a939ef..905b123 100644
--- a/libs/hwui/apex/android_canvas.cpp
+++ b/libs/hwui/apex/android_canvas.cpp
@@ -23,7 +23,9 @@
 #include <utils/Color.h>
 
 #include <SkBitmap.h>
+#include <SkColorSpace.h>
 #include <SkSurface.h>
+#include <SkRefCnt.h>
 
 using namespace android;
 
diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h
index fdc97a4..2dcbca8 100644
--- a/libs/hwui/canvas/CanvasOps.h
+++ b/libs/hwui/canvas/CanvasOps.h
@@ -17,13 +17,19 @@
 #pragma once
 
 #include <SkAndroidFrameworkUtils.h>
+#include <SkBlendMode.h>
 #include <SkCanvas.h>
-#include <SkPath.h>
-#include <SkRegion.h>
-#include <SkVertices.h>
+#include <SkClipOp.h>
 #include <SkImage.h>
+#include <SkPaint.h>
+#include <SkPath.h>
 #include <SkPicture.h>
+#include <SkRRect.h>
+#include <SkRect.h>
+#include <SkRegion.h>
 #include <SkRuntimeEffect.h>
+#include <SkSamplingOptions.h>
+#include <SkVertices.h>
 
 #include <log/log.h>
 
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 67f4758..feafc23 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -35,9 +35,15 @@
 #endif
 
 #include <SkCanvas.h>
-#include <SkImagePriv.h>
-#include <SkWebpEncoder.h>
+#include <SkColor.h>
+#include <SkEncodedImageFormat.h>
 #include <SkHighContrastFilter.h>
+#include <SkImageEncoder.h>
+#include <SkImagePriv.h>
+#include <SkPixmap.h>
+#include <SkRect.h>
+#include <SkStream.h>
+#include <SkWebpEncoder.h>
 #include <limits>
 
 namespace android {
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 94a047c..133f1fe 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -19,9 +19,9 @@
 #include <SkColorFilter.h>
 #include <SkColorSpace.h>
 #include <SkImage.h>
-#include <SkImage.h>
 #include <SkImageInfo.h>
 #include <SkPixelRef.h>
+#include <SkRefCnt.h>
 #include <cutils/compiler.h>
 #ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
 #include <android/hardware_buffer.h>
diff --git a/libs/hwui/hwui/BlurDrawLooper.cpp b/libs/hwui/hwui/BlurDrawLooper.cpp
index 270d24a..d4b0198 100644
--- a/libs/hwui/hwui/BlurDrawLooper.cpp
+++ b/libs/hwui/hwui/BlurDrawLooper.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "BlurDrawLooper.h"
+#include <SkColorSpace.h>
 #include <SkMaskFilter.h>
 
 namespace android {
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index b046f45..cd8af3d 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -26,6 +26,7 @@
 #include "hwui/PaintFilter.h"
 
 #include <SkFontMetrics.h>
+#include <SkRRect.h>
 
 namespace android {
 
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 8277764..7378351 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -31,6 +31,7 @@
 
 class SkAnimatedImage;
 class SkCanvasState;
+class SkRRect;
 class SkRuntimeShaderBuilder;
 class SkVertices;
 
diff --git a/libs/hwui/hwui/ImageDecoder.h b/libs/hwui/hwui/ImageDecoder.h
index cef2233..b6d73b3 100644
--- a/libs/hwui/hwui/ImageDecoder.h
+++ b/libs/hwui/hwui/ImageDecoder.h
@@ -17,9 +17,11 @@
 
 #include <SkAndroidCodec.h>
 #include <SkCodec.h>
+#include <SkColorSpace.h>
 #include <SkImageInfo.h>
 #include <SkPngChunkReader.h>
 #include <SkRect.h>
+#include <SkRefCnt.h>
 #include <SkSize.h>
 #include <cutils/compiler.h>
 
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index 2db3ace..34cb4ae 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -16,10 +16,13 @@
 
 #include "MinikinSkia.h"
 
-#include <SkFontDescriptor.h>
 #include <SkFont.h>
+#include <SkFontDescriptor.h>
 #include <SkFontMetrics.h>
 #include <SkFontMgr.h>
+#include <SkRect.h>
+#include <SkScalar.h>
+#include <SkStream.h>
 #include <SkTypeface.h>
 #include <log/log.h>
 
diff --git a/libs/hwui/jni/AnimatedImageDrawable.cpp b/libs/hwui/jni/AnimatedImageDrawable.cpp
index c40b858..373e893 100644
--- a/libs/hwui/jni/AnimatedImageDrawable.cpp
+++ b/libs/hwui/jni/AnimatedImageDrawable.cpp
@@ -21,8 +21,11 @@
 #include <SkAndroidCodec.h>
 #include <SkAnimatedImage.h>
 #include <SkColorFilter.h>
+#include <SkEncodedImageFormat.h>
 #include <SkPicture.h>
 #include <SkPictureRecorder.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
 #include <hwui/AnimatedImageDrawable.h>
 #include <hwui/ImageDecoder.h>
 #include <hwui/Canvas.h>
diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp
index 5db0783..94cea65 100755
--- a/libs/hwui/jni/Bitmap.cpp
+++ b/libs/hwui/jni/Bitmap.cpp
@@ -2,17 +2,25 @@
 #define LOG_TAG "Bitmap"
 #include "Bitmap.h"
 
+#include "GraphicsJNI.h"
 #include "SkBitmap.h"
+#include "SkBlendMode.h"
 #include "SkCanvas.h"
 #include "SkColor.h"
 #include "SkColorSpace.h"
-#include "SkPixelRef.h"
+#include "SkData.h"
 #include "SkImageEncoder.h"
 #include "SkImageInfo.h"
-#include "GraphicsJNI.h"
+#include "SkPaint.h"
+#include "SkPixelRef.h"
+#include "SkPixmap.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
 #include "SkStream.h"
+#include "SkTypes.h"
 #include "SkWebpEncoder.h"
 
+
 #include "android_nio_utils.h"
 #include "CreateJavaOutputStreamAdaptor.h"
 #include <hwui/Paint.h>
diff --git a/libs/hwui/jni/Bitmap.h b/libs/hwui/jni/Bitmap.h
index 73eca3a..21a93f0 100644
--- a/libs/hwui/jni/Bitmap.h
+++ b/libs/hwui/jni/Bitmap.h
@@ -19,7 +19,6 @@
 #include <jni.h>
 #include <android/bitmap.h>
 
-class SkBitmap;
 struct SkImageInfo;
 
 namespace android {
diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp
index 4e9daa4..320d332 100644
--- a/libs/hwui/jni/BitmapFactory.cpp
+++ b/libs/hwui/jni/BitmapFactory.cpp
@@ -8,9 +8,19 @@
 #include "MimeType.h"
 #include "NinePatchPeeker.h"
 #include "SkAndroidCodec.h"
+#include "SkBitmap.h"
+#include "SkBlendMode.h"
 #include "SkCanvas.h"
+#include "SkColorSpace.h"
+#include "SkEncodedImageFormat.h"
+#include "SkImageInfo.h"
 #include "SkMath.h"
+#include "SkPaint.h"
 #include "SkPixelRef.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkSamplingOptions.h"
+#include "SkSize.h"
 #include "SkStream.h"
 #include "SkString.h"
 #include "SkUtils.h"
diff --git a/libs/hwui/jni/BitmapRegionDecoder.cpp b/libs/hwui/jni/BitmapRegionDecoder.cpp
index 1c20415..eb56ae3 100644
--- a/libs/hwui/jni/BitmapRegionDecoder.cpp
+++ b/libs/hwui/jni/BitmapRegionDecoder.cpp
@@ -25,6 +25,7 @@
 #include "BitmapRegionDecoder.h"
 #include "SkBitmap.h"
 #include "SkCodec.h"
+#include "SkColorSpace.h"
 #include "SkData.h"
 #include "SkStream.h"
 
diff --git a/libs/hwui/jni/ByteBufferStreamAdaptor.cpp b/libs/hwui/jni/ByteBufferStreamAdaptor.cpp
index b10540c..97dbc9a 100644
--- a/libs/hwui/jni/ByteBufferStreamAdaptor.cpp
+++ b/libs/hwui/jni/ByteBufferStreamAdaptor.cpp
@@ -2,6 +2,7 @@
 #include "GraphicsJNI.h"
 #include "Utils.h"
 
+#include <SkData.h>
 #include <SkStream.h>
 
 using namespace android;
diff --git a/libs/hwui/jni/FontFamily.cpp b/libs/hwui/jni/FontFamily.cpp
index ce5ac38..acc1b04 100644
--- a/libs/hwui/jni/FontFamily.cpp
+++ b/libs/hwui/jni/FontFamily.cpp
@@ -24,6 +24,7 @@
 #include "SkData.h"
 #include "SkFontMgr.h"
 #include "SkRefCnt.h"
+#include "SkStream.h"
 #include "SkTypeface.h"
 #include "Utils.h"
 #include "fonts/Font.h"
diff --git a/libs/hwui/jni/GIFMovie.cpp b/libs/hwui/jni/GIFMovie.cpp
index fef51b8..ae6ac4c 100644
--- a/libs/hwui/jni/GIFMovie.cpp
+++ b/libs/hwui/jni/GIFMovie.cpp
@@ -7,9 +7,11 @@
 
 
 #include "Movie.h"
+#include "SkBitmap.h"
 #include "SkColor.h"
 #include "SkColorPriv.h"
 #include "SkStream.h"
+#include "SkTypes.h"
 
 #include "gif_lib.h"
 
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index 33669ac..6a3bc8f 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -8,10 +8,18 @@
 #include <nativehelper/JNIHelp.h>
 #include "GraphicsJNI.h"
 
+#include "include/private/SkTemplates.h" // SkTAddOffset
+#include "SkBitmap.h"
 #include "SkCanvas.h"
+#include "SkColorSpace.h"
 #include "SkFontMetrics.h"
+#include "SkImageInfo.h"
 #include "SkMath.h"
+#include "SkPixelRef.h"
+#include "SkPoint.h"
+#include "SkRect.h"
 #include "SkRegion.h"
+#include "SkTypes.h"
 #include <cutils/ashmem.h>
 #include <hwui/Canvas.h>
 
diff --git a/libs/hwui/jni/ImageDecoder.cpp b/libs/hwui/jni/ImageDecoder.cpp
index f7b8c01..bad710d 100644
--- a/libs/hwui/jni/ImageDecoder.cpp
+++ b/libs/hwui/jni/ImageDecoder.cpp
@@ -29,8 +29,12 @@
 
 #include <FrontBufferedStream.h>
 #include <SkAndroidCodec.h>
-#include <SkEncodedImageFormat.h>
+#include <SkBitmap.h>
+#include <SkColorSpace.h>
+#include <SkImageInfo.h>
+#include <SkRect.h>
 #include <SkStream.h>
+#include <SkString.h>
 
 #include <androidfw/Asset.h>
 #include <fcntl.h>
diff --git a/libs/hwui/jni/Movie.h b/libs/hwui/jni/Movie.h
index 736890d..02113dd 100644
--- a/libs/hwui/jni/Movie.h
+++ b/libs/hwui/jni/Movie.h
@@ -13,6 +13,7 @@
 #include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkRefCnt.h"
+#include "SkTypes.h"
 
 class SkStreamRewindable;
 
diff --git a/libs/hwui/jni/MovieImpl.cpp b/libs/hwui/jni/MovieImpl.cpp
index ae9e04e..abb75fa 100644
--- a/libs/hwui/jni/MovieImpl.cpp
+++ b/libs/hwui/jni/MovieImpl.cpp
@@ -5,11 +5,12 @@
  * found in the LICENSE file.
  */
 #include "Movie.h"
-#include "SkCanvas.h"
-#include "SkPaint.h"
+#include "SkBitmap.h"
+#include "SkStream.h"
+#include "SkTypes.h"
 
 // We should never see this in normal operation since our time values are
-// 0-based. So we use it as a sentinal.
+// 0-based. So we use it as a sentinel.
 #define UNINITIALIZED_MSEC ((SkMSec)-1)
 
 Movie::Movie()
@@ -81,8 +82,6 @@
 
 ////////////////////////////////////////////////////////////////////
 
-#include "SkStream.h"
-
 Movie* Movie::DecodeMemory(const void* data, size_t length) {
     SkMemoryStream stream(data, length, false);
     return Movie::DecodeStream(&stream);
diff --git a/libs/hwui/jni/NinePatch.cpp b/libs/hwui/jni/NinePatch.cpp
index 08fc80f..d50a8a2 100644
--- a/libs/hwui/jni/NinePatch.cpp
+++ b/libs/hwui/jni/NinePatch.cpp
@@ -24,8 +24,10 @@
 #include <hwui/Paint.h>
 #include <utils/Log.h>
 
+#include "SkBitmap.h"
 #include "SkCanvas.h"
 #include "SkLatticeIter.h"
+#include "SkRect.h"
 #include "SkRegion.h"
 #include "GraphicsJNI.h"
 #include "NinePatchPeeker.h"
diff --git a/libs/hwui/jni/NinePatchPeeker.cpp b/libs/hwui/jni/NinePatchPeeker.cpp
index 9171fc6..d85ede5 100644
--- a/libs/hwui/jni/NinePatchPeeker.cpp
+++ b/libs/hwui/jni/NinePatchPeeker.cpp
@@ -16,7 +16,7 @@
 
 #include "NinePatchPeeker.h"
 
-#include <SkBitmap.h>
+#include <SkScalar.h>
 #include <cutils/compiler.h>
 
 using namespace android;
diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp
index f768632..0aa1465 100644
--- a/libs/hwui/jni/Paint.cpp
+++ b/libs/hwui/jni/Paint.cpp
@@ -26,6 +26,7 @@
 #include <nativehelper/ScopedPrimitiveArray.h>
 
 #include "SkColorFilter.h"
+#include "SkColorSpace.h"
 #include "SkFont.h"
 #include "SkFontMetrics.h"
 #include "SkFontTypes.h"
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index 0bbd8a8..fa8e2e7 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -2,11 +2,21 @@
 #define LOG_TAG "ShaderJNI"
 
 #include "GraphicsJNI.h"
+#include "SkBitmap.h"
+#include "SkBlendMode.h"
+#include "SkColor.h"
 #include "SkColorFilter.h"
 #include "SkGradientShader.h"
+#include "SkImage.h"
 #include "SkImagePriv.h"
+#include "SkMatrix.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
+#include "SkSamplingOptions.h"
+#include "SkScalar.h"
 #include "SkShader.h"
-#include "SkBlendMode.h"
+#include "SkString.h"
+#include "SkTileMode.h"
 #include "include/effects/SkRuntimeEffect.h"
 
 #include <vector>
@@ -16,7 +26,7 @@
 /**
  * By default Skia gradients will interpolate their colors in unpremul space
  * and then premultiply each of the results. We must set this flag to preserve
- * backwards compatiblity by premultiplying the colors of the gradient first,
+ * backwards compatibility by premultiplying the colors of the gradient first,
  * and then interpolating between them.
  */
 static const uint32_t sGradientShaderFlags = SkGradientShader::kInterpolateColorsInPremul_Flag;
diff --git a/libs/hwui/jni/Utils.h b/libs/hwui/jni/Utils.h
index 6cdf44d..f6e3a0e 100644
--- a/libs/hwui/jni/Utils.h
+++ b/libs/hwui/jni/Utils.h
@@ -17,8 +17,11 @@
 #ifndef _ANDROID_GRAPHICS_UTILS_H_
 #define _ANDROID_GRAPHICS_UTILS_H_
 
+#include "SkRefCnt.h"
 #include "SkStream.h"
 
+class SkData;
+
 #include <jni.h>
 #include <androidfw/Asset.h>
 
diff --git a/libs/hwui/jni/YuvToJpegEncoder.cpp b/libs/hwui/jni/YuvToJpegEncoder.cpp
index 77f42ae..87eda7e 100644
--- a/libs/hwui/jni/YuvToJpegEncoder.cpp
+++ b/libs/hwui/jni/YuvToJpegEncoder.cpp
@@ -1,5 +1,7 @@
 #include "CreateJavaOutputStreamAdaptor.h"
 #include "SkJPEGWriteUtility.h"
+#include "SkStream.h"
+#include "SkTypes.h"
 #include "YuvToJpegEncoder.h"
 #include <ui/PixelFormat.h>
 #include <hardware/hardware.h>
diff --git a/libs/hwui/jni/YuvToJpegEncoder.h b/libs/hwui/jni/YuvToJpegEncoder.h
index 7e7b935..a69726b1 100644
--- a/libs/hwui/jni/YuvToJpegEncoder.h
+++ b/libs/hwui/jni/YuvToJpegEncoder.h
@@ -1,13 +1,13 @@
 #ifndef _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
 #define _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
 
-#include "SkTypes.h"
-#include "SkStream.h"
 extern "C" {
     #include "jpeglib.h"
     #include "jerror.h"
 }
 
+class SkWStream;
+
 class YuvToJpegEncoder {
 public:
     /** Create an encoder based on the YUV format.
diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp
index 0ef80ee..61bb665 100644
--- a/libs/hwui/jni/android_graphics_Canvas.cpp
+++ b/libs/hwui/jni/android_graphics_Canvas.cpp
@@ -32,10 +32,22 @@
 
 #include "FontUtils.h"
 #include "Bitmap.h"
+#include "SkBitmap.h"
+#include "SkBlendMode.h"
+#include "SkClipOp.h"
+#include "SkColor.h"
+#include "SkColorSpace.h"
 #include "SkGraphics.h"
+#include "SkImageInfo.h"
+#include "SkMatrix.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
 #include "SkRegion.h"
-#include "SkVertices.h"
 #include "SkRRect.h"
+#include "SkScalar.h"
+#include "SkVertices.h"
 
 namespace minikin {
 class MeasuredText;
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index c48448d..55b1f23 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -23,8 +23,16 @@
 #include <Picture.h>
 #include <Properties.h>
 #include <RootRenderNode.h>
+#include <SkBitmap.h>
+#include <SkColorSpace.h>
+#include <SkData.h>
+#include <SkImage.h>
 #include <SkImagePriv.h>
+#include <SkPicture.h>
+#include <SkPixmap.h>
 #include <SkSerialProcs.h>
+#include <SkStream.h>
+#include <SkTypeface.h>
 #include <dlfcn.h>
 #include <gui/TraceUtils.h>
 #include <inttypes.h>
@@ -451,7 +459,7 @@
 };
 
 // TODO: This & Multi-SKP & Single-SKP should all be de-duped into
-// a single "make a SkPicture serailizable-safe" utility somewhere
+// a single "make a SkPicture serializable-safe" utility somewhere
 class PictureWrapper : public Picture {
 public:
     PictureWrapper(sk_sp<SkPicture>&& src, const std::shared_ptr<PictureCaptureState>& state)
diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp
index 09be630..2c421f8 100644
--- a/libs/hwui/jni/fonts/Font.cpp
+++ b/libs/hwui/jni/fonts/Font.cpp
@@ -22,7 +22,10 @@
 #include "SkFont.h"
 #include "SkFontMetrics.h"
 #include "SkFontMgr.h"
+#include "SkRect.h"
 #include "SkRefCnt.h"
+#include "SkScalar.h"
+#include "SkStream.h"
 #include "SkTypeface.h"
 #include "GraphicsJNI.h"
 #include <nativehelper/ScopedUtfChars.h>
diff --git a/libs/hwui/pipeline/skia/DumpOpsCanvas.h b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
index 3f89c07..6a052db 100644
--- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h
+++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
@@ -19,6 +19,8 @@
 #include "RenderNode.h"
 #include "SkiaDisplayList.h"
 
+class SkRRect;
+
 namespace android {
 namespace uirenderer {
 namespace skiapipeline {
diff --git a/libs/hwui/pipeline/skia/HolePunch.h b/libs/hwui/pipeline/skia/HolePunch.h
index 92c6f77..d0e1ca3 100644
--- a/libs/hwui/pipeline/skia/HolePunch.h
+++ b/libs/hwui/pipeline/skia/HolePunch.h
@@ -17,7 +17,6 @@
 #pragma once
 
 #include <string>
-#include "SkRRect.h"
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 507d3dc..3bf2b2e 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -15,7 +15,11 @@
  */
 
 #include "RenderNodeDrawable.h"
+#include <SkPaint.h>
 #include <SkPaintFilterCanvas.h>
+#include <SkPoint.h>
+#include <SkRRect.h>
+#include <SkRect.h>
 #include <gui/TraceUtils.h>
 #include "RenderNode.h"
 #include "SkiaDisplayList.h"
diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp
index e7432ac..ef3f1ca 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.cpp
+++ b/libs/hwui/pipeline/skia/ShaderCache.cpp
@@ -16,6 +16,7 @@
 
 #include "ShaderCache.h"
 #include <GrDirectContext.h>
+#include <SkData.h>
 #include <gui/TraceUtils.h>
 #include <log/log.h>
 #include <openssl/sha.h>
diff --git a/libs/hwui/pipeline/skia/ShaderCache.h b/libs/hwui/pipeline/skia/ShaderCache.h
index 4dcc9fb..dd57d42 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.h
+++ b/libs/hwui/pipeline/skia/ShaderCache.h
@@ -17,12 +17,15 @@
 #pragma once
 
 #include <GrContextOptions.h>
+#include <SkRefCnt.h>
 #include <cutils/compiler.h>
 #include <memory>
 #include <mutex>
 #include <string>
 #include <vector>
 
+class SkData;
+
 namespace android {
 
 class BlobCache;
@@ -45,7 +48,7 @@
      * and puts the ShaderCache into an initialized state, such that it is
      * able to insert and retrieve entries from the cache. If identity is
      * non-null and validation fails, the cache is initialized but contains
-     * no data. If size is less than zero, the cache is initilaized but
+     * no data. If size is less than zero, the cache is initialized but
      * contains no data.
      *
      * This should be called when HWUI pipeline is initialized. When not in
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index bc386fe..c546ada 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -16,15 +16,25 @@
 
 #include "SkiaPipeline.h"
 
+#include <SkCanvas.h>
+#include <SkColor.h>
+#include <SkColorSpace.h>
+#include <SkData.h>
+#include <SkImage.h>
 #include <SkImageEncoder.h>
 #include <SkImageInfo.h>
 #include <SkImagePriv.h>
+#include <SkMatrix.h>
 #include <SkMultiPictureDocument.h>
 #include <SkOverdrawCanvas.h>
 #include <SkOverdrawColorFilter.h>
 #include <SkPicture.h>
 #include <SkPictureRecorder.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
 #include <SkSerialProcs.h>
+#include <SkStream.h>
+#include <SkString.h>
 #include <SkTypeface.h>
 #include <android-base/properties.h>
 #include <unistd.h>
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index bc8a565..7887d1a 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -16,14 +16,16 @@
 
 #pragma once
 
-#include <SkSurface.h>
+#include <SkColorSpace.h>
 #include <SkDocument.h>
 #include <SkMultiPictureDocument.h>
+#include <SkSurface.h>
 #include "Lighting.h"
 #include "hwui/AnimatedImageDrawable.h"
 #include "renderthread/CanvasContext.h"
 #include "renderthread/IRenderPipeline.h"
 
+class SkFILEWStream;
 class SkPictureRecorder;
 struct SkSharingSerialContext;
 
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 9c51e62..5c6117d 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -16,7 +16,20 @@
 
 #include "SkiaRecordingCanvas.h"
 #include "hwui/Paint.h"
+#include <include/private/SkTemplates.h> // SkAutoSTMalloc
+#include <SkBlendMode.h>
+#include <SkData.h>
+#include <SkDrawable.h>
+#include <SkImage.h>
 #include <SkImagePriv.h>
+#include <SkMatrix.h>
+#include <SkPaint.h>
+#include <SkPoint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+#include <SkRRect.h>
+#include <SkSamplingOptions.h>
+#include <SkTypes.h>
 #include "CanvasTransform.h"
 #ifdef __ANDROID__ // Layoutlib does not support Layers
 #include "Layer.h"
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 1445a27..89e3a2c 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -22,6 +22,11 @@
 #include "SkiaDisplayList.h"
 #include "pipeline/skia/AnimatedDrawables.h"
 
+class SkBitmap;
+class SkMatrix;
+class SkPaint;
+class SkRRect;
+
 namespace android {
 namespace uirenderer {
 namespace skiapipeline {
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 56d42e0..a721be3 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -22,6 +22,11 @@
 
 #include "renderstate/RenderState.h"
 
+#include "SkRefCnt.h"
+
+class SkBitmap;
+struct SkRect;
+
 namespace android {
 namespace uirenderer {
 namespace skiapipeline {
diff --git a/libs/hwui/pipeline/skia/TransformCanvas.cpp b/libs/hwui/pipeline/skia/TransformCanvas.cpp
index 41e3687..33160d0 100644
--- a/libs/hwui/pipeline/skia/TransformCanvas.cpp
+++ b/libs/hwui/pipeline/skia/TransformCanvas.cpp
@@ -19,6 +19,10 @@
 #include "HolePunch.h"
 #include "SkData.h"
 #include "SkDrawable.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+#include "SkRect.h"
+#include "SkRRect.h"
 
 using namespace android::uirenderer::skiapipeline;
 
diff --git a/libs/hwui/pipeline/skia/TransformCanvas.h b/libs/hwui/pipeline/skia/TransformCanvas.h
index 685b71d..15f0c1a 100644
--- a/libs/hwui/pipeline/skia/TransformCanvas.h
+++ b/libs/hwui/pipeline/skia/TransformCanvas.h
@@ -19,6 +19,13 @@
 #include "SkPaintFilterCanvas.h"
 #include <effects/StretchEffect.h>
 
+class SkData;
+class SkDrawable;
+class SkMatrix;
+class SkPaint;
+enum class SkBlendMode;
+struct SkRect;
+
 class TransformCanvas : public SkPaintFilterCanvas {
 public:
     TransformCanvas(SkCanvas* target, SkBlendMode blendmode) :
diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h
index fc6b28d..b8f8c92 100644
--- a/libs/hwui/renderthread/EglManager.h
+++ b/libs/hwui/renderthread/EglManager.h
@@ -18,6 +18,7 @@
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
+#include <SkColorSpace.h>
 #include <SkImageInfo.h>
 #include <SkRect.h>
 #include <cutils/compiler.h>
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index aceb5a5..0238889 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -24,6 +24,7 @@
 #include "hwui/Bitmap.h"
 #include "ColorMode.h"
 
+#include <SkColorSpace.h>
 #include <SkRect.h>
 #include <utils/RefBase.h>
 
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index a44b498..b2ba15c 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -29,6 +29,10 @@
 #include "utils/Macros.h"
 #include "utils/TimeUtils.h"
 
+#include <SkBitmap.h>
+#include <SkImage.h>
+#include <SkPicture.h>
+
 #include <pthread.h>
 
 namespace android {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index ee9efd4..bbfeeac 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -17,7 +17,7 @@
 #ifndef RENDERPROXY_H_
 #define RENDERPROXY_H_
 
-#include <SkBitmap.h>
+#include <SkRefCnt.h>
 #include <android/native_window.h>
 #include <cutils/compiler.h>
 #include <android/surface_control.h>
@@ -30,6 +30,10 @@
 #include "SwapBehavior.h"
 #include "hwui/Bitmap.h"
 
+class SkBitmap;
+class SkPicture;
+class SkImage;
+
 namespace android {
 class GraphicBuffer;
 class Surface;
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 01b956c..3ff4081 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -266,7 +266,7 @@
     }
     mEglManager->initialize();
 
-    sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
+    sk_sp<const GrGLInterface> glInterface = GrGLMakeNativeInterface();
     LOG_ALWAYS_FATAL_IF(!glInterface.get());
 
     GrContextOptions options;
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index b816649..cba210d 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -51,6 +51,9 @@
 #include "VulkanSurface.h"
 #include "private/hwui/DrawVkInfo.h"
 
+#include <SkColorSpace.h>
+#include <SkRefCnt.h>
+
 class GrVkExtensions;
 
 namespace android {
diff --git a/libs/hwui/renderthread/VulkanSurface.h b/libs/hwui/renderthread/VulkanSurface.h
index beb71b72..2648666 100644
--- a/libs/hwui/renderthread/VulkanSurface.h
+++ b/libs/hwui/renderthread/VulkanSurface.h
@@ -20,6 +20,7 @@
 #include <system/window.h>
 #include <vulkan/vulkan.h>
 
+#include <SkColorSpace.h>
 #include <SkRefCnt.h>
 #include <SkSize.h>
 
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 491af43..a4890ed 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -26,7 +26,13 @@
 #include <renderthread/VulkanManager.h>
 #include <utils/Unicode.h>
 
+#include "SkCanvas.h"
 #include "SkColorData.h"
+#include "SkMatrix.h"
+#include "SkPath.h"
+#include "SkPixmap.h"
+#include "SkRect.h"
+#include "SkSurface.h"
 #include "SkUnPreMultiply.h"
 
 namespace android {
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 5092675..75865c7 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -27,10 +27,20 @@
 #include <renderstate/RenderState.h>
 #include <renderthread/RenderThread.h>
 
+#include <SkBitmap.h>
+#include <SkColor.h>
+#include <SkImageInfo.h>
+#include <SkRefCnt.h>
+
 #include <gtest/gtest.h>
 #include <memory>
 #include <unordered_map>
 
+class SkCanvas;
+class SkMatrix;
+class SkPath;
+struct SkRect;
+
 namespace android {
 namespace uirenderer {
 
diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
index 03aeb55..a07cdf7 100644
--- a/libs/hwui/tests/common/scenes/BitmapShaders.cpp
+++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
@@ -14,7 +14,17 @@
  * limitations under the License.
  */
 
-#include <SkImagePriv.h>
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkCanvas.h>
+#include <SkImage.h>
+#include <SkImageInfo.h>
+#include <SkPaint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+#include <SkSamplingOptions.h>
+#include <SkShader.h>
+#include <SkTileMode.h>
 #include "hwui/Paint.h"
 #include "TestSceneBase.h"
 #include "tests/common/BitmapAllocationTestUtils.h"
diff --git a/libs/hwui/tests/common/scenes/HwBitmap565.cpp b/libs/hwui/tests/common/scenes/HwBitmap565.cpp
index cbdb756..de0ef6d 100644
--- a/libs/hwui/tests/common/scenes/HwBitmap565.cpp
+++ b/libs/hwui/tests/common/scenes/HwBitmap565.cpp
@@ -18,6 +18,12 @@
 #include "tests/common/BitmapAllocationTestUtils.h"
 #include "utils/Color.h"
 
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkCanvas.h>
+#include <SkPaint.h>
+#include <SkRefCnt.h>
+
 class HwBitmap565;
 
 static TestScene::Registrar _HwBitmap565(TestScene::Info{
diff --git a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
index 564354f..0d5ca6d 100644
--- a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
+++ b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
@@ -17,6 +17,7 @@
 #include "TestSceneBase.h"
 #include "utils/Color.h"
 
+#include <SkColorSpace.h>
 #include <SkGradientShader.h>
 #include <SkImagePriv.h>
 #include <ui/PixelFormat.h>
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index d031923..4a5d946 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -17,7 +17,16 @@
 #include "TestSceneBase.h"
 #include "tests/common/TestListViewSceneBase.h"
 #include "hwui/Paint.h"
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkColor.h>
 #include <SkFont.h>
+#include <SkFontTypes.h>
+#include <SkPaint.h>
+#include <SkPoint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+#include <SkScalar.h>
 #include <cstdio>
 
 class ListViewAnimation;
@@ -48,7 +57,7 @@
                 128 * 3;
         paint.setColor(bgDark ? Color::White : Color::Grey_700);
 
-	SkFont font;
+        SkFont font;
         font.setSize(size / 2);
         char charToShow = 'A' + (rand() % 26);
         const SkPoint pos = {SkIntToScalar(size / 2),
diff --git a/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp b/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp
index edadf78..070a339 100644
--- a/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp
@@ -19,6 +19,10 @@
 #include "utils/Color.h"
 #include "hwui/Paint.h"
 
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkFont.h>
+
 class MagnifierAnimation;
 
 static TestScene::Registrar _Magnifier(TestScene::Info{
diff --git a/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp
index 716d397..3caaf82 100644
--- a/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp
+++ b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp
@@ -16,6 +16,12 @@
 
 #include "TestSceneBase.h"
 
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkPaint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+
 class ReadbackFromHardware;
 
 static TestScene::Registrar _SaveLayer(TestScene::Info{
diff --git a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
index 1c25078..27948f8 100644
--- a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
@@ -17,6 +17,11 @@
 #include "TestSceneBase.h"
 #include "utils/Color.h"
 
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkColor.h>
+#include <SkRefCnt.h>
+
 class RecentsAnimation;
 
 static TestScene::Registrar _Recents(TestScene::Info{
diff --git a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
index e677549..59230a7 100644
--- a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
@@ -14,7 +14,15 @@
  * limitations under the License.
  */
 
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkColor.h>
 #include <SkFont.h>
+#include <SkFontTypes.h>
+#include <SkPaint.h>
+#include <SkPoint.h>
+#include <SkRefCnt.h>
+#include <SkRRect.h>
 #include <cstdio>
 #include "TestSceneBase.h"
 #include "hwui/Paint.h"
diff --git a/libs/hwui/tests/common/scenes/TvApp.cpp b/libs/hwui/tests/common/scenes/TvApp.cpp
index c6219c48..aff8ca1 100644
--- a/libs/hwui/tests/common/scenes/TvApp.cpp
+++ b/libs/hwui/tests/common/scenes/TvApp.cpp
@@ -14,7 +14,12 @@
  * limitations under the License.
  */
 
+#include "SkBitmap.h"
 #include "SkBlendMode.h"
+#include "SkColorFilter.h"
+#include "SkFont.h"
+#include "SkImageInfo.h"
+#include "SkRefCnt.h"
 #include "TestSceneBase.h"
 #include "tests/common/BitmapAllocationTestUtils.h"
 #include "hwui/Paint.h"
diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp
index 2cf3456..d2b1ef9 100644
--- a/libs/hwui/tests/unit/CanvasOpTests.cpp
+++ b/libs/hwui/tests/unit/CanvasOpTests.cpp
@@ -23,9 +23,17 @@
 
 #include <tests/common/CallCountingCanvas.h>
 
-#include "SkPictureRecorder.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
 #include "SkColor.h"
+#include "SkImageInfo.h"
 #include "SkLatticeIter.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkPictureRecorder.h"
+#include "SkRRect.h"
+#include "SkRect.h"
+#include "SkRegion.h"
 #include "pipeline/skia/AnimatedDrawables.h"
 #include <SkNoDrawCanvas.h>
 
diff --git a/libs/hwui/tests/unit/EglManagerTests.cpp b/libs/hwui/tests/unit/EglManagerTests.cpp
index 7f2e158..ec9ab90 100644
--- a/libs/hwui/tests/unit/EglManagerTests.cpp
+++ b/libs/hwui/tests/unit/EglManagerTests.cpp
@@ -20,6 +20,8 @@
 #include "renderthread/RenderEffectCapabilityQuery.h"
 #include "tests/common/TestContext.h"
 
+#include <SkColorSpace.h>
+
 using namespace android;
 using namespace android::uirenderer;
 using namespace android::uirenderer::renderthread;
diff --git a/libs/hwui/tests/unit/FatalTestCanvas.h b/libs/hwui/tests/unit/FatalTestCanvas.h
index 2a74afc..96a0c61 100644
--- a/libs/hwui/tests/unit/FatalTestCanvas.h
+++ b/libs/hwui/tests/unit/FatalTestCanvas.h
@@ -19,6 +19,8 @@
 #include <SkCanvas.h>
 #include <gtest/gtest.h>
 
+class SkRRect;
+
 namespace {
 
 class TestCanvasBase : public SkCanvas {
diff --git a/libs/hwui/tests/unit/ShaderCacheTests.cpp b/libs/hwui/tests/unit/ShaderCacheTests.cpp
index 87981f1..105fea4 100644
--- a/libs/hwui/tests/unit/ShaderCacheTests.cpp
+++ b/libs/hwui/tests/unit/ShaderCacheTests.cpp
@@ -25,6 +25,8 @@
 #include <cstdint>
 #include "FileBlobCache.h"
 #include "pipeline/skia/ShaderCache.h"
+#include <SkData.h>
+#include <SkRefCnt.h>
 
 using namespace android::uirenderer::skiapipeline;
 
diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index dc1b2e6..c1ddbd36 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -16,9 +16,14 @@
 
 #include "tests/common/TestUtils.h"
 
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkColor.h>
 #include <SkColorMatrixFilter.h>
 #include <SkColorSpace.h>
-#include <SkImagePriv.h>
+#include <SkImageInfo.h>
+#include <SkPaint.h>
+#include <SkPath.h>
 #include <SkPathOps.h>
 #include <SkShader.h>
 #include <gtest/gtest.h>
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
index dae3c94..50d9f56 100644
--- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -18,6 +18,7 @@
 
 #include <hwui/Paint.h>
 #include <SkCanvasStateUtils.h>
+#include <SkColorSpace.h>
 #include <SkPicture.h>
 #include <SkPictureRecorder.h>
 #include <gtest/gtest.h>
diff --git a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
index 15ecf58..ced667e 100644
--- a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
+++ b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
@@ -17,6 +17,7 @@
 #include <VectorDrawable.h>
 #include <gtest/gtest.h>
 
+#include <SkCanvas.h>
 #include <SkClipStack.h>
 #include <SkSurface_Base.h>
 #include <string.h>
diff --git a/libs/hwui/tests/unit/TypefaceTests.cpp b/libs/hwui/tests/unit/TypefaceTests.cpp
index ab23448..9295a93 100644
--- a/libs/hwui/tests/unit/TypefaceTests.cpp
+++ b/libs/hwui/tests/unit/TypefaceTests.cpp
@@ -21,8 +21,11 @@
 #include <sys/stat.h>
 #include <utils/Log.h>
 
+#include "SkData.h"
 #include "SkFontMgr.h"
+#include "SkRefCnt.h"
 #include "SkStream.h"
+#include "SkTypeface.h"
 
 #include "hwui/MinikinSkia.h"
 #include "hwui/Typeface.h"
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 6d4c574..c1c21bd 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -21,6 +21,12 @@
 #include "utils/MathUtils.h"
 #include "utils/VectorDrawableUtils.h"
 
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkPath.h>
+#include <SkRefCnt.h>
+#include <SkShader.h>
+
 #include <functional>
 
 namespace android {
diff --git a/libs/input/MouseCursorController.cpp b/libs/input/MouseCursorController.cpp
index 45da008..956101e 100644
--- a/libs/input/MouseCursorController.cpp
+++ b/libs/input/MouseCursorController.cpp
@@ -24,12 +24,6 @@
 
 #include <log/log.h>
 
-#include <SkBitmap.h>
-#include <SkBlendMode.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkPaint.h>
-
 namespace {
 // Time to spend fading out the pointer completely.
 const nsecs_t POINTER_FADE_DURATION = 500 * 1000000LL; // 500 ms
diff --git a/libs/input/TouchSpotController.cpp b/libs/input/TouchSpotController.cpp
index f7c685f..4ac66c4 100644
--- a/libs/input/TouchSpotController.cpp
+++ b/libs/input/TouchSpotController.cpp
@@ -23,12 +23,6 @@
 
 #include <log/log.h>
 
-#include <SkBitmap.h>
-#include <SkBlendMode.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkPaint.h>
-
 namespace {
 // Time to spend fading out the spot completely.
 const nsecs_t SPOT_FADE_DURATION = 200 * 1000000LL; // 200 ms
diff --git a/media/aidl/android/media/audio/common/AudioPort.aidl b/media/aidl/android/media/audio/common/AudioPort.aidl
index 84675e3..d32b840 100644
--- a/media/aidl/android/media/audio/common/AudioPort.aidl
+++ b/media/aidl/android/media/audio/common/AudioPort.aidl
@@ -23,8 +23,9 @@
 import android.media.audio.common.ExtraAudioDescriptor;
 
 /**
- * Audio port structure describes the capabilities of an audio port
- * as well as its current configuration.
+ * Audio port structure describes the capabilities of an audio port.
+ * This is a "blueprint" which contains all the possible configurations
+ * that are supported by the port.
  *
  * {@hide}
  */
diff --git a/media/aidl/android/media/audio/common/AudioPortExt.aidl b/media/aidl/android/media/audio/common/AudioPortExt.aidl
index c4681cb..eadc0ab 100644
--- a/media/aidl/android/media/audio/common/AudioPortExt.aidl
+++ b/media/aidl/android/media/audio/common/AudioPortExt.aidl
@@ -34,6 +34,9 @@
     AudioPortDeviceExt device;
     /** Information specific to mix ports. */
     AudioPortMixExt mix;
-    /** Audio session identifier. */
+    /**
+     * NOT USED. Framework audio session identifier.
+     * Use android.media.AudioPortExtSys.session on the system side.
+     */
     int session;
 }
diff --git a/media/aidl/android/media/audio/common/AudioPortMixExt.aidl b/media/aidl/android/media/audio/common/AudioPortMixExt.aidl
index f3613a4..eb117ec 100644
--- a/media/aidl/android/media/audio/common/AudioPortMixExt.aidl
+++ b/media/aidl/android/media/audio/common/AudioPortMixExt.aidl
@@ -32,12 +32,12 @@
     AudioPortMixExtUseCase usecase;
     /**
      * Maximum number of input or output streams that can be simultaneously
-     * opened for this port.
+     * opened for this port. '0' means 'unlimited'.
      */
     int maxOpenStreamCount;
     /**
      * Maximum number of input or output streams that can be simultaneously
-     * active for this port.
+     * active for this port. '0' means 'all opened streams'.
      */
     int maxActiveStreamCount;
     /** Mute duration while changing device, when used for output. */
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index e7eda3e..2c68273 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1636,8 +1636,10 @@
      *
      * @param on set <var>true</var> to turn on speakerphone;
      *           <var>false</var> to turn it off
+     * @deprecated Use {@link AudioManager#setCommunicationDevice(AudioDeviceInfo)} or
+     *           {@link AudioManager#clearCommunicationDevice()} instead.
      */
-    public void setSpeakerphoneOn(boolean on){
+    @Deprecated public void setSpeakerphoneOn(boolean on) {
         final IAudioService service = getService();
         try {
             service.setSpeakerphoneOn(mICallBack, on);
@@ -1650,8 +1652,9 @@
      * Checks whether the speakerphone is on or off.
      *
      * @return true if speakerphone is on, false if it's off
+     * @deprecated Use {@link AudioManager#getCommunicationDevice()} instead.
      */
-    public boolean isSpeakerphoneOn() {
+    @Deprecated public boolean isSpeakerphoneOn() {
         final IAudioService service = getService();
         try {
             return service.isSpeakerphoneOn();
@@ -2717,8 +2720,9 @@
      * connection is established.
      * @see #stopBluetoothSco()
      * @see #ACTION_SCO_AUDIO_STATE_UPDATED
+     * @deprecated Use {@link AudioManager#setCommunicationDevice(AudioDeviceInfo)} instead.
      */
-    public void startBluetoothSco(){
+    @Deprecated public void startBluetoothSco() {
         final IAudioService service = getService();
         try {
             service.startBluetoothSco(mICallBack,
@@ -2761,9 +2765,10 @@
      * bluetooth SCO audio with {@link #startBluetoothSco()} when finished with the SCO
      * connection or if connection fails.
      * @see #startBluetoothSco()
+     * @deprecated Use {@link AudioManager#clearCommunicationDevice()} instead.
      */
     // Also used for connections started with {@link #startBluetoothScoVirtualCall()}
-    public void stopBluetoothSco(){
+    @Deprecated public void stopBluetoothSco() {
         final IAudioService service = getService();
         try {
             service.stopBluetoothSco(mICallBack);
@@ -2795,8 +2800,9 @@
      *
      * @return true if SCO is used for communications;
      *         false if otherwise
+     * @deprecated Use {@link AudioManager#getCommunicationDevice()} instead.
      */
-    public boolean isBluetoothScoOn() {
+    @Deprecated public boolean isBluetoothScoOn() {
         final IAudioService service = getService();
         try {
             return service.isBluetoothScoOn();
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 149c2f4..04d28e7 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -60,7 +60,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -484,7 +483,7 @@
     private final Object mLock = new Object();
 
     // @GuardedBy("mLock")
-    private final List<TvInputCallbackRecord> mCallbackRecords = new LinkedList<>();
+    private final List<TvInputCallbackRecord> mCallbackRecords = new ArrayList<>();
 
     // A mapping from TV input ID to the state of corresponding input.
     // @GuardedBy("mLock")
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
index 43d4605..88ca30c 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
@@ -50,8 +50,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.Executor;
 
@@ -302,7 +302,7 @@
             new SparseArray<>();
 
     // @GuardedBy("mLock")
-    private final List<TvInteractiveAppCallbackRecord> mCallbackRecords = new LinkedList<>();
+    private final List<TvInteractiveAppCallbackRecord> mCallbackRecords = new ArrayList<>();
 
     // A sequence number for the next session to be created. Should be protected by a lock
     // {@code mSessionCallbackRecordMap}.
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 18b779f..e3e200f 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -129,6 +129,7 @@
 cc_library_shared {
     name: "libmedia_jni_utils",
     srcs: [
+        ":libgui_frame_event_aidl",
         "android_media_Utils.cpp",
     ],
 
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 1ebdc27..98edcc3 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -669,6 +669,8 @@
                                           AVsyncId vsyncId) {
     CHECK_NOT_NULL(aSurfaceTransaction);
     const auto startTime = AChoreographer_getStartTimeNanosForVsyncId(vsyncId);
-    ASurfaceTransaction_to_Transaction(aSurfaceTransaction)
-            ->setFrameTimelineInfo({.vsyncId = vsyncId, .startTimeNanos = startTime});
+    FrameTimelineInfo ftInfo;
+    ftInfo.vsyncId = vsyncId;
+    ftInfo.startTimeNanos = startTime;
+    ASurfaceTransaction_to_Transaction(aSurfaceTransaction)->setFrameTimelineInfo(ftInfo);
 }
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index bb25274..cd6ed23 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -25,6 +25,12 @@
 #include <hwui/ImageDecoder.h>
 #include <log/log.h>
 #include <SkAndroidCodec.h>
+#include <SkCodec.h>
+#include <SkColorSpace.h>
+#include <SkImageInfo.h>
+#include <SkRect.h>
+#include <SkSize.h>
+#include <SkStream.h>
 #include <utils/Color.h>
 
 #include <fcntl.h>
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
index 8b5d214..c1fce7c 100644
--- a/packages/CompanionDeviceManager/AndroidManifest.xml
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -48,6 +48,14 @@
             android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
             android:theme="@style/ChooserActivity"/>
 
+        <activity
+            android:name=".CompanionDeviceDataTransferActivity"
+            android:exported="true"
+            android:launchMode="singleInstance"
+            android:excludeFromRecents="true"
+            android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
+            android:theme="@style/ChooserActivity"/>
+
         <service
             android:name=".CompanionDeviceDiscoveryService"
             android:exported="false" />
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 3f86dd5..ff72a1c 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Laat toe"</string>
     <string name="consent_no" msgid="2640796915611404382">"Moenie toelaat nie"</string>
     <string name="consent_back" msgid="2560683030046918882">"Terug"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Dra programtoestemmings na jou horlosie toe oor"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Om dit makliker te maak om jou horlosie op te stel, sal programme wat gedurende opstelling op jou horlosie geïnstalleer word, dieselfde toestemmings as jou foon gebruik.\n\n Hierdie toestemmings kan toegang tot jou horlosie se mikrofoon en ligging insluit."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index 0c85047..609ef2e 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"ፍቀድ"</string>
     <string name="consent_no" msgid="2640796915611404382">"አትፍቀድ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ተመለስ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"የመተግበሪያ ፈቃዶችን ወደ የእጅ ሰዓትዎ ያስተላልፉ"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"የእጅ ሰዓትዎን ማቀናበርን ለማቅለል በማዋቀር ጊዜ በእጅ ሰዓትዎ ላይ የተጫኑ መተግበሪያዎች እንደ ስልክዎ ተመሳሳይ ፈቃዶችን ይጠቀማሉ።\n\n እነዚህ ፈቃዶች የእጅ ሰዓትዎ ማይክሮፎን እና አካባቢ መዳረሻን ሊያካትቱ ይችላሉ።"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index 4386e6a..dcf3436 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"السماح"</string>
     <string name="consent_no" msgid="2640796915611404382">"عدم السماح"</string>
     <string name="consent_back" msgid="2560683030046918882">"رجوع"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"نقل أذونات التطبيقات إلى ساعتك"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"لتسهيل إعداد ساعتك، فإن التطبيقات التي يتم تثبيتها على ساعتك أثناء الإعداد ستستخدم الأذونات نفسها التي يستخدمها هاتفك.\n\n قد تشتمل هذه الأذونات على الوصول إلى ميكروفون ساعتك وبيانات موقعها الجغرافي."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index b099d0c..e03d6c9 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিয়ক"</string>
     <string name="consent_no" msgid="2640796915611404382">"অনুমতি নিদিব"</string>
     <string name="consent_back" msgid="2560683030046918882">"উভতি যাওক"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"আপোনাৰ ঘড়ীলৈ এপৰ অনুমতিসমূহ স্থানান্তৰ কৰক"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"আপোনাৰ ঘড়ীটো ছেটআপ কৰাটো অধিক সহজ কৰি তুলিবলৈ, এয়া কৰাৰ সময়ত আপোনাৰ ঘড়ীটোত ইনষ্টল কৰি থোৱা এপ্‌সমূহে আপোনাৰ ফ’নৰ দৰে একেই অনুমতিসমূহ ব্যৱহাৰ কৰিব।\n\n এই অনুমতিসমূহত আপোনাৰ ঘড়ীৰ মাইক্ৰ’ফ’ন আৰু অৱস্থানৰ এক্সেছ অন্তৰ্ভুক্ত হ’ব পাৰে।"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index 1166ca1..fcc0683 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"İcazə verin"</string>
     <string name="consent_no" msgid="2640796915611404382">"İcazə verməyin"</string>
     <string name="consent_back" msgid="2560683030046918882">"Geriyə"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Tətbiq icazələrini saatınıza köçürün"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Saatınızı ayarlamağı asanlaşdırmaq üçün ayarlama zamanı saatınızda quraşdırılmış tətbiqlər telefonunuzla eyni icazələrdən istifadə edəcək.\n\n Bu icazələrə saatınızın mikrofonuna və məkanına giriş daxil ola bilər."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 9123e05..466ffef 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne dozvoli"</string>
     <string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prenesite dozvole za aplikacije na sat"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Da bismo pojednostavili podešavanje sata, aplikacije instalirane na satu tokom podešavanja će koristiti iste dozvole kao telefon.\n\n Te dozvole mogu da obuhvataju pristup mikrofonu i lokaciji sata."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 32264b4..12e2c85 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Дазволіць"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дазваляць"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Перанос дазволаў праграм на ваш гадзіннік"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Для праграм, усталяваных на гадзіннік падчас наладжвання, будуць дзейнічаць тыя самыя дазволы, што і на тэлефоне.\n\n Так гадзіннік можа атрымаць доступ да мікрафона і даных пра месцазнаходжанне."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index b603cb2..75db90a 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Разрешаване"</string>
     <string name="consent_no" msgid="2640796915611404382">"Забраняване"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Прехвърляне на разрешенията за приложенията към часовника"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"За по-лесно конфигуриране на часовника ви приложенията, инсталирани на него по време на настройването, ще използват същите разрешения като предоставените на телефона ви.\n\nТе може да включват достъп до микрофона и местоположението на часовника ви."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 498ea9a..805bf7a 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"অনুমতি দিন"</string>
     <string name="consent_no" msgid="2640796915611404382">"অনুমতি দেবেন না"</string>
     <string name="consent_back" msgid="2560683030046918882">"ফিরুন"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"অ্যাপকে দেওয়া অনুমতি আপনার ঘড়িতে ট্রান্সফার করুন"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"ঘড়ি আরও সহজে সেট আপ করতে, সেট আপ চলাকালীন আপনার ঘড়িতে ইনস্টল করা অ্যাপ ফোনের মতো একই অনুমতি ব্যবহার করবে।\n\n এইসব অনুমতির মধ্যে আপনার ঘড়ির মাইক্রোফোন ও লোকেশন সম্পর্কে তথ্যের অ্যাক্সেস অন্তর্ভুক্ত থাকতে পারে।"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index dc7efa0..f0a8351 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Dozvoli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nemoj dozvoliti"</string>
     <string name="consent_back" msgid="2560683030046918882">"Nazad"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prijenos odobrenja za aplikaciju na sat"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Radi lakšeg postavljanja sata, aplikacije instalirane na satu tokom postavljanja će koristiti ista odobrenja kao i na telefonu.\n\n Ta odobrenja mogu uključivati pristup mikrofonu i lokaciji sata."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 34fc76a..65fbf6d 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Permet"</string>
     <string name="consent_no" msgid="2640796915611404382">"No permetis"</string>
     <string name="consent_back" msgid="2560683030046918882">"Enrere"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfereix els permisos de les aplicacions al teu rellotge"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Per facilitar la configuració del rellotge, les aplicacions instal·lades al rellotge durant la configuració utilitzaran els mateixos permisos que al teu telèfon.\n\n Aquests permisos poden incloure l\'accés al micròfon i a la ubicació del rellotge."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index e8c7b09..4b5a546 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Povolit"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nepovolovat"</string>
     <string name="consent_back" msgid="2560683030046918882">"Zpět"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Přesunout oprávnění aplikací do hodinek"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Abychom vám usnadnili nastavení hodinek, aplikace nainstalované do hodinek během úvodního nastavení budou používat stejná oprávnění jako váš telefon.\n\n Tato oprávnění mohou zahrnovat přístup k mikrofonu a poloze hodinek."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index df41300..9cd6880 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Tillad"</string>
     <string name="consent_no" msgid="2640796915611404382">"Tillad ikke"</string>
     <string name="consent_back" msgid="2560683030046918882">"Tilbage"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Overfør apptilladelser til dit ur"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"For at gøre det nemmere at konfigurere dit ur vil de apps, der installeres under konfigurationen, anvende de samme tilladelser som din telefon.\n\n Disse tilladelser kan omfatte adgang til dit urs mikrofon og lokation."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 6134390..19266fd 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Zulassen"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nicht zulassen"</string>
     <string name="consent_back" msgid="2560683030046918882">"Zurück"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"App-Berechtigungen auf Smartwatch übertragen"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Damit sich deine Smartwatch leichter einrichten lässt, erhalten die Apps, die während der Einrichtung auf deiner Smartwatch installiert werden, automatisch die gleichen Berechtigungen wie deine Smartphone-Apps.\n\n Zu diesen Berechtigungen kann der Zugriff auf das Mikrofon und den Standort deiner Smartwatch gehören."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 4713c5d..b6108cd 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Να επιτρέπεται"</string>
     <string name="consent_no" msgid="2640796915611404382">"Να μην επιτρέπεται"</string>
     <string name="consent_back" msgid="2560683030046918882">"Πίσω"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Μεταφορά αδειών εφαρμογών στο ρολόι σας"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Για να είναι πιο εύκολη η ρύθμιση του ρολογιού σας, οι εφαρμογές που εγκαθίστανται στο ρολόι σας κατά τη ρύθμιση, θα χρησιμοποιούν τις ίδιες άδειες με το τηλέφωνό σας.\n\n Στις άδειες ενδέχεται να περιλαμβάνεται άδεια πρόσβασης στο μικρόφωνο και την τοποθεσία του ρολογιού σας."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index fff1e5e..34f1cb3 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
     <string name="consent_back" msgid="2560683030046918882">"Back"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer app permissions to your watch"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch’s microphone and location."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
index fff1e5e..34f1cb3 100644
--- a/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rCA/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
     <string name="consent_back" msgid="2560683030046918882">"Back"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer app permissions to your watch"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch’s microphone and location."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index fff1e5e..34f1cb3 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
     <string name="consent_back" msgid="2560683030046918882">"Back"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer app permissions to your watch"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch’s microphone and location."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index fff1e5e..34f1cb3 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Allow"</string>
     <string name="consent_no" msgid="2640796915611404382">"Don\'t allow"</string>
     <string name="consent_back" msgid="2560683030046918882">"Back"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer app permissions to your watch"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.\n\n These permissions may include access to your watch’s microphone and location."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
index a9a9631..69a212a 100644
--- a/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rXC/strings.xml
@@ -42,6 +42,6 @@
     <string name="consent_yes" msgid="8344487259618762872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎Allow‎‏‎‎‏‎"</string>
     <string name="consent_no" msgid="2640796915611404382">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎Don’t allow‎‏‎‎‏‎"</string>
     <string name="consent_back" msgid="2560683030046918882">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‏‎‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎Back‎‏‎‎‏‎"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‏‎‎‎‎‏‎‎Transfer app permissions to your watch‎‏‎‎‏‎"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎To make it easier to set up your watch, apps installed on your watch during setup will use the same permissions as your phone.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎ These permissions may include access to your watch’s microphone and location.‎‏‎‎‏‎"</string>
+    <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‏‏‏‏‎‎Give apps on &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt; the same permissions as on &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;?‎‏‎‎‏‎"</string>
+    <string name="permission_sync_summary" msgid="4866838188678457084">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‎&lt;p&gt;This may include Microphone, Camera, and Location access, and other sensitive permissions on &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;You can change these permissions any time in your Settings on &lt;strong&gt;‎‏‎‎‏‏‎<xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/strong&gt;.&lt;/p&gt;‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index 60b136a..12a8006 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfiere los permisos de la app a tu reloj"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Para que sea más fácil configurar tu reloj, las apps que se instalen en este durante la configuración usarán los mismos permisos que tu teléfono.\n\n Es posible que estos permisos incluyan el acceso al micrófono y a la ubicación del reloj."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index bcf6621..8293213 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"No permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir permisos de aplicaciones a tu reloj"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Para configurar fácilmente tu reloj, las aplicaciones que instales en él durante la configuración usarán los mismos permisos que tengan en tu teléfono.\n\n Estos permisos pueden incluir acceso al micrófono y a la ubicación del reloj."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index 49483ec..a5249e8 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Luba"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ära luba"</string>
     <string name="consent_back" msgid="2560683030046918882">"Tagasi"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Rakenduste lubade kellale ülekandmine"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Selleks et muuta kella seadistamine lihtsamaks, kasutavad teie kellas seadistamise ajal installitud rakendused samasid lubasid, mis neile telefonis antud on.\n\n Need load võivad hõlmata juurdepääsuluba kella mikrofonile ja asukohale."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index ec0ac20..1566479 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Eman baimena"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ez eman baimenik"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atzera"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferitu aplikazio-baimenak erlojura"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Erlojua errazago konfiguratzeko, konfigurazio-prozesua abian zen bitartean erlojuan instalatutako aplikazioek telefonoak darabiltzan baimen berak erabiliko dituzte.\n\n Baliteke baimen horien artean erlojuaren mikrofonoa eta kokapena atzitzeko baimenak egotea."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 663d7c5..e0f7d53 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"مجاز است"</string>
     <string name="consent_no" msgid="2640796915611404382">"مجاز نبودن"</string>
     <string name="consent_back" msgid="2560683030046918882">"برگشت"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"انتقال اجازه‌های برنامه به ساعت"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"برای آسان‌تر کردن راه‌اندازی ساعت، برنامه‌های نصب‌شده در ساعت درحین راه‌اندازی از همان اجازه‌های تلفن استفاده خواهند کرد.\n\n ممکن است این اجازه‌ها شامل دسترسی به میکروفون و مکان ساعت باشد."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index b10dc69..e18f634 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Salli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Älä salli"</string>
     <string name="consent_back" msgid="2560683030046918882">"Takaisin"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Siirrä sovellusluvat kelloon"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Sovellukset, jotka on asennettu kelloon käyttöönoton aikana, käyttävät samoja lupia kuin puhelin. Näin kello on helpompi ottaa käyttöön.\n\n Näihin lupiin saattaa kuulua pääsy kellon mikrofoniin ja sijaintiin."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 8d2b99e..773a345 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
     <string name="consent_back" msgid="2560683030046918882">"Retour"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transférer les autorisations de l\'application à votre montre"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Pour faciliter la configuration de votre montre, les applications installées sur celle-ci reprennent les mêmes autorisations que celles installées sur votre téléphone.\n\n Ces autorisations peuvent comprendre l\'accès au microphone et à la position de votre montre."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index e6167cd..73781b9 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Autoriser"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne pas autoriser"</string>
     <string name="consent_back" msgid="2560683030046918882">"Retour"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transférer les autorisations de l\'appli vers la montre"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Pour que votre montre soit plus facile à configurer, les applis qui y sont installées pendant la configuration utiliseront les mêmes autorisations que votre téléphone.\n\n Il peut s\'agir, par exemple, de l\'accès au micro et à la position de votre montre."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 3a94863..1c65e11 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Non permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atrás"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir os permisos de aplicacións ao reloxo"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Para que che resulte máis doado configurar o reloxo, as aplicacións que instales nel durante a configuración usarán os mesmos permisos que o teléfono.\n\n Entre estes permisos poden estar incluídos os de acceso ao micrófono e á localización do teléfono."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 6012c6c..879dfd1 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"મંજૂરી આપો"</string>
     <string name="consent_no" msgid="2640796915611404382">"મંજૂરી આપશો નહીં"</string>
     <string name="consent_back" msgid="2560683030046918882">"પાછળ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"તમારી ઘડિયાળમાં ઍપ પરવાનગીઓ ટ્રાન્સફર કરો"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"તમારી ઘડિયાળનું સેટઅપ કરવાનું સરળ બનાવવા માટે, સેટઅપ દરમિયાન તમારી ઘડિયાળ પર ઇન્સ્ટૉલ કરેલી ઍપ દ્વારા તમારા ફોન પર મળેલી પરવાનગીઓનો ઉપયોગ કરવામાં આવશે.\n\n આ પરવાનગીઓમાં તમારી ઘડિયાળના માઇક્રોફોન અને સ્થાન સંબંધિત માહિતીનો ઍક્સેસ શામેલ હોઈ શકે છે."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index aa0628e..7e071f3 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दें"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमति न दें"</string>
     <string name="consent_back" msgid="2560683030046918882">"वापस जाएं"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"ऐप्लिकेशन से जुड़ी अनुमतियों को अपनी वॉच में ट्रांसफ़र करें"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"वॉच को सेट अप करने की प्रोसेस को आसान बनाने के लिए, उस पर इंस्टॉल किए गए ऐप्लिकेशन को भी वही अनुमतियां मिलेंगी जो आपने उन ऐप्लिकेशन को फ़ोन पर दी होंगी.\n\n इन अनुमतियों में, आपकी वॉच के माइक्रोफ़ोन और जगह की जानकारी का ऐक्सेस शामिल हो सकता है."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index f5cd428..c1f8b57 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Dopusti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nemoj dopustiti"</string>
     <string name="consent_back" msgid="2560683030046918882">"Natrag"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prijenos dopuštenja aplikacije na sat"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Kako bi postavljanje sata bilo jednostavnije, aplikacije instalirane na satu će tijekom postavljanja upotrebljavati ista dopuštenja kao telefon.\n\n Ta dopuštenja mogu uključivati pristup mikrofonu i lokaciji sata."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index 1ea2de1..1d8a399 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Engedélyezés"</string>
     <string name="consent_no" msgid="2640796915611404382">"Tiltás"</string>
     <string name="consent_back" msgid="2560683030046918882">"Vissza"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Alkalmazásengedélyek átvitele az órára"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Az óra beállításának megkönnyítése érdekében a beállítás során az órára telepített alkalmazások ugyanazokat az engedélyeket használják majd, mint a telefonja.\n\n Ezek az engedélyek magukban foglalhatják az óra mikrofonjához és helyadataihoz való hozzáférést."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index 592a6c3..caa1c24 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Թույլատրել"</string>
     <string name="consent_no" msgid="2640796915611404382">"Չթույլատրել"</string>
     <string name="consent_back" msgid="2560683030046918882">"Հետ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Հավելվածների թույլտվությունների տեղափոխում ժամացույց"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Կարգավորման ժամանակ ժամացույցում տեղադրված հավելվածների համար կօգտագործվեն նույն թույլտվությունները, ինչ հեռախոսում։\n\n Այդ թույլտվությունները կարող են ներառել ժամացույցի խոսափողի կամ տեղադրության տվյալների օգտագործումը։"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 905f7c5..c328a6b 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Izinkan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Jangan izinkan"</string>
     <string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfer izin aplikasi ke smartwatch"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Untuk mempermudah penyiapan smartwatch, aplikasi yang diinstal di smartwatch selama penyiapan akan menggunakan izin yang sama dengan ponsel.\n\n Izin ini dapat meliputi akses ke mikrofon dan lokasi smartwatch."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index b389184..4425b11 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Leyfa"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ekki leyfa"</string>
     <string name="consent_back" msgid="2560683030046918882">"Til baka"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Flytja heimildir forrita yfir í úrið"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Til að auðvelda uppsetningu úrsins munu forrit sem eru sett upp í úrinu við uppsetningu nota sömu heimildir og stilltar eru í símanum.\n\n Þessar heimildir kunna að fela í sér aðgang að hljóðnema og staðsetningu úrsins."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index ccf7e55..a3a5410 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Consenti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Non consentire"</string>
     <string name="consent_back" msgid="2560683030046918882">"Indietro"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Trasferisci le autorizzazioni app all\'orologio"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Per facilitare la configurazione dell\'orologio, le app installate su quest\'ultimo durante la configurazione useranno le stesse autorizzazioni delle app sul telefono.\n\n Queste autorizzazioni potrebbero includere l\'accesso al microfono e alla posizione dell\'orologio."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 2f9c7e4..cfdb66a 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
     <string name="consent_no" msgid="2640796915611404382">"אין אישור"</string>
     <string name="consent_back" msgid="2560683030046918882">"חזרה"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"העברת ההרשאות הניתנות לאפליקציות אל השעון שלך"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"כדי לפשט את הגדרת השעון, אפליקציות שמותקנות במהלך ההגדרה יקבלו את אותן הרשאות שניתנו בטלפון.\n\n ההרשאות האלה עשויות לכלול גישה למיקרופון ולמיקום של השעון."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index 7c887ff..d81f4d2 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"許可"</string>
     <string name="consent_no" msgid="2640796915611404382">"許可しない"</string>
     <string name="consent_back" msgid="2560683030046918882">"戻る"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"スマートウォッチへのアプリの権限の移行"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"スマートウォッチのセットアップを簡単にするため、セットアップ時にスマートウォッチにインストールされたアプリに、スマートフォンと同じ権限が適用されます。\n\n これらの権限には、スマートウォッチのマイクや位置情報へのアクセス権も含まれることがあります。"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 5b56c33..ef2e66b 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"დაშვება"</string>
     <string name="consent_no" msgid="2640796915611404382">"არ დაიშვას"</string>
     <string name="consent_back" msgid="2560683030046918882">"უკან"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"აპის ნებართვების საათისთვის გადაცემა"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"საათის დაყენების გასამარტივებლად თქვენს საათში დაინსტალირებული აპები იმავე ნებართვებს გამოიყენებს, რასაც ტელეფონზე იყენებს.\n\n ეს ნებართვები, შესაძლოა, მოიცავდეს თქვენი საათის მიკროფონსა და მდებარეობაზე წვდომას."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index 67d3e8e..c1129bb 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Рұқсат беру"</string>
     <string name="consent_no" msgid="2640796915611404382">"Рұқсат бермеу"</string>
     <string name="consent_back" msgid="2560683030046918882">"Артқа"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Қолданба рұқсаттарын сағатқа ауыстыру"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Реттеу кезінде сағатқа орнатылған қолданбалар телефондағыдай рұқсаттарды пайдаланады. Осылайша сағат оңай реттеледі.\n\n Бұл рұқсаттар сағаттың микрофоны мен геодерегін пайдалануды қамтиды."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index 6c9c8747..bf8168f 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"អនុញ្ញាត"</string>
     <string name="consent_no" msgid="2640796915611404382">"កុំអនុញ្ញាត"</string>
     <string name="consent_back" msgid="2560683030046918882">"ថយក្រោយ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"ផ្ទេរការអនុញ្ញាតកម្មវិធីទៅនាឡិការបស់អ្នក"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"ដើម្បីជួយឱ្យការរៀបចំនាឡិការបស់អ្នកកាន់តែងាយស្រួល កម្មវិធីដែលបានដំឡើងនៅលើនាឡិការបស់អ្នកអំឡុងពេលរៀបចំនឹងប្រើការអនុញ្ញាតដូចគ្នានឹងទូរសព្ទរបស់អ្នកដែរ។\n\n ការអនុញ្ញាតទាំងនេះអាចរួមបញ្ចូលសិទ្ធិចូលប្រើទីតាំង និងមីក្រូហ្វូនរបស់នាឡិកាអ្នក។"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 3c71300..e31176f 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"ಅನುಮತಿಸಿ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ಅನುಮತಿಸಬೇಡಿ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ಹಿಂದೆ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"ಆ್ಯಪ್ ಅನುಮತಿಗಳನ್ನು ನಿಮ್ಮ ವಾಚ್‌ಗೆ ವರ್ಗಾವಣೆ ಮಾಡಿ"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"ನಿಮ್ಮ ವಾಚ್ ಸೆಟಪ್ ಮಾಡುವುದನ್ನು ಸುಲಭವಾಗಿಸಲು, ಸೆಟಪ್‌ನ ಸಮಯದಲ್ಲಿ ನಿಮ್ಮ ವಾಚ್‌ನಲ್ಲಿ ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್‌ಗಳು, ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿನ ಅನುಮತಿಗಳನ್ನೇ ಬಳಸಿಕೊಳ್ಳುತ್ತವೆ.\n\n ಈ ಅನುಮತಿಗಳು ನಿಮ್ಮ ವಾಚ್‌ನ ಮೈಕ್ರೊಫೋನ್ ಮತ್ತು ಸ್ಥಳದ ಪ್ರವೇಶವನ್ನು ಒಳಗೊಳ್ಳಬಹುದು."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 8a3ad35..af97339 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"허용"</string>
     <string name="consent_no" msgid="2640796915611404382">"허용 안함"</string>
     <string name="consent_back" msgid="2560683030046918882">"뒤"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"앱 권한을 시계로 이전"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"시계를 더 쉽게 설정하기 위해 설정하는 동안 시계에 설치된 앱에서 휴대전화와 동일한 권한을 사용합니다.\n\n 이러한 권한에는 시계의 마이크 및 위치 정보에 대한 액세스가 포함될 수 있습니다."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 5125297..6540e58 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Уруксат берүү"</string>
     <string name="consent_no" msgid="2640796915611404382">"Уруксат берилбесин"</string>
     <string name="consent_back" msgid="2560683030046918882">"Артка"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Колдонмонун уруксаттарын саатка өткөрүү"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Сааттын жөндөлүшүн жеңилдетүү үчүн жөндөө учурунда саатыңызга орнотулган колдонмолор телефонуңуздагы уруксаттарды колдонот.\n\n Мындай уруксаттарга саатыңыздын микрофонун же жайгашкан жерин колдонуу кириши мүмкүн."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index 42400a0..7c269fe 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"ອະນຸຍາດ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ບໍ່ອະນຸຍາດ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ກັບຄືນ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"ໂອນຍ້າຍການອະນຸຍາດແອັບໄປຫາໂມງຂອງທ່ານ"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"ເພື່ອເຮັດໃຫ້ຕັ້ງຄ່າໂມງຂອງທ່ານໄດ້ງ່າຍຂຶ້ນ, ແອັບທີ່ຕິດຕັ້ງຢູ່ໂມງຂອງທ່ານໃນລະຫວ່າງການຕັ້ງຄ່າຈະໃຊ້ການອະນຸຍາດດຽວກັນກັບໂທລະສັບຂອງທ່ານ.\n\n ການອະນຸຍາດເຫຼົ່ານີ້ອາດຮວມສິດເຂົ້າເຖິງໄມໂຄຣໂຟນ ແລະ ສະຖານທີ່ຂອງທ່ານນຳ."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index f79ea07..06099dc 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Leisti"</string>
     <string name="consent_no" msgid="2640796915611404382">"Neleisti"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atgal"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Laikrodžio programų perkėlimo leidimai"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Kad būtų lengviau nustatyti laikrodį, jame atliekant sąranką įdiegtoms programoms bus naudojami tie patys leidimai kaip jūsų telefone.\n\n Šie leidimai gali apimti prieigą prie laikrodžio mikrofono ir vietovės."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index ce4f7ac..34fc5f1 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Atļaut"</string>
     <string name="consent_no" msgid="2640796915611404382">"Neatļaut"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atpakaļ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Lietotņu atļauju pārsūtīšana uz pulksteni"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Lai atvieglotu pulksteņa iestatīšanu, iestatīšanas laikā pulkstenī instalētās lietotnes saņems tādas pašas atļaujas, kādas tām ir tālrunī.\n\n Tostarp lietotnes var saņemt atļauju piekļūt pulksteņa mikrofonam un atrašanās vietai."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 7ea24e7..e0de7ad 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволувај"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Префрлете ги дозволите за апликациите на вашиот часовник"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"За полесно поставувањето на часовникот, апликациите инсталирани на часовникот при поставувањето ќе ги користат истите дозволи како на телефонот.\n\n Овие дозволи може да опфаќаат пристап до микрофонот и локацијата на часовникот."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index 0de423c..abeefd9 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"അനുവദിക്കുക"</string>
     <string name="consent_no" msgid="2640796915611404382">"അനുവദിക്കരുത്"</string>
     <string name="consent_back" msgid="2560683030046918882">"മടങ്ങുക"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"നിങ്ങളുടെ വാച്ചിലേക്ക് ആപ്പ് അനുമതികൾ കൈമാറുക"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"നിങ്ങളുടെ വാച്ച് സജ്ജീകരിക്കുന്നത് എളുപ്പമാക്കാൻ, സജ്ജീകരിക്കുമ്പോൾ ഫോണിലുള്ള അതേ അനുമതികൾ നിങ്ങളുടെ വാച്ചിൽ ഇൻസ്റ്റാൾ ചെയ്തിട്ടുള്ള ആപ്പുകൾ ഉപയോഗിക്കും.\n\n ഈ അനുമതികളിൽ നിങ്ങളുടെ വാച്ചിന്റെ മൈക്രോഫോണിലേക്കും ലോക്കേഷനിലേക്കുമുള്ള ആക്‌സസ് ഉൾപ്പെട്ടേക്കാം."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index f4dd0e1..33d2053 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Зөвшөөрөх"</string>
     <string name="consent_no" msgid="2640796915611404382">"Бүү зөвшөөр"</string>
     <string name="consent_back" msgid="2560683030046918882">"Буцах"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Цагандаа аппын зөвшөөрлийг шилжүүлэх"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Таны цагийг тохируулахад илүү хялбар болгохын тулд тохируулгын үеэр таны цаган дээр суулгасан аппууд нь утастай тань ижил зөвшөөрлийг ашиглана.\n\n Эдгээр зөвшөөрөлд таны цагийн микрофон болон байршлын хандалт зэрэг багтаж магадгүй."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index 30e6820..4838091 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"अनुमती द्या"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमती देऊ नका"</string>
     <string name="consent_back" msgid="2560683030046918882">"मागे जा"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"अ‍ॅप परवानग्या तुमच्या वॉचवर ट्रान्सफर करा"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"तुमचे वॉच सेट करणे आणखी सोपे करण्यासाठी, सेटअपदरम्यान तुमच्या वॉचवर इंस्टॉल केलेली ॲप्स ही तुमच्या फोनप्रमाणेच परवानग्या वापरतील.\n\n या परवानग्यांमध्ये तुमच्या वॉचचा मायक्रोफोन आणि स्थानाच्या अ‍ॅक्सेसचा समावेश असू शकतो."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index a0b561a..4ad02eb 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Benarkan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Jangan benarkan"</string>
     <string name="consent_back" msgid="2560683030046918882">"Kembali"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Pindahkan kebenaran apl pada jam tangan anda"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Untuk memudahkan penyediaan jam tangan anda, apl yang dipasang pada jam tangan anda semasa persediaan akan menggunakan kebenaran yang sama seperti telefon anda.\n\n Kebenaran ini mungkin termasuk akses kepada mikrofon dan lokasi jam tangan anda."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index 31663e3..4710303 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"ခွင့်ပြုရန်"</string>
     <string name="consent_no" msgid="2640796915611404382">"ခွင့်မပြုပါ"</string>
     <string name="consent_back" msgid="2560683030046918882">"နောက်သို့"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"သင်၏နာရီသို့ အက်ပ်ခွင့်ပြုချက်များ လွှဲပြောင်းရန်"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"သင်၏နာရီ စနစ်ထည့်သွင်းရာတွင် ပိုလွယ်ကူစေရန် စနစ်ထည့်သွင်းနေစဉ်အတွင်း နာရီတွင်ထည့်သွင်းသော အက်ပ်များသည် သင့်ဖုန်းနှင့် အလားတူခွင့်ပြုချက်များကို သုံးပါမည်။\n\n ဤခွင့်ပြုချက်များတွင် သင့်နာရီ၏ မိုက်ခရိုဖုန်းနှင့် တည်နေရာတို့ကို သုံးခွင့် ပါဝင်နိုင်သည်။"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 3f4db79..5333477 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Tillat"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ikke tillat"</string>
     <string name="consent_back" msgid="2560683030046918882">"Tilbake"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Overfør apptillatelser til klokken din"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"For å gjøre det enklere å konfigurere klokken din bruker apper som installeres på klokken under konfigureringen, samme tillatelser som på telefonen.\n\n Disse tillatelsene kan inkludere tilgang til mikrofonen på klokken og posisjon."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index b13741e..6336ee4 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"अनुमति दिनुहोस्"</string>
     <string name="consent_no" msgid="2640796915611404382">"अनुमति नदिनुहोस्"</string>
     <string name="consent_back" msgid="2560683030046918882">"पछाडि"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"एपलाई दिइएका अनुमति घडीमा ट्रान्स्फर गर्नुहोस्"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"तपाईंको घडी सेटअप गर्ने कार्य सजिलो बनाउनका लागि सेटअप गर्ने क्रममा तपाईंको घडीमा इन्स्टल गरिएका एपहरूले पनि तपाईंको फोनमा दिइएको जस्तै अनुमति प्रयोग गर्ने छन्।\n\n यी अनुमतिमा तपाईंको घडीको माइक्रोफोन र लोकेसन प्रयोग गर्ने जस्ता अनुमति पर्न सक्छन्।"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index 4001c81..367800f 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Toestaan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Niet toestaan"</string>
     <string name="consent_back" msgid="2560683030046918882">"Terug"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"App-rechten overzetten naar je horloge"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"We willen het makkelijker voor je maken om je horloge in te stellen. Daarom gebruiken apps die tijdens het instellen worden geïnstalleerd op je horloge, dezelfde rechten als op je telefoon.\n\n Deze rechten kunnen toegang tot de microfoon en locatie van je horloge omvatten."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 888f6e3..36b55aa 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ଅନୁମତି ଦିଅନ୍ତୁ ନାହିଁ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ପଛକୁ ଫେରନ୍ତୁ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"ଆପଣଙ୍କ ୱାଚକୁ ଆପ ଅନୁମତିଗୁଡ଼ିକ ଟ୍ରାନ୍ସଫର କରନ୍ତୁ"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"ଆପଣଙ୍କ ୱାଚ ସେଟ ଅପ କରିବାକୁ ସହଜ କରିବା ପାଇଁ, ସେଟଅପ ସମୟରେ ଆପଣଙ୍କର ୱାଚରେ ଇନଷ୍ଟଲ କରାଯାଇଥିବା ଆପଗୁଡ଼ିକ ଆପଣଙ୍କ ଫୋନରେ ଥିବା ଆପଗୁଡ଼ିକ ପରି ସମାନ ଅନୁମତିଗୁଡ଼ିକ ବ୍ୟବହାର କରିବ।\n\n ଏହି ଅନୁମତିଗୁଡ଼ିକରେ ଆପଣଙ୍କ ୱାଚର ମାଇକ୍ରୋଫୋନ ଏବଂ ଲୋକେସନକୁ ଆକ୍ସେସ ଅନ୍ତର୍ଭୁକ୍ତ ହୋଇପାରେ।"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 8f16c54..fec6195 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"ਇਜਾਜ਼ਤ ਦਿਓ"</string>
     <string name="consent_no" msgid="2640796915611404382">"ਇਜਾਜ਼ਤ ਨਾ ਦਿਓ"</string>
     <string name="consent_back" msgid="2560683030046918882">"ਪਿੱਛੇ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"ਐਪ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਆਪਣੀ ਘੜੀ \'ਤੇ ਟ੍ਰਾਂਸਫ਼ਰ ਕਰੋ"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"ਤੁਹਾਡੀ ਘੜੀ ਦਾ ਸੈੱਟਅੱਪ ਕਰਨਾ ਆਸਾਨ ਬਣਾਉਣ ਲਈ, ਤੁਹਾਡੀ ਘੜੀ \'ਤੇ ਸਥਾਪਤ ਐਪਾਂ ਸੈੱਟਅੱਪ ਦੌਰਾਨ ਉਹੀ ਇਜਾਜ਼ਤਾਂ ਵਰਤਣਗੀਆਂ ਜੋ ਤੁਹਾਡਾ ਫ਼ੋਨ ਵਰਤਦਾ ਹੈ।\n\n ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਵਿੱਚ ਤੁਹਾਡੀ ਘੜੀ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਤੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਸ਼ਾਮਲ ਹੋ ਸਕਦੀ ਹੈ।"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index 8403238..f84746a 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Zezwól"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nie zezwalaj"</string>
     <string name="consent_back" msgid="2560683030046918882">"Wstecz"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Przenieś uprawnienia aplikacji na zegarek"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Aby łatwiej było skonfigurować zegarek, aplikacje zainstalowane na nim podczas konfiguracji będą korzystały z tych samych uprawnień co telefon.\n\n Może to oznaczać dostęp do mikrofonu i lokalizacji na zegarku."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 7f081f0..c87eacd 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir as permissões de apps para o relógio"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Para facilitar a configuração do relógio, os apps instalados nele durante a configuração vão usar as mesmas permissões que o smartphone.\n\n Essas permissões podem incluir acesso ao microfone ou à localização do relógio."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
index 6b0ac35..219d32a 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rPT/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfira as autorizações da app para o seu relógio"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Para facilitar a configuração do seu relógio, as apps instaladas no mesmo durante a configuração utilizarão as mesmas autorizações que o telemóvel.\n\n Estas autorizações podem incluir o acesso ao microfone e à localização do seu relógio."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 7f081f0..c87eacd 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Permitir"</string>
     <string name="consent_no" msgid="2640796915611404382">"Não permitir"</string>
     <string name="consent_back" msgid="2560683030046918882">"Voltar"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferir as permissões de apps para o relógio"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Para facilitar a configuração do relógio, os apps instalados nele durante a configuração vão usar as mesmas permissões que o smartphone.\n\n Essas permissões podem incluir acesso ao microfone ou à localização do relógio."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 2cfbdbb..73a9ab5 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Permiteți"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nu permiteți"</string>
     <string name="consent_back" msgid="2560683030046918882">"Înapoi"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transferați permisiunile pentru aplicații pe ceas"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Ca să configurați mai ușor ceasul, aplicațiile instalate pe ceas în timpul procesului de configurare vor folosi aceleași permisiuni ca telefonul.\n\n Între acestea se poate număra accesul la microfonul și locația ceasului."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index 2b24fa2..706f9f8 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Разрешить"</string>
     <string name="consent_no" msgid="2640796915611404382">"Запретить"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Перенос разрешений для приложений на часы"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Для приложений, установленных на часы во время настройки, будут использоваться те же разрешения, что и на телефоне.\n\n Например, может быть включен доступ к микрофону на часах или сведениям о местоположении."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 94078a4..3180e42 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"ඉඩ දෙන්න"</string>
     <string name="consent_no" msgid="2640796915611404382">"ඉඩ නොදෙන්න"</string>
     <string name="consent_back" msgid="2560683030046918882">"ආපසු"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"ඔබගේ ඔරලෝසුවට යෙදුම් අවසර මාරු කිරීම"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"ඔබගේ ඔරලෝසුව පිහිටුවීම පහසු කිරීමට, පිහිටුවීමේදී ඔබගේ ඔරලෝසුවේ ස්ථාපනය කර ඇති යෙදුම් ඔබගේ දුරකථනයට සමාන අවසර භාවිත කරනු ඇත.\n\n මෙම අවසරවලට ඔබගේ ඔරලෝසුවේ මයික්‍රෆෝනයට සහ ස්ථානයට ප්‍රවේශය ඇතුළත් විය හැකිය."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index 9a5c87e..0fbf4f4 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Povoliť"</string>
     <string name="consent_no" msgid="2640796915611404382">"Nepovoliť"</string>
     <string name="consent_back" msgid="2560683030046918882">"Späť"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Presun povolení aplikácie do hodiniek"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"V rámci zjednodušenia nastavenia hodiniek budú aplikácie nainštalované do hodiniek pri nastavovaní používať rovnaké povolenia ako váš telefón.\n\n Tieto povolenia môžu zahrnovať prístup k mikrofónu a polohe hodiniek."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index e28ba2f..14dd841 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Dovoli"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ne dovoli"</string>
     <string name="consent_back" msgid="2560683030046918882">"Nazaj"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Prenos dovoljenj za aplikacije v uro"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Za lažjo nastavitev ure bodo aplikacije, ki so bile med nastavljanjem nameščene v uri, uporabljale enaka dovoljenja kot tiste v telefonu.\n\n Ta dovoljenja lahko vključujejo dostop do mikrofona in lokacije ure."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index ba13505..ac89bab 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Lejo"</string>
     <string name="consent_no" msgid="2640796915611404382">"Mos lejo"</string>
     <string name="consent_back" msgid="2560683030046918882">"Pas"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Transfero lejet e aplikacionit te ora jote"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Për ta bërë më të lehtë konfigurimin e orës, aplikacionet e instaluara në orën tënde gjatë konfigurimit do të përdorin të njëjtat leje si telefoni yt.\n\n Këto leje mund të përfshijnë qasje në mikrofonin dhe vendndodhjen e orës."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index 3be67ff..2ae7aee 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Дозволи"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволи"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Пренесите дозволе за апликације на сат"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Да бисмо поједноставили подешавање сата, апликације инсталиране на сату током подешавања ће користити исте дозволе као телефон.\n\n Те дозволе могу да обухватају приступ микрофону и локацији сата."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index 19a2456..234552d 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Tillåt"</string>
     <string name="consent_no" msgid="2640796915611404382">"Tillåt inte"</string>
     <string name="consent_back" msgid="2560683030046918882">"Tillbaka"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Överför appbehörigheter till klockan"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Appar som installeras på klockan under konfigureringen får samma behörigheter som de har på telefonen så att konfigureringen ska bli enklare.\n\n Behörigheterna kan omfatta åtkomst till klockans mikrofon och plats."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index 68a1534..a5f0b54 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Ruhusu"</string>
     <string name="consent_no" msgid="2640796915611404382">"Usiruhusu"</string>
     <string name="consent_back" msgid="2560683030046918882">"Nyuma"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Hamishia idhini za programu kwenye saa yako"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Ili kurahisisha kuweka mipangilio ya saa yako, programu ambazo zimesakinishwa kwenye saa yako wakati wa kuweka mipangilio zitatumia ruhusa sawa na zinazotumika kwenye simu yako.\n\n Ruhusa hizi huenda zikajumuisha ufikiaji wa maikrofoni ya saa yako na maelezo ya mahali ilipo saa yako."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index c3c7eec..0a1bc89 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"அனுமதி"</string>
     <string name="consent_no" msgid="2640796915611404382">"அனுமதிக்க வேண்டாம்"</string>
     <string name="consent_back" msgid="2560683030046918882">"பின்செல்"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"ஆப்ஸ் அனுமதிகளை உங்கள் வாட்ச்சிற்கு மாற்றுதல்"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"உங்கள் வாட்ச் அமைவை எளிதாக்க, உங்கள் மொபைலில் வழங்கியுள்ள அனுமதிகளையே அமைவின்போது வாட்ச்சில் நிறுவப்பட்ட ஆப்ஸும் பயன்படுத்தும்.\n\n உங்கள் வாட்ச்சிலுள்ள மைக்ரோஃபோன், இருப்பிடம் ஆகியவற்றுக்கான அணுகலும் இந்த அனுமதிகளில் அடங்கக்கூடும்."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index ec3289d..cef475f 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"అనుమతించు"</string>
     <string name="consent_no" msgid="2640796915611404382">"అనుమతించవద్దు"</string>
     <string name="consent_back" msgid="2560683030046918882">"వెనుకకు"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"మీ వాచ్‌కు యాప్ అనుమతులను బదిలీ చేయండి"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"మీ వాచ్‌ను సెటప్ చేయడాన్ని సులభతరం చేయడానికి, సెటప్ సమయంలో మీ వాచ్‌లో ఇన్‌స్టాల్ చేయబడిన యాప్‌లు మీ ఫోన్‌లో యాప్‌లకు ఉన్న అవే అనుమతులను ఉపయోగిస్తాయి.\n\n ఈ అనుమతులతో మీ వాచ్ మైక్రోఫోన్, అలాగే లొకేషన్ కూడా ఉండవచ్చు."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index 2b47426..31c746a 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"อนุญาต"</string>
     <string name="consent_no" msgid="2640796915611404382">"ไม่อนุญาต"</string>
     <string name="consent_back" msgid="2560683030046918882">"กลับ"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"โอนสิทธิ์ของแอปไปยังนาฬิกา"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"แอปที่ติดตั้งในนาฬิการะหว่างการตั้งค่าจะใช้สิทธิ์เดียวกันกับโทรศัพท์เพื่อให้การตั้งค่านาฬิกาง่ายขึ้น\n\n สิทธิ์เหล่านี้อาจรวมการเข้าถึงไมโครโฟนและตำแหน่งของนาฬิกา"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 15953a6..66d0ae6 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Payagan"</string>
     <string name="consent_no" msgid="2640796915611404382">"Huwag payagan"</string>
     <string name="consent_back" msgid="2560683030046918882">"Bumalik"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Ilipat sa iyong relo ang mga pahintulot sa app"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Para gawing mas madali na i-set up ang iyong relo, gagamitin ng mga app na naka-install sa relo mo sa oras ng pag-set up ang mga pahintulot na ginagamit din sa iyong telepono.\n\n Posibleng kasama sa mga pahintulot na ito ang access sa mikropono at lokasyon ng iyong relo."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 8e0938b..487ecb3 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
     <string name="consent_no" msgid="2640796915611404382">"İzin verme"</string>
     <string name="consent_back" msgid="2560683030046918882">"Geri"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Uygulama izinlerini saatinize aktarma"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Kurulum sırasında saatinize yüklenen uygulamalar, saat kurulumunuzu kolaylaştırmak için telefonunuzla aynı izinleri kullanır.\n\n Saatinizin mikrofonuna ve konumuna erişim bu izinlere dahil olabilir."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 3638058..ba3d9b5 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Дозволити"</string>
     <string name="consent_no" msgid="2640796915611404382">"Не дозволяти"</string>
     <string name="consent_back" msgid="2560683030046918882">"Назад"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Перенести дозволи для додатків на годинник"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Задля зручності додатки, установлені на годиннику протягом налаштування, використовуватимуть ті самі дозволи, що й на телефоні.\n\n До таких дозволів може належати доступ до мікрофона й геоданих годинника."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index a951209..fba5c45 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"اجازت دیں"</string>
     <string name="consent_no" msgid="2640796915611404382">"اجازت نہ دیں"</string>
     <string name="consent_back" msgid="2560683030046918882">"پیچھے"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"اپنی گھڑی پر ایپ کی اجازتیں منتقل کریں"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"آپ کی گھڑی کو سیٹ اپ کرنے کے عمل کو زیادہ آسان بنانے کے لیے، سیٹ اپ کے دوران آپ کی گھڑی پر انسٹال کردہ ایپس انہیں اجازتوں کا استعمال کریں گی جن کا استعمال آپ کا فون کرتا ہے۔\n\n ان اجازتوں میں آپ کی گھڑی کے مائیکروفون اور مقام تک کی رسائی شامل ہو سکتی ہے۔"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 455f9ef..b1912f8 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Ruxsat"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ruxsat berilmasin"</string>
     <string name="consent_back" msgid="2560683030046918882">"Orqaga"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Ilova uchun ruxsatlarni soatingizga uzating"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Soatingizni sozlashni qulaylashtirish maqsadida sozlash paytida soatingizga oʻrnatilgan ilovalar telefoningiz bilan bir xil ruxsatlardan foydalanadi.\n\n Bunday ruxsatlarga soatingiz mikrofoni va joylashuv axborotiga ruxsatlar kirishi mumkin."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 0cc362b8..28b66ad 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Cho phép"</string>
     <string name="consent_no" msgid="2640796915611404382">"Không cho phép"</string>
     <string name="consent_back" msgid="2560683030046918882">"Quay lại"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Chuyển quyền cho ứng dụng sang đồng hồ"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Để thiết lập đồng hồ dễ dàng hơn, trong quá trình thiết lập, các ứng dụng được cài đặt trên đồng hồ của bạn sẽ sử dụng các quyền giống như trên điện thoại.\n\n Các quyền này có thể bao gồm quyền sử dụng micrô và thông tin vị trí của đồng hồ."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 5286d75..21db274 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"允许"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允许"</string>
     <string name="consent_back" msgid="2560683030046918882">"返回"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"将应用权限转让给手表"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"为了让您更轻松地设置手表,在设置过程中安装在手表上的应用将使用与手机相同的权限。\n\n这些权限可能包括使用手表的麦克风和位置信息。"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 1e6f515..9dd03ea 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允許"</string>
     <string name="consent_back" msgid="2560683030046918882">"返回"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"將應用程式權限轉移至手錶"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"為簡化手錶的設定程序,在設定過程中安裝到手錶上的應用程式都將沿用手機上的權限。\n\n這些權限可能包括手錶麥克風和位置的存取權。"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index 9cb91d0..0b6fa44 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"允許"</string>
     <string name="consent_no" msgid="2640796915611404382">"不允許"</string>
     <string name="consent_back" msgid="2560683030046918882">"返回"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"將應用程式權限轉移到手錶上"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"為簡化手錶的設定程序,只要是在設定過程中安裝到手錶上的應用程式,都將沿用手機上的權限。\n\n 這些權限可能包括手錶的麥克風和位置資訊存取權。"</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index a86eec2..38622a4 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -42,6 +42,8 @@
     <string name="consent_yes" msgid="8344487259618762872">"Vumela"</string>
     <string name="consent_no" msgid="2640796915611404382">"Ungavumeli"</string>
     <string name="consent_back" msgid="2560683030046918882">"Emuva"</string>
-    <string name="permission_sync_confirmation_title" msgid="667074294393493186">"Dlulisela izimvume ze-app ewashini lakho"</string>
-    <string name="permission_sync_summary" msgid="8873391306499120778">"Ukuze wenze kube lula ukusetha iwashi lakho, ama-app afakwe ewashini lakho phakathi nokusetha azosebenzisa izimvume ezifanayo nezefoni yakho.\n\n Lezi zimvume zingabandakanya ukufinyelela kumakrofoni nendawo yewashi lakho."</string>
+    <!-- no translation found for permission_sync_confirmation_title (4409622174437248702) -->
+    <skip />
+    <!-- no translation found for permission_sync_summary (4866838188678457084) -->
+    <skip />
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values/strings.xml b/packages/CompanionDeviceManager/res/values/strings.xml
index 586a022..fca9ab9 100644
--- a/packages/CompanionDeviceManager/res/values/strings.xml
+++ b/packages/CompanionDeviceManager/res/values/strings.xml
@@ -107,13 +107,11 @@
     <string name="consent_back">Back</string>
 
     <!-- ================== System data transfer ==================== -->
-    <!-- Title of the permission sync confirmation dialog. [CHAR LIMIT=60] -->
-    <string name="permission_sync_confirmation_title">Transfer app permissions to your
-        watch</string>
+    <!-- Title of the permission sync confirmation dialog. [CHAR LIMIT=NONE] -->
+    <string name="permission_sync_confirmation_title">Give apps on &lt;strong&gt;<xliff:g id="companion_device_name" example="Galaxy Watch 5">%1$s</xliff:g>&lt;/strong&gt; the same permissions as on &lt;strong&gt;<xliff:g id="primary_device_name" example="Pixel 6">%2$s</xliff:g>&lt;/strong&gt;?</string>
 
-    <!-- Text of the permission sync explanation in the confirmation dialog. [CHAR LIMIT=400] -->
-    <string name="permission_sync_summary">To make it easier to set up your watch,
-        apps installed on your watch during setup will use the same permissions as your phone.\n\n
-        These permissions may include access to your watch\u2019s microphone and location.</string>
+    <!-- Text of the permission sync explanation in the confirmation dialog. [CHAR LIMIT=NONE] -->
+    <string name="permission_sync_summary">&lt;p&gt;This may include Microphone, Camera, and Location access, and other sensitive permissions on &lt;strong&gt;<xliff:g id="companion_device_name" example="Galaxy Watch 5">%1$s</xliff:g>&lt;/strong&gt;.&lt;/p&gt;
+        &lt;p&gt;You can change these permissions any time in your Settings on &lt;strong&gt;<xliff:g id="companion_device_name" example="Galaxy Watch 5">%1$s</xliff:g>&lt;/strong&gt;.&lt;/p&gt;</string>
 
 </resources>
diff --git a/packages/CompanionDeviceManager/res/values/styles.xml b/packages/CompanionDeviceManager/res/values/styles.xml
index c38323f..809e98e 100644
--- a/packages/CompanionDeviceManager/res/values/styles.xml
+++ b/packages/CompanionDeviceManager/res/values/styles.xml
@@ -49,7 +49,6 @@
     <style name="DescriptionSummary">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:gravity">center</item>
         <item name="android:layout_marginTop">18dp</item>
         <item name="android:layout_marginLeft">18dp</item>
         <item name="android:layout_marginRight">18dp</item>
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 37cbf30..e71c945 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -307,6 +307,7 @@
 
     private void onUserSelectedDevice(@NonNull DeviceFilterPair<?> selectedDevice) {
         final MacAddress macAddress = selectedDevice.getMacAddress();
+        mRequest.setDisplayName(selectedDevice.getDisplayName());
         onAssociationApproved(macAddress);
     }
 
@@ -486,6 +487,7 @@
         mSelectedDevice = requireNonNull(deviceFilterPairs.get(0));
 
         final String deviceName = mSelectedDevice.getDisplayName();
+        mRequest.setDisplayName(deviceName);
         final Spanned title = getHtmlFromResources(
                 this, R.string.confirmation_title, appLabel, deviceName);
         final Spanned summary;
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDataTransferActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDataTransferActivity.java
index 67efa03..93040b5 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDataTransferActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDataTransferActivity.java
@@ -16,20 +16,22 @@
 
 package com.android.companiondevicemanager;
 
+import static android.companion.datatransfer.SystemDataTransferRequest.DATA_TYPE_PERMISSION_SYNC;
 import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
+import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
+
 import static java.util.Objects.requireNonNull;
 
 import android.app.Activity;
-import android.companion.SystemDataTransferRequest;
+import android.companion.datatransfer.PermissionSyncRequest;
+import android.companion.datatransfer.SystemDataTransferRequest;
 import android.content.Intent;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.ResultReceiver;
-import android.text.Html;
 import android.util.Log;
-import android.view.View;
 import android.widget.Button;
-import android.widget.ListView;
 import android.widget.TextView;
 
 /**
@@ -39,14 +41,18 @@
 
     private static final String LOG_TAG = CompanionDeviceDataTransferActivity.class.getSimpleName();
 
-    // UI -> SystemDataTransferProcessor
-    private static final int RESULT_CODE_SYSTEM_DATA_TRANSFER_ALLOWED = 0;
-    private static final int RESULT_CODE_SYSTEM_DATA_TRANSFER_DISALLOWED = 1;
-    private static final String EXTRA_SYSTEM_DATA_TRANSFER_REQUEST = "system_data_transfer_request";
+    // Intent data keys from SystemDataTransferProcessor
+    private static final String EXTRA_PERMISSION_SYNC_REQUEST = "permission_sync_request";
+    private static final String EXTRA_COMPANION_DEVICE_NAME = "companion_device_name";
     private static final String EXTRA_SYSTEM_DATA_TRANSFER_RESULT_RECEIVER =
             "system_data_transfer_result_receiver";
 
+    // Intent data keys to SystemDataTransferProcessor
+    private static final int RESULT_CODE_SYSTEM_DATA_TRANSFER_ALLOWED = 0;
+    private static final int RESULT_CODE_SYSTEM_DATA_TRANSFER_DISALLOWED = 1;
+
     private SystemDataTransferRequest mRequest;
+    private CharSequence mCompanionDeviceName;
     private ResultReceiver mCdmServiceReceiver;
 
     @Override
@@ -61,23 +67,27 @@
 
         TextView titleView = findViewById(R.id.title);
         TextView summaryView = findViewById(R.id.summary);
-        ListView listView = findViewById(R.id.device_list);
-        listView.setVisibility(View.GONE);
         Button allowButton = findViewById(R.id.btn_positive);
         Button disallowButton = findViewById(R.id.btn_negative);
 
         final Intent intent = getIntent();
-        mRequest = intent.getParcelableExtra(EXTRA_SYSTEM_DATA_TRANSFER_REQUEST);
-        mCdmServiceReceiver = intent.getParcelableExtra(EXTRA_SYSTEM_DATA_TRANSFER_RESULT_RECEIVER);
+        mRequest = intent.getParcelableExtra(EXTRA_PERMISSION_SYNC_REQUEST,
+                PermissionSyncRequest.class);
+        mCompanionDeviceName = intent.getCharSequenceExtra(EXTRA_COMPANION_DEVICE_NAME);
+        mCdmServiceReceiver = intent.getParcelableExtra(EXTRA_SYSTEM_DATA_TRANSFER_RESULT_RECEIVER,
+                ResultReceiver.class);
 
         requireNonNull(mRequest);
         requireNonNull(mCdmServiceReceiver);
 
-        if (mRequest.isPermissionSyncAllPackages()
-                || !mRequest.getPermissionSyncPackages().isEmpty()) {
-            titleView.setText(Html.fromHtml(getString(
-                    R.string.permission_sync_confirmation_title), 0));
-            summaryView.setText(getString(R.string.permission_sync_summary));
+        final String primaryDeviceName = Build.MODEL;
+
+        if (mRequest.getDataType() == DATA_TYPE_PERMISSION_SYNC) {
+            titleView.setText(getHtmlFromResources(this,
+                    R.string.permission_sync_confirmation_title, mCompanionDeviceName,
+                    primaryDeviceName));
+            summaryView.setText(getHtmlFromResources(this, R.string.permission_sync_summary,
+                    mCompanionDeviceName));
             allowButton.setOnClickListener(v -> allow());
             disallowButton.setOnClickListener(v -> disallow());
         }
@@ -101,7 +111,9 @@
 
     private void sendDataToReceiver(int cdmResultCode) {
         Bundle data = new Bundle();
-        data.putParcelable(EXTRA_SYSTEM_DATA_TRANSFER_REQUEST, mRequest);
+        if (mRequest instanceof PermissionSyncRequest) {
+            data.putParcelable(EXTRA_PERMISSION_SYNC_REQUEST, (PermissionSyncRequest) mRequest);
+        }
         mCdmServiceReceiver.send(cdmResultCode, data);
     }
 
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 53309fe..a91b03a 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Stel terug"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Verwyder"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Stel tans gassessie terug …"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Neem \'n foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Kies \'n prent"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Kies foto"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index d24bbae..b23f827 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ዳግም አስጀምር"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"አስወግድ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"እንግዳን ዳግም በማስጀመር ላይ…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ፎቶ አንሳ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ምስል ይምረጡ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ፎቶ ይምረጡ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index d901b92..95d1eb1 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"إعادة الضبط"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"إزالة"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"جارٍ إعادة ضبط جلسة الضيف…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"التقاط صورة"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"اختيار صورة"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"اختيار صورة"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 261ee3e..390a296 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ৰিছেট কৰক"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"আঁতৰাওক"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"অতিথিৰ ছেশ্বন ৰিছেট কৰি থকা হৈছে…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"এখন ফট’ তোলক"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ফট’ বাছনি কৰক"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index fa8c515..3c27384 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Sıfırlayın"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Silin"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Qonaq məlumatı sıfırlanır…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Foto çəkin"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Şəkil seçin"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Foto seçin"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index fb7e21d..b486572 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ukloni"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Sesija gosta se resetuje…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Izaberite sliku"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index da9caf6..ca25ed9 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Скінуць"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Выдаліць"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Ідзе скід гасцявога сеанса…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Зрабіць фота"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбраць відарыс"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Выбраць фота"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index c5ac71c..7a0316c 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Нулиране"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Премахване"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Сесията като гост се нулира…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Правене на снимка"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Избиране на изображение"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Избиране на снимката"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 11e9f1d..3ad80dd 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"রিসেট করুন"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"সরান"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"গেস্ট সেশন রিসেট করা হচ্ছে..."</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ফটো তুলুন"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"একটি ইমেজ বেছে নিন"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ফটো বেছে নিন"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 7499bbc..b03c4a0 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Poništi"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ukloni"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Poništavanje sesije gosta…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Snimite fotografiju"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberite sliku"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir fotografije"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 5620cce..475b922 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restableix"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Suprimeix"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"S\'està restablint el convidat…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Fes una foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Tria una imatge"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecciona una foto"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 8d4aacd..6cbb8af 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetovat"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Odstranit"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetování hosta…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Pořídit fotku"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrat obrázek"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Vybrat fotku"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index c982aa7..17327af 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Nulstil"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Fjern"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Nulstiller gæst…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Tag et billede"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Vælg et billede"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Vælg billede"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 68d0256..be5964b 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Zurücksetzen"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Entfernen"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Gast wird zurückgesetzt…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Foto machen"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Bild auswählen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Foto auswählen"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 44fd24f..25334b6 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Επαναφορά"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Κατάργηση"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Επαναφορά επισκέπτη…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Λήψη φωτογραφίας"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Επιλογή εικόνας"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Επιλογή φωτογραφίας"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index e9a8da9..d58b036 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -598,6 +598,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remove"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Reset guest session?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"This will start a new guest session and delete all apps and data from the current session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Exit guest mode?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"This will delete apps and data from the current guest session"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Exit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Save guest activity?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"You can save activity from the current session or delete all apps and data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Delete"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Save"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Exit guest mode"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reset guest session"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Exit guest"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 788968f..d24083b 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -598,6 +598,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remove"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Reset guest session?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"This will start a new guest session and delete all apps and data from the current session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Exit guest mode?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"This will delete apps and data from the current guest session"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Exit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Save guest activity?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"You can save activity from the current session or delete all apps and data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Delete"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Save"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Exit guest mode"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reset guest session"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Exit guest"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index e9a8da9..d58b036 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -598,6 +598,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remove"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Reset guest session?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"This will start a new guest session and delete all apps and data from the current session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Exit guest mode?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"This will delete apps and data from the current guest session"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Exit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Save guest activity?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"You can save activity from the current session or delete all apps and data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Delete"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Save"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Exit guest mode"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reset guest session"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Exit guest"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index e9a8da9..d58b036 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -598,6 +598,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remove"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetting guest…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Reset guest session?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"This will start a new guest session and delete all apps and data from the current session"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Exit guest mode?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"This will delete apps and data from the current guest session"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Exit"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Save guest activity?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"You can save activity from the current session or delete all apps and data"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Delete"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Save"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Exit guest mode"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Reset guest session"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Exit guest"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 70227dc..df280cd 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -598,6 +598,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‎‏‎‏‎Reset‎‏‎‎‏‎"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‎‏‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‏‏‎Remove‎‏‎‎‏‎"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎Resetting guest…‎‏‎‎‏‎"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‏‎‏‎‎‏‎Reset guest session?‎‏‎‎‏‎"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎This will start a new guest session and delete all apps and data from the current session‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‏‎‏‎‏‏‎‎‎Exit guest mode?‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎This will delete apps and data from the current guest session‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎Exit‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‏‎‎Save guest activity?‎‏‎‎‏‎"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎You can save activity from the current session or delete all apps and data‎‏‎‎‏‎"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‎‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‏‏‎‎Delete‎‏‎‎‏‎"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎Save‎‏‎‎‏‎"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎Exit guest mode‎‏‎‎‏‎"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎Reset guest session‎‏‎‎‏‎"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎Exit guest‎‏‎‎‏‎"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎All activity will be deleted on exit‎‏‎‎‏‎"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‎You can save or delete your activity on exit‎‏‎‎‏‎"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎Reset to delete session activity now, or you can save or delete activity on exit‎‏‎‎‏‎"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎Take a photo‎‏‎‎‏‎"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎Choose an image‎‏‎‎‏‎"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‎‏‎Select photo‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 20baf88..0ac9fe1 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Quitar"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Tomar una foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Elegir una imagen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 6ec3f8e..60e79f0 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Quitar"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Hacer foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Seleccionar una imagen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 996b92f..5bd64c0 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Lähtesta"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Eemalda"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Külastajaseansi lähtestamine …"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Pildistage"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Valige pilt"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Valige foto"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index d6741dc..6604077 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Berrezarri"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Kendu"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Gonbidatuentzako saioa berrezartzen…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Atera argazki bat"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Aukeratu irudi bat"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Hautatu argazki bat"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 95ea4c2..9db9be7 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"بازنشانی"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"برداشتن"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"درحال بازنشانی مهمان…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"عکس گرفتن"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"انتخاب تصویر"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"انتخاب عکس"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index dd0e50e..734515c 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Nollaa"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Poista"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Nollataan vierasta…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Ota kuva"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Valitse kuva"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Valitse kuva"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index a4d9ccc..d62ce16 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Réinitialiser"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Retirer"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Réinitialisation de la session Invité en cours…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Sélectionner une image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionnez une photo"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 921cf2b..eafe539 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Réinitialiser"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Supprimer"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Réinitialisation de la session Invité…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Choisir une image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionner une photo"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index bbb4285..a1d7cd8 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Quitar"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Restablecendo sesión de convidado…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escoller imaxe"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 88e22a1..24ed1fb 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"રીસેટ કરો"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"કાઢી નાખો"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"અતિથિને રીસેટ કરી રહ્યાં છીએ…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ફોટો લો"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"છબી પસંદ કરો"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ફોટો પસંદ કરો"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 859c876..12e9ec5 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रीसेट करें"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"हटाएं"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"मेहमान के तौर पर ब्राउज़ करने का सेशन रीसेट किया जा रहा है…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"फ़ोटो खींचें"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"कोई इमेज चुनें"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"फ़ोटो चुनें"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 369406f..bc49846 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Poništi"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ukloni"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Poništavanje gostujuće sesije…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiraj"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir slike"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index e4bc191..be150bf 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Visszaállítás"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Eltávolítás"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Vendég munkamenet visszaállítása…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotó készítése"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Kép kiválasztása"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Fotó kiválasztása"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 79a657b..b5f817b 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Զրոյացնել"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Հեռացնել"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Հյուրի աշխատաշրջանը վերակայվում է…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Լուսանկարել"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Ընտրել պատկեր"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Ընտրեք լուսանկար"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 3bad8e8..a8e86d2 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Hapus"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Mereset tamu …"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih gambar"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 9616618..56972d2 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Endurstilla"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Fjarlægja"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Endurstillir gest…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Taka mynd"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Velja mynd"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Velja mynd"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index c80e290..76e9891 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Reimposta"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Rimuovi"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Reimpostazione sessione Ospite in corso…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Scatta una foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Scegli un\'immagine"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleziona la foto"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 4304abd..b3de615 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"איפוס"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"הסרה"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"מתבצע איפוס של הגלישה כאורח…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"צילום תמונה"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"לבחירת תמונה"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"בחירת תמונה"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 770f944..f5cfb2a 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"リセット"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"削除"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ゲストをリセットしています…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"写真を撮る"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"画像を選択"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"写真を選択"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 66a05f1..d854646 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"გადაყენება"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ამოშლა"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"მიმდინარეობს სტუმრის გადაყენება…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ფოტოს გადაღება"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"აირჩიეთ სურათი"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ფოტოს არჩევა"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index bbfa2a3..c14a134 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Бастапқы күйге қайтару"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Өшіру"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Қонақ сеансы бастапқы күйге қайтарылуда…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Фотосуретке түсіру"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Сурет таңдау"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Фотосурет таңдау"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 9085fb6..6bcf1d0 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"កំណត់​ឡើងវិញ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ដកចេញ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"កំពុងកំណត់​ភ្ញៀវឡើងវិញ…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ថតរូប"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ជ្រើសរើស​រូបភាព"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ជ្រើសរើស​​រូបថត"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index a5c97cd..a95377e 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ರೀಸೆಟ್ ಮಾಡಿ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ತೆಗೆದುಹಾಕಿ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ಅತಿಥಿ ಬಳಕೆದಾರರ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ಫೋಟೋ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ಚಿತ್ರವನ್ನು ಆರಿಸಿ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ಫೋಟೋ ಆಯ್ಕೆಮಾಡಿ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index ccd27c2..c856b5c 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"재설정"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"삭제"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"게스트 재설정 중…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"사진 찍기"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"이미지 선택"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"사진 선택"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index fc0df56..9210a53 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -598,6 +598,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Баштапкы абалга келтирүү"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Өчүрүү"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Конок сеансы баштапкы абалга келтирилүүдө…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Конок сеансы баштапкы абалга келтирилсинби?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Бул аракет жаңы конок сеансын баштап, учурдагы сеанстагы бардык колдонмолорду жана дайындарды жок кылат"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Конок режиминен чыгасызбы?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Бул учурдагы конок сеансындагы колдонмолорду жана дайындарды жок кылат"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"Чыгуу"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"Коноктун аракеттери сакталсынбы?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Учурдагы сеанстагы аракеттерди сактап же бардык колдонмолорду жана дайындарды жок кылсаңыз болот"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Өчүрүү"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Сактоо"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Конок режиминен чыгуу"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Конок сеансын кайра коюу"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Конок режиминен чыгуу"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Чыксаңыз, бардык аракеттер өчүрүлөт"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Чыгуудан мурун аракеттериңизди сактап же жок кылсаңыз болот"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сеанстагы аракеттерди азыр жок кылуу үчүн баштапкы абалга келтириңиз, же болбосо чыгуу учурунда аракеттерди сактап же жок кылсаңыз болот"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"Сүрөткө тартуу"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Сүрөт тандаңыз"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Сүрөт тандаңыз"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 9ad5087..92452a1 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ຣີເຊັດ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ລຶບອອກ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ກຳລັງຣີເຊັດແຂກ…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ຖ່າຍຮູບ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ເລືອກຮູບ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ເລືອກຮູບ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 6f2f7042..630bf4a 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Nustatyti iš naujo"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Pašalinti"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Svečias nustatomas iš naujo…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotografuoti"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pasirinkti vaizdą"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pasirinkti nuotrauką"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 0b3eb94..fdf3d7d 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Atiestatīt"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Noņemt"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Notiek viesa sesijas atiestatīšana…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Uzņemt fotoattēlu"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Izvēlēties attēlu"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Atlasīt fotoattēlu"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index bbd792e..c4b2c44 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетирај"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Отстрани"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Се ресетира гостинот…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Фотографирајте"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Одберете слика"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Изберете фотографија"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index a8a6bec..14c1fb9 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"റീസെറ്റ് ചെയ്യുക"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"നീക്കം ചെയ്യുക"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"അതിഥിയെ റീസെറ്റ് ചെയ്യുന്നു…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ഫോട്ടോ തിരഞ്ഞെടുക്കുക"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index fe35772..b85c708 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Шинэчлэх"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Хасах"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Зочныг шинэчилж байна…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Зураг авах"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Зураг сонгох"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Зураг сонгох"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 9e483c2..8f93697 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -598,6 +598,21 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रीसेट करा"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"काढून टाका"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"अतिथीला रीसेट करत आहे…"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"अतिथी सत्र रीसेट करायचे का?"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"हे नवीन अतिथी सत्र सुरू करेल आणि सध्याच्या सत्रातील सर्व अ‍ॅप्स व डेटा हटवेल"</string>
+    <string name="guest_exit_dialog_title" msgid="1846494656849381804">"अतिथी मोडमधून बाहेर पडायचे का?"</string>
+    <string name="guest_exit_dialog_message" msgid="1743218864242719783">"हे सध्याच्या अतिथी सत्रातील अ‍ॅप्स आणि डेटा हटवेल"</string>
+    <string name="guest_exit_dialog_button" msgid="1736401897067442044">"बाहेर पडा"</string>
+    <string name="guest_exit_dialog_title_non_ephemeral" msgid="7675327443743162986">"अतिथी अ‍ॅक्टिव्हिटी सेव्ह करायची का?"</string>
+    <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"सध्याच्या सत्रातील अ‍ॅक्टिव्हिटी सेव्ह करू किंवा सर्व अ‍ॅप्स व डेटा हटवू शकता"</string>
+    <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"हटवा"</string>
+    <string name="guest_exit_save_data_button" msgid="3690974510644963547">"सेव्ह करा"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"अतिथी मोडमधून बाहेर पडा"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"अतिथी सत्र रीसेट करा"</string>
+    <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"अतिथी मोडमधून बाहेर पडा"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"बाहेर पडल्यावर सर्व अ‍ॅक्टिव्हिटी हटवली जाईल"</string>
+    <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"बाहेर पडल्यावर तुमची अ‍ॅक्टिव्हिटी सेव्ह करू किंवा हटवू शकता"</string>
+    <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"सत्र अ‍ॅक्टिव्हिटी आता हटवण्यासाठी रीसेट करा किंवा तुम्ही बाहेर पडल्यावर अ‍ॅक्टिव्हिटी सेव्ह करू अथवा हटवू शकता"</string>
     <string name="user_image_take_photo" msgid="467512954561638530">"फोटो काढा"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"इमेज निवडा"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"फोटो निवडा"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index c989def..831de3f 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tetapkan semula"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Alih keluar"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Menetapkan semula tetamu…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih imej"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index a6749ee..fd490f9 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -599,6 +599,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ပြင်ဆင်သတ်မှတ်ရန်"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ဖယ်ရှားရန်"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ဧည့်သည်ကို ပြင်ဆင်သတ်မှတ်နေသည်…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ဓာတ်ပုံရိုက်ရန်"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ပုံရွေးရန်"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ဓာတ်ပုံရွေးရန်"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 57178fd..baf9c54 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tilbakestill"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Fjern"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Tilbakestiller gjesten …"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Ta et bilde"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Velg et bilde"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Velg et bilde"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 51d5a2c..4880ec2 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"रिसेट गर्नुहोस्"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"हटाउनुहोस्"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"अतिथिका रूपमा ब्राउज गर्ने सेसन रिसेट गरिँदै छ…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"फोटो खिच्नुहोस्"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"कुनै फोटो छनौट गर्नुहोस्"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"फोटो चयन गर्नुहोस्"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 8af0136..2f5313c 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetten"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Verwijderen"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Gast resetten…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Foto maken"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Afbeelding kiezen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Foto selecteren"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 908fa96..167c69b 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ରିସେଟ୍ କରନ୍ତୁ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ଅତିଥି ସେସନକୁ ରିସେଟ୍ କରାଯାଉଛି…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ଗୋଟିଏ ଫଟୋ ଉଠାନ୍ତୁ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ଏକ ଛବି ବାଛନ୍ତୁ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ଫଟୋ ବାଛନ୍ତୁ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index ac95365..372a36f 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ਰੀਸੈੱਟ ਕਰੋ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ਹਟਾਓ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ਮਹਿਮਾਨ ਨੂੰ ਰੀਸੈੱਟ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ਇੱਕ ਫ਼ੋਟੋ ਖਿੱਚੋ"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ਕੋਈ ਚਿੱਤਰ ਚੁਣੋ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ਫ਼ੋਟੋ ਚੁਣੋ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index d523148..2ce250a 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetuj"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Usuń"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Resetuję sesję gościa…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Zrób zdjęcie"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Wybierz obraz"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Wybierz zdjęcie"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 627d7ba..db04473 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Redefinir"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remover"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Redefinindo visitante…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 98d65f5..25eb62c 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Repor"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remover"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"A repor o convidado…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 627d7ba..db04473 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Redefinir"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remover"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Redefinindo visitante…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index c38bd78..a2e2670 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetați"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Eliminați"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Se resetează invitatul…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Faceți o fotografie"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Alegeți o imagine"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selectați fotografia"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 2d7ed11..cfb6c6a 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Сбросить"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Удалить"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Сброс гостевого сеанса…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Сделать снимок"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбрать фото"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Выбрать фотографию"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 7477e52..c4a2da4 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"යළි සකසන්න"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ඉවත් කරන්න"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"අමුත්තා යළි සකසමින්…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ඡායාරූපයක් ගන්න"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"රූපයක් තෝරන්න"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ඡායාරූපය තෝරන්න"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index d5dd6c5..e9eb3a3 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetovať"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Odstrániť"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Relácia hosťa sa resetuje…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Odfotiť"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrať obrázok"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Vybrať fotku"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index a609ab8..e6645c4 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ponastavi"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Odstrani"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Ponastavljanje gosta …"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiranje"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Izberi sliko"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Izbira fotografije"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 25f3b97..21d21e4 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Rivendos"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Hiq"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Vizitori po rivendoset…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Bëj një fotografi"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Zgjidh një imazh"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Zgjidh një fotografi"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 0e2f0d0..1607adf 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ресетуј"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Уклони"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Сесија госта се ресетује…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Изаберите слику"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 430dd45..72d13cc 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Återställ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ta bort"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Gästsessionen återställs …"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Ta ett foto"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Välj en bild"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Välj foto"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 79d9532..b24fc40 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Badilisha"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Ondoa"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Inabadilisha kipindi cha mgeni…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Piga picha"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Chagua picha"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Chagua picha"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 9a5d1ee..d792650 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"மீட்டமை"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"அகற்று"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"கெஸ்ட்டை மீட்டமைக்கிறது…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"படமெடுங்கள்"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"படத்தைத் தேர்வுசெய்யுங்கள்"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"படத்தைத் தேர்ந்தெடுங்கள்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index 97bd52e..591c095 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"రీసెట్ చేయండి"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"తీసివేయండి"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"గెస్ట్ సెషన్‌ను రీసెట్ చేస్తోంది…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ఒక ఫోటో తీయండి"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ఇమేజ్‌ను ఎంచుకోండి"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ఫోటోను ఎంచుకోండి"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 96b40d5..62598d8 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"รีเซ็ต"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"นำออก"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"กำลังรีเซ็ตผู้เข้าร่วม…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ถ่ายรูป"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"เลือกรูปภาพ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"เลือกรูปภาพ"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 73d3dd5..ad9b582 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"I-reset"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Alisin"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Nire-reset ang bisita…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Kumuha ng larawan"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Pumili ng larawan"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pumili ng larawan"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index cca694b..57e66d4 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Sıfırla"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Kaldır"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Misafir oturumu sıfırlanıyor…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Fotoğraf çek"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Resim seç"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Fotoğraf seç"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 0f4ee0d..1c85dfd 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Скинути"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Вилучити"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Скидання сеансу в режимі \"Гість\"…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Зробити фотографію"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Вибрати зображення"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Вибрати фотографію"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index ebbd45e..e772457 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ری سیٹ کریں"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ہٹائیں"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"مہمان کو ری سیٹ کرنا…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"ایک تصویر لیں"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"ایک تصویر منتخب کریں"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"تصویر منتخب کریں"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 7837779..1c49f1d 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Tiklash"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Olib tashlash"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Mehmon seansi tiklanmoqda…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Suratga olish"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Rasm tanlash"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Surat tanlash"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index dac955e..d2cdb1e 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Đặt lại"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Xoá"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Đang đặt lại phiên khách…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Chụp ảnh"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Chọn một hình ảnh"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Chọn ảnh"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index b669708..115a118 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"重置"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"移除"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"正在重置访客会话…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"拍摄照片"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"选择图片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"选择照片"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 1cd9d22..7b6921c 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"重設"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"移除"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"正在重設訪客…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"揀相"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 8a85ed1..36ebb24 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"重設"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"移除"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"正在重設訪客…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"選取相片"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 6ef85d2..67625e4 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -598,6 +598,36 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Setha kabusha"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Susa"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Ukusetha kabusha isimenywa…"</string>
+    <!-- no translation found for guest_reset_and_restart_dialog_title (3396657008451616041) -->
+    <skip />
+    <!-- no translation found for guest_reset_and_restart_dialog_message (2764425635305200790) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title (1846494656849381804) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message (1743218864242719783) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_button (1736401897067442044) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_title_non_ephemeral (7675327443743162986) -->
+    <skip />
+    <!-- no translation found for guest_exit_dialog_message_non_ephemeral (223385323235719442) -->
+    <skip />
+    <!-- no translation found for guest_exit_clear_data_button (3425812652180679014) -->
+    <skip />
+    <!-- no translation found for guest_exit_save_data_button (3690974510644963547) -->
+    <skip />
+    <!-- no translation found for guest_exit_button (5774985819191803960) -->
+    <skip />
+    <!-- no translation found for guest_reset_button (2515069346223503479) -->
+    <skip />
+    <!-- no translation found for guest_exit_quick_settings_button (1912362095913765471) -->
+    <skip />
+    <!-- no translation found for guest_notification_ephemeral (7263252466950923871) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral (6843799963012259330) -->
+    <skip />
+    <!-- no translation found for guest_notification_non_ephemeral_non_first_login (8009307983766934876) -->
+    <skip />
     <string name="user_image_take_photo" msgid="467512954561638530">"Thatha isithombe"</string>
     <string name="user_image_choose_photo" msgid="1363820919146782908">"Khetha isithombe"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Khetha isithombe"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index df2685d..8ef712a 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1438,6 +1438,44 @@
     <string name="guest_remove_guest_confirm_button">Remove</string>
     <!-- Status message indicating the device is in the process of resetting the guest user. [CHAR_LIMIT=NONE] -->
     <string name="guest_resetting">Resetting guest\u2026</string>
+    <!-- Dialog title on action reset and restart guest [CHAR LIMIT=60] -->
+    <string name="guest_reset_and_restart_dialog_title">Reset guest session?</string>
+    <!-- Dialog message on action reset and restart guest [CHAR LIMIT=160] -->
+    <string name="guest_reset_and_restart_dialog_message">This will start a new guest
+        session and delete all apps and data from the current session</string>
+    <!-- Dialog title on action exit guest (ephemeral guest) [CHAR LIMIT=32] -->
+    <string name="guest_exit_dialog_title">Exit guest mode?</string>
+    <!-- Dialog message on action exit guest (ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_dialog_message">This will delete
+        apps and data from the current guest session</string>
+    <!-- Dialog button on action exit guest (ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_dialog_button">Exit</string>
+    <!-- Dialog title on action exit guest (non-ephemeral guest) [CHAR LIMIT=32] -->
+    <string name="guest_exit_dialog_title_non_ephemeral">Save guest activity?</string>
+    <!-- Dialog message on action exit guest (non-ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_dialog_message_non_ephemeral">You can save activity from
+        the current session or delete all apps and data</string>
+    <!-- Button on guest exit, clear data (non-ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_clear_data_button">Delete</string>
+    <!-- Button on guest exit, save data (non-ephemeral guest) [CHAR LIMIT=80] -->
+    <string name="guest_exit_save_data_button">Save</string>
+    <!-- Label for button in confirmation dialog when exiting guest user [CHAR LIMIT=35] -->
+    <string name="guest_exit_button">Exit guest mode</string>
+    <!-- Label for button in confirmation dialog when resetting guest user [CHAR LIMIT=35] -->
+    <string name="guest_reset_button">Reset guest session</string>
+    <!-- Label for guest icon in quick settings user switcher [CHAR LIMIT=35] -->
+    <string name="guest_exit_quick_settings_button">Exit guest</string>
+    <!-- Message of the notification when guest mode is entered
+         and it's a ephemeral guest [CHAR LIMIT=60] -->
+    <string name="guest_notification_ephemeral">All activity will be deleted on exit</string>
+    <!-- Message of the notification when guest mode is entered
+         and it's not a ephemeral guest and it's a first time guest login [CHAR LIMIT=60] -->
+    <string name="guest_notification_non_ephemeral">You can save or delete your activity on exit</string>
+    <!-- Message of the notification when guest mode is entered
+         and it's not a ephemeral guest and it's not a first time guest login [CHAR LIMIT=NONE] -->
+    <string name="guest_notification_non_ephemeral_non_first_login">Reset to delete session
+        activity now, or you can save or delete activity on exit</string>
+
     <!-- An option in a photo selection dialog to take a new photo [CHAR LIMIT=50] -->
     <string name="user_image_take_photo">Take a photo</string>
     <!-- An option in a photo selection dialog to choose a pre-existing image [CHAR LIMIT=50] -->
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
index f28572f..69484ed 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
@@ -37,9 +37,9 @@
 import androidx.fragment.app.FragmentActivity;
 
 import com.android.settingslib.R;
+import com.android.settingslib.RestrictedLockUtils;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
@@ -55,7 +55,6 @@
 import java.util.stream.Stream;
 
 @RunWith(RobolectricTestRunner.class)
-@Ignore
 public class EditUserInfoControllerTest {
     private static final int MAX_USER_NAME_LENGTH = 100;
 
@@ -87,6 +86,11 @@
         }
 
         @Override
+        RestrictedLockUtils.EnforcedAdmin getChangePhotoAdminRestriction(Context context) {
+            return null;
+        }
+
+        @Override
         boolean isChangePhotoRestrictedByBase(Context context) {
             return mPhotoRestrictedByBase;
         }
@@ -98,7 +102,7 @@
         mActivity = spy(ActivityController.of(new FragmentActivity()).get());
         mActivity.setTheme(R.style.Theme_AppCompat_DayNight);
         mController = new TestEditUserInfoController();
-        mPhotoRestrictedByBase = true;
+        mPhotoRestrictedByBase = false;
     }
 
     @Test
@@ -262,7 +266,7 @@
 
     @Test
     public void createDialog_canNotChangePhoto_nullPhotoController() {
-        mPhotoRestrictedByBase = false;
+        mPhotoRestrictedByBase = true;
 
         mController.createDialog(mActivity, mActivityStarter, mCurrentIcon,
                 "test", "title", null, null);
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index acb33c3..75068cb 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -317,6 +317,9 @@
         VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_WIDTH, ANY_INTEGER_VALIDATOR);
         VALIDATORS.put(Global.Wearable.WET_MODE_ON, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Global.Wearable.COOLDOWN_MODE_ON, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Global.Wearable.TOUCH_AND_HOLD_WATCH_FACE, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Global.Wearable.SCREEN_UNLOCK_SOUND_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Global.Wearable.CHARGING_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
     }
 }
 
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 077337c..700c04c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -5220,7 +5220,7 @@
                                     .getResources()
                                     .getBoolean(R.bool.def_wearable_hotwordDetectionEnabled));
                     initGlobalSettingsDefaultValForWearLocked(
-                            Global.Wearable.SMART_REPLIES_ENABLED, false);
+                            Global.Wearable.SMART_REPLIES_ENABLED, true);
                     Setting locationMode =
                             getSecureSettingsLocked(userId).getSettingLocked(Secure.LOCATION_MODE);
                     initGlobalSettingsDefaultValForWearLocked(
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index d122cf5..f06e349 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -422,6 +422,7 @@
                     Settings.Global.RADIO_NFC,
                     Settings.Global.RADIO_WIFI,
                     Settings.Global.RADIO_WIMAX,
+                    Settings.Global.REMOVE_GUEST_ON_EXIT,
                     Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS,
                     Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT,
                     Settings.Global.RESTRICTED_NETWORKING_MODE,
@@ -664,7 +665,9 @@
                     Settings.Global.Wearable.CLOCKWORK_LONG_PRESS_TO_ASSISTANT_ENABLED,
                     Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_SET_BY_USER,
                     Settings.Global.Wearable.WET_MODE_ON,
-                    Settings.Global.Wearable.COOLDOWN_MODE_ON);
+                    Settings.Global.Wearable.COOLDOWN_MODE_ON,
+                    Settings.Global.Wearable.TOUCH_AND_HOLD_WATCH_FACE,
+                    Settings.Global.Wearable.SCREEN_UNLOCK_SOUND_ENABLED);
 
     private static final Set<String> BACKUP_DENY_LIST_SECURE_SETTINGS =
              newHashSet(
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index a28c4cf..1d101ee 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -683,8 +683,8 @@
     <!-- Permission required for CTS test - CtsAppEnumerationTestCases -->
     <uses-permission android:name="android.permission.MAKE_UID_VISIBLE" />
 
-    <!-- Permission required for CTS test - CtsKeystoreTestCases -->
-    <uses-permission android:name="android.permission.REQUEST_UNIQUE_ID_ATTESTATION" />
+    <!-- Permission required for CTS test - CtsInputTestCases -->
+    <uses-permission android:name="android.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY" />
 
     <application android:label="@string/app_label"
                 android:theme="@android:style/Theme.DeviceDefault.DayNight"
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 1ce4c64..68679c79 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -572,6 +572,7 @@
                     break;
                 case INTENT_BUGREPORT_DONE:
                     maybeShowWarningMessageAndCloseNotification(id);
+                    break;
                 case INTENT_BUGREPORT_CANCEL:
                     cancel(id);
                     break;
@@ -843,16 +844,11 @@
                 PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
     }
 
-    @GuardedBy("mLock")
-    private void stopProgressLocked(int id) {
-        stopProgressLocked(id, /* cancelNotification */ true);
-    }
-
     /**
      * Finalizes the progress on a given bugreport and cancel its notification.
      */
     @GuardedBy("mLock")
-    private void stopProgressLocked(int id, boolean cancelNotification) {
+    private void stopProgressLocked(int id) {
         if (mBugreportInfos.indexOfKey(id) < 0) {
             Log.w(TAG, "ID not watched: " + id);
         } else {
@@ -862,12 +858,10 @@
         // Must stop foreground service first, otherwise notif.cancel() will fail below.
         stopForegroundWhenDoneLocked(id);
 
-        if (cancelNotification) {
-            Log.d(TAG, "stopProgress(" + id + "): cancel notification");
-            NotificationManager.from(mContext).cancel(id);
-        } else {
-            Log.d(TAG, "stopProgress(" + id + ")");
-        }
+
+        Log.d(TAG, "stopProgress(" + id + "): cancel notification");
+        NotificationManager.from(mContext).cancel(id);
+
         stopSelfWhenDoneLocked();
     }
 
@@ -1112,30 +1106,7 @@
             return;
         }
 
-        if (mIsWatch) {
-            // Wear wants to send the notification directly and not wait for the user to tap on the
-            // notification.
-            triggerShareBugreportAndLocalNotification(info);
-        } else {
-            triggerLocalNotification(info);
-        }
-    }
-
-    /**
-     * Responsible for starting the bugerport sharing process and posting a notification which
-     * shows that the bugreport has been taken and that the sharing process has kicked-off.
-     */
-    private void triggerShareBugreportAndLocalNotification(final BugreportInfo info) {
-        boolean isPlainText = info.bugreportFile.getName().toLowerCase().endsWith(".txt");
-        if (!isPlainText) {
-            // Already zipped, share it right away.
-            shareBugreport(info.id, info, /* showWarning */ false,
-                /* cancelNotificationWhenStoppingProgress */ false);
-            sendBugreportNotification(info, mTakingScreenshot);
-        } else {
-            // Asynchronously zip the file first, then share it.
-            shareAndPostNotificationForZippedBugreport(info, mTakingScreenshot);
-        }
+        triggerLocalNotification(info);
     }
 
     /**
@@ -1249,16 +1220,14 @@
     }
 
     private void shareBugreport(int id, BugreportInfo sharedInfo) {
-        shareBugreport(id, sharedInfo, !hasUserDecidedNotToGetWarningMessage(),
-            /* cancelNotificationWhenStoppingProgress */ true);
+        shareBugreport(id, sharedInfo, !hasUserDecidedNotToGetWarningMessage());
     }
 
     /**
      * Shares the bugreport upon user's request by issuing a {@link Intent#ACTION_SEND_MULTIPLE}
      * intent, but issuing a warning dialog the first time.
      */
-    private void shareBugreport(int id, BugreportInfo sharedInfo, boolean showWarning,
-            boolean cancelNotificationWhenStoppingProgress) {
+    private void shareBugreport(int id, BugreportInfo sharedInfo, boolean showWarning) {
         MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_NOTIFICATION_ACTION_SHARE);
         BugreportInfo info;
         synchronized (mLock) {
@@ -1307,7 +1276,7 @@
         }
         synchronized (mLock) {
             // ... and stop watching this process.
-            stopProgressLocked(id, cancelNotificationWhenStoppingProgress);
+            stopProgressLocked(id);
         }
     }
 
@@ -1362,7 +1331,7 @@
                         PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
                     .setDeleteIntent(newCancelIntent(mContext, info));
         } else {
-            // Device is a watch.
+            // Device is a watch
             if (hasUserDecidedNotToGetWarningMessage()) {
                 // No action button needed for the notification. User can swipe to dimiss.
                 builder.setActions(new Action[0]);
@@ -1433,24 +1402,6 @@
     }
 
     /**
-     * Zips a bugreport, shares it, and sends for it a bugreport notification.
-     */
-    private void shareAndPostNotificationForZippedBugreport(final BugreportInfo info,
-            final boolean takingScreenshot) {
-        new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                Looper.prepare();
-                zipBugreport(info);
-                shareBugreport(info.id, info, /* showWarning */ false,
-                /* cancelNotificationWhenStoppingProgress */ false);
-                sendBugreportNotification(info, mTakingScreenshot);
-                return null;
-            }
-        }.execute();
-    }
-
-    /**
      * Zips a bugreport file, returning the path to the new file (or to the
      * original in case of failure).
      */
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index f05c1e2..de9e1f4 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -125,6 +125,7 @@
     ],
     manifest: "AndroidManifest.xml",
 
+    javacflags: ["-Adagger.fastInit=enabled"],
     kotlincflags: ["-Xjvm-default=enable"],
 
     plugins: ["dagger2-compiler"],
diff --git a/packages/SystemUI/res/drawable/ic_circular_unchecked.xml b/packages/SystemUI/res/drawable/ic_circular_unchecked.xml
index 779ab81..9b43cf6 100644
--- a/packages/SystemUI/res/drawable/ic_circular_unchecked.xml
+++ b/packages/SystemUI/res/drawable/ic_circular_unchecked.xml
@@ -4,6 +4,6 @@
     android:viewportWidth="24"
     android:viewportHeight="24">
   <path
-      android:fillColor="@color/media_dialog_item_main_content"
+      android:fillColor="@color/media_dialog_inactive_item_main_content"
       android:pathData="M12,22q-2.075,0 -3.9,-0.788 -1.825,-0.787 -3.175,-2.137 -1.35,-1.35 -2.137,-3.175Q2,14.075 2,12t0.788,-3.9q0.787,-1.825 2.137,-3.175 1.35,-1.35 3.175,-2.137Q9.925,2 12,2t3.9,0.788q1.825,0.787 3.175,2.137 1.35,1.35 2.137,3.175Q22,9.925 22,12t-0.788,3.9q-0.787,1.825 -2.137,3.175 -1.35,1.35 -3.175,2.137Q14.075,22 12,22zM12,12zM12,20q3.325,0 5.663,-2.337Q20,15.325 20,12t-2.337,-5.662Q15.325,4 12,4T6.338,6.338Q4,8.675 4,12q0,3.325 2.338,5.663Q8.675,20 12,20z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/media_output_status_check.xml b/packages/SystemUI/res/drawable/media_output_status_check.xml
index 5fbc42b..1b750f8 100644
--- a/packages/SystemUI/res/drawable/media_output_status_check.xml
+++ b/packages/SystemUI/res/drawable/media_output_status_check.xml
@@ -21,6 +21,6 @@
         android:viewportHeight="24"
         android:tint="?attr/colorControlNormal">
     <path
-        android:fillColor="@color/media_dialog_item_main_content"
+        android:fillColor="@color/media_dialog_item_status"
         android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
 </vector>
diff --git a/packages/SystemUI/res/drawable/media_output_status_failed.xml b/packages/SystemUI/res/drawable/media_output_status_failed.xml
index 0599e23..05c6358 100644
--- a/packages/SystemUI/res/drawable/media_output_status_failed.xml
+++ b/packages/SystemUI/res/drawable/media_output_status_failed.xml
@@ -21,6 +21,6 @@
         android:viewportHeight="24"
         android:tint="?attr/colorControlNormal">
     <path
-        android:fillColor="@color/media_dialog_item_main_content"
+        android:fillColor="@color/media_dialog_inactive_item_main_content"
         android:pathData="M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
 </vector>
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index 1efb479..39c5c45 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -137,7 +137,7 @@
             style="@style/Widget.Dialog.Button.BorderButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/media_output_dialog_button_stop_casting"
+            android:text="@string/keyboard_key_media_stop"
             android:visibility="gone"/>
 
         <Space
diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml
index d39b0d5..eeb37c7 100644
--- a/packages/SystemUI/res/layout/media_output_list_item.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item.xml
@@ -33,7 +33,7 @@
             android:layout_height="match_parent"
             android:background="@drawable/media_output_item_background"
             android:layout_gravity="center_vertical|start">
-            <com.android.systemui.media.dialog.MediaOutputSeekbar
+            <SeekBar
                 android:id="@+id/volume_seekbar"
                 android:splitTrack="false"
                 android:visibility="gone"
@@ -83,7 +83,7 @@
                 android:ellipsize="end"
                 android:maxLines="1"
                 android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
-                android:textColor="@color/media_dialog_item_main_content"
+                android:textColor="@color/media_dialog_inactive_item_main_content"
                 android:textSize="16sp"/>
             <TextView
                 android:id="@+id/subtitle"
@@ -91,7 +91,7 @@
                 android:layout_height="wrap_content"
                 android:ellipsize="end"
                 android:maxLines="1"
-                android:textColor="@color/media_dialog_item_main_content"
+                android:textColor="@color/media_dialog_inactive_item_main_content"
                 android:textSize="14sp"
                 android:fontFamily="@*android:string/config_bodyFontFamily"
                 android:visibility="gone"/>
@@ -127,7 +127,6 @@
             android:layout_gravity="right|center"
             android:button="@drawable/ic_circle_check_box"
             android:visibility="gone"
-            android:clickable="false"
         />
     </FrameLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index ecc52d3ad..fc299a4 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wiil jy jou sessie voortsit?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Begin van voor af"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, gaan voort"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Voeg nuwe gebruiker by?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Wanneer jy \'n nuwe gebruiker byvoeg, moet daardie persoon hul spasie opstel.\n\nEnige gebruiker kan programme vir al die ander gebruikers opdateer."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Gebruikerlimiet is bereik"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Jy kan tot <xliff:g id="COUNT">%d</xliff:g> gebruikers byvoeg.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bind nuwe toestel saam"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Maak die program oop om hierdie sessie uit te saai."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende program"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hou op uitsaai"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitsaai werk"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Saai uit"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mense in jou omtrek met versoenbare Bluetooth-toestelle kan na die media luister wat jy uitsaai"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 6b7e301..0194422 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ክፍለ-ጊዜዎን መቀጠል ይፈልጋሉ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"እንደገና ጀምር"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"አዎ፣ ቀጥል"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"አዲስ ተጠቃሚ ይታከል?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"እርስዎ አንድ አዲስ ተጠቃሚ ሲያክሉ ያ ሰው የራሱ ቦታ ማዘጋጀት አለበት።\n\nማንኛውም ተጠቃሚ መተግበሪያዎችን ለሌሎች ተጠቃሚዎች ሁሉ ሊያዘምን ይችላል።"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"የተጠቃሚ ገደብ ላይ ተደርሷል"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one"><xliff:g id="COUNT">%d</xliff:g> ተጠቃሚዎች ብቻ ናቸው ሊፈጠሩ የሚችሉት።</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"አዲስ መሣሪያ ያጣምሩ"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ይህን ክፍለ ጊዜ cast ለማድረግ፣ እባክዎ መተግበሪያውን ይክፈቱ።"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"የማይታወቅ መተግበሪያ"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Cast ማድረግ አቁም"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ማሰራጨት እንዴት እንደሚሠራ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ስርጭት"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ተኳሃኝ የብሉቱዝ መሣሪያዎች ያላቸው በአቅራቢያዎ ያሉ ሰዎች እርስዎ እያሰራጩት ያሉትን ሚዲያ ማዳመጥ ይችላሉ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 91a0338..9a3c052 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -346,6 +346,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"هل تريد متابعة جلستك؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"البدء من جديد"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"نعم، متابعة"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"هل تريد إضافة مستخدم جديد؟"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"عند إضافة مستخدم جديد، عليه إعداد مساحته.\n\nويُمكن لأي مستخدم تحديث التطبيقات لجميع المستخدمين الآخرين."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"تم الوصول إلى أقصى عدد للمستخدمين"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="zero">يمكنك إضافة ما يصل إلى <xliff:g id="COUNT">%d</xliff:g> مستخدم.</item>
@@ -859,7 +867,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"إقران جهاز جديد"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"لبث هذه الجلسة، يُرجى فتح التطبيق"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"تطبيق غير معروف"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"إيقاف البث"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"كيفية عمل البث"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"البث"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"يمكن للأشخاص القريبين منك الذين لديهم أجهزة متوافقة تتضمّن بلوتوث الاستماع إلى الوسائط التي تبثها."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index acc4acf..d61cce3 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপুনি আপোনাৰ ছেশ্বন অব্যাহত ৰাখিব বিচাৰেনে?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আকৌ আৰম্ভ কৰক"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হয়, অব্যাহত ৰাখক"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"নতুন ব্যৱহাৰকাৰী যোগ কৰিবনে?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"আপুনি যেতিয়া এজন নতুন ব্যৱহাৰকাৰী যোগ কৰে, তেওঁ নিজৰ স্থান ছেট আপ কৰা প্ৰয়োজন।\n\nযিকোনো ব্যৱহাৰকাৰীয়ে নিজৰ লগতে আন ব্যৱহাৰকাৰীৰো এপ্ আপডে’ট কৰিব পাৰে।"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"অধিকতম ব্যৱহাৰকাৰী সৃষ্টি কৰা হ’ল"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">আপুনি <xliff:g id="COUNT">%d</xliff:g> জনলৈকে ব্যৱহাৰকাৰী যোগ কৰিব পাৰে।</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইচ পেয়াৰ কৰক"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই ছেশ্বনটো কাষ্ট কৰিবলৈ, অনুগ্ৰহ কৰি এপ্‌টো খোলক"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজ্ঞাত এপ্"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"কাষ্ট বন্ধ কৰক"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"সম্প্ৰচাৰ কৰাটোৱে কেনেকৈ কাম কৰে"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্ৰচাৰ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"সমিল ব্লুটুথ ডিভাইচৰ সৈতে আপোনাৰ নিকটৱৰ্তী স্থানত থকা লোকসকলে আপুনি সম্প্ৰচাৰ কৰা মিডিয়াটো শুনিব পাৰে"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 5ad9207..41e17cf 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Sessiya davam etsin?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Yenidən başlayın"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Bəli, davam edin"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Yeni istifadəçi əlavə edilsin?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Yeni istifadəçi əlavə etdiyiniz zaman həmin şəxs öz yerini quraşdırmalıdır. \n\n İstənilən istifadəçi bütün digər istifadəçilərdən olan tətbiqləri güncəlləşdirə bilər."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"İstifadəçi limitinə çatmısınız"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Maksimum <xliff:g id="COUNT">%d</xliff:g> istifadəçi əlavə edə bilərsiniz.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Cihaz əlavə edin"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu sessiyanı yayımlamaq üçün tətbiqi açın."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Naməlum tətbiq"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayımı dayandırın"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayım necə işləyir"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Yayım"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Uyğun Bluetooth cihazları olan yaxınlığınızdakı insanlar yayımladığınız medianı dinləyə bilər"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index b539c47..89796c0 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -340,6 +340,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li da nastavite sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni iz početka"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodajete novog korisnika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba treba da podesi svoj prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut maksimalni broj korisnika"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Možete da dodate najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
@@ -841,7 +849,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Upari novi uređaj"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste prebacivali ovu sesiju, otvorite aplikaciju."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi prebacivanje"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcioniše emitovanje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emitovanje"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ljudi u blizini sa kompatibilnim Bluetooth uređajima mogu da slušaju medijski sadržaj koji emitujete"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 3338388..4a1bd7b 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -342,6 +342,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Хочаце працягнуць сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Пачаць зноў"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Так, працягнуць"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Дадаць новага карыстальніка?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Пасля стварэння профілю яго трэба наладзіць.\n\nЛюбы карыстальнік прылады можа абнаўляць праграмы ўсіх іншых карыстальнікаў."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Дасягнуты ліміт карыстальнікаў"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Можна дадаць <xliff:g id="COUNT">%d</xliff:g> карыстальніка.</item>
@@ -847,7 +855,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спалучыць з новай прыладай"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Для трансляцыі гэтага сеанса адкрыйце праграму."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невядомая праграма"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спыніць трансляцыю"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як адбываецца трансляцыя"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляцыя"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Людзі паблізу, у якіх ёсць прылады з Bluetooth, змогуць праслухваць мультымедыйнае змесціва, якое вы трансліруеце"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 97f1d60..104c915 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Искате ли да продължите сесията си?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Започване отначало"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продължавам"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Да се добави ли нов потребител?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Когато добавите нов потребител, той трябва да настрои работното си пространство.\n\nВсеки потребител може да актуализира приложенията за всички останали потребители."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнахте огранич. за потребители"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Можете да добавите до <xliff:g id="COUNT">%d</xliff:g> потребители.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Сдвояване на ново устройство"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да предавате тази сесия, моля, отворете приложението."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестно приложение"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Спиране на предаването"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работи предаването"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Предаване"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Хората в близост със съвместими устройства с Bluetooth могат да слушат мултимедията, която предавате"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index b3f20da..0f5306c 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"আপনি কি আপনার সেশনটি চালিয়ে যেতে চান?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"আবার শুরু করুন"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"হ্যাঁ, চালিয়ে যান"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"নতুন ব্যবহারকারীকে যোগ করবেন?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"আপনি একজন নতুন ব্যবহারকারী যোগ করলে তাকে তার জায়গা সেট-আপ করে নিতে হবে৷\n\nযেকোনও ব্যবহারকারী অন্য সব ব্যবহারকারীর জন্য অ্যাপ আপডেট করতে পারবেন৷"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"আর কোনও প্রোফাইল যোগ করা যাবে না"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">আপনি <xliff:g id="COUNT">%d</xliff:g> জন পর্যন্ত ব্যবহারকারীর প্রোফাইল যোগ করতে পারেন।</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"নতুন ডিভাইস পেয়ার করুন"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"এই সেশন কাস্ট করার জন্য, অ্যাপ খুলুন।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"অজানা অ্যাপ"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"কাস্ট করা বন্ধ করুন"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ব্রডকাস্ট কীভাবে কাজ করে"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"সম্প্রচার করুন"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"আশপাশে লোকজন যাদের মানানসই ব্লুটুথ ডিভাইস আছে, তারা আপনার ব্রডকাস্ট করা মিডিয়া শুনতে পারবেন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index fad3ec8..5b499d6 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -340,6 +340,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodati novog korisnika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba treba postaviti svoj prostor.\n\nSvaki korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dostignut limit za broj korisnika"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
@@ -841,7 +849,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da emitirate ovu sesiju, otvorite aplikaciju."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi emitiranje"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako funkcionira emitiranje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emitirajte"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osobe u vašoj blizini s kompatibilnim Bluetooth uređajima mogu slušati medijske sadržaje koje emitirate"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 13b53fb..8cf9dee 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vols continuar amb la sessió?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Torna a començar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continua"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Vols afegir un usuari nou?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Quan s\'afegeix un usuari nou, aquest usuari ha de configurar-se l\'espai.\n\nQualsevol usuari pot actualitzar les aplicacions de la resta d\'usuaris."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"S\'ha assolit el límit d\'usuaris"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Pots afegir fins a <xliff:g id="COUNT">%d</xliff:g> usuaris.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincula un dispositiu nou"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per emetre aquesta sessió, obre l\'aplicació."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicació desconeguda"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Atura l\'emissió"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Com funciona l\'emissió"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emet"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les persones properes amb dispositius Bluetooth compatibles poden escoltar el contingut multimèdia que emets"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 69e5fcc..4392018 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -342,6 +342,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relaci pokračovat?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začít znovu"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ano, pokračovat"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Přidat nového uživatele?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Když přidáte nového uživatele, musí si nastavit vlastní prostor.\n\nJakýkoli uživatel může aktualizovat aplikace všech ostatních uživatelů."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Bylo dosaženo limitu uživatelů"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="few">Lze přidat až <xliff:g id="COUNT">%d</xliff:g> uživatele.</item>
@@ -847,7 +855,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovat nové zařízení"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pokud chcete odesílat relaci, otevřete aplikaci."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznámá aplikace"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zastavit odesílání"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak vysílání funguje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Vysílání"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lidé ve vašem okolí s kompatibilními zařízeními Bluetooth mohou poslouchat média, která vysíláte"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 9fed9c5..7bdaf67 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsætte din session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start forfra"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsæt"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Vil du tilføje en ny bruger?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Når du tilføjer en ny bruger, skal personen konfigurere sit område.\n\nAlle brugere kan opdatere apps for alle de andre brugere."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Grænsen for antal brugere er nået"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Du kan tilføje op til <xliff:g id="COUNT">%d</xliff:g> bruger.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Par ny enhed"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Åbn appen for at caste denne session."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukendt app"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop med at caste"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Sådan fungerer udsendelser"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Udsendelse"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i nærheden, som har kompatible Bluetooth-enheder, kan lytte til det medie, du udsender"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 2aefa8f..b92bd62 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Möchtest du deine Sitzung fortsetzen?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Neu starten"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, weiter"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Neuen Nutzer hinzufügen?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Wenn du einen neuen Nutzer hinzufügst, muss dieser seinen Bereich einrichten.\n\nJeder Nutzer kann Apps für alle anderen Nutzer aktualisieren."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Nutzerlimit erreicht"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Du kannst bis zu <xliff:g id="COUNT">%d</xliff:g> Nutzer hinzufügen.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Neues Gerät koppeln"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öffne zum Streamen dieser Sitzung die App."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unbekannte App"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Streaming beenden"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Funktionsweise von Nachrichten an alle"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Nachricht an alle"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personen, die in der Nähe sind und kompatible Bluetooth-Geräten haben, können sich die Medien anhören, die du per Nachricht an alle sendest"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 4b5c7b0..787f24f 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Θέλετε να συνεχίσετε την περίοδο σύνδεσής σας;"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Έναρξη από την αρχή"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ναι, συνέχεια"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Προσθήκη νέου χρήστη;"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Κατά την προσθήκη ενός νέου χρήστη, αυτός θα πρέπει να ρυθμίσει τον χώρο του.\n\nΟποιοσδήποτε χρήστης μπορεί να ενημερώσει τις εφαρμογές για όλους τους άλλους χρήστες."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Συμπληρώθηκε το όριο χρηστών"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Μπορείτε να προσθέσετε έως <xliff:g id="COUNT">%d</xliff:g> χρήστες.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Σύζευξη νέας συσκευής"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Για μετάδοση της περιόδου σύνδεσης, ανοίξτε την εφαρμογή."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Άγνωστη εφαρμογή"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Διακοπή μετάδοσης"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Πώς λειτουργεί η μετάδοση"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Μετάδοση"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Οι άνθρωποι με συμβατές συσκευές Bluetooth που βρίσκονται κοντά σας μπορούν να ακούσουν το μέσο που μεταδίδετε."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index bedeea1..608bb4c 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -338,6 +338,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -834,7 +839,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index d886e9f..caa1283 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -338,6 +338,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -834,7 +839,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index bedeea1..608bb4c 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -338,6 +338,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -834,7 +839,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index bedeea1..608bb4c 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -338,6 +338,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Do you want to continue your session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start again"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yes, continue"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Guest mode"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"You are in guest mode"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Add new user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Adding a new user will exit guest mode and delete all apps and data from the current guest session."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"User limit reached"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">You can add up to <xliff:g id="COUNT">%d</xliff:g> users.</item>
@@ -834,7 +839,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Pair new device"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"To cast this session, please open the app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Unknown app"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stop casting"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"How broadcasting works"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"People near you with compatible Bluetooth devices can listen to the media that you\'re broadcasting"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 2da2bdf4..f8f7312 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -338,6 +338,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎Do you want to continue your session?‎‏‎‎‏‎"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‎Start over‎‏‎‎‏‎"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎Yes, continue‎‏‎‎‏‎"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎Guest mode‎‏‎‎‏‎"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎You are in guest mode‎‏‎‎‏‎"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‎‎Add new user?‎‏‎‎‏‎"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‏‎When you add a new user, that person needs to set up their space.‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Any user can update apps for all other users.‎‏‎‎‏‎"</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎‎‏‎‎‏‏‎\n‎‏‎‎‏‏‏‎Adding a new user will exit guest mode and delete all apps and data from the current guest session.‎‏‎‎‏‎"</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎User limit reached‎‏‎‎‏‎"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎You can add up to ‎‏‎‎‏‏‎<xliff:g id="COUNT">%d</xliff:g>‎‏‎‎‏‏‏‎ users.‎‏‎‎‏‎</item>
@@ -834,7 +839,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‎‏‏‎‎Pair new device‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎To cast this session, please open the app.‎‏‎‎‏‎"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎Unknown app‎‏‎‎‏‎"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎Stop casting‎‏‎‎‏‎"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎How broadcasting works‎‏‎‎‏‎"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎Broadcast‎‏‎‎‏‎"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‎‎People near you with compatible Bluetooth devices can listen to the media you\'re broadcasting‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 51b5b66..39b3519 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"¿Agregar usuario nuevo?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Cuando agregas un nuevo usuario, esa persona debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de los usuarios."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzaste el límite de usuarios"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Puedes agregar hasta <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo nuevo"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sesión, abre la app"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconocida"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Detener transmisión"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la transmisión"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que transmites"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index b51ae5f..e7d9549 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres continuar con la sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"¿Añadir nuevo usuario?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Al añadir un nuevo usuario, este debe configurar su espacio.\n\nCualquier usuario puede actualizar las aplicaciones del resto de usuarios."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Has alcanzado el límite de usuarios"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Puedes añadir hasta <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Emparejar nuevo dispositivo"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para enviar esta sesión, abre la aplicación."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación desconocida"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dejar de enviar contenido"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cómo funciona la emisión"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emisión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Las personas cercanas con dispositivos Bluetooth compatibles pueden escuchar el contenido multimedia que emites"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index acadbed..9b05c6d 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Kas soovite seansiga jätkata?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Alusta uuesti"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Jah, jätka"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Kas lisada uus kasutaja?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kui lisate uue kasutaja, siis peab ta seadistama oma ruumi.\n\nIga kasutaja saab värskendada rakendusi kõigi kasutajate jaoks."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Kasutajate limiit on täis"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Võite lisada kuni <xliff:g id="COUNT">%d</xliff:g> kasutajat.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uue seadme sidumine"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Selle seansi ülekandmiseks avage rakendus."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tundmatu rakendus"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lõpeta ülekanne"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kuidas ülekandmine toimib?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Ülekanne"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Teie läheduses olevad inimesed, kellel on ühilduvad Bluetooth-seadmed, saavad kuulata teie ülekantavat meediat"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index d609555..6f0034a 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Saioarekin jarraitu nahi duzu?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Hasi berriro"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Bai, jarraitu"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Beste erabiltzaile bat gehitu?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Erabiltzaile bat gehitzen duzunean, erabiltzaile horrek bere eremua konfiguratu beharko du.\n\nEdozein erabiltzailek egunera ditzake beste erabiltzaile guztien aplikazioak."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Erabiltzaile-mugara iritsi zara"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Gehienez, <xliff:g id="COUNT">%d</xliff:g> erabiltzaile gehi ditzakezu.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parekatu beste gailu batekin"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Saioa ireki nahi baduzu, ireki aplikazioa."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikazio ezezaguna"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Utzi igortzeari"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Nola funtzionatzen dute iragarpenek?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Iragarri"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth bidezko gailu bateragarriak dituzten inguruko pertsonek iragartzen ari zaren multimedia-edukia entzun dezakete"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 6d7bf05..76f7ca1 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"آیا می‌خواهید جلسه‌تان را ادامه دهید؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"شروع مجدد"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"بله، ادامه داده شود"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"کاربر جدیدی اضافه می‌کنید؟"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"وقتی کاربر جدیدی اضافه می‌کنید آن فرد باید فضای خودش را تنظیم کند.\n\nهر کاربری می‌تواند برنامه‌ها را برای همه کاربران دیگر به‌روزرسانی کند."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"به تعداد مجاز تعداد کاربر رسیده‌اید"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">می‌توانید حداکثر <xliff:g id="COUNT">%d</xliff:g> کاربر اضافه کنید.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"مرتبط کردن دستگاه جدید"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"برای ارسال محتوای این جلسه، لطفاً برنامه را باز کنید."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"برنامه ناشناس"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"توقف ارسال محتوا"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"همه‌فرتستی چطور کار می‌کند"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"همه‌فرستی"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"‏افرادی که در اطرافتان دستگاه‌های Bluetooth سازگار دارند می‌توانند به رسانه‌ای که همه‌فرستی می‌کنید گوش کنند"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 6b9f683..85d0e20 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Haluatko jatkaa istuntoa?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Aloita alusta"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Kyllä, haluan jatkaa"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Lisätäänkö uusi käyttäjä?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Käyttäjäraja saavutettu"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Voit lisätä korkeintaan <xliff:g id="COUNT">%d</xliff:g> käyttäjää.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Muodosta uusi laitepari"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jos haluat striimata tämän käyttökerran, avaa sovellus."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Tuntematon sovellus"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Lopeta striimaus"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Miten lähetys toimii"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Lähetys"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Lähistöllä olevat ihmiset, joilla on yhteensopiva Bluetooth-laite, voivat kuunnella lähettämääsi mediaa"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index e90fa29..e9db78d 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recommencer"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Ajouter un utilisateur?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nTout utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite d\'utilisateurs atteinte"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Vous pouvez ajouter jusqu\'à <xliff:g id="COUNT">%d</xliff:g> utilisateur.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un autre appareil"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour diffuser cette session, veuillez ouvrir l\'application."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Application inconnue"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement de la diffusion"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Diffusion"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité disposant d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index e214353..95a351b 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Voulez-vous poursuivre la dernière session ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Non, nouvelle session"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oui, continuer"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Ajouter un utilisateur ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Lorsque vous ajoutez un utilisateur, celui-ci doit configurer son espace.\n\nN\'importe quel utilisateur peut mettre à jour les applications pour tous les autres utilisateurs."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite nombre utilisateurs atteinte"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Vous pouvez ajouter <xliff:g id="COUNT">%d</xliff:g> profil utilisateur.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Associer un nouvel appareil"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pour caster cette session, veuillez ouvrir l\'appli."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Appli inconnue"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Arrêter la diffusion"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Fonctionnement des annonces"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Annonce"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Les personnes à proximité équipées d\'appareils Bluetooth compatibles peuvent écouter le contenu multimédia que vous diffusez"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 55a4d92..a3dc2a2 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Queres continuar coa túa sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Comezar de novo"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Si, continuar"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Engadir un usuario novo?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Cando engadas un usuario novo, este deberá configurar o seu espazo.\n\nCalquera usuario pode actualizar as aplicacións para todos os demais usuarios."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzouse o límite de usuarios"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Podes engadir ata <xliff:g id="COUNT">%d</xliff:g> usuarios.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Vincular dispositivo novo"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para emitir esta sesión, abre a aplicación."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicación descoñecida"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Deter emisión"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funcionan as difusións?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Difusión"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As persoas que estean preto de ti e que dispoñan de dispositivos Bluetooth compatibles poden escoitar o contido multimedia que difundas"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 604a1ee..300ac4d 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"શું તમે તમારું સત્ર ચાલુ રાખવા માંગો છો?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"શરૂ કરો"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"હા, ચાલુ રાખો"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"નવા વપરાશકર્તાને ઉમેરીએ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"જ્યારે તમે કોઈ નવા વપરાશકર્તાને ઉમેરો છો, ત્યારે તે વ્યક્તિને તેમનું સ્થાન સેટ કરવાની જરૂર પડે છે.\n\nકોઈપણ વપરાશકર્તા બધા અન્ય વપરાશકર્તાઓ માટે ઍપને અપડેટ કરી શકે છે."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"વપરાશકર્તા સંખ્યાની મર્યાદા"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">તમે <xliff:g id="COUNT">%d</xliff:g> વપરાશકર્તા સુધી ઉમેરી શકો છો.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"નવા ડિવાઇસ સાથે જોડાણ કરો"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"આ સત્ર કાસ્ટ કરવા માટે, કૃપા કરીને ઍપ ખોલો."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"અજાણી ઍપ"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"કાસ્ટ કરવાનું રોકો"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"બ્રોડકાસ્ટ પ્રક્રિયાની કામ કરવાની રીત"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"બ્રોડકાસ્ટ કરો"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"સુસંગત બ્લૂટૂથ ડિવાઇસ ધરાવતા નજીકના લોકો તમે જે મીડિયા બ્રોડકાસ્ટ કરી રહ્યાં છો તે સાંભળી શકે છે"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 2822eb2..c6674d0 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"क्‍या आप अपना सत्र जारी रखना चाहते हैं?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"फिर से शुरू करें"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हां, जारी रखें"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"नया उपयोगकर्ता जोड़ें?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"जब आप कोई नया उपयोगकर्ता जोड़ते हैं, तो उसे अपनी जगह सेट करनी होती है.\n\nकोई भी उपयोगकर्ता बाकी सभी उपयोगकर्ताओं के लिए ऐप्लिकेशन अपडेट कर सकता है."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"अब और उपयोगकर्ता नहीं जोड़े जा सकते"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">आप ज़्यादा से ज़्यादा <xliff:g id="COUNT">%d</xliff:g> उपयोगकर्ता जोड़ सकते हैं.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नया डिवाइस जोड़ें"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"इस सेशन को कास्ट करने के लिए, कृपया ऐप्लिकेशन खोलें."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अनजान ऐप्लिकेशन"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्टिंग करना रोकें"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्ट करने की सुविधा कैसे काम करती है"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करें"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"आपके आस-पास मौजूद लोग, ब्रॉडकास्ट किए जा रहे मीडिया को सुन सकते हैं. हालांकि, इसके लिए उनके पास ऐसे ब्लूटूथ डिवाइस होने चाहिए जिन पर मीडिया चलाया जा सके"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index ef31620..4d153e9 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -340,6 +340,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite li nastaviti sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Počni ispočetka"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nastavi"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodati novog korisnika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kada dodate novog korisnika, ta osoba mora postaviti vlastiti prostor.\n\nBilo koji korisnik može ažurirati aplikacije za sve ostale korisnike."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dosegnuto je ograničenje korisnika"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Možete dodati najviše <xliff:g id="COUNT">%d</xliff:g> korisnika.</item>
@@ -841,7 +849,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Uparite novi uređaj"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Da biste emitirali ovu sesiju, otvorite aplikaciju."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nepoznata aplikacija"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zaustavi emitiranje"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako emitiranje funkcionira"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Emitiranje"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osobe u blizini s kompatibilnim Bluetooth uređajima mogu slušati medije koje emitirate"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index a37c237..895b61e 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Folytatja a munkamenetet?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Újrakezdés"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Igen, folytatom"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Új felhasználó hozzáadása?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Ha új felhasználót ad hozzá, az illetőnek be kell állítania saját tárterületét.\n\nBármely felhasználó frissítheti az alkalmazásokat valamennyi felhasználó számára."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Maximális felhasználószám elérve"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Legfeljebb <xliff:g id="COUNT">%d</xliff:g> felhasználót adhat hozzá.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Új eszköz párosítása"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"A munkamenet átküldéséhez nyissa meg az alkalmazást."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ismeretlen alkalmazás"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Átküldés leállítása"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"A közvetítés működése"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Közvetítés"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"A közelben tartózkodó, kompatibilis Bluetooth-eszközzel rendelkező személyek meghallgathatják az Ön közvetített médiatartalmait"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index f724bd8..c7024b5 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Շարունակե՞լ աշխատաշրջանը։"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Վերսկսել"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Այո, շարունակել"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Ավելացնե՞լ նոր օգտատեր"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Երբ նոր օգտատեր եք ավելացնում, նա պետք է կարգավորի իր պրոֆիլը:\n\nՑանկացած օգտատեր կարող է թարմացնել հավելվածները մյուս բոլոր հաշիվների համար:"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Սահմանաչափը սպառված է"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Հնարավոր է ավելացնել առավելագույնը <xliff:g id="COUNT">%d</xliff:g> օգտատեր։</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Նոր սարքի զուգակցում"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Այս աշխատաշրջանը հեռարձակելու համար բացեք հավելվածը"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Անհայտ հավելված"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Կանգնեցնել հեռարձակումը"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ինչպես է աշխատում հեռարձակումը"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Հեռարձակում"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ձեր մոտակայքում գտնվող՝ համատեղելի Bluetooth սարքերով մարդիկ կարող են լսել մեդիա ֆայլերը, որոնք դուք հեռարձակում եք։"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 8c7569c..8114306 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Lanjutkan sesi Anda?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulai ulang"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ya, lanjutkan"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Tambahkan pengguna baru?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri.\n\nPengguna mana pun dapat mengupdate aplikasi untuk semua pengguna lain."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Batas pengguna tercapai"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Anda dapat menambahkan hingga <xliff:g id="COUNT">%d</xliff:g> pengguna.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sambungkan perangkat baru"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Buka aplikasi untuk mentransmisikan sesi ini."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikasi tidak dikenal"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Hentikan transmisi"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara kerja siaran"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Siaran"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang di dekat Anda dengan perangkat Bluetooth yang kompatibel dapat mendengarkan media yang sedang Anda siarkan"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 80a6945..e75a8f1 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Viltu halda áfram með lotuna?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Byrja upp á nýtt"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Já, halda áfram"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Bæta nýjum notanda við?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Þegar þú bætir nýjum notanda við þarf sá notandi að setja upp svæðið sitt.\n\nHvaða notandi sem er getur uppfært forrit fyrir alla aðra notendur."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Notandahámarki náð"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Þú getur bætt við allt að <xliff:g id="COUNT">%d</xliff:g> notanda.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Para nýtt tæki"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Opnaðu forritið til að senda þessa lotu út."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Óþekkt forrit"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stöðva útsendingu"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Svona virkar útsending"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Útsending"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Fólk nálægt þér með samhæf Bluetooth-tæki getur hlustað á efnið sem þú sendir út"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 9b2178a..10c6a59 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vuoi continuare la sessione?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Ricomincia"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sì, continua"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Aggiungere un nuovo utente?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Il nuovo utente, una volta aggiunto, deve impostare il proprio spazio.\n\nQualsiasi utente può aggiornare le app per tutti gli altri."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite di utenti raggiunto"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Puoi aggiungere fino a <xliff:g id="COUNT">%d</xliff:g> utenti.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Accoppia nuovo dispositivo"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Per trasmettere questa sessione devi aprire l\'app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App sconosciuta"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Interrompi trasmissione"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Come funziona la trasmissione"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Annuncio"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Le persone vicine a te che hanno dispositivi Bluetooth compatibili possono ascoltare i contenuti multimediali che stai trasmettendo"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index e4d3dca..451d96c 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -342,6 +342,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"האם ברצונך להמשיך בפעילות באתר?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"סשן חדש"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"כן, להמשיך"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"להוסיף משתמש חדש?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"כשמוסיפים משתמש חדש, המשתמש הזה צריך להגדיר את השטח שלו.\n\nכל משתמש יכול לעדכן אפליקציות עבור כל המשתמשים האחרים."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"הגעת למגבלת המשתמשים שניתן להוסיף"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="two">ניתן להוסיף עד <xliff:g id="COUNT">%d</xliff:g> משתמשים.</item>
@@ -847,7 +855,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"התאמה של מכשיר חדש"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"‏כדי להעביר (cast) את הסשן הזה, צריך לפתוח את האפליקציה."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"אפליקציה לא ידועה"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"‏עצירת ההעברה (casting)"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"הסבר על שידורים"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"שידור"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"‏אנשים בקרבת מקום עם מכשירי Bluetooth תואמים יכולים להאזין למדיה שמשודרת על ידך"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 170b31f..0cde116 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"セッションを続行しますか?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"最初から開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"続行"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"新しいユーザーを追加しますか?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"新しいユーザーを追加したら、そのユーザーは自分のスペースをセットアップする必要があります。\n\nすべてのユーザーは他のユーザーに代わってアプリを更新できます。"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ユーザー数が上限に達しました"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">最大 <xliff:g id="COUNT">%d</xliff:g> 人のユーザーを追加できます。</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"新しいデバイスとのペア設定"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"このセッションをキャストするには、アプリを開いてください。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明なアプリ"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"キャストを停止"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ブロードキャストの仕組み"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ブロードキャスト"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Bluetooth 対応デバイスを持っている付近のユーザーは、あなたがブロードキャストしているメディアを聴けます"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 69f4ba1..a15dd67 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"გსურთ, თქვენი სესიის გაგრძელება?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ხელახლა დაწყება"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"დიახ, გავაგრძელოთ"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"დაემატოს ახალი მომხმარებელი?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ახალი მომხმარებლის დამატებისას, ამ მომხმარებელს საკუთარი სივრცის შექმნა მოუწევს.\n\nნებისმიერ მომხმარებელს შეუძლია აპები ყველა სხვა მომხმარებლისათვის განაახლოს."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"მიღწეულია მომხმარებელთა ლიმიტი"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">შესაძლებელია <xliff:g id="COUNT">%d</xliff:g>-მდე მომხმარებლის დამატება.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ახალი მოწყობილობის დაწყვილება"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ამ სესიის ტრანსლირებისთვის გახსენით აპი."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"უცნობი აპი"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ტრანსლირების შეწყვეტა"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ტრანსლირების მუშაობის პრინციპი"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ტრანსლაცია"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"თქვენთან ახლოს მყოფ ხალხს თავსებადი Bluetooth მოწყობილობით შეუძლიათ თქვენ მიერ ტრანსლირებული მედიის მოსმენა"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 0538ddb..9408df5 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансты жалғастыру керек пе?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Қайта бастау"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Иә, жалғастыру"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Жаңа пайдаланушы қосылсын ба?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Жаңа пайдаланушыны қосқанда, сол адам өз кеңістігін реттеуі керек.\n\nКез келген пайдаланушы барлық басқа пайдаланушылар үшін қолданбаларды жаңарта алады."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Пайдаланушылар саны шегіне жетті"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> пайдаланушыға дейін енгізуге болады.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңа құрылғымен жұптау"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бұл сеансты трансляциялау үшін қолданбаны ашыңыз."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгісіз қолданба"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Трансляцияны тоқтату"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Тарату қалай жүзеге асады"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Тарату"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Үйлесімді Bluetooth құрылғылары бар маңайдағы адамдар сіз таратып жатқан медиамазмұнды тыңдай алады."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 37ba518..751f8e6 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"តើ​អ្នក​ចង់​បន្ត​វគ្គ​របស់​អ្នក​ទេ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ចាប់ផ្ដើមសាជាថ្មី"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"បាទ​/ចាស ​បន្ត"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"បញ្ចូល​អ្នកប្រើ​ថ្មីឬ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"នៅពេល​អ្នក​បញ្ចូល​អ្នកប្រើ​ថ្មី អ្នកប្រើ​នោះ​ត្រូវ​រៀបចំកន្លែងរបស់​គេ។\n\nអ្នក​ប្រើ​ណា​ក៏​អាច​ដំឡើងកំណែ​កម្មវិធី​សម្រាប់​អ្នកប្រើទាំងអស់ផ្សេងទៀត​បាន​ដែរ។"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"​បាន​ឈាន​ដល់ចំនួន​កំណត់អ្នកប្រើប្រាស់"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">អ្នកអាចបញ្ចូល​អ្នក​ប្រើប្រាស់បាន​រហូតដល់ <xliff:g id="COUNT">%d</xliff:g> នាក់។</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ផ្គូផ្គង​ឧបករណ៍ថ្មី"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ដើម្បីភ្ជាប់វគ្គនេះ សូមបើកកម្មវិធី។"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"កម្មវិធី​ដែលមិន​ស្គាល់"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"បញ្ឈប់ការភ្ជាប់"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"របៀបដែលការផ្សាយដំណើរការ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ការ​ផ្សាយ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"មនុស្សនៅជិត​អ្នកដែលមាន​ឧបករណ៍ប៊្លូធូស​ត្រូវគ្នា​អាចស្តាប់​មេឌៀ​ដែលអ្នកកំពុងផ្សាយបាន"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index fa6e18ee..406fa17 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ನಿಮ್ಮ ಸೆಷನ್‌ ಮುಂದುವರಿಸಲು ಇಚ್ಚಿಸುವಿರಾ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ಹೌದು, ಮುಂದುವರಿಸಿ"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸುವುದೇ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ಅವರ ಸ್ಥಳವನ್ನು ಸ್ಥಾಪಿಸಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ಬಳಕೆದಾರರ ಮಿತಿ ತಲುಪಿದೆ"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">ನೀವು <xliff:g id="COUNT">%d</xliff:g> ಬಳಕೆದಾರರವರೆಗೆ ಸೇರಿಸಬಹುದು.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಿ"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ಈ ಸೆಶನ್ ಕಾಸ್ಟ್ ಮಾಡಲು, ಆ್ಯಪ್ ಅನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ಅಪರಿಚಿತ ಆ್ಯಪ್"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ಪ್ರಸಾರವು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ಪ್ರಸಾರ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ಹೊಂದಾಣಿಕೆಯಾಗುವ ಬ್ಲೂಟೂತ್ ಸಾಧನಗಳನ್ನು ಹೊಂದಿರುವ ಸಮೀಪದಲ್ಲಿರುವ ಜನರು ನೀವು ಪ್ರಸಾರ ಮಾಡುತ್ತಿರುವ ಮಾಧ್ಯಮವನ್ನು ಆಲಿಸಬಹುದು"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index e4e4dbf..60bb933 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"세션을 계속 진행하시겠습니까?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"다시 시작"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"계속 진행"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"신규 사용자를 추가할까요?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"추가된 새로운 사용자는 자신의 공간을 설정해야 합니다.\n\n사용자라면 누구든 다른 사용자를 위해 앱을 업데이트할 수 있습니다."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"사용자 제한 도달"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">사용자를 <xliff:g id="COUNT">%d</xliff:g>명까지 추가할 수 있습니다.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"새 기기와 페어링"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"세션을 전송하려면 앱을 열어 주세요"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"알 수 없는 앱"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"전송 중지"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"브로드캐스팅 작동 원리"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"브로드캐스트"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"호환되는 블루투스 기기를 가진 근처의 사용자가 내가 브로드캐스트 중인 미디어를 수신 대기할 수 있습니다."</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index be9db2e..784e583 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -338,6 +338,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Сеансыңызды улантасызбы?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Кайра баштоо"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ооба, уланта берели"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Конок режими"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Конок режиминдесиз"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"Жаңы колдонуучу кошосузбу?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Жаңы колдонуучу кошулганда, ал өз мейкиндигин түзүп алышы керек.\n\nКолдонмолорду бир колдонуучу жаңыртканда, ал калган бардык колдонуучулар үчүн да жаңырат."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Жаңы колдонуучуну кошсоңуз, конок режими жабылат жана учурдагы конок сеансындагы бардык колдонмолор жана дайындар өчүрүлөт."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Дагы колдонуучу кошууга болбойт"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> колдонуучуга чейин кошууга болот.</item>
@@ -834,7 +839,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Жаңы түзмөк кошуу"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Бул сеансты тышкы экранга чыгаруу үчүн колдонмону ачыңыз."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Белгисиз колдонмо"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Тышкы экранга чыгарууну токтотуу"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Кабарлоо кантип иштейт"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Кабарлоо"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Шайкеш Bluetooth түзмөктөрү болгон жакын жердеги кишилер кабарлап жаткан медиаңызды уга алышат"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index a5d8fd9..8d561c8 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ທ່ານ​ຕ້ອງ​ການ​ສືບ​ຕໍ່​ເຊດ​ຊັນ​ຂອງ​ທ່ານບໍ່?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ເລີ່ມຕົ້ນໃຫມ່"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"​ຕົກ​ລົງ, ດຳ​ເນີນ​ການ​ຕໍ່"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"ເພີ່ມຜູ້ໃຊ້ໃໝ່ບໍ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ເມື່ອ​ທ່ານ​ເພີ່ມ​ຜູ້ໃຊ້​ໃໝ່, ຜູ້ໃຊ້​ນັ້ນ​ຈະ​ຕ້ອງ​ຕັ້ງ​ຄ່າ​ພື້ນ​ທີ່​ບ່ອນ​ຈັດ​ເກັບ​ຂໍ້​ມູນ​ຂອງ​ລາວ.\n\nຜູ້ໃຊ້​ທຸກ​ຄົນ​ສາ​ມາດ​ອັບ​ເດດ​ແອັບຂອງ​ຜູ້​ໃຊ້​ຄົນ​ອື່ນ​ທັງ​ໝົດ​ໄດ້."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ຮອດຂີດຈຳກັດຜູ້ໃຊ້ແລ້ວ"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">ທ່ານສາມາດເພີ່ມໄດ້ສູງສຸດ <xliff:g id="COUNT">%d</xliff:g> ຄົນ.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ຈັບຄູ່ອຸປະກອນໃໝ່"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ເພື່ອສົ່ງສັນຍານເຊດຊັນນີ້, ກະລຸນາເປີດແອັບ."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ແອັບທີ່ບໍ່ຮູ້ຈັກ"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ຢຸດການສົ່ງສັນຍານ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ການອອກອາກາດເຮັດວຽກແນວໃດ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ອອກອາກາດ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ຄົນທີ່ຢູ່ໃກ້ທ່ານທີ່ມີອຸປະກອນ Bluetooth ທີ່ເຂົ້າກັນໄດ້ຈະສາມາດຟັງມີເດຍທີ່ທ່ານກຳລັງອອກອາກາດຢູ່ໄດ້"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 667a666..ab99dde 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -342,6 +342,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ar norite tęsti sesiją?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Pradėti iš naujo"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Taip, tęsti"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Pridėti naują naudotoją?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kai pridedate naują naudotoją, šis asmuo turi nustatyti savo erdvę.\n\nBet kuris naudotojas gali atnaujinti visų kitų naudotojų programas."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Pasiekta naudotojų riba"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Galite pridėti iki <xliff:g id="COUNT">%d</xliff:g> naudotojo.</item>
@@ -847,7 +855,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Naujo įrenginio susiejimas"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Jei norite perduoti šį seansą, atidarykite programą."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nežinoma programa"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sustabdyti perdavimą"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kaip veikia transliacija"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transliacija"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Netoliese esantys žmonės, turintys suderinamus „Bluetooth“ įrenginius, gali klausyti jūsų transliuojamos medijos"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 516bcab..e22c1bb 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -340,6 +340,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vai vēlaties turpināt savu sesiju?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Sākt no sākuma"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Jā, turpināt"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Vai pievienot jaunu lietotāju?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kad pievienosiet jaunu lietotāju, viņam būs jāizveido savs profils.\n\nIkviens lietotājs var atjaunināt lietotnes citu lietotāju vietā."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Sasniegts lietotāju ierobežojums"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="zero">Varat pievienot ne vairāk kā <xliff:g id="COUNT">%d</xliff:g> lietotājus.</item>
@@ -841,7 +849,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Savienošana pārī ar jaunu ierīci"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Lai apraidītu šo sesiju, lūdzu, atveriet lietotni."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nezināma lietotne"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Apturēt apraidi"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kā darbojas apraide"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Apraide"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Tuvumā esošās personas ar saderīgām Bluetooth ierīcēm var klausīties jūsu apraidīto multivides saturu."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index b58338c..1498549 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Дали сакате да продолжите со сесијата?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни одново"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продолжи"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Да се додаде нов корисник?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Кога додавате нов корисник, тоа лице треба да го постави својот простор.\n\nСекој корисник може да ажурира апликации за сите други корисници."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнато ограничување на корисник"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Може да додадете најмногу <xliff:g id="COUNT">%d</xliff:g> корисник.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Спарете нов уред"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"За да ја емитувате сесијава, отворете ја апликацијата."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Сопри со емитување"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционира емитувањето"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Емитување"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Луѓето во ваша близина со компатибилни уреди со Bluetooth може да ги слушаат аудиозаписите што ги емитувате"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index be345ac..4bc8ac2 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"നിങ്ങളുടെ സെഷൻ തുടരണോ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"പുനരാംരംഭിക്കുക"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"അതെ, തുടരുക"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"പുതിയ ഉപയോക്താവിനെ ചേർക്കണോ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"നിങ്ങൾ പുതിയൊരു ഉപയോക്താവിനെ ചേർക്കുമ്പോൾ, ആ വ്യക്തിക്ക് അവരുടെ ഇടം സജ്ജീകരിക്കേണ്ടതുണ്ട്.\n\nമറ്റ് എല്ലാ ഉപയോക്താക്കൾക്കുമായി ഏതൊരു ഉപയോക്താവിനും ആപ്പുകൾ അപ്‌ഡേറ്റ് ചെയ്യാനാവും."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ഉപയോക്തൃ പരിധി എത്തി"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">നിങ്ങൾക്ക് <xliff:g id="COUNT">%d</xliff:g> ഉപയോക്താക്കളെ വരെ ചേർക്കാനാവും.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"പുതിയ ഉപകരണവുമായി ജോടിയാക്കുക"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ഈ സെഷൻ കാസ്റ്റ് ചെയ്യാൻ, ആപ്പ് തുറക്കുക."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"അജ്ഞാതമായ ആപ്പ്"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"കാസ്റ്റ് ചെയ്യുന്നത് നിർത്തുക"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ബ്രോഡ്‌കാസ്‌റ്റ് എങ്ങനെയാണ് പ്രവർത്തിക്കുന്നത്"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ബ്രോഡ്‌കാസ്റ്റ്"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"അനുയോജ്യമായ Bluetooth ഉപകരണങ്ങളോടെ സമീപമുള്ള ആളുകൾക്ക് നിങ്ങൾ ബ്രോഡ്‌കാസ്‌റ്റ് ചെയ്യുന്ന മീഡിയ കേൾക്കാനാകും"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 45211c4..399414b 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Та үргэлжлүүлэхийг хүсэж байна уу?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Дахин эхлүүлэх"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Тийм, үргэлжлүүлэх"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Шинэ хэрэглэгч нэмэх үү?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Та шинэ хэрэглэгч нэмбэл тухайн хүн өөрийн профайлыг тохируулах шаардлагатай.\n\nАль ч хэрэглэгч бүх хэрэглэгчийн аппуудыг шинэчлэх боломжтой."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Хэрэглэгчийн хязгаарт хүрсэн"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Та <xliff:g id="COUNT">%d</xliff:g> хүртэлх хэрэглэгч нэмэх боломжтой.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Шинэ төхөөрөмж хослуулах"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Энэ үйл явдлыг дамжуулахын тулд аппыг нээнэ үү."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Үл мэдэгдэх апп"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Дамжуулахыг зогсоох"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Нэвтрүүлэлт хэрхэн ажилладаг вэ?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Нэвтрүүлэлт"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Тохиромжтой Bluetooth төхөөрөмжүүдтэй таны ойролцоох хүмүүс таны нэвтрүүлж буй медиаг сонсох боломжтой"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index d431a2b..7c3504e 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -338,6 +338,11 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"तुम्ही तुमचे सत्र सुरू ठेवू इच्छिता?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"येथून सुरू करा"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"होय, सुरू ठेवा"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"अतिथी मोड"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"तुम्ही अतिथी मोडमध्ये आहात"</string>
+    <string name="user_add_user_title" msgid="4172327541504825032">"नवीन वापरकर्ता जोडायचा?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"तुम्ही एक नवीन वापरकर्ता जोडता तेव्हा, त्या व्यक्तीने त्यांचे स्थान सेट करणे आवश्यक असते.\n\nकोणताही वापरकर्ता इतर सर्व वापरकर्त्यांसाठी अ‍ॅप्स अपडेट करू शकतो."</string>
+    <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"नवीन वापरकर्ता जोडल्याने अतिथी मोडमधून बाहेर पडेल आणि सध्याच्या अतिथी सत्रातील सर्व अ‍ॅप्स व डेटा हटवला जाईल."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"वापरकर्ता मर्यादा गाठली"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">तुम्ही <xliff:g id="COUNT">%d</xliff:g> वापरकर्त्यांपर्यंत जोडू शकता.</item>
@@ -834,7 +839,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नवीन डिव्हाइससोबत पेअर करा"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"हे सेशन कास्ट करण्यासाठी, कृपया ॲप उघडा."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात अ‍ॅप"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट करणे थांबवा"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ब्रॉडकास्टिंग कसे काम करते"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ब्रॉडकास्ट करा"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कंपॅटिबिल ब्लूटूथ डिव्‍हाइस असलेले तुमच्या जवळपासचे लोक हे तुम्ही ब्रॉडकास्ट करत असलेला मीडिया ऐकू शकतात"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 9bab5cb..c625cf3 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Adakah anda ingin meneruskan sesi anda?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Mulakan semula"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ya, teruskan"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Tambah pengguna baharu?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Apabila anda menambah pengguna baharu, orang itu perlu menyediakan ruang mereka.\n\nMana-mana pengguna boleh mengemas kini apl untuk semua pengguna lain."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Had pengguna dicapai"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Anda boleh menambah sehingga <xliff:g id="COUNT">%d</xliff:g> pengguna.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Gandingkan peranti baharu"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Untuk menghantar sesi ini, sila buka apl."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Apl yang tidak diketahui"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Berhenti menghantar"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cara siaran berfungsi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Siarkan"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Orang berdekatan anda dengan peranti Bluetooth yang serasi boleh mendengar media yang sedang anda siarkan"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 00079fc..08c3f40 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"သင်၏ စက်ရှင်ကို ဆက်လုပ်လိုပါသလား။"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ပြန်စပါ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ဆက်လုပ်ပါ"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"အသုံးပြုသူအသစ်ကို ထည့်မလား။"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"သင်ထည့်လိုက်သော အသုံးပြုသူအသစ်သည် ၎င်း၏နေရာကို သတ်မှတ်စီစဉ်ရန် လိုအပ်သည်။\n\nမည်သည့်အသုံးပြုသူမဆို ကျန်သူများအားလုံးအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်ပေးနိုင်သည်။"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"အသုံးပြုသူ အကန့်အသတ် ပြည့်သွားပါပြီ"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">အသုံးပြုသူ <xliff:g id="COUNT">%d</xliff:g> ဦးအထိ ထည့်နိုင်သည်။</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"စက်အသစ် တွဲချိတ်ရန်"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"အက်ပ်ဖွင့်ပြီး ဤစက်ရှင်ကို ကာစ်လုပ်နိုင်သည်။"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"အမည်မသိ အက်ပ်"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ကာစ် ရပ်ရန်"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ထုတ်လွှင့်မှုဆောင်ရွက်ပုံ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ထုတ်လွှင့်ခြင်း"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"အနီးရှိတွဲသုံးနိုင်သော ဘလူးတုသ်သုံးစက် အသုံးပြုသူများက သင်ထုတ်လွှင့်နေသော မီဒီယာကို နားဆင်နိုင်သည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 37f0a53..bccc9e0 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vil du fortsette økten?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Start på nytt"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsett"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Vil du legge til en ny bruker?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Når du legger til en ny bruker, må vedkommende konfigurere sitt eget område.\n\nAlle brukere kan oppdatere apper for alle andre brukere."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Grensen for antall brukere er nådd"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Du kan legge til opptil <xliff:g id="COUNT">%d</xliff:g> brukere.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Koble til en ny enhet"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"For å caste denne økten, åpne appen."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ukjent app"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Stopp castingen"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Slik fungerer kringkasting"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Kringkasting"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Folk i nærheten med kompatible Bluetooth-enheter kan lytte til mediene du kringkaster"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index cc025b7..9d89584 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"तपाईं आफ्नो सत्र जारी गर्न चाहनुहुन्छ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"सुरु गर्नुहोस्"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"हो, जारी राख्नुहोस्"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"नयाँ प्रयोगकर्ता थप्ने हो?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"जब तपाईँले नयाँ प्रयोगकर्ता थप्नुहुन्छ, त्यस प्रयोगकर्ताले आफ्नो स्थान स्थापना गर्न पर्ने छ।\n\nसबै प्रयोगकर्ताले अरू प्रयोगकर्ताका एपहरू अपडेट गर्न सक्छन्।"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"प्रयोगकर्ताको सीमा पुग्यो"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">तपाईं अधिकतम <xliff:g id="COUNT">%d</xliff:g> प्रयोगहरू मात्र थप्न सक्नुहुन्छ।</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"नयाँ डिभाइस कनेक्ट गर्नुहोस्"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"यो सत्र कास्ट गर्न चाहनुहुन्छ भने कृपया एप खोल्नुहोस्।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"अज्ञात एप"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"कास्ट गर्न छाड्नुहोस्"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"प्रसारण गर्ने सुविधाले कसरी काम गर्छ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"प्रसारण"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"कम्प्याटिबल ब्लुटुथ डिभाइस भएका नजिकैका मान्छेहरू तपाईंले प्रसारण गरिरहनुभएको मिडिया सुन्न सक्छन्"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 3a638b1..4b96d5d 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -67,12 +67,10 @@
 
     <!-- media output dialog-->
     <color name="media_dialog_background">@color/material_dynamic_neutral10</color>
-    <color name="media_dialog_item_main_content">@color/material_dynamic_primary90</color>
-    <color name="media_dialog_item_background">@color/material_dynamic_neutral_variant20</color>
-    <color name="media_dialog_connected_item_background">@color/material_dynamic_secondary20</color>
-    <color name="media_dialog_seekbar_progress">@color/material_dynamic_secondary40</color>
-    <color name="media_dialog_button_background">@color/material_dynamic_primary70</color>
-    <color name="media_dialog_solid_button_text">@color/material_dynamic_secondary20</color>
+    <color name="media_dialog_active_item_main_content">@color/material_dynamic_neutral10</color>
+    <color name="media_dialog_inactive_item_main_content">@color/material_dynamic_neutral10</color>
+    <color name="media_dialog_item_status">@color/material_dynamic_neutral10</color>
+    <color name="media_dialog_item_background">@color/material_dynamic_secondary95</color>
 
     <!-- Biometric dialog colors -->
     <color name="biometric_dialog_gray">#ffcccccc</color>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 8e54529..764ca8c 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Wil je doorgaan met je sessie?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Opnieuw starten"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, doorgaan"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Nieuwe gebruiker toevoegen?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Als je een nieuwe gebruiker toevoegt, moet die persoon zijn eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Gebruikerslimiet bereikt"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Je kunt maximaal <xliff:g id="COUNT">%d</xliff:g> gebruikers toevoegen.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Nieuw apparaat koppelen"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Als je deze sessie wilt casten, open je de app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Onbekende app"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Casten stoppen"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Hoe uitzenden werkt"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Uitzending"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Mensen bij jou in de buurt met geschikte bluetooth-apparaten kunnen luisteren naar de media die je uitzendt"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 258e9a1..9894d70 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ଆପଣ ନିଜର ସେସନ୍ ଜାରି ରଖିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ହଁ, ଜାରି ରଖନ୍ତୁ"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"ନୂତନ ଉପଯୋଗକର୍ତ୍ତା ଯୋଗ କରିବେ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ଆପଣ ଜଣେ ନୂଆ ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଯୋଗ କଲେ,ତାଙ୍କୁ ସ୍ପେସ୍ ସେଟ୍ ଅପ୍ କରିବାକୁ ପଡ଼ିବ। \n \n ଅନ୍ୟ ସମସ୍ତ ଉପଯୋଗକର୍ତ୍ତାଙ୍କ ପାଇଁ ଯେ କୌଣସି ଉପଯୋଗକର୍ତ୍ତା ଆପଗୁଡ଼ିକୁ ଅପଡେଟ୍‌ କରିପାରିବେ।"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ଉପଯୋଗକର୍ତ୍ତା ସୀମାରେ ପହଞ୍ଚିଛି"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">କେବଳ <xliff:g id="COUNT">%d</xliff:g> ଉପଯୋଗକର୍ତ୍ତା ହିଁ ତିଆରି କରିହେବ।</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ନୂଆ ଡିଭାଇସକୁ ପେୟାର୍ କରନ୍ତୁ"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ଏହି ସେସନକୁ କାଷ୍ଟ କରିବା ପାଇଁ, ଦୟାକରି ଆପ ଖୋଲନ୍ତୁ।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ଅଜଣା ଆପ"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ବ୍ରଡକାଷ୍ଟିଂ କିପରି କାମ କରେ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ବ୍ରଡକାଷ୍ଟ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ଆପଣଙ୍କ ଆଖପାଖର କମ୍ପାଟିବଲ ବ୍ଲୁଟୁଥ ଡିଭାଇସ ଥିବା ଲୋକମାନେ ଆପଣ ବ୍ରଡକାଷ୍ଟ କରୁଥିବା ମିଡିଆ ଶୁଣିପାରିବେ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 6492303..855ec1a 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ਹਾਂ, ਜਾਰੀ ਰੱਖੋ"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"ਕੀ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨਾ ਹੈ?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ਜਦੋਂ ਤੁਸੀਂ ਇੱਕ ਨਵਾਂ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਦੇ ਹੋ, ਉਸ ਵਿਅਕਤੀ ਨੂੰ ਆਪਣੀ ਜਗ੍ਹਾ ਸਥਾਪਤ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।\n\nਕੋਈ ਵੀ ਵਰਤੋਂਕਾਰ ਹੋਰ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਅੱਪਡੇਟ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰਨ ਦੀ ਸੀਮਾ ਪੂਰੀ ਹੋਈ"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">ਤੁਸੀਂ <xliff:g id="COUNT">%d</xliff:g> ਤੱਕ ਵਰਤੋਂਕਾਰ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ।</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ਇਸ ਸੈਸ਼ਨ ਨੂੰ ਕਾਸਟ ਕਰਨ ਲਈ, ਕਿਰਪਾ ਕਰਕੇ ਐਪ ਖੋਲ੍ਹੋ।"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"ਅਗਿਆਤ ਐਪ"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ਪ੍ਰਸਾਰਨ ਕਿਵੇਂ ਕੰਮ ਕਰਦਾ ਹੈ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ਪ੍ਰਸਾਰਨ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ਅਨੁਰੂਪ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸਾਂ ਨਾਲ ਨਜ਼ਦੀਕੀ ਲੋਕ ਤੁਹਾਡੇ ਵੱਲੋਂ ਪ੍ਰਸਾਰਨ ਕੀਤੇ ਜਾ ਰਹੇ ਮੀਡੀਆ ਨੂੰ ਸੁਣ ਸਕਦੇ ਹਨ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 7196471..9526d62 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -342,6 +342,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcesz kontynuować sesję?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Rozpocznij nową"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Tak, kontynuuj"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodać nowego użytkownika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Gdy dodasz nowego użytkownika, musi on skonfigurować swój profil.\n\nKażdy użytkownik może aktualizować aplikacje wszystkich innych użytkowników."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Osiągnięto limit użytkowników"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="few">Możesz dodać maksymalnie <xliff:g id="COUNT">%d</xliff:g> użytkowników.</item>
@@ -847,7 +855,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sparuj nowe urządzenie"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Aby przesłać tę sesję, otwórz aplikację."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Nieznana aplikacja"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zatrzymaj przesyłanie"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jak działa transmitowanie"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmisja"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osoby w pobliżu ze zgodnymi urządzeniami Bluetooth mogą słuchać transmitowanych przez Ciebie multimediów"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index d2f246c..3bb02ab0 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar novo usuário?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de usuários atingido"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuário.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 5ad4272..e76ccc8 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Pretende continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar um novo utilizador?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Ao adicionar um novo utilizador, essa pessoa tem de configurar o respetivo espaço.\n\nQualquer utilizador pode atualizar apps para todos os outros utilizadores."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de utilizadores alcançado"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Pode adicionar até <xliff:g id="COUNT">%d</xliff:g> utilizadores.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Sincronize o novo dispositivo"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sessão, abra a app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecida"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmissão"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas de si com dispositivos Bluetooth compatíveis podem ouvir o conteúdo multimédia que está a transmitir"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index d2f246c..3bb02ab0 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Quer continuar a sessão?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Recomeçar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sim, continuar"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Adicionar novo usuário?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Quando você adiciona um novo usuário, essa pessoa precisa configurar o próprio espaço.\n\nQualquer usuário pode atualizar apps para os demais usuários."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limite de usuários atingido"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">É possível adicionar até <xliff:g id="COUNT">%d</xliff:g> usuário.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parear novo dispositivo"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Abra o app para transmitir esta sessão."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecido"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Como funciona a transmissão"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmitir"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"As pessoas próximas a você com dispositivos Bluetooth compatíveis podem ouvir a mídia que você está transmitindo"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 6af0388..f47d82a 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -340,6 +340,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vreți să continuați sesiunea?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Începeți din nou"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, continuați"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Adăugați un utilizator nou?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Când adăugați un utilizator nou, acesta trebuie să-și configureze spațiul.\n\nOrice utilizator poate actualiza aplicațiile pentru toți ceilalți utilizatori."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Ați atins limita de utilizatori"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="few">Puteți adăuga maximum <xliff:g id="COUNT">%d</xliff:g> utilizatori.</item>
@@ -841,7 +849,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Asociați un nou dispozitiv"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Pentru a proiecta această sesiune, deschideți aplicația."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplicație necunoscută"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Nu mai proiectați"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cum funcționează transmisia"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmiteți"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Persoanele din apropiere cu dispozitive Bluetooth compatibile pot asculta conținutul pe care îl transmiteți"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 427c4be..1af2ebe 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -342,6 +342,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Продолжить сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Начать заново"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, продолжить"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Добавить пользователя?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Когда вы добавите пользователя, ему потребуется настроить профиль.\n\nЛюбой пользователь устройства может обновлять приложения для всех аккаунтов."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут лимит"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Можно добавить не более <xliff:g id="COUNT">%d</xliff:g> пользователя.</item>
@@ -847,7 +855,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Подключить новое устройство"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Чтобы начать трансляцию сеанса, откройте приложение"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Неизвестное приложение"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Остановить трансляцию"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Как работают трансляции"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляция"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Находящиеся рядом с вами люди с совместимыми устройствами Bluetooth могут слушать медиафайлы, которые вы транслируете."</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index d9cefbf..e01b143 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ඔබගේ සැසිය දිගටම කරගෙන යෑමට ඔබට අවශ්‍යද?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"යළි මුල සිට අරඹන්න"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ඔව්, දිගටම කරගෙන යන්න"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"අලුත් පරිශීලකයෙක් එක් කරන්නද?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ඔබ අලුත් පරිශීලකයෙක් එකතු කරන විට, එම පුද්ගලයා ඔහුගේ වැඩ කරන ඉඩ සකසා ගත යුතුය.\n\nසියළුම අනෙක් පරිශීලකයින් සඳහා ඕනෑම පරිශීලකයෙකුට යාවත්කාලීන කළ හැක."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"පරිශීලක සීමාවට ළඟා විය"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">ඔබට පරිශීලකයින් <xliff:g id="COUNT">%d</xliff:g>ක් දක්වා එක් කළ හැකිය.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"නව උපාංගය යුගල කරන්න"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"මෙම සැසිය විකාශය කිරීමට, කරුණාකර යෙදුම විවෘත කරන්න."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"නොදන්නා යෙදුම"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"විකාශය නවතන්න"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"විකාශනය ක්‍රියා කරන ආකාරය"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"විකාශනය"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ගැළපෙන බ්ලූටූත් උපාංග සහිත ඔබ අවට සිටින පුද්ගලයින්ට ඔබ විකාශනය කරන මාධ්‍යයට සවන් දිය හැකිය"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 1e2949e..8e10d3b 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -342,6 +342,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Chcete v relácii pokračovať?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začať odznova"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Áno, pokračovať"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Pridať nového používateľa?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Keď pridáte nového používateľa, musí si nastaviť vlastný priestor.\n\nKtorýkoľvek používateľ môže aktualizovať aplikácie všetkých ostatných používateľov."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Dosiahnutý limit počtu používateľov"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="few">Môžete pridať maximálne <xliff:g id="COUNT">%d</xliff:g> používateľov.</item>
@@ -847,7 +855,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Spárovať nové zariadenie"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ak chcete túto reláciu prenášať, otvorte aplikáciu."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznáma aplikácia"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Zastaviť prenos"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Ako vysielanie funguje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Vysielanie"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Ľudia v okolí s kompatibilnými zariadeniami s rozhraním Bluetooth si môžu vypočuť médiá, ktoré vysielate"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 8ff71a4..7c88401 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -342,6 +342,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Želite nadaljevati sejo?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Začni znova"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, nadaljuj"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Dodajanje novega uporabnika?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Ko dodate novega uporabnika, mora ta nastaviti svoj prostor.\n\nVsak uporabnik lahko posodobi aplikacije za vse druge uporabnike."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Omejitev uporabnikov je dosežena"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Dodate lahko do <xliff:g id="COUNT">%d</xliff:g> uporabnika.</item>
@@ -847,7 +855,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Seznanitev nove naprave"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Če želite predvajati to sejo, odprite aplikacijo."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Neznana aplikacija"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ustavi predvajanje"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Kako deluje oddajanje"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Oddajanje"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Osebe v bližini z združljivo napravo Bluetooth lahko poslušajo predstavnost, ki jo oddajate."</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 3ddea24..bacc6d2 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Dëshiron ta vazhdosh sesionin tënd?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Fillo nga e para"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Po, vazhdo"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Të shtohet përdorues i ri?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kur shton një përdorues të ri, ai person duhet të konfigurojë hapësirën e vet.\n\nÇdo përdorues mund t\'i përditësojë aplikacionet për të gjithë përdoruesit e tjerë."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"U arrit kufiri i përdoruesve"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Mund të shtosh deri në <xliff:g id="COUNT">%d</xliff:g> përdorues.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Çifto pajisjen e re"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Hap aplikacionin për të transmetuar këtë seancë."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Aplikacion i panjohur"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ndalo transmetimin"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Si funksionon transmetimi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Transmetimi"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personat në afërsi me ty me pajisje të përputhshme me Bluetooth mund të dëgjojnë median që ti po transmeton"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index e1cd04f..58e8b1f 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -340,6 +340,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Желите ли да наставите сесију?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни из почетка"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Да, настави"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Додајете новог корисника?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Када додате новог корисника, та особа треба да подеси свој простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Достигнут максимални број корисника"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Можете да додате највише <xliff:g id="COUNT">%d</xliff:g> корисника.</item>
@@ -841,7 +849,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Упари нови уређај"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Да бисте пребацивали ову сесију, отворите апликацију."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Непозната апликација"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Заустави пребацивање"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Како функционише емитовање"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Емитовање"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Људи у близини са компатибилним Bluetooth уређајима могу да слушају медијски садржај који емитујете"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index caed132..521cdbb 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Vill du fortsätta sessionen?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Börja om"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ja, fortsätt"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Lägga till ny användare?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"När du lägger till en ny användare måste den personen konfigurera sitt utrymme.\n\nAlla användare kan uppdatera appar för samtliga användares räkning."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Användargränsen har nåtts"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Det går att lägga till upp till <xliff:g id="COUNT">%d</xliff:g> användare.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Parkoppla en ny enhet"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Öppna appen om du vill casta den här sessionen."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Okänd app"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Sluta casta"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Så fungerar utsändning"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Utsändning"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Personer i närheten med kompatibla Bluetooth-enheter kan lyssna på medieinnehåll som du sänder ut"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 6d13e15..a4f7bd6 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Je, unataka kuendelea na kipindi chako?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Anza upya"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ndiyo, endelea"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Ungependa kuongeza mtumiaji?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Mtumiaji mpya utakayemwongeza atahitaji kuongeza akaunti yake.\n\nMtumiaji yoyote anaweza kusasisha programu kwa niaba ya wengine wote."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Umefikia kima cha juu cha watumiaji"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Unaruhusiwa kuongeza hadi watumiaji <xliff:g id="COUNT">%d</xliff:g>.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Oanisha kifaa kipya"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ili utume kipindi hiki, tafadhali fungua programu."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Programu isiyojulikana"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Acha kutuma"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Jinsi utangazaji unavyofanya kazi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Tangaza"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Watu walio karibu nawe wenye vifaa oanifu vya Bluetooth wanaweza kusikiliza maudhui unayoyatangaza"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 111da21..f0e1321 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"உங்கள் அமர்வைத் தொடர விருப்பமா?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"மீண்டும் தொடங்கு"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"தொடரவும்"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"புதியவரைச் சேர்க்கவா?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"புதிய பயனரைச் சேர்க்கும்போது, அவர் தனக்கான இடத்தை அமைக்க வேண்டும்.\n\nஎந்தவொரு பயனரும், மற்ற எல்லா பயனர்களுக்காகவும் ஆப்ஸைப் புதுப்பிக்கலாம்."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"பயனர் வரம்பை அடைந்துவிட்டீர்கள்"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> பயனர்கள் வரை சேர்க்க முடியும்.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"புதிய சாதனத்தை இணைத்தல்"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"இந்த அமர்வை அலைபரப்ப ஆப்ஸைத் திறங்கள்."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"அறியப்படாத ஆப்ஸ்"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"அலைபரப்புவதை நிறுத்து"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"பிராட்காஸ்ட் எவ்வாறு செயல்படுகிறது?"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"பிராட்காஸ்ட்"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"நீங்கள் பிராட்காஸ்ட் செய்யும் மீடியாவை அருகிலுள்ளவர்கள் இணக்கமான புளூடூத் சாதனங்கள் மூலம் கேட்கலாம்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index e76253a..76980335 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"మీరు మీ సెషన్‌ని కొనసాగించాలనుకుంటున్నారా?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"మొదటి నుండి ప్రారంభించు"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"అవును, కొనసాగించు"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"కొత్త యూజర్‌ను జోడించాలా?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"ఒక కొత్త యూజర్‌ను మీరు జోడించినప్పుడు, ఆ వ్యక్తి తన స్పేస్‌ను సెటప్ చేసుకోవాలి.\n\nఏ యూజర్ అయినా మిగతా అందరు యూజర్‌ల కోసం యాప్‌లను అప్‌డేట్ చేయగలరు."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"వినియోగదారు పరిమితిని చేరుకున్నారు"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">మీరు <xliff:g id="COUNT">%d</xliff:g> వినియోగదారుల వరకు జోడించవచ్చు.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"కొత్త పరికరాన్ని పెయిర్ చేయండి"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"ఈ సెషన్‌ను ప్రసారం చేయడానికి, దయచేసి యాప్‌ను తెరవండి."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"తెలియని యాప్"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"ప్రసారాన్ని ఆపివేయండి"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"ప్రసారం కావడం అనేది ఎలా పని చేస్తుంది"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ప్రసారం"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"మీకు సమీపంలో ఉన్న వ్యక్తులు అనుకూలత ఉన్న బ్లూటూత్ పరికరాలతో మీరు ప్రసారం చేస్తున్న మీడియాను వినగలరు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index df36f46..b9c8b30 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"คุณต้องการอยู่ในเซสชันต่อไปไหม"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"เริ่มต้นใหม่"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ใช่ ดำเนินการต่อ"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"ต้องการเพิ่มผู้ใช้ใหม่ใช่ไหม"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"เมื่อคุณเพิ่มผู้ใช้ใหม่ ผู้ใช้ดังกล่าวจะต้องตั้งค่าพื้นที่ของตนเอง\n\nผู้ใช้ทุกคนสามารถอัปเดตแอปสำหรับผู้ใช้รายอื่นทุกคนได้"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"ถึงขีดจำกัดผู้ใช้แล้ว"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">คุณเพิ่มผู้ใช้ได้สูงสุด <xliff:g id="COUNT">%d</xliff:g> คน</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"จับคู่อุปกรณ์ใหม่"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"โปรดเปิดแอปหากต้องการแคสต์เซสชันนี้"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"แอปที่ไม่รู้จัก"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"หยุดแคสต์"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"วิธีการทำงานของการออกอากาศ"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"ประกาศ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"ผู้ที่อยู่ใกล้คุณและมีอุปกรณ์บลูทูธที่รองรับสามารถรับฟังสื่อที่คุณกำลังออกอากาศได้"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index e4650b7..85efeda 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Gusto mo bang ipagpatuloy ang iyong session?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Magsimulang muli"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Oo, magpatuloy"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Magdagdag ng bagong user?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Kapag nagdagdag ka ng bagong user, kailangang i-set up ng taong iyon ang kanyang espasyo.\n\nAng sinumang user ay maaaring mag-update ng mga app para sa lahat ng iba pang user."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Naabot na ang limitasyon sa user"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Maaari kang magdagdag ng hanggang <xliff:g id="COUNT">%d</xliff:g> user.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Magpares ng bagong device"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para ma-cast ang session na ito, buksan ang app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Hindi kilalang app"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Ihinto ang pag-cast"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Paano gumagana ang pag-broadcast"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Broadcast"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Makakapakinig ang mga taong malapit sa iyo na may mga compatible na Bluetooth device sa media na bino-broadcast mo"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 4c4e49b..fca9a0a 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Oturumunuza devam etmek istiyor musunuz?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Baştan başla"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Evet, devam et"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Yeni kullanıcı eklensin mi?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Yeni bir kullanıcı eklediğinizde, bu kişinin kendi alanını ayarlaması gerekir.\n\nHerhangi bir kullanıcı, diğer tüm kullanıcılar için uygulamaları güncelleyebilir."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Kullanıcı sınırına ulaşıldı"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">En fazla <xliff:g id="COUNT">%d</xliff:g> kullanıcı ekleyebilirsiniz.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yeni cihaz eşle"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu oturumu yayınlamak için lütfen uygulamayı açın."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Bilinmeyen uygulama"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Yayını durdur"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Yayınlamanın işleyiş şekli"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Anons"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Yakınınızda ve uyumlu Bluetooth cihazları olan kişiler yayınladığınız medya içeriğini dinleyebilir"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index c928972..aeaec2b 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -342,6 +342,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Продовжити сеанс?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почати знову"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Так, продовжити"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Додати нового користувача?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Користувач має налаштувати свій профіль після створення.\n\nБудь-який користувач пристрою може оновлювати додатки для решти користувачів."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Ви досягли ліміту користувачів"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Можна додати до <xliff:g id="COUNT">%d</xliff:g> користувача.</item>
@@ -847,7 +855,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Підключити новий пристрій"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Щоб транслювати цей сеанс, відкрийте додаток."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Невідомий додаток"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Припинити трансляцію"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Як працює трансляція"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Трансляція"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Люди поблизу, які мають сумісні пристрої з Bluetooth, можуть слухати медіаконтент, який ви транслюєте."</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index f5228a2..92bc68a 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"کیا آپ اپنا سیشن جاری رکھنا چاہتے ہیں؟"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"دوبارہ شروع کریں"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"ہاں، جاری رکھیں"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"نیا صارف شامل کریں؟"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"جب آپ ایک نیا صارف شامل کرتے ہیں تو اس شخص کو اپنی جگہ کو ترتیب دینے کی ضرورت ہوتی ہے۔\n\nکوئی بھی صارف دیگر سبھی صارفین کیلئے ایپس کو اپ ڈیٹ کر سکتا ہے۔"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"صارف کی حد مکمل ہو گئی"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">صرف <xliff:g id="COUNT">%d</xliff:g> صارفین بنائے جا سکتے ہیں۔</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"نئے آلہ کا جوڑا بنائیں"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"اس سیشن کو کاسٹ کرنے کیلئے، براہ کرم ایپ کھولیں۔"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"نامعلوم ایپ"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"کاسٹ کرنا بند کریں"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"براڈکاسٹنگ کیسے کام کرتا ہے"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"براڈکاسٹ"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"موافق بلوٹوتھ آلات کے ساتھ آپ کے قریبی لوگ آپ کے نشر کردہ میڈیا کو سن سکتے ہیں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index c0f12bd..54a36d8 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Seansni davom ettirmoqchimisiz?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Boshidan boshlansin"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Ha, davom ettirilsin"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Foydalanuvchi qo‘shilsinmi?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Yangi profil qo‘shilgach, uni sozlash lozim.\n\nQurilmaning istalgan foydalanuvchisi ilovalarni barcha hisoblar uchun yangilashi mumkin."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Limitga yetib keldi"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> tagacha foydalanuvchi qo‘shish mumkin.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Yangi qurilmani ulash"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Bu seansni translatsiya qilish uchun ilovani oching."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Notanish ilova"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Toʻxtatish"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Translatsiya qanday ishlaydi"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Translatsiya"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Atrofingizdagi mos Bluetooth qurilmasiga ega foydalanuvchilar siz translatsiya qilayotgan mediani tinglay olishadi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 872f6ce..551c6c2 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -341,6 +341,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Bạn có muốn tiếp tục phiên của mình không?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Bắt đầu lại"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Có, tiếp tục"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Thêm người dùng mới?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Khi bạn thêm người dùng mới, họ cần thiết lập không gian của mình.\n\nMọi người dùng đều có thể cập nhật ứng dụng cho tất cả người dùng khác."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Đã đạt đến giới hạn người dùng"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">Bạn có thể thêm tối đa <xliff:g id="COUNT">%d</xliff:g> người dùng.</item>
@@ -838,7 +846,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Ghép nối thiết bị mới"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Vui lòng mở ứng dụng để truyền phiên này."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"Ứng dụng không xác định"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Dừng truyền"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Cách tính năng truyền hoạt động"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Truyền"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Những người ở gần có thiết bị Bluetooth tương thích có thể nghe nội dung nghe nhìn bạn đang truyền"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 15a32fe..5de85dd 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"要继续您的会话吗?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新开始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是,继续"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"要添加新用户吗?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"当您添加新用户时,该用户必须设置自己的空间。\n\n任何用户均可为其他所有用户更新应用。"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已达到用户数上限"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">您最多可以添加 <xliff:g id="COUNT">%d</xliff:g> 位用户。</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"与新设备配对"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如需投射此会话,请打开相关应用。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"未知应用"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投射"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"广播的运作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"广播"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近使用兼容蓝牙设备的用户可以收听您广播的媒体内容"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 9b18393..cbb2960 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"您要繼續您的工作階段嗎?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是的,請繼續"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"新增使用者?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"新增的使用者需要自行設定個人空間。\n\n任何使用者均可為所有其他使用者更新應用程式。"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已達到使用者上限"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">您可以加入多達 <xliff:g id="COUNT">%d</xliff:g> 個使用者。</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放此工作階段,請開啟應用程式。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明應用程式"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播運作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"附近有兼容藍牙裝置的人可收聽您正在廣播的媒體內容"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 402679a..05c41dd 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"你要繼續這個工作階段嗎?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"是,繼續"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"要新增使用者嗎?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"新增的使用者需要自行設定個人空間。\n\n任何使用者皆可為其他所有使用者更新應用程式。"</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"已達使用者數量上限"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="other">最多可新增 <xliff:g id="COUNT">%d</xliff:g> 位使用者。</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"配對新裝置"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"如要投放這個工作階段,請開啟應用程式。"</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"不明的應用程式"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"停止投放"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"廣播功能的運作方式"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"廣播"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"如果附近的人有相容的藍牙裝置,就可以聽到你正在廣播的媒體內容"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index d85703b..f20b556 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -338,6 +338,14 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Ingabe ufuna ukuqhubeka ngesikhathi sakho?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Qala phansi"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Yebo, qhubeka"</string>
+    <!-- no translation found for guest_notification_app_name (2110425506754205509) -->
+    <skip />
+    <!-- no translation found for guest_notification_session_active (5567273684713471450) -->
+    <skip />
+    <string name="user_add_user_title" msgid="4172327541504825032">"Engeza umsebenzisi omusha?"</string>
+    <string name="user_add_user_message_short" msgid="2599370307878014791">"Uma ungeza umsebenzisi omusha, loyo muntu udinga ukusetha isikhala sakhe.\n\nNoma yimuphi umsebenzisi angabuyekeza izinhlelo zokusebenza kubo bonke abasebenzisi."</string>
+    <!-- no translation found for user_add_user_message_guest_remove (5589286604543355007) -->
+    <skip />
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Kufinyelelwe kumkhawulo womsebenzisi"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
       <item quantity="one">Ungangeza kufikela kubasebenzisi abangu-<xliff:g id="COUNT">%d</xliff:g>.</item>
@@ -835,7 +843,6 @@
     <string name="media_output_dialog_pairing_new" msgid="9099497976087485862">"Bhangqa idivayisi entsha"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Ukuze usakaze le seshini, sicela uvule i-app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"I-app engaziwa"</string>
-    <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Misa ukusakaza"</string>
     <string name="media_output_first_broadcast_title" msgid="6292237789860753022">"Indlela ukusakaza okusebenza ngayo"</string>
     <string name="media_output_broadcast" msgid="3555580945878071543">"Sakaza"</string>
     <string name="media_output_first_notify_broadcast_message" msgid="6353857724136398494">"Abantu abaseduze nawe abanamadivayisi e-Bluetooth ahambisanayo bangalalela imidiya oyisakazayo"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 24118d2..a06201c 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -179,12 +179,10 @@
 
     <!-- media output dialog-->
     <color name="media_dialog_background" android:lstar="98">@color/material_dynamic_neutral90</color>
-    <color name="media_dialog_item_main_content">@color/material_dynamic_primary20</color>
+    <color name="media_dialog_active_item_main_content">@color/material_dynamic_primary10</color>
+    <color name="media_dialog_inactive_item_main_content">@color/material_dynamic_primary40</color>
+    <color name="media_dialog_item_status">@color/material_dynamic_primary10</color>
     <color name="media_dialog_item_background">@color/material_dynamic_secondary95</color>
-    <color name="media_dialog_connected_item_background">@color/material_dynamic_primary90</color>
-    <color name="media_dialog_seekbar_progress">@color/material_dynamic_secondary40</color>
-    <color name="media_dialog_button_background">@color/material_dynamic_primary40</color>
-    <color name="media_dialog_solid_button_text">@color/material_dynamic_neutral95</color>
 
     <!-- controls -->
     <color name="control_primary_text">#E6FFFFFF</color>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index b248efe..c2d7f819 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -888,6 +888,23 @@
     <!-- Notification when resuming an existing guest session: Action that continues with the current session [CHAR LIMIT=35] -->
     <string name="guest_wipe_session_dontwipe">Yes, continue</string>
 
+    <!-- App name of the notification when guest mode is entered [CHAR LIMIT=35] -->
+    <string name="guest_notification_app_name">Guest mode</string>
+    <!-- Title of the notification when guest mode is entered [CHAR LIMIT=35] -->
+    <string name="guest_notification_session_active">You are in guest mode</string>
+
+    <!-- Title for add user confirmation dialog [CHAR LIMIT=30] -->
+    <string name="user_add_user_title" msgid="2108112641783146007">Add new user?</string>
+
+    <!-- Message for add user confirmation dialog - short version. [CHAR LIMIT=none] -->
+    <string name="user_add_user_message_short" msgid="1511354412249044381">When you add a new user, that person needs to set up their space.\n\nAny user can update apps for all other users. </string>
+
+    <!-- Additional message for add user confirmation dialog that is appended when current user is
+         guest and guest is ephemeral. This is to warn users that current guest session
+         would get removed after a new user is added and switched to [CHAR LIMIT=none] -->
+    <string name="user_add_user_message_guest_remove">\n\nAdding a new user will exit guest mode
+        and delete all apps and data from the current guest session.</string>
+
     <!-- Title for the dialog that lets users know that the maximum allowed number of users on the device has been reached. [CHAR LIMIT=35]-->
     <string name="user_limit_reached_title">User limit reached</string>
 
@@ -2262,8 +2279,6 @@
     <string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string>
     <!-- App name when can't get app name [CHAR LIMIT=60] -->
     <string name="media_output_dialog_unknown_launch_app_name">Unknown app</string>
-    <!-- Button text for stopping casting [CHAR LIMIT=60] -->
-    <string name="media_output_dialog_button_stop_casting">Stop casting</string>
 
     <!-- Media Output Broadcast Dialog -->
     <!-- Title for Broadcast First Notify Dialog [CHAR LIMIT=60] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index d7799a7..2806ce8 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -486,7 +486,7 @@
 
     <style name="MediaOutputItemInactiveTitle">
         <item name="android:textSize">16sp</item>
-        <item name="android:textColor">@color/media_dialog_item_main_content</item>
+        <item name="android:textColor">@color/media_dialog_inactive_item_main_content</item>
     </style>
 
     <style name="TunerSettings" parent="@android:style/Theme.DeviceDefault.Settings">
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/tracing/FrameProtoTracer.java b/packages/SystemUI/shared/src/com/android/systemui/shared/tracing/FrameProtoTracer.java
index 4394ecb..98212e1 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/tracing/FrameProtoTracer.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/tracing/FrameProtoTracer.java
@@ -25,8 +25,8 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.Queue;
 import java.util.function.Consumer;
 
@@ -50,7 +50,7 @@
     private final File mTraceFile;
     private final ProtoTraceParams<P, S, T, R> mParams;
     private Choreographer mChoreographer;
-    private final Queue<T> mPool = new LinkedList<>();
+    private final Queue<T> mPool = new ArrayDeque<>();
     private final ArrayList<ProtoTraceable<R>> mTraceables = new ArrayList<>();
     private final ArrayList<ProtoTraceable<R>> mTmpTraceables = new ArrayList<>();
 
diff --git a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.kt b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.kt
index 19d39d5..d445980 100644
--- a/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.kt
+++ b/packages/SystemUI/src/com/android/keyguard/AnimatableClockView.kt
@@ -284,6 +284,8 @@
         )
     }
 
+    private val glyphFilter: GlyphCallback? = null // Add text animation tweak here.
+
     /**
      * Set text style with an optional animation.
      *
@@ -315,6 +317,7 @@
                 delay = delay,
                 onAnimationEnd = onAnimationEnd
             )
+            textAnimator?.glyphFilter = glyphFilter
         } else {
             // when the text animator is set, update its start values
             onTextAnimatorInitialized = Runnable {
@@ -328,6 +331,7 @@
                     delay = delay,
                     onAnimationEnd = onAnimationEnd
                 )
+                textAnimator?.glyphFilter = glyphFilter
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/keyguard/TextAnimator.kt b/packages/SystemUI/src/com/android/keyguard/TextAnimator.kt
index 3361015..ade89af 100644
--- a/packages/SystemUI/src/com/android/keyguard/TextAnimator.kt
+++ b/packages/SystemUI/src/com/android/keyguard/TextAnimator.kt
@@ -22,12 +22,14 @@
 import android.animation.ValueAnimator
 import android.graphics.Canvas
 import android.graphics.Typeface
+import android.graphics.fonts.Font
 import android.text.Layout
 import android.util.SparseArray
 
 private const val TAG_WGHT = "wght"
 private const val DEFAULT_ANIMATION_DURATION: Long = 300
 
+typealias GlyphCallback = (TextAnimator.PositionedGlyph, Float) -> Unit
 /**
  * This class provides text animation between two styles.
  *
@@ -74,6 +76,59 @@
         })
     }
 
+    sealed class PositionedGlyph {
+
+        /**
+         * Mutable X coordinate of the glyph position relative from drawing offset.
+         */
+        var x: Float = 0f
+
+        /**
+         * Mutable Y coordinate of the glyph position relative from the baseline.
+         */
+        var y: Float = 0f
+
+        /**
+         * Mutable text size of the glyph in pixels.
+         */
+        var textSize: Float = 0f
+
+        /**
+         * Mutable color of the glyph.
+         */
+        var color: Int = 0
+
+        /**
+         * Immutable character offset in the text that the current font run start.
+         */
+        abstract var runStart: Int
+            protected set
+
+        /**
+         * Immutable run length of the font run.
+         */
+        abstract var runLength: Int
+            protected set
+
+        /**
+         * Immutable glyph index of the font run.
+         */
+        abstract var glyphIndex: Int
+            protected set
+
+        /**
+         * Immutable font instance for this font run.
+         */
+        abstract var font: Font
+            protected set
+
+        /**
+         * Immutable glyph ID for this glyph.
+         */
+        abstract var glyphId: Int
+            protected set
+    }
+
     private val typefaceCache = SparseArray<Typeface?>()
 
     fun updateLayout(layout: Layout) {
@@ -84,6 +139,57 @@
         return animator.isRunning
     }
 
+    /**
+     * GlyphFilter applied just before drawing to canvas for tweaking positions and text size.
+     *
+     * This callback is called for each glyphs just before drawing the glyphs. This function will
+     * be called with the intrinsic position, size, color, glyph ID and font instance. You can
+     * mutate the position, size and color for tweaking animations.
+     * Do not keep the reference of passed glyph object. The interpolator reuses that object for
+     * avoiding object allocations.
+     *
+     * Details:
+     * The text is drawn with font run units. The font run is a text segment that draws with the
+     * same font. The {@code runStart} and {@code runLimit} is a range of the font run in the text
+     * that current glyph is in. Once the font run is determined, the system will convert characters
+     * into glyph IDs. The {@code glyphId} is the glyph identifier in the font and
+     * {@code glyphIndex} is the offset of the converted glyph array. Please note that the
+     * {@code glyphIndex} is not a character index, because the character will not be converted to
+     * glyph one-by-one. If there are ligatures including emoji sequence, etc, the glyph ID may be
+     * composed from multiple characters.
+     *
+     * Here is an example of font runs: "fin. 終わり"
+     *
+     * Characters :    f      i      n      .      _      終     わ     り
+     * Code Points: \u0066 \u0069 \u006E \u002E \u0020 \u7D42 \u308F \u308A
+     * Font Runs  : <-- Roboto-Regular.ttf          --><-- NotoSans-CJK.otf -->
+     *                  runStart = 0, runLength = 5        runStart = 5, runLength = 3
+     * Glyph IDs  :      194        48     7      8     4367   1039   1002
+     * Glyph Index:       0          1     2      3       0      1      2
+     *
+     * In this example, the "fi" is converted into ligature form, thus the single glyph ID is
+     * assigned for two characters, f and i.
+     *
+     * Example:
+     * ```
+     * private val glyphFilter: GlyphCallback = { glyph, progress ->
+     *     val index = glyph.runStart
+     *     val i = glyph.glyphIndex
+     *     val moveAmount = 1.3f
+     *     val sign = (-1 + 2 * ((i + index) % 2))
+     *     val turnProgress = if (progress < .5f) progress / 0.5f else (1.0f - progress) / 0.5f
+     *
+     *     // You can modify (x, y) coordinates, textSize and color during animation.
+     *     glyph.textSize += glyph.textSize * sign * moveAmount * turnProgress
+     *     glyph.y += glyph.y * sign * moveAmount * turnProgress
+     *     glyph.x += glyph.x * sign * moveAmount * turnProgress
+     * }
+     * ```
+     */
+    var glyphFilter: GlyphCallback?
+        get() = textInterpolator.glyphFilter
+        set(value) { textInterpolator.glyphFilter = value }
+
     fun draw(c: Canvas) = textInterpolator.draw(c)
 
     /**
diff --git a/packages/SystemUI/src/com/android/keyguard/TextInterpolator.kt b/packages/SystemUI/src/com/android/keyguard/TextInterpolator.kt
index 5d5797c..20dbe29 100644
--- a/packages/SystemUI/src/com/android/keyguard/TextInterpolator.kt
+++ b/packages/SystemUI/src/com/android/keyguard/TextInterpolator.kt
@@ -89,8 +89,11 @@
     private var lines = listOf<Line>()
     private val fontInterpolator = FontInterpolator()
 
-    // Recycling object for glyph drawing. Will be extended for the longest font run if needed.
-    private val tmpDrawPaint = TextPaint()
+    // Recycling object for glyph drawing and tweaking.
+    private val tmpPaint = TextPaint()
+    private val tmpPaintForGlyph by lazy { TextPaint() }
+    private val tmpGlyph by lazy { MutablePositionedGlyph() }
+    // Will be extended for the longest font run if needed.
     private var tmpPositionArray = FloatArray(20)
 
     /**
@@ -206,8 +209,8 @@
         } else if (progress == 1f) {
             basePaint.set(targetPaint)
         } else {
-            lerp(basePaint, targetPaint, progress, tmpDrawPaint)
-            basePaint.set(tmpDrawPaint)
+            lerp(basePaint, targetPaint, progress, tmpPaint)
+            basePaint.set(tmpPaint)
         }
 
         lines.forEach { line ->
@@ -231,7 +234,7 @@
      * @param canvas a canvas.
      */
     fun draw(canvas: Canvas) {
-        lerp(basePaint, targetPaint, progress, tmpDrawPaint)
+        lerp(basePaint, targetPaint, progress, tmpPaint)
         lines.forEachIndexed { lineNo, line ->
             line.runs.forEach { run ->
                 canvas.save()
@@ -241,7 +244,7 @@
                     canvas.translate(origin, layout.getLineBaseline(lineNo).toFloat())
 
                     run.fontRuns.forEach { fontRun ->
-                        drawFontRun(canvas, run, fontRun, tmpDrawPaint)
+                        drawFontRun(canvas, run, fontRun, tmpPaint)
                     }
                 } finally {
                     canvas.restore()
@@ -330,24 +333,82 @@
         }
     }
 
+    private class MutablePositionedGlyph : TextAnimator.PositionedGlyph() {
+        override var runStart: Int = 0
+            public set
+        override var runLength: Int = 0
+            public set
+        override var glyphIndex: Int = 0
+            public set
+        override lateinit var font: Font
+            public set
+        override var glyphId: Int = 0
+            public set
+    }
+
+    var glyphFilter: GlyphCallback? = null
+
     // Draws single font run.
     private fun drawFontRun(c: Canvas, line: Run, run: FontRun, paint: Paint) {
         var arrayIndex = 0
+        val font = fontInterpolator.lerp(run.baseFont, run.targetFont, progress)
+
+        val glyphFilter = glyphFilter
+        if (glyphFilter == null) {
+            for (i in run.start until run.end) {
+                tmpPositionArray[arrayIndex++] =
+                        MathUtils.lerp(line.baseX[i], line.targetX[i], progress)
+                tmpPositionArray[arrayIndex++] =
+                        MathUtils.lerp(line.baseY[i], line.targetY[i], progress)
+            }
+            c.drawGlyphs(line.glyphIds, run.start, tmpPositionArray, 0, run.length, font, paint)
+            return
+        }
+
+        tmpGlyph.font = font
+        tmpGlyph.runStart = run.start
+        tmpGlyph.runLength = run.end - run.start
+
+        tmpPaintForGlyph.set(paint)
+        var prevStart = run.start
+
         for (i in run.start until run.end) {
-            tmpPositionArray[arrayIndex++] =
-                    MathUtils.lerp(line.baseX[i], line.targetX[i], progress)
-            tmpPositionArray[arrayIndex++] =
-                    MathUtils.lerp(line.baseY[i], line.targetY[i], progress)
+            tmpGlyph.glyphId = line.glyphIds[i]
+            tmpGlyph.x = MathUtils.lerp(line.baseX[i], line.targetX[i], progress)
+            tmpGlyph.y = MathUtils.lerp(line.baseY[i], line.targetY[i], progress)
+            tmpGlyph.textSize = paint.textSize
+            tmpGlyph.color = paint.color
+
+            glyphFilter(tmpGlyph, progress)
+
+            if (tmpGlyph.textSize != paint.textSize || tmpGlyph.color != paint.color) {
+                tmpPaintForGlyph.textSize = tmpGlyph.textSize
+                tmpPaintForGlyph.color = tmpGlyph.color
+
+                c.drawGlyphs(
+                        line.glyphIds,
+                        prevStart,
+                        tmpPositionArray,
+                        0,
+                        i - prevStart,
+                        font,
+                        tmpPaintForGlyph)
+                prevStart = i
+                arrayIndex = 0
+            }
+
+            tmpPositionArray[arrayIndex++] = tmpGlyph.x
+            tmpPositionArray[arrayIndex++] = tmpGlyph.y
         }
 
         c.drawGlyphs(
                 line.glyphIds,
-                run.start,
+                prevStart,
                 tmpPositionArray,
                 0,
-                run.length,
-                fontInterpolator.lerp(run.baseFont, run.targetFont, progress),
-                paint)
+                run.end - prevStart,
+                font,
+                tmpPaintForGlyph)
     }
 
     private fun updatePositionsAndFonts(
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResetOrExitSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResetOrExitSessionReceiver.java
new file mode 100644
index 0000000..fd84543
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/GuestResetOrExitSessionReceiver.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2022 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;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.UserInfo;
+import android.os.UserHandle;
+
+import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.qs.QSUserSwitcherEvent;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
+
+import javax.inject.Inject;
+
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedFactory;
+import dagger.assisted.AssistedInject;
+
+/**
+ * Manages handling of guest session persistent notification
+ * and actions to reset guest or exit guest session
+ */
+public final class GuestResetOrExitSessionReceiver extends BroadcastReceiver {
+
+    private static final String TAG = GuestResetOrExitSessionReceiver.class.getSimpleName();
+
+    /**
+     * Broadcast sent to the system when guest user needs to be reset.
+     * This is only sent to registered receivers, not manifest receivers.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_GUEST_RESET = "android.intent.action.GUEST_RESET";
+
+    /**
+     * Broadcast sent to the system when guest user needs to exit.
+     * This is only sent to registered receivers, not manifest receivers.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_GUEST_EXIT = "android.intent.action.GUEST_EXIT";
+
+    public AlertDialog mExitSessionDialog;
+    public AlertDialog mResetSessionDialog;
+    private final UserTracker mUserTracker;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final ResetSessionDialog.Factory mResetSessionDialogFactory;
+    private final ExitSessionDialog.Factory mExitSessionDialogFactory;
+
+    @Inject
+    public GuestResetOrExitSessionReceiver(UserTracker userTracker,
+            BroadcastDispatcher broadcastDispatcher,
+            ResetSessionDialog.Factory resetSessionDialogFactory,
+            ExitSessionDialog.Factory exitSessionDialogFactory) {
+        mUserTracker = userTracker;
+        mBroadcastDispatcher = broadcastDispatcher;
+        mResetSessionDialogFactory = resetSessionDialogFactory;
+        mExitSessionDialogFactory = exitSessionDialogFactory;
+    }
+
+    /**
+     * Register this receiver with the {@link BroadcastDispatcher}
+     */
+    public void register() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ACTION_GUEST_RESET);
+        intentFilter.addAction(ACTION_GUEST_EXIT);
+        mBroadcastDispatcher.registerReceiver(this, intentFilter, null /* handler */,
+                                             UserHandle.SYSTEM);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+
+        cancelResetDialog();
+        cancelExitDialog();
+
+        UserInfo currentUser = mUserTracker.getUserInfo();
+        if (!currentUser.isGuest()) {
+            return;
+        }
+
+        if (ACTION_GUEST_RESET.equals(action)) {
+            mResetSessionDialog = mResetSessionDialogFactory.create(currentUser.id);
+            mResetSessionDialog.show();
+        } else if (ACTION_GUEST_EXIT.equals(action)) {
+            mExitSessionDialog = mExitSessionDialogFactory.create(currentUser.id,
+                        currentUser.isEphemeral());
+            mExitSessionDialog.show();
+        }
+    }
+
+    private void cancelResetDialog() {
+        if (mResetSessionDialog != null && mResetSessionDialog.isShowing()) {
+            mResetSessionDialog.cancel();
+            mResetSessionDialog = null;
+        }
+    }
+
+    private void cancelExitDialog() {
+        if (mExitSessionDialog != null && mExitSessionDialog.isShowing()) {
+            mExitSessionDialog.cancel();
+            mExitSessionDialog = null;
+        }
+    }
+
+    /**
+     * Dialog shown when asking for confirmation before
+     * reset and restart of guest user.
+     */
+    public static final class ResetSessionDialog extends SystemUIDialog implements
+            DialogInterface.OnClickListener {
+
+        private final UserSwitcherController mUserSwitcherController;
+        private final UiEventLogger mUiEventLogger;
+        private final int mUserId;
+
+        /** Factory class to create guest reset dialog instance */
+        @AssistedFactory
+        public interface Factory {
+            /** Create a guest reset dialog instance */
+            ResetSessionDialog create(int userId);
+        }
+
+        @AssistedInject
+        ResetSessionDialog(Context context,
+                UserSwitcherController userSwitcherController,
+                UiEventLogger uiEventLogger,
+                @Assisted int userId) {
+            super(context);
+
+            setTitle(com.android.settingslib.R.string.guest_reset_and_restart_dialog_title);
+            setMessage(context.getString(
+                        com.android.settingslib.R.string.guest_reset_and_restart_dialog_message));
+            setButton(DialogInterface.BUTTON_NEUTRAL,
+                    context.getString(android.R.string.cancel), this);
+            setButton(DialogInterface.BUTTON_POSITIVE,
+                    context.getString(
+                        com.android.settingslib.R.string.guest_reset_guest_confirm_button), this);
+            setCanceledOnTouchOutside(false);
+
+            mUserSwitcherController = userSwitcherController;
+            mUiEventLogger = uiEventLogger;
+            mUserId = userId;
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (which == DialogInterface.BUTTON_POSITIVE) {
+                mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE);
+                mUserSwitcherController.removeGuestUser(mUserId, UserHandle.USER_NULL);
+            } else if (which == DialogInterface.BUTTON_NEUTRAL) {
+                cancel();
+            }
+        }
+    }
+
+    /**
+     * Dialog shown when asking for confirmation before
+     * exit of guest user.
+     */
+    public static final class ExitSessionDialog extends SystemUIDialog implements
+            DialogInterface.OnClickListener {
+
+        private final UserSwitcherController mUserSwitcherController;
+        private final int mUserId;
+        private boolean mIsEphemeral;
+
+        /** Factory class to create guest exit dialog instance */
+        @AssistedFactory
+        public interface Factory {
+            /** Create a guest exit dialog instance */
+            ExitSessionDialog create(int userId, boolean isEphemeral);
+        }
+
+        @AssistedInject
+        ExitSessionDialog(Context context,
+                UserSwitcherController userSwitcherController,
+                @Assisted int userId,
+                @Assisted boolean isEphemeral) {
+            super(context);
+
+            if (isEphemeral) {
+                setTitle(context.getString(
+                            com.android.settingslib.R.string.guest_exit_dialog_title));
+                setMessage(context.getString(
+                            com.android.settingslib.R.string.guest_exit_dialog_message));
+                setButton(DialogInterface.BUTTON_NEUTRAL,
+                        context.getString(android.R.string.cancel), this);
+                setButton(DialogInterface.BUTTON_POSITIVE,
+                        context.getString(
+                            com.android.settingslib.R.string.guest_exit_dialog_button), this);
+            } else {
+                setTitle(context.getString(
+                            com.android.settingslib
+                                .R.string.guest_exit_dialog_title_non_ephemeral));
+                setMessage(context.getString(
+                            com.android.settingslib
+                                .R.string.guest_exit_dialog_message_non_ephemeral));
+                setButton(DialogInterface.BUTTON_NEUTRAL,
+                        context.getString(android.R.string.cancel), this);
+                setButton(DialogInterface.BUTTON_NEGATIVE,
+                        context.getString(
+                            com.android.settingslib.R.string.guest_exit_clear_data_button), this);
+                setButton(DialogInterface.BUTTON_POSITIVE,
+                        context.getString(
+                            com.android.settingslib.R.string.guest_exit_save_data_button), this);
+            }
+            setCanceledOnTouchOutside(false);
+
+            mUserSwitcherController = userSwitcherController;
+            mUserId = userId;
+            mIsEphemeral = isEphemeral;
+        }
+
+        @Override
+        public void onClick(DialogInterface dialog, int which) {
+            if (mIsEphemeral) {
+                if (which == DialogInterface.BUTTON_POSITIVE) {
+                    // Ephemeral guest: exit guest, guest is removed by the system
+                    // on exit, since its marked ephemeral
+                    mUserSwitcherController.exitGuestUser(mUserId, UserHandle.USER_NULL, false);
+                } else if (which == DialogInterface.BUTTON_NEUTRAL) {
+                    // Cancel clicked, do nothing
+                    cancel();
+                }
+            } else {
+                if (which == DialogInterface.BUTTON_POSITIVE) {
+                    // Non-ephemeral guest: exit guest, guest is not removed by the system
+                    // on exit, since its marked non-ephemeral
+                    mUserSwitcherController.exitGuestUser(mUserId, UserHandle.USER_NULL, false);
+                } else if (which == DialogInterface.BUTTON_NEGATIVE) {
+                    // Non-ephemeral guest: remove guest and then exit
+                    mUserSwitcherController.exitGuestUser(mUserId, UserHandle.USER_NULL, true);
+                } else if (which == DialogInterface.BUTTON_NEUTRAL) {
+                    // Cancel clicked, do nothing
+                    cancel();
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
index 9a6020f..76a7cad 100644
--- a/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/GuestResumeSessionReceiver.java
@@ -35,12 +35,18 @@
 import com.android.systemui.statusbar.policy.UserSwitcherController;
 import com.android.systemui.util.settings.SecureSettings;
 
+import javax.inject.Inject;
+
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedFactory;
+import dagger.assisted.AssistedInject;
+
 /**
  * Manages notification when a guest session is resumed.
  */
 public class GuestResumeSessionReceiver extends BroadcastReceiver {
 
-    private static final String TAG = "GuestResumeSessionReceiver";
+    private static final String TAG = GuestResumeSessionReceiver.class.getSimpleName();
 
     @VisibleForTesting
     public static final String SETTING_GUEST_HAS_LOGGED_IN = "systemui.guest_has_logged_in";
@@ -48,27 +54,31 @@
     @VisibleForTesting
     public AlertDialog mNewSessionDialog;
     private final UserTracker mUserTracker;
-    private final UserSwitcherController mUserSwitcherController;
-    private final UiEventLogger mUiEventLogger;
     private final SecureSettings mSecureSettings;
+    private final BroadcastDispatcher mBroadcastDispatcher;
+    private final ResetSessionDialog.Factory mResetSessionDialogFactory;
+    private final GuestSessionNotification mGuestSessionNotification;
 
-    public GuestResumeSessionReceiver(UserSwitcherController userSwitcherController,
-            UserTracker userTracker, UiEventLogger uiEventLogger,
-            SecureSettings secureSettings) {
-        mUserSwitcherController = userSwitcherController;
+    @Inject
+    public GuestResumeSessionReceiver(
+            UserTracker userTracker,
+            SecureSettings secureSettings,
+            BroadcastDispatcher broadcastDispatcher,
+            GuestSessionNotification guestSessionNotification,
+            ResetSessionDialog.Factory resetSessionDialogFactory) {
         mUserTracker = userTracker;
-        mUiEventLogger = uiEventLogger;
         mSecureSettings = secureSettings;
+        mBroadcastDispatcher = broadcastDispatcher;
+        mGuestSessionNotification = guestSessionNotification;
+        mResetSessionDialogFactory = resetSessionDialogFactory;
     }
 
     /**
      * Register this receiver with the {@link BroadcastDispatcher}
-     *
-     * @param broadcastDispatcher to register the receiver.
      */
-    public void register(BroadcastDispatcher broadcastDispatcher) {
+    public void register() {
         IntentFilter f = new IntentFilter(Intent.ACTION_USER_SWITCHED);
-        broadcastDispatcher.registerReceiver(this, f, null /* handler */, UserHandle.SYSTEM);
+        mBroadcastDispatcher.registerReceiver(this, f, null /* handler */, UserHandle.SYSTEM);
     }
 
     @Override
@@ -89,14 +99,25 @@
                 return;
             }
 
-            int notFirstLogin = mSecureSettings.getIntForUser(
+            int guestLoginState = mSecureSettings.getIntForUser(
                     SETTING_GUEST_HAS_LOGGED_IN, 0, userId);
-            if (notFirstLogin != 0) {
-                mNewSessionDialog = new ResetSessionDialog(context, mUserSwitcherController,
-                        mUiEventLogger, userId);
+
+            if (guestLoginState == 0) {
+                // set 1 to indicate, 1st login
+                guestLoginState = 1;
+                mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, guestLoginState, userId);
+            } else if (guestLoginState == 1) {
+                // set 2 to indicate, 2nd or later login
+                guestLoginState = 2;
+                mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, guestLoginState, userId);
+            }
+
+            mGuestSessionNotification.createPersistentNotification(currentUser,
+                                                                   (guestLoginState <= 1));
+
+            if (guestLoginState > 1) {
+                mNewSessionDialog = mResetSessionDialogFactory.create(userId);
                 mNewSessionDialog.show();
-            } else {
-                mSecureSettings.putIntForUser(SETTING_GUEST_HAS_LOGGED_IN, 1, userId);
             }
         }
     }
@@ -124,10 +145,19 @@
         private final UiEventLogger mUiEventLogger;
         private final int mUserId;
 
-        ResetSessionDialog(Context context,
+
+        /** Factory class to create guest reset dialog instance */
+        @AssistedFactory
+        public interface Factory {
+            /** Create a guest reset dialog instance */
+            ResetSessionDialog create(int userId);
+        }
+
+        @AssistedInject
+        public ResetSessionDialog(Context context,
                 UserSwitcherController userSwitcherController,
                 UiEventLogger uiEventLogger,
-                int userId) {
+                @Assisted int userId) {
             super(context, false /* dismissOnDeviceLock */);
 
             setTitle(context.getString(R.string.guest_wipe_session_title));
diff --git a/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java b/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java
new file mode 100644
index 0000000..b0eaab9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/GuestSessionNotification.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 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;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.FeatureFlagUtils;
+
+import com.android.internal.messages.nano.SystemMessageProto;
+import com.android.systemui.util.NotificationChannels;
+
+import javax.inject.Inject;
+
+/**
+ * Posts a persistent notification on entry to guest mode
+ */
+public final class GuestSessionNotification {
+
+    private static final String TAG = GuestSessionNotification.class.getSimpleName();
+
+    private final Context mContext;
+    private final NotificationManager mNotificationManager;
+
+    @Inject
+    public GuestSessionNotification(Context context,
+            NotificationManager notificationManager) {
+        mContext = context;
+        mNotificationManager = notificationManager;
+    }
+
+    private void overrideNotificationAppName(Notification.Builder notificationBuilder) {
+        final Bundle extras = new Bundle();
+        String appName = mContext.getString(R.string.guest_notification_app_name);
+
+        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, appName);
+
+        notificationBuilder.addExtras(extras);
+    }
+
+    void createPersistentNotification(UserInfo userInfo, boolean isGuestFirstLogin) {
+        if (!FeatureFlagUtils.isEnabled(mContext,
+                FeatureFlagUtils.SETTINGS_GUEST_MODE_UX_CHANGES)
+                || !userInfo.isGuest()) {
+            // we create a persistent notification only if enabled and only for guests
+            return;
+        }
+        String contentText;
+        if (userInfo.isEphemeral()) {
+            contentText = mContext.getString(R.string.guest_notification_ephemeral);
+        } else if (isGuestFirstLogin) {
+            contentText = mContext.getString(R.string.guest_notification_non_ephemeral);
+        } else {
+            contentText = mContext.getString(
+                            R.string.guest_notification_non_ephemeral_non_first_login);
+        }
+
+        final Intent guestExitIntent = new Intent(
+                        GuestResetOrExitSessionReceiver.ACTION_GUEST_EXIT);
+        final Intent userSettingsIntent = new Intent(Settings.ACTION_USER_SETTINGS);
+
+        PendingIntent guestExitPendingIntent =
+                PendingIntent.getBroadcastAsUser(mContext, 0, guestExitIntent,
+                    PendingIntent.FLAG_IMMUTABLE,
+                    UserHandle.SYSTEM);
+
+        PendingIntent userSettingsPendingIntent =
+                PendingIntent.getActivityAsUser(mContext, 0, userSettingsIntent,
+                    PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE,
+                    null,
+                    UserHandle.of(userInfo.id));
+
+        Notification.Builder builder = new Notification.Builder(mContext,
+                                                                NotificationChannels.ALERTS)
+                .setSmallIcon(R.drawable.ic_account_circle)
+                .setContentTitle(mContext.getString(R.string.guest_notification_session_active))
+                .setContentText(contentText)
+                .setPriority(Notification.PRIORITY_DEFAULT)
+                .setOngoing(true)
+                .setContentIntent(userSettingsPendingIntent);
+
+        // we show reset button only if this is a 2nd or later login
+        if (!isGuestFirstLogin) {
+            final Intent guestResetIntent = new Intent(
+                            GuestResetOrExitSessionReceiver.ACTION_GUEST_RESET);
+
+            PendingIntent guestResetPendingIntent =
+                    PendingIntent.getBroadcastAsUser(mContext, 0, guestResetIntent,
+                        PendingIntent.FLAG_IMMUTABLE,
+                        UserHandle.SYSTEM);
+
+            builder.addAction(R.drawable.ic_sysbar_home,
+                        mContext.getString(
+                            com.android.settingslib.R.string.guest_reset_guest_confirm_button),
+                        guestResetPendingIntent);
+        }
+        builder.addAction(R.drawable.ic_sysbar_home,
+                        mContext.getString(
+                            com.android.settingslib.R.string.guest_exit_button),
+                        guestExitPendingIntent);
+
+        overrideNotificationAppName(builder);
+
+        mNotificationManager.notifyAsUser(null,
+                                         SystemMessageProto.SystemMessage.NOTE_GUEST_SESSION,
+                                         builder.build(),
+                                         UserHandle.of(userInfo.id));
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index ff5715c..9aa5fae 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -63,7 +63,6 @@
             Key.QS_WORK_ADDED,
             Key.QS_NIGHTDISPLAY_ADDED,
             Key.QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT,
-            Key.SEEN_MULTI_USER,
             Key.SEEN_RINGER_GUIDANCE_COUNT,
             Key.QS_HAS_TURNED_OFF_MOBILE_DATA,
             Key.TOUCHED_RINGER_TOGGLE,
@@ -106,7 +105,6 @@
          * Settings panel.
          */
         String QS_LONG_PRESS_TOOLTIP_SHOWN_COUNT = "QsLongPressTooltipShownCount";
-        String SEEN_MULTI_USER = "HasSeenMultiUser";
         String SEEN_RINGER_GUIDANCE_COUNT = "RingerGuidanceCount";
         String QS_TILE_SPECS_REVEALED = "QsTileSpecsRevealed";
         String QS_HAS_TURNED_OFF_MOBILE_DATA = "QsHasTurnedOffMobileData";
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
index e5da389..4773f2a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
@@ -18,9 +18,9 @@
 
 import android.view.MotionEvent;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 
@@ -33,13 +33,13 @@
  */
 public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
 
-    private final LinkedList<MotionEvent> mMotionEvents;
+    private final List<MotionEvent> mMotionEvents;
     private final long mMaxAgeMs;
 
     public TimeLimitedMotionEventBuffer(long maxAgeMs) {
         super();
         mMaxAgeMs = maxAgeMs;
-        mMotionEvents = new LinkedList<>();
+        mMotionEvents = new ArrayList<>();
     }
 
     private void ejectOldEvents() {
@@ -47,7 +47,7 @@
             return;
         }
         Iterator<MotionEvent> iter = listIterator();
-        long mostRecentMs = mMotionEvents.getLast().getEventTime();
+        long mostRecentMs = mMotionEvents.get(mMotionEvents.size() - 1).getEventTime();
         while (iter.hasNext()) {
             MotionEvent ev = iter.next();
             if (mostRecentMs - ev.getEventTime() > mMaxAgeMs) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
index bed553e..2ea5967 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
@@ -33,6 +33,7 @@
 import android.util.ArrayMap
 import android.util.Log
 import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.notification.NotificationAccessConfirmationActivityContract.EXTRA_USER_ID
 import com.android.systemui.Dumpable
 import com.android.systemui.backup.BackupHelper
 import com.android.systemui.broadcast.BroadcastDispatcher
@@ -43,6 +44,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.people.widget.PeopleSpaceWidgetProvider.EXTRA_USER_HANDLE
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_FILE
 import com.android.systemui.statusbar.policy.DeviceControlsControllerImpl.Companion.PREFS_CONTROLS_SEEDING_COMPLETED
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index f9115b2..3eb58bb 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -343,7 +343,7 @@
         info.className = Switch::class.java.name
     }
 
-    override fun performAccessibilityAction(host: View?, action: Int, args: Bundle?): Boolean {
+    override fun performAccessibilityAction(host: View, action: Int, args: Bundle?): Boolean {
         if (super.performAccessibilityAction(host, action, args)) {
             return true
         }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
index 0cf3333..8ba6f1c 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
@@ -18,6 +18,8 @@
 
 import android.content.BroadcastReceiver;
 
+import com.android.systemui.GuestResetOrExitSessionReceiver;
+import com.android.systemui.GuestResumeSessionReceiver;
 import com.android.systemui.media.dialog.MediaOutputDialogReceiver;
 import com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver;
 import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
@@ -89,4 +91,21 @@
     public abstract BroadcastReceiver bindPeopleSpaceWidgetProvider(
             PeopleSpaceWidgetProvider broadcastReceiver);
 
+    /**
+     *
+     */
+    @Binds
+    @IntoMap
+    @ClassKey(GuestResumeSessionReceiver.class)
+    public abstract BroadcastReceiver bindGuestResumeSessionReceiver(
+            GuestResumeSessionReceiver broadcastReceiver);
+
+    /**
+     *
+     */
+    @Binds
+    @IntoMap
+    @ClassKey(GuestResetOrExitSessionReceiver.class)
+    public abstract BroadcastReceiver bindGuestResetOrExitSessionReceiver(
+            GuestResetOrExitSessionReceiver broadcastReceiver);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 5d154c3..c870b89 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -178,7 +178,8 @@
             KeyguardBypassController bypassController,
             GroupMembershipManager groupManager,
             VisualStabilityProvider visualStabilityProvider,
-            ConfigurationController configurationController) {
+            ConfigurationController configurationController,
+            @Main Handler handler) {
         return new HeadsUpManagerPhone(
                 context,
                 headsUpManagerLogger,
@@ -186,7 +187,8 @@
                 bypassController,
                 groupManager,
                 visualStabilityProvider,
-                configurationController
+                configurationController,
+                handler
         );
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
index 5aedbdc..bd00ce6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
@@ -34,8 +34,8 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
@@ -71,7 +71,7 @@
     @Nullable private ShowNextIndication mShowNextIndicationRunnable;
 
     // List of indication types to show. The next indication to show is always at index 0
-    private final List<Integer> mIndicationQueue = new LinkedList<>();
+    private final List<Integer> mIndicationQueue = new ArrayList<>();
     private @IndicationType int mCurrIndicationType = INDICATION_TYPE_NONE;
     private CharSequence mCurrMessage;
     private long mLastIndicationSwitch;
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
index 7f25642..5e810f2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
@@ -33,6 +33,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.people.widget.PeopleSpaceWidgetProvider.EXTRA_USER_HANDLE
 import com.android.systemui.tuner.TunerService
 import com.android.systemui.util.Utils
 import com.android.systemui.util.time.SystemClock
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index 0edadcc..9e4ee61 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -118,9 +118,7 @@
             mCheckBox.setVisibility(View.GONE);
             mStatusIcon.setVisibility(View.GONE);
             mContainerLayout.setOnClickListener(null);
-            mTitleText.setTextColor(mController.getColorItemContent());
-            mSubTitleText.setTextColor(mController.getColorItemContent());
-            mTwoLineTitleText.setTextColor(mController.getColorItemContent());
+            mTitleText.setTextColor(mController.getColorInactiveItem());
             mSeekBar.getProgressDrawable().setColorFilter(
                     new PorterDuffColorFilter(mController.getColorSeekbarProgress(),
                             PorterDuff.Mode.SRC_IN));
@@ -141,7 +139,7 @@
                         && !mController.hasAdjustVolumeUserRestriction()) {
                     mProgressBar.getIndeterminateDrawable().setColorFilter(
                             new PorterDuffColorFilter(
-                                    mController.getColorItemContent(),
+                                    mController.getColorInactiveItem(),
                                     PorterDuff.Mode.SRC_IN));
                     setSingleLineLayout(getItemTitle(device), true /* bFocused */,
                             false /* showSeekBar*/,
@@ -156,7 +154,7 @@
                     mTitleIcon.setAlpha(DEVICE_CONNECTED_ALPHA);
                     mStatusIcon.setImageDrawable(
                             mContext.getDrawable(R.drawable.media_output_status_failed));
-                    mStatusIcon.setColorFilter(mController.getColorItemContent());
+                    mStatusIcon.setColorFilter(mController.getColorInactiveItem());
                     setTwoLineLayout(device, false /* bFocused */,
                             false /* showSeekBar */, false /* showProgressBar */,
                             true /* showSubtitle */, true /* showStatus */);
@@ -164,34 +162,40 @@
                     mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
                 } else if (mController.getSelectedMediaDevice().size() > 1
                         && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) {
-                    mTitleText.setTextColor(mController.getColorItemContent());
+                    mTitleText.setTextColor(mController.getColorActiveItem());
                     setSingleLineLayout(getItemTitle(device), true /* bFocused */,
                             true /* showSeekBar */,
                             false /* showProgressBar */, false /* showStatus */);
+                    mCheckBox.setOnCheckedChangeListener(null);
                     mCheckBox.setVisibility(View.VISIBLE);
                     mCheckBox.setChecked(true);
-                    mSeekBar.setOnClickListener(null);
-                    mSeekBar.setOnClickListener(v -> onGroupActionTriggered(false, device));
-                    setCheckBoxColor(mCheckBox, mController.getColorItemContent());
+                    mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
+                        onCheckBoxClicked(false, device);
+                    });
+                    setCheckBoxColor(mCheckBox, mController.getColorActiveItem());
                     initSeekbar(device);
                 } else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) {
                     mStatusIcon.setImageDrawable(
                             mContext.getDrawable(R.drawable.media_output_status_check));
-                    mStatusIcon.setColorFilter(mController.getColorItemContent());
-                    mTitleText.setTextColor(mController.getColorItemContent());
+                    mStatusIcon.setColorFilter(mController.getColorActiveItem());
+                    mTitleText.setTextColor(mController.getColorActiveItem());
                     setSingleLineLayout(getItemTitle(device), true /* bFocused */,
                             true /* showSeekBar */,
                             false /* showProgressBar */, true /* showStatus */);
                     initSeekbar(device);
                     mCurrentActivePosition = position;
                 } else if (isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
+                    mCheckBox.setOnCheckedChangeListener(null);
                     mCheckBox.setVisibility(View.VISIBLE);
                     mCheckBox.setChecked(false);
-                    mContainerLayout.setOnClickListener(v -> onGroupActionTriggered(true, device));
-                    setCheckBoxColor(mCheckBox, mController.getColorItemContent());
+                    mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
+                        onCheckBoxClicked(true, device);
+                    });
+                    setCheckBoxColor(mCheckBox, mController.getColorInactiveItem());
                     setSingleLineLayout(getItemTitle(device), false /* bFocused */,
                             false /* showSeekBar */,
                             false /* showProgressBar */, false /* showStatus */);
+                    mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
                 } else {
                     setSingleLineLayout(getItemTitle(device), false /* bFocused */);
                     mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
@@ -209,7 +213,7 @@
         @Override
         void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) {
             if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
-                mTitleText.setTextColor(mController.getColorItemContent());
+                mTitleText.setTextColor(mController.getColorInactiveItem());
                 mCheckBox.setVisibility(View.GONE);
                 setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new),
                         false /* bFocused */);
@@ -221,7 +225,7 @@
             }
         }
 
-        private void onGroupActionTriggered(boolean isChecked, MediaDevice device) {
+        private void onCheckBoxClicked(boolean isChecked, MediaDevice device) {
             if (isChecked && isDeviceIncluded(mController.getSelectableMediaDevice(), device)) {
                 mController.addDeviceToPlayMedia(device);
             } else if (!isChecked && isDeviceIncluded(mController.getDeselectableMediaDevice(),
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index 5c536d4..958e9ed 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -183,16 +183,14 @@
         void setSingleLineLayout(CharSequence title, boolean bFocused, boolean showSeekBar,
                 boolean showProgressBar, boolean showStatus) {
             mTwoLineLayout.setVisibility(View.GONE);
-            boolean isActive = showSeekBar || showProgressBar;
             final Drawable backgroundDrawable =
-                    isActive
+                    showSeekBar || showProgressBar
                             ? mContext.getDrawable(R.drawable.media_output_item_background_active)
                                     .mutate() : mContext.getDrawable(
                             R.drawable.media_output_item_background)
                             .mutate();
             backgroundDrawable.setColorFilter(new PorterDuffColorFilter(
-                    isActive ? mController.getColorConnectedItemBackground()
-                            : mController.getColorItemBackground(),
+                    mController.getColorItemBackground(),
                     PorterDuff.Mode.SRC_IN));
             mItemLayout.setBackground(backgroundDrawable);
             mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
@@ -381,7 +379,7 @@
                     .mutate();
             drawable.setColorFilter(
                     new PorterDuffColorFilter(Utils.getColorStateListDefaultColor(mContext,
-                            R.color.media_dialog_item_main_content),
+                            R.color.media_dialog_active_item_main_content),
                             PorterDuff.Mode.SRC_IN));
             return drawable;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index bde772d..79be916 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -218,9 +218,10 @@
                 ColorFilter buttonColorFilter = new PorterDuffColorFilter(
                         mAdapter.getController().getColorButtonBackground(),
                         PorterDuff.Mode.SRC_IN);
+                ColorFilter onlineButtonColorFilter = new PorterDuffColorFilter(
+                        mAdapter.getController().getColorInactiveItem(), PorterDuff.Mode.SRC_IN);
                 mDoneButton.getBackground().setColorFilter(buttonColorFilter);
-                mStopButton.getBackground().setColorFilter(buttonColorFilter);
-                mDoneButton.setTextColor(mAdapter.getController().getColorPositiveButtonText());
+                mStopButton.getBackground().setColorFilter(onlineButtonColorFilter);
             }
             mHeaderIcon.setVisibility(View.VISIBLE);
             mHeaderIcon.setImageIcon(icon);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index ec2a950..af52a2f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -117,12 +117,11 @@
 
     private MediaOutputMetricLogger mMetricLogger;
 
-    private int mColorItemContent;
+    private int mColorActiveItem;
+    private int mColorInactiveItem;
     private int mColorSeekbarProgress;
     private int mColorButtonBackground;
     private int mColorItemBackground;
-    private int mColorConnectedItemBackground;
-    private int mColorPositiveButtonText;
 
     public enum BroadcastNotifyDialog {
         ACTION_FIRST_LAUNCH,
@@ -147,18 +146,16 @@
         mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
         mDialogLaunchAnimator = dialogLaunchAnimator;
         mNearbyMediaDevicesManager = nearbyMediaDevicesManagerOptional.orElse(null);
-        mColorItemContent = Utils.getColorStateListDefaultColor(mContext,
-                R.color.media_dialog_item_main_content);
+        mColorActiveItem = Utils.getColorStateListDefaultColor(mContext,
+                R.color.media_dialog_active_item_main_content);
+        mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext,
+                R.color.media_dialog_inactive_item_main_content);
         mColorSeekbarProgress = Utils.getColorStateListDefaultColor(mContext,
-                R.color.media_dialog_seekbar_progress);
+                android.R.color.system_accent1_200);
         mColorButtonBackground = Utils.getColorStateListDefaultColor(mContext,
-                R.color.media_dialog_button_background);
-        mColorItemBackground = Utils.getColorStateListDefaultColor(mContext,
                 R.color.media_dialog_item_background);
-        mColorConnectedItemBackground = Utils.getColorStateListDefaultColor(mContext,
-                R.color.media_dialog_connected_item_background);
-        mColorPositiveButtonText = Utils.getColorStateListDefaultColor(mContext,
-                R.color.media_dialog_solid_button_text);
+        mColorItemBackground = Utils.getColorStateListDefaultColor(mContext,
+                android.R.color.system_accent2_50);
     }
 
     void start(@NonNull Callback cb) {
@@ -338,7 +335,8 @@
     }
 
     void setColorFilter(Drawable drawable, boolean isActive) {
-        drawable.setColorFilter(new PorterDuffColorFilter(mColorItemContent,
+        drawable.setColorFilter(new PorterDuffColorFilter(isActive
+                ? mColorActiveItem : mColorInactiveItem,
                 PorterDuff.Mode.SRC_IN));
     }
 
@@ -373,32 +371,26 @@
         ColorScheme mCurrentColorScheme = new ColorScheme(wallpaperColors,
                 isDarkTheme);
         if (isDarkTheme) {
-            mColorItemContent = mCurrentColorScheme.getAccent1().get(2); // A1-100
-            mColorSeekbarProgress = mCurrentColorScheme.getAccent2().get(7); // A2-600
-            mColorButtonBackground = mCurrentColorScheme.getAccent1().get(4); // A1-300
-            mColorItemBackground = mCurrentColorScheme.getNeutral2().get(9); // N2-800
-            mColorConnectedItemBackground = mCurrentColorScheme.getAccent2().get(9); // A2-800
-            mColorPositiveButtonText = mCurrentColorScheme.getAccent2().get(9); // A2-800
+            mColorActiveItem = mCurrentColorScheme.getNeutral1().get(10);
+            mColorInactiveItem = mCurrentColorScheme.getNeutral1().get(10);
+            mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(2);
+            mColorButtonBackground = mCurrentColorScheme.getAccent1().get(2);
+            mColorItemBackground = mCurrentColorScheme.getAccent2().get(0);
         } else {
-            mColorItemContent = mCurrentColorScheme.getAccent1().get(9); // A1-800
-            mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(4); // A1-300
-            mColorButtonBackground = mCurrentColorScheme.getAccent1().get(7); // A1-600
-            mColorItemBackground = mCurrentColorScheme.getAccent2().get(1); // A2-50
-            mColorConnectedItemBackground = mCurrentColorScheme.getAccent1().get(2); // A1-100
-            mColorPositiveButtonText = mCurrentColorScheme.getNeutral1().get(1); // N1-50
+            mColorActiveItem = mCurrentColorScheme.getNeutral1().get(10);
+            mColorInactiveItem = mCurrentColorScheme.getAccent1().get(7);
+            mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(3);
+            mColorButtonBackground = mCurrentColorScheme.getAccent1().get(3);
+            mColorItemBackground = mCurrentColorScheme.getAccent2().get(0);
         }
     }
 
-    public int getColorConnectedItemBackground() {
-        return mColorConnectedItemBackground;
+    public int getColorActiveItem() {
+        return mColorActiveItem;
     }
 
-    public int getColorPositiveButtonText() {
-        return mColorPositiveButtonText;
-    }
-
-    public int getColorItemContent() {
-        return mColorItemContent;
+    public int getColorInactiveItem() {
+        return mColorInactiveItem;
     }
 
     public int getColorSeekbarProgress() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java
deleted file mode 100644
index 0a3c5bf..0000000
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSeekbar.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2022 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.media.dialog;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.SeekBar;
-
-/**
- * Customized seekbar used by MediaOutputDialog, which only changes progress when dragging,
- * otherwise performs click.
- */
-public class MediaOutputSeekbar extends SeekBar {
-    private static final int DRAGGING_THRESHOLD = 20;
-    private boolean mIsDragging = false;
-
-    public MediaOutputSeekbar(Context context) {
-        super(context);
-    }
-
-    public MediaOutputSeekbar(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        int width = getWidth()
-                - getPaddingLeft()
-                - getPaddingRight();
-        int thumbPos = getPaddingLeft()
-                + width
-                * getProgress()
-                / getMax();
-        if (event.getAction() == MotionEvent.ACTION_DOWN
-                && Math.abs(event.getX() - thumbPos) < DRAGGING_THRESHOLD) {
-            mIsDragging = true;
-            super.onTouchEvent(event);
-        } else if (event.getAction() == MotionEvent.ACTION_MOVE && mIsDragging) {
-            super.onTouchEvent(event);
-        } else if (event.getAction() == MotionEvent.ACTION_UP && mIsDragging) {
-            mIsDragging = false;
-            super.onTouchEvent(event);
-        } else if (event.getAction() == MotionEvent.ACTION_UP && !mIsDragging) {
-            performClick();
-        }
-        return true;
-    }
-
-    @Override
-    public boolean performClick() {
-        return super.performClick();
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
index 5510eb1..09c4cb7 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
+++ b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
@@ -57,7 +57,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 
 import javax.inject.Inject;
@@ -126,7 +125,7 @@
     private final Runnable mCollapseRunnable = this::collapseChip;
 
     private final Runnable mAccessibilityRunnable = this::makeAccessibilityAnnouncement;
-    private final List<PrivacyItem> mItemsBeforeLastAnnouncement = new LinkedList<>();
+    private final List<PrivacyItem> mItemsBeforeLastAnnouncement = new ArrayList<>();
 
     @State
     private int mState = STATE_NOT_SHOWN;
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index 3a6248b..6b79a28 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -30,9 +30,9 @@
 import androidx.annotation.WorkerThread
 import com.android.systemui.Dumpable
 import com.android.systemui.dump.DumpManager
+import com.android.systemui.people.widget.PeopleSpaceWidgetProvider.EXTRA_USER_HANDLE
 import com.android.systemui.util.Assert
 import java.io.PrintWriter
-import java.lang.IllegalStateException
 import java.lang.ref.WeakReference
 import java.util.concurrent.Executor
 import kotlin.properties.ReadWriteProperty
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
index 6cfbb43..1ffa6f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
@@ -19,13 +19,12 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.os.Handler;
-import android.os.Looper;
 import android.os.SystemClock;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.view.accessibility.AccessibilityEvent;
 
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
 import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
@@ -43,8 +42,9 @@
     protected final ArrayMap<String, AlertEntry> mAlertEntries = new ArrayMap<>();
     protected final HeadsUpManagerLogger mLogger;
 
-    public AlertingNotificationManager(HeadsUpManagerLogger logger) {
+    public AlertingNotificationManager(HeadsUpManagerLogger logger, @Main Handler handler) {
         mLogger = logger;
+        mHandler = handler;
     }
 
     /**
@@ -57,8 +57,7 @@
     protected NotificationSafeToRemoveCallback mNotificationLifetimeFinishedCallback;
     protected int mMinimumDisplayTime;
     protected int mAutoDismissNotificationDecay;
-    @VisibleForTesting
-    public Handler mHandler = new Handler(Looper.getMainLooper());
+    private final Handler mHandler;
 
     /**
      * Called when posting a new notification that should alert the user and appear on screen.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 61f49e0..83138f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -896,21 +896,8 @@
         }
     }
 
-    private void showTryFingerprintMsg(int msgId, String a11yString) {
-        if (mKeyguardUpdateMonitor.isUdfpsSupported()) {
-            // if udfps available, there will always be a tappable affordance to unlock
-            // For example, the lock icon
-            if (mKeyguardBypassController.getUserHasDeviceEntryIntent()) {
-                showBiometricMessage(R.string.keyguard_unlock_press);
-            } else if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
-                // since face is locked out, simply show "try fingerprint"
-                showBiometricMessage(R.string.keyguard_try_fingerprint);
-            } else {
-                showBiometricMessage(R.string.keyguard_face_failed_use_fp);
-            }
-        } else {
-            showBiometricMessage(R.string.keyguard_try_fingerprint);
-        }
+    private void showFaceFailedTryFingerprintMsg(int msgId, String a11yString) {
+        showBiometricMessage(R.string.keyguard_face_failed_use_fp);
 
         // Although we suppress face auth errors visually, we still announce them for a11y
         if (!TextUtils.isEmpty(a11yString)) {
@@ -1002,7 +989,7 @@
             } else if (mScreenLifecycle.getScreenState() == SCREEN_ON) {
                 if (biometricSourceType == BiometricSourceType.FACE
                         && shouldSuppressFaceMsgAndShowTryFingerprintMsg()) {
-                    showTryFingerprintMsg(msgId, helpString);
+                    showFaceFailedTryFingerprintMsg(msgId, helpString);
                     return;
                 }
                 showBiometricMessage(helpString);
@@ -1022,7 +1009,7 @@
                     && shouldSuppressFaceMsgAndShowTryFingerprintMsg()
                     && !mStatusBarKeyguardViewManager.isBouncerShowing()
                     && mScreenLifecycle.getScreenState() == SCREEN_ON) {
-                showTryFingerprintMsg(msgId, errString);
+                showFaceFailedTryFingerprintMsg(msgId, errString);
                 return;
             }
             if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
@@ -1031,10 +1018,10 @@
                 if (!mStatusBarKeyguardViewManager.isBouncerShowing()
                         && mKeyguardUpdateMonitor.isUdfpsEnrolled()
                         && mKeyguardUpdateMonitor.isFingerprintDetectionRunning()) {
-                    showTryFingerprintMsg(msgId, errString);
+                    showFaceFailedTryFingerprintMsg(msgId, errString);
                 } else if (mStatusBarKeyguardViewManager.isShowingAlternateAuth()) {
                     mStatusBarKeyguardViewManager.showBouncerMessage(
-                            mContext.getResources().getString(R.string.keyguard_unlock_press),
+                            mContext.getResources().getString(R.string.keyguard_try_fingerprint),
                             mInitialTextColorState
                     );
                 } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index aac5b8d..4895fa3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -19,12 +19,12 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 
 import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
index 57fd197..5ac4813 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
@@ -20,7 +20,6 @@
 import android.annotation.Nullable;
 
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.SectionClassifier;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -28,6 +27,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
 import com.android.systemui.statusbar.notification.collection.render.NodeController;
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
 import com.android.systemui.statusbar.notification.dagger.AlertingHeader;
@@ -51,7 +51,7 @@
     public static final boolean SHOW_ALL_SECTIONS = false;
     private final StatusBarStateController mStatusBarStateController;
     private final HighPriorityProvider mHighPriorityProvider;
-    private final SectionClassifier mSectionClassifier;
+    private final SectionStyleProvider mSectionStyleProvider;
     private final NodeController mSilentNodeController;
     private final SectionHeaderController mSilentHeaderController;
     private final NodeController mAlertingHeaderController;
@@ -62,13 +62,13 @@
     public RankingCoordinator(
             StatusBarStateController statusBarStateController,
             HighPriorityProvider highPriorityProvider,
-            SectionClassifier sectionClassifier,
+            SectionStyleProvider sectionStyleProvider,
             @AlertingHeader NodeController alertingHeaderController,
             @SilentHeader SectionHeaderController silentHeaderController,
             @SilentHeader NodeController silentNodeController) {
         mStatusBarStateController = statusBarStateController;
         mHighPriorityProvider = highPriorityProvider;
-        mSectionClassifier = sectionClassifier;
+        mSectionStyleProvider = sectionStyleProvider;
         mAlertingHeaderController = alertingHeaderController;
         mSilentNodeController = silentNodeController;
         mSilentHeaderController = silentHeaderController;
@@ -77,7 +77,7 @@
     @Override
     public void attach(NotifPipeline pipeline) {
         mStatusBarStateController.addCallback(mStatusBarStateCallback);
-        mSectionClassifier.setMinimizedSections(Collections.singleton(mMinimizedNotifSectioner));
+        mSectionStyleProvider.setMinimizedSections(Collections.singleton(mMinimizedNotifSectioner));
 
         pipeline.addPreGroupFilter(mSuspendedFilter);
         pipeline.addPreGroupFilter(mDndVisualEffectsFilter);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
index 4e9d3ac..9e8b35a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
@@ -19,11 +19,11 @@
 import android.content.Context
 import com.android.systemui.R
 import com.android.systemui.statusbar.notification.AssistantFeedbackController
-import com.android.systemui.statusbar.notification.SectionClassifier
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
 import com.android.systemui.statusbar.notification.collection.render.NotifRowController
 import javax.inject.Inject
 
@@ -35,7 +35,7 @@
 class RowAppearanceCoordinator @Inject internal constructor(
     context: Context,
     private var mAssistantFeedbackController: AssistantFeedbackController,
-    private var mSectionClassifier: SectionClassifier
+    private var mSectionStyleProvider: SectionStyleProvider
 ) : Coordinator {
 
     private var entryToExpand: NotificationEntry? = null
@@ -55,7 +55,7 @@
 
     private fun onBeforeRenderList(list: List<ListEntry>) {
         entryToExpand = list.firstOrNull()?.representativeEntry?.takeIf { entry ->
-            !mSectionClassifier.isMinimizedSection(entry.section!!)
+            !mSectionStyleProvider.isMinimizedSection(entry.section!!)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
index 497691d..2227be1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
@@ -17,9 +17,9 @@
 package com.android.systemui.statusbar.notification.collection.inflation
 
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.SectionClassifier
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
 import javax.inject.Inject
 
 /**
@@ -28,13 +28,13 @@
  */
 @SysUISingleton
 open class NotifUiAdjustmentProvider @Inject constructor(
-    private val sectionClassifier: SectionClassifier
+    private val sectionStyleProvider: SectionStyleProvider
 ) {
 
     private fun isEntryMinimized(entry: NotificationEntry): Boolean {
         val section = entry.section ?: error("Entry must have a section to determine if minimized")
         val parent = entry.parent ?: error("Entry must have a parent to determine if minimized")
-        val isMinimizedSection = sectionClassifier.isMinimizedSection(section)
+        val isMinimizedSection = sectionStyleProvider.isMinimizedSection(section)
         val isTopLevelEntry = parent == GroupEntry.ROOT_ENTRY
         val isGroupSummary = parent.summary == entry
         return isMinimizedSection && (isTopLevelEntry || isGroupSummary)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
index 68bdd18..2148d3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification
+package com.android.systemui.statusbar.notification.collection.provider
 
 import android.content.Context
 import com.android.systemui.dagger.SysUISingleton
@@ -34,7 +34,7 @@
 class SectionHeaderVisibilityProvider @Inject constructor(
     context: Context
 ) {
-    var neverShowSectionHeaders = context.resources.getBoolean(R.bool.config_notification_never_show_section_headers)
-        private set
+    val neverShowSectionHeaders =
+        context.resources.getBoolean(R.bool.config_notification_never_show_section_headers)
     var sectionHeadersVisible = true
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionClassifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionClassifier.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
index 1f2d0fe..50e7d1ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionClassifier.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification
+package com.android.systemui.statusbar.notification.collection.provider
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
@@ -26,7 +26,7 @@
  * NOTE: This class exists to avoid putting metadata like "isMinimized" on the NotifSection
  */
 @SysUISingleton
-class SectionClassifier @Inject constructor() {
+class SectionStyleProvider @Inject constructor() {
     private lateinit var lowPrioritySections: Set<NotifSectioner>
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
index 6db544c..75a71af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
@@ -16,12 +16,12 @@
 
 package com.android.systemui.statusbar.notification.collection.render
 
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
 import com.android.systemui.util.Compile
 import com.android.systemui.util.traceSection
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
index 6ed8107..51dc728 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
@@ -19,10 +19,10 @@
 import android.content.Context
 import android.view.View
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
 import com.android.systemui.util.traceSection
 import dagger.assisted.Assisted
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 415bd90..f3ee64f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Region;
+import android.os.Handler;
 import android.util.Pools;
 
 import androidx.collection.ArraySet;
@@ -29,6 +30,7 @@
 import com.android.internal.policy.SystemBarUtils;
 import com.android.systemui.Dumpable;
 import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.StatusBarState;
@@ -104,8 +106,9 @@
             KeyguardBypassController bypassController,
             GroupMembershipManager groupMembershipManager,
             VisualStabilityProvider visualStabilityProvider,
-            ConfigurationController configurationController) {
-        super(context, logger);
+            ConfigurationController configurationController,
+            @Main Handler handler) {
+        super(context, logger, handler);
         Resources resources = mContext.getResources();
         mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
         statusBarStateController.addCallback(mStatusBarStateListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
index 67de4e3..6b700a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
@@ -38,7 +38,6 @@
 import com.android.systemui.util.leak.RotationUtils.Rotation
 import com.android.systemui.util.leak.RotationUtils.getExactRotation
 import com.android.systemui.util.leak.RotationUtils.getResourcesForRotation
-
 import java.io.PrintWriter
 import java.lang.Math.max
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index bce5a15..e5d5ed4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.database.ContentObserver;
+import android.os.Handler;
 import android.provider.Settings;
 import android.util.ArrayMap;
 import android.view.accessibility.AccessibilityManager;
@@ -34,6 +35,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.statusbar.AlertingNotificationManager;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
@@ -79,8 +81,9 @@
         }
     }
 
-    public HeadsUpManager(@NonNull final Context context, HeadsUpManagerLogger logger) {
-        super(logger);
+    public HeadsUpManager(@NonNull final Context context, HeadsUpManagerLogger logger,
+            @Main Handler handler) {
+        super(logger, handler);
         mContext = context;
         mAccessibilityMgr = Dependency.get(AccessibilityManagerWrapper.class);
         mUiEventLogger = Dependency.get(UiEventLogger.class);
@@ -94,7 +97,7 @@
 
         mSnoozeLengthMs = Settings.Global.getInt(context.getContentResolver(),
                 SETTING_HEADS_UP_SNOOZE_LENGTH_MS, defaultSnoozeLengthMs);
-        ContentObserver settingsObserver = new ContentObserver(mHandler) {
+        ContentObserver settingsObserver = new ContentObserver(handler) {
             @Override
             public void onChange(boolean selfChange) {
                 final int packageSnoozeLengthMs = Settings.Global.getInt(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 846e07f..5eff8cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -45,6 +45,7 @@
 import android.provider.Settings;
 import android.telephony.TelephonyCallback;
 import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -63,9 +64,8 @@
 import com.android.settingslib.users.UserCreatingDialog;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.systemui.Dumpable;
+import com.android.systemui.GuestResetOrExitSessionReceiver;
 import com.android.systemui.GuestResumeSessionReceiver;
-import com.android.systemui.Prefs;
-import com.android.systemui.Prefs.Key;
 import com.android.systemui.R;
 import com.android.systemui.SystemUISecondaryUserService;
 import com.android.systemui.animation.DialogLaunchAnimator;
@@ -84,6 +84,7 @@
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.telephony.TelephonyListenerManager;
 import com.android.systemui.user.CreateUserActivity;
+import com.android.systemui.util.settings.GlobalSettings;
 import com.android.systemui.util.settings.SecureSettings;
 
 import java.io.PrintWriter;
@@ -121,6 +122,8 @@
     private final ArrayList<WeakReference<BaseUserAdapter>> mAdapters = new ArrayList<>();
     @VisibleForTesting
     final GuestResumeSessionReceiver mGuestResumeSessionReceiver;
+    @VisibleForTesting
+    final GuestResetOrExitSessionReceiver mGuestResetOrExitSessionReceiver;
     private final KeyguardStateController mKeyguardStateController;
     private final DeviceProvisionedController mDeviceProvisionedController;
     private final DevicePolicyManager mDevicePolicyManager;
@@ -144,6 +147,7 @@
     // When false, there won't be any visual affordance to add a new user from the keyguard even if
     // the user is unlocked
     private boolean mAddUsersFromLockScreen;
+    private boolean mUserSwitcherEnabled;
     @VisibleForTesting
     boolean mPauseRefreshUsers;
     private int mSecondaryUser = UserHandle.USER_NULL;
@@ -160,6 +164,7 @@
     private FalsingManager mFalsingManager;
     private View mView;
     private String mCreateSupervisedUserPackage;
+    private GlobalSettings mGlobalSettings;
 
     @Inject
     public UserSwitcherController(Context context,
@@ -177,13 +182,16 @@
             FalsingManager falsingManager,
             TelephonyListenerManager telephonyListenerManager,
             SecureSettings secureSettings,
+            GlobalSettings globalSettings,
             @Background Executor bgExecutor,
             @LongRunning Executor longRunningExecutor,
             @Main Executor uiExecutor,
             InteractionJankMonitor interactionJankMonitor,
             LatencyTracker latencyTracker,
             DumpManager dumpManager,
-            DialogLaunchAnimator dialogLaunchAnimator) {
+            DialogLaunchAnimator dialogLaunchAnimator,
+            GuestResumeSessionReceiver guestResumeSessionReceiver,
+            GuestResetOrExitSessionReceiver guestResetOrExitSessionReceiver) {
         mContext = context;
         mActivityManager = activityManager;
         mUserTracker = userTracker;
@@ -194,14 +202,14 @@
         mFalsingManager = falsingManager;
         mInteractionJankMonitor = interactionJankMonitor;
         mLatencyTracker = latencyTracker;
-        mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(
-                this, mUserTracker, mUiEventLogger, secureSettings);
+        mGuestResumeSessionReceiver = guestResumeSessionReceiver;
+        mGuestResetOrExitSessionReceiver = guestResetOrExitSessionReceiver;
+        mGlobalSettings = globalSettings;
         mBgExecutor = bgExecutor;
         mLongRunningExecutor = longRunningExecutor;
         mUiExecutor = uiExecutor;
-        if (!UserManager.isGuestUserEphemeral()) {
-            mGuestResumeSessionReceiver.register(mBroadcastDispatcher);
-        }
+        mGuestResumeSessionReceiver.register();
+        mGuestResetOrExitSessionReceiver.register();
         mGuestUserAutoCreated = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_guestUserAutoCreated);
         mGuestIsResetting = new AtomicBoolean();
@@ -237,8 +245,10 @@
             @Override
             public void onChange(boolean selfChange) {
                 mSimpleUserSwitcher = shouldUseSimpleUserSwitcher();
-                mAddUsersFromLockScreen = Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.ADD_USERS_WHEN_LOCKED, 0) != 0;
+                mAddUsersFromLockScreen = mGlobalSettings.getIntForUser(
+                        Settings.Global.ADD_USERS_WHEN_LOCKED, 0, UserHandle.USER_SYSTEM) != 0;
+                mUserSwitcherEnabled = mGlobalSettings.getIntForUser(
+                        Settings.Global.USER_SWITCHER_ENABLED, 0, UserHandle.USER_SYSTEM) != 0;
                 refreshUsers(UserHandle.USER_NULL);
             };
         };
@@ -246,6 +256,9 @@
                 Settings.Global.getUriFor(SIMPLE_USER_SWITCHER_GLOBAL_SETTING), true,
                 mSettingsObserver);
         mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.USER_SWITCHER_ENABLED), true,
+                mSettingsObserver);
+        mContext.getContentResolver().registerContentObserver(
                 Settings.Global.getUriFor(Settings.Global.ADD_USERS_WHEN_LOCKED), true,
                 mSettingsObserver);
         mContext.getContentResolver().registerContentObserver(
@@ -266,6 +279,10 @@
         refreshUsers(UserHandle.USER_NULL);
     }
 
+    private static boolean isEnableGuestModeUxChanges(Context context) {
+        return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_GUEST_MODE_UX_CHANGES);
+    }
+
     /**
      * Refreshes users from UserManager.
      *
@@ -314,6 +331,10 @@
             for (UserInfo info : infos) {
                 boolean isCurrent = currentId == info.id;
                 boolean switchToEnabled = canSwitchUsers || isCurrent;
+                if (!mUserSwitcherEnabled && !info.isPrimary()) {
+                    continue;
+                }
+
                 if (info.isEnabled()) {
                     if (info.isGuest()) {
                         // Tapping guest icon triggers remove and a user switch therefore
@@ -340,9 +361,6 @@
                     }
                 }
             }
-            if (records.size() > 1 || guestRecord != null) {
-                Prefs.putBoolean(mContext, Key.SEEN_MULTI_USER, true);
-            }
 
             if (guestRecord == null) {
                 if (mGuestUserAutoCreated) {
@@ -411,12 +429,14 @@
     }
 
     boolean canCreateGuest(boolean hasExistingGuest) {
-        return (currentUserCanCreateUsers() || anyoneCanCreateUsers())
+        return mUserSwitcherEnabled
+                && (currentUserCanCreateUsers() || anyoneCanCreateUsers())
                 && !hasExistingGuest;
     }
 
     boolean canCreateUser() {
-        return (currentUserCanCreateUsers() || anyoneCanCreateUsers())
+        return mUserSwitcherEnabled
+                && (currentUserCanCreateUsers() || anyoneCanCreateUsers())
                 && mUserManager.canAddMoreUsers(UserManager.USER_TYPE_FULL_SECONDARY);
     }
 
@@ -509,20 +529,31 @@
 
     private void onUserListItemClicked(int id, UserRecord record, DialogShower dialogShower) {
         int currUserId = mUserTracker.getUserId();
+        // If switching from guest and guest is ephemeral, then follow the flow
+        // of showExitGuestDialog to remove current guest,
+        // and switch to selected user
+        UserInfo currUserInfo = mUserTracker.getUserInfo();
         if (currUserId == id) {
             if (record.isGuest) {
-                showExitGuestDialog(id, dialogShower);
+                showExitGuestDialog(id, currUserInfo.isEphemeral(), dialogShower);
             }
             return;
         }
-        if (UserManager.isGuestUserEphemeral()) {
-            // If switching from guest, we want to bring up the guest exit dialog instead of switching
-            UserInfo currUserInfo = mUserManager.getUserInfo(currUserId);
-            if (currUserInfo != null && currUserInfo.isGuest()) {
-                showExitGuestDialog(currUserId, record.resolveId(), dialogShower);
+
+        if (currUserInfo != null && currUserInfo.isGuest()) {
+            if (isEnableGuestModeUxChanges(mContext)) {
+                showExitGuestDialog(currUserId, currUserInfo.isEphemeral(),
+                        record.resolveId(), dialogShower);
                 return;
+            } else {
+                if (currUserInfo.isEphemeral()) {
+                    showExitGuestDialog(currUserId, currUserInfo.isEphemeral(),
+                            record.resolveId(), dialogShower);
+                    return;
+                }
             }
         }
+
         if (dialogShower != null) {
             // If we haven't morphed into another dialog, it means we have just switched users.
             // Then, dismiss the dialog.
@@ -544,7 +575,7 @@
         }
     }
 
-    private void showExitGuestDialog(int id, DialogShower dialogShower) {
+    private void showExitGuestDialog(int id, boolean isGuestEphemeral, DialogShower dialogShower) {
         int newId = UserHandle.USER_SYSTEM;
         if (mResumeUserOnGuestLogout && mLastNonGuestUser != UserHandle.USER_SYSTEM) {
             UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
@@ -552,14 +583,15 @@
                 newId = info.id;
             }
         }
-        showExitGuestDialog(id, newId, dialogShower);
+        showExitGuestDialog(id, isGuestEphemeral, newId, dialogShower);
     }
 
-    private void showExitGuestDialog(int id, int targetId, DialogShower dialogShower) {
+    private void showExitGuestDialog(int id, boolean isGuestEphemeral,
+                        int targetId, DialogShower dialogShower) {
         if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) {
             mExitGuestDialog.cancel();
         }
-        mExitGuestDialog = new ExitGuestDialog(mContext, id, targetId);
+        mExitGuestDialog = new ExitGuestDialog(mContext, id, isGuestEphemeral, targetId);
         if (dialogShower != null) {
             dialogShower.showDialog(mExitGuestDialog);
         } else {
@@ -792,6 +824,52 @@
         }
     }
 
+    /**
+     * Exits guest user and switches to previous non-guest user. The guest must be the current
+     * user.
+     *
+     * @param guestUserId user id of the guest user to exit
+     * @param targetUserId user id of the guest user to exit, set to UserHandle.USER_NULL when
+     *                       target user id is not known
+     * @param forceRemoveGuestOnExit true: remove guest before switching user,
+     *                               false: remove guest only if its ephemeral, else keep guest
+     */
+    public void exitGuestUser(@UserIdInt int guestUserId, @UserIdInt int targetUserId,
+                    boolean forceRemoveGuestOnExit) {
+        UserInfo currentUser = mUserTracker.getUserInfo();
+        if (currentUser.id != guestUserId) {
+            Log.w(TAG, "User requesting to start a new session (" + guestUserId + ")"
+                    + " is not current user (" + currentUser.id + ")");
+            return;
+        }
+        if (!currentUser.isGuest()) {
+            Log.w(TAG, "User requesting to start a new session (" + guestUserId + ")"
+                    + " is not a guest");
+            return;
+        }
+
+        int newUserId = UserHandle.USER_SYSTEM;
+        if (targetUserId == UserHandle.USER_NULL) {
+            // when target user is not specified switch to last non guest user
+            if (mResumeUserOnGuestLogout && mLastNonGuestUser != UserHandle.USER_SYSTEM) {
+                UserInfo info = mUserManager.getUserInfo(mLastNonGuestUser);
+                if (info != null && info.isEnabled() && info.supportsSwitchToByUser()) {
+                    newUserId = info.id;
+                }
+            }
+        } else {
+            newUserId = targetUserId;
+        }
+
+        if (currentUser.isEphemeral() || forceRemoveGuestOnExit) {
+            mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE);
+            removeGuestUser(currentUser.id, newUserId);
+        } else {
+            mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_SWITCH);
+            switchToUserId(newUserId);
+        }
+    }
+
     private void scheduleGuestCreation() {
         if (!mGuestCreationScheduled.compareAndSet(false, true)) {
             return;
@@ -959,9 +1037,14 @@
         public String getName(Context context, UserRecord item) {
             if (item.isGuest) {
                 if (item.isCurrent) {
-                    return context.getString(mController.mGuestUserAutoCreated
+                    if (isEnableGuestModeUxChanges(context)) {
+                        return context.getString(
+                                com.android.settingslib.R.string.guest_exit_quick_settings_button);
+                    } else {
+                        return context.getString(mController.mGuestUserAutoCreated
                             ? com.android.settingslib.R.string.guest_reset_guest
                             : com.android.settingslib.R.string.guest_exit_guest);
+                    }
                 } else {
                     if (item.info != null) {
                         return context.getString(com.android.internal.R.string.guest_name);
@@ -978,8 +1061,13 @@
                                             ? com.android.settingslib.R.string.guest_resetting
                                             : com.android.internal.R.string.guest_name);
                         } else {
-                            return context.getString(
-                                    com.android.settingslib.R.string.guest_new_guest);
+                            if (isEnableGuestModeUxChanges(context)) {
+                                // we always show "guest" as string, instead of "add guest"
+                                return context.getString(com.android.internal.R.string.guest_name);
+                            } else {
+                                return context.getString(
+                                        com.android.settingslib.R.string.guest_new_guest);
+                            }
                         }
                     }
                 }
@@ -1001,7 +1089,11 @@
         protected static Drawable getIconDrawable(Context context, UserRecord item) {
             int iconRes;
             if (item.isAddUser) {
-                iconRes = R.drawable.ic_account_circle_filled;
+                if (isEnableGuestModeUxChanges(context)) {
+                    iconRes = R.drawable.ic_add;
+                } else {
+                    iconRes = R.drawable.ic_account_circle_filled;
+                }
             } else if (item.isGuest) {
                 iconRes = R.drawable.ic_account_circle;
             } else if (item.isAddSupervisedUser) {
@@ -1034,8 +1126,8 @@
     private boolean shouldUseSimpleUserSwitcher() {
         int defaultSimpleUserSwitcher = mContext.getResources().getBoolean(
                 com.android.internal.R.bool.config_expandLockScreenUserSwitcher) ? 1 : 0;
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                SIMPLE_USER_SWITCHER_GLOBAL_SETTING, defaultSimpleUserSwitcher) != 0;
+        return mGlobalSettings.getIntForUser(SIMPLE_USER_SWITCHER_GLOBAL_SETTING,
+                defaultSimpleUserSwitcher, UserHandle.USER_SYSTEM) != 0;
     }
 
     public void startActivity(Intent intent) {
@@ -1146,24 +1238,58 @@
 
         private final int mGuestId;
         private final int mTargetId;
+        private final boolean mIsGuestEphemeral;
 
-        public ExitGuestDialog(Context context, int guestId, int targetId) {
+        ExitGuestDialog(Context context, int guestId, boolean isGuestEphemeral,
+                    int targetId) {
             super(context);
-            setTitle(mGuestUserAutoCreated
-                    ? com.android.settingslib.R.string.guest_reset_guest_dialog_title
-                    : com.android.settingslib.R.string.guest_remove_guest_dialog_title);
-            setMessage(context.getString(R.string.guest_exit_guest_dialog_message));
-            setButton(DialogInterface.BUTTON_NEUTRAL,
-                    context.getString(android.R.string.cancel), this);
-            setButton(DialogInterface.BUTTON_POSITIVE,
-                    context.getString(mGuestUserAutoCreated
+            if (isEnableGuestModeUxChanges(context)) {
+                if (isGuestEphemeral) {
+                    setTitle(context.getString(
+                                com.android.settingslib.R.string.guest_exit_dialog_title));
+                    setMessage(context.getString(
+                                com.android.settingslib.R.string.guest_exit_dialog_message));
+                    setButton(DialogInterface.BUTTON_NEUTRAL,
+                            context.getString(android.R.string.cancel), this);
+                    setButton(DialogInterface.BUTTON_POSITIVE,
+                            context.getString(
+                                com.android.settingslib.R.string.guest_exit_dialog_button), this);
+                } else {
+                    setTitle(context.getString(
+                                com.android.settingslib
+                                    .R.string.guest_exit_dialog_title_non_ephemeral));
+                    setMessage(context.getString(
+                                com.android.settingslib
+                                    .R.string.guest_exit_dialog_message_non_ephemeral));
+                    setButton(DialogInterface.BUTTON_NEUTRAL,
+                            context.getString(android.R.string.cancel), this);
+                    setButton(DialogInterface.BUTTON_NEGATIVE,
+                            context.getString(
+                                com.android.settingslib.R.string.guest_exit_clear_data_button),
+                            this);
+                    setButton(DialogInterface.BUTTON_POSITIVE,
+                            context.getString(
+                                com.android.settingslib.R.string.guest_exit_save_data_button),
+                            this);
+                }
+            } else {
+                setTitle(mGuestUserAutoCreated
+                        ? com.android.settingslib.R.string.guest_reset_guest_dialog_title
+                        : com.android.settingslib.R.string.guest_remove_guest_dialog_title);
+                setMessage(context.getString(R.string.guest_exit_guest_dialog_message));
+                setButton(DialogInterface.BUTTON_NEUTRAL,
+                        context.getString(android.R.string.cancel), this);
+                setButton(DialogInterface.BUTTON_POSITIVE,
+                        context.getString(mGuestUserAutoCreated
                             ? com.android.settingslib.R.string.guest_reset_guest_confirm_button
                             : com.android.settingslib.R.string.guest_remove_guest_confirm_button),
-                    this);
+                        this);
+            }
             SystemUIDialog.setWindowOnTop(this, mKeyguardStateController.isShowing());
             setCanceledOnTouchOutside(false);
             mGuestId = guestId;
             mTargetId = targetId;
+            mIsGuestEphemeral = isGuestEphemeral;
         }
 
         @Override
@@ -1173,12 +1299,40 @@
             if (mFalsingManager.isFalseTap(penalty)) {
                 return;
             }
-            if (which == BUTTON_NEUTRAL) {
-                cancel();
+            if (isEnableGuestModeUxChanges(getContext())) {
+                if (mIsGuestEphemeral) {
+                    if (which == DialogInterface.BUTTON_POSITIVE) {
+                        mDialogLaunchAnimator.dismissStack(this);
+                        // Ephemeral guest: exit guest, guest is removed by the system
+                        // on exit, since its marked ephemeral
+                        exitGuestUser(mGuestId, mTargetId, false);
+                    } else if (which == DialogInterface.BUTTON_NEGATIVE) {
+                        // Cancel clicked, do nothing
+                        cancel();
+                    }
+                } else {
+                    if (which == DialogInterface.BUTTON_POSITIVE) {
+                        mDialogLaunchAnimator.dismissStack(this);
+                        // Non-ephemeral guest: exit guest, guest is not removed by the system
+                        // on exit, since its marked non-ephemeral
+                        exitGuestUser(mGuestId, mTargetId, false);
+                    } else if (which == DialogInterface.BUTTON_NEGATIVE) {
+                        mDialogLaunchAnimator.dismissStack(this);
+                        // Non-ephemeral guest: remove guest and then exit
+                        exitGuestUser(mGuestId, mTargetId, true);
+                    } else if (which == DialogInterface.BUTTON_NEUTRAL) {
+                        // Cancel clicked, do nothing
+                        cancel();
+                    }
+                }
             } else {
-                mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE);
-                mDialogLaunchAnimator.dismissStack(this);
-                removeGuestUser(mGuestId, mTargetId);
+                if (which == BUTTON_NEUTRAL) {
+                    cancel();
+                } else {
+                    mUiEventLogger.log(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE);
+                    mDialogLaunchAnimator.dismissStack(this);
+                    removeGuestUser(mGuestId, mTargetId);
+                }
             }
         }
     }
@@ -1187,10 +1341,17 @@
     final class AddUserDialog extends SystemUIDialog implements
             DialogInterface.OnClickListener {
 
-        public AddUserDialog(Context context) {
+        AddUserDialog(Context context) {
             super(context);
+
             setTitle(com.android.settingslib.R.string.user_add_user_title);
-            setMessage(com.android.settingslib.R.string.user_add_user_message_short);
+            String message = context.getString(
+                                com.android.settingslib.R.string.user_add_user_message_short);
+            UserInfo currentUser = mUserTracker.getUserInfo();
+            if (currentUser != null && currentUser.isGuest() && currentUser.isEphemeral()) {
+                message += context.getString(R.string.user_add_user_message_guest_remove);
+            }
+            setMessage(message);
             setButton(DialogInterface.BUTTON_NEUTRAL,
                     context.getString(android.R.string.cancel), this);
             setButton(DialogInterface.BUTTON_POSITIVE,
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index b7f90a4..c92491e 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -169,7 +169,8 @@
             KeyguardBypassController bypassController,
             GroupMembershipManager groupManager,
             VisualStabilityProvider visualStabilityProvider,
-            ConfigurationController configurationController) {
+            ConfigurationController configurationController,
+            @Main Handler handler) {
         return new HeadsUpManagerPhone(
                 context,
                 headsUpManagerLogger,
@@ -177,7 +178,8 @@
                 bypassController,
                 groupManager,
                 visualStabilityProvider,
-                configurationController
+                configurationController,
+                handler
         );
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/TextInterpolatorTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/TextInterpolatorTest.kt
index e42d537..603cf3b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/TextInterpolatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/TextInterpolatorTest.kt
@@ -18,6 +18,7 @@
 
 import android.graphics.Bitmap
 import android.graphics.Canvas
+import android.graphics.Color
 import android.graphics.Typeface
 import android.graphics.fonts.Font
 import android.graphics.fonts.FontFamily
@@ -194,6 +195,128 @@
 
         assertThat(expected.sameAs(actual)).isTrue()
     }
+
+    @Test
+    fun testGlyphCallback_Empty() {
+        val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
+
+        val interp = TextInterpolator(layout).apply {
+            glyphFilter = { glyph, progress ->
+            }
+        }
+        interp.basePaint.set(START_PAINT)
+        interp.onBasePaintModified()
+
+        interp.targetPaint.set(END_PAINT)
+        interp.onTargetPaintModified()
+
+        // Just after created TextInterpolator, it should have 0 progress.
+        val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
+        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+                .toBitmap(BMP_WIDTH, BMP_HEIGHT)
+
+        assertThat(expected.sameAs(actual)).isTrue()
+    }
+
+    @Test
+    fun testGlyphCallback_Xcoordinate() {
+        val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
+
+        val interp = TextInterpolator(layout).apply {
+            glyphFilter = { glyph, progress ->
+                glyph.x += 30f
+            }
+        }
+        interp.basePaint.set(START_PAINT)
+        interp.onBasePaintModified()
+
+        interp.targetPaint.set(END_PAINT)
+        interp.onTargetPaintModified()
+
+        // Just after created TextInterpolator, it should have 0 progress.
+        val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
+        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+                .toBitmap(BMP_WIDTH, BMP_HEIGHT)
+
+        // The glyph position was modified by callback, so the bitmap should not be the same.
+        // We cannot modify the result of StaticLayout, so we cannot expect the exact  bitmaps.
+        assertThat(expected.sameAs(actual)).isFalse()
+    }
+
+    @Test
+    fun testGlyphCallback_Ycoordinate() {
+        val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
+
+        val interp = TextInterpolator(layout).apply {
+            glyphFilter = { glyph, progress ->
+                glyph.y += 30f
+            }
+        }
+        interp.basePaint.set(START_PAINT)
+        interp.onBasePaintModified()
+
+        interp.targetPaint.set(END_PAINT)
+        interp.onTargetPaintModified()
+
+        // Just after created TextInterpolator, it should have 0 progress.
+        val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
+        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+                .toBitmap(BMP_WIDTH, BMP_HEIGHT)
+
+        // The glyph position was modified by callback, so the bitmap should not be the same.
+        // We cannot modify the result of StaticLayout, so we cannot expect the exact  bitmaps.
+        assertThat(expected.sameAs(actual)).isFalse()
+    }
+
+    @Test
+    fun testGlyphCallback_TextSize() {
+        val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
+
+        val interp = TextInterpolator(layout).apply {
+            glyphFilter = { glyph, progress ->
+                glyph.textSize += 10f
+            }
+        }
+        interp.basePaint.set(START_PAINT)
+        interp.onBasePaintModified()
+
+        interp.targetPaint.set(END_PAINT)
+        interp.onTargetPaintModified()
+
+        // Just after created TextInterpolator, it should have 0 progress.
+        val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
+        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+                .toBitmap(BMP_WIDTH, BMP_HEIGHT)
+
+        // The glyph position was modified by callback, so the bitmap should not be the same.
+        // We cannot modify the result of StaticLayout, so we cannot expect the exact  bitmaps.
+        assertThat(expected.sameAs(actual)).isFalse()
+    }
+
+    @Test
+    fun testGlyphCallback_Color() {
+        val layout = makeLayout(BIDI_TEXT, PAINT, TextDirectionHeuristics.RTL)
+
+        val interp = TextInterpolator(layout).apply {
+            glyphFilter = { glyph, progress ->
+                glyph.color = Color.RED
+            }
+        }
+        interp.basePaint.set(START_PAINT)
+        interp.onBasePaintModified()
+
+        interp.targetPaint.set(END_PAINT)
+        interp.onTargetPaintModified()
+
+        // Just after created TextInterpolator, it should have 0 progress.
+        val actual = interp.toBitmap(BMP_WIDTH, BMP_HEIGHT)
+        val expected = makeLayout(BIDI_TEXT, START_PAINT, TextDirectionHeuristics.RTL)
+                .toBitmap(BMP_WIDTH, BMP_HEIGHT)
+
+        // The glyph position was modified by callback, so the bitmap should not be the same.
+        // We cannot modify the result of StaticLayout, so we cannot expect the exact  bitmaps.
+        assertThat(expected.sameAs(actual)).isFalse()
+    }
 }
 
 private fun Layout.toBitmap(width: Int, height: Int) =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
index 8a38847..65d0adc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
@@ -83,12 +83,10 @@
     private final class TestableAlertingNotificationManager extends AlertingNotificationManager {
         private AlertEntry mLastCreatedEntry;
 
-        private TestableAlertingNotificationManager() {
-            super(mock(HeadsUpManagerLogger.class));
+        private TestableAlertingNotificationManager(Handler handler) {
+            super(mock(HeadsUpManagerLogger.class), handler);
             mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
             mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
-            mHandler.removeCallbacksAndMessages(null);
-            mHandler = mTestHandler;
         }
 
         @Override
@@ -109,8 +107,8 @@
         }
     }
 
-    protected AlertingNotificationManager createAlertingNotificationManager() {
-        return new TestableAlertingNotificationManager();
+    protected AlertingNotificationManager createAlertingNotificationManager(Handler handler) {
+        return new TestableAlertingNotificationManager(handler);
     }
 
     protected StatusBarNotification createNewSbn(int id, Notification.Builder n) {
@@ -144,7 +142,7 @@
                 .build();
         mEntry.setRow(mRow);
 
-        mAlertingNotificationManager = createAlertingNotificationManager();
+        mAlertingNotificationManager = createAlertingNotificationManager(mTestHandler);
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index a2a02cd..30c01b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -816,8 +816,11 @@
         mExecutor.runAllReady();
         reset(mRotateTextViewController);
 
-        // GIVEN keyguard is showing
+        // GIVEN keyguard is showing and not dozing
         when(mKeyguardStateController.isShowing()).thenReturn(true);
+        mController.setVisible(true);
+        mExecutor.runAllReady();
+        reset(mRotateTextViewController);
 
         // WHEN keyguard showing changed called
         mKeyguardStateControllerCallback.onKeyguardShowingChanged();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
index 52bacd2..d8a98d1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
@@ -29,12 +29,12 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider;
 import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index 3b034f7..fc74f39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -41,7 +41,6 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.RankingBuilder;
-import com.android.systemui.statusbar.notification.SectionClassifier;
 import com.android.systemui.statusbar.notification.collection.GroupEntry;
 import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
@@ -56,6 +55,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
 import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn;
 import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
 
@@ -96,9 +96,9 @@
     @Mock private IStatusBarService mService;
     @Mock private BindEventManagerImpl mBindEventManagerImpl;
     @Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
-    private final SectionClassifier mSectionClassifier = new SectionClassifier();
+    private final SectionStyleProvider mSectionStyleProvider = new SectionStyleProvider();
     private final NotifUiAdjustmentProvider mAdjustmentProvider =
-            new NotifUiAdjustmentProvider(mSectionClassifier);
+            new NotifUiAdjustmentProvider(mSectionStyleProvider);
 
     @NonNull
     private NotificationEntryBuilder getNotificationEntryBuilder() {
@@ -487,7 +487,7 @@
     private static final int TEST_MAX_GROUP_DELAY = 100;
 
     private void setSectionIsLowPriority(boolean minimized) {
-        mSectionClassifier.setMinimizedSections(minimized
+        mSectionStyleProvider.setMinimizedSections(minimized
                 ? Collections.singleton(mNotifSection.getSectioner())
                 : Collections.emptyList());
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
index f4d8405..ff08bc3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
@@ -40,7 +40,6 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.RankingBuilder;
 import com.android.systemui.statusbar.SbnBuilder;
-import com.android.systemui.statusbar.notification.SectionClassifier;
 import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -48,6 +47,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
 import com.android.systemui.statusbar.notification.collection.render.NodeController;
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
 
@@ -68,7 +68,7 @@
 
     @Mock private StatusBarStateController mStatusBarStateController;
     @Mock private HighPriorityProvider mHighPriorityProvider;
-    @Mock private SectionClassifier mSectionClassifier;
+    @Mock private SectionStyleProvider mSectionStyleProvider;
     @Mock private NotifPipeline mNotifPipeline;
     @Mock private NodeController mAlertingHeaderController;
     @Mock private NodeController mSilentNodeController;
@@ -92,7 +92,7 @@
         mRankingCoordinator = new RankingCoordinator(
                 mStatusBarStateController,
                 mHighPriorityProvider,
-                mSectionClassifier,
+                mSectionStyleProvider,
                 mAlertingHeaderController,
                 mSilentHeaderController,
                 mSilentNodeController);
@@ -100,7 +100,7 @@
         mEntry.setRanking(getRankingForUnfilteredNotif().build());
 
         mRankingCoordinator.attach(mNotifPipeline);
-        verify(mSectionClassifier).setMinimizedSections(any());
+        verify(mSectionStyleProvider).setMinimizedSections(any());
         verify(mNotifPipeline, times(2)).addPreGroupFilter(mNotifFilterCaptor.capture());
         mCapturedSuspendedFilter = mNotifFilterCaptor.getAllValues().get(0);
         mCapturedDozingFilter = mNotifFilterCaptor.getAllValues().get(1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
index 447ba15..40859d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
@@ -21,13 +21,13 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.notification.AssistantFeedbackController
 import com.android.systemui.statusbar.notification.FeedbackIcon
-import com.android.systemui.statusbar.notification.SectionClassifier
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
 import com.android.systemui.statusbar.notification.collection.render.NotifRowController
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
@@ -53,7 +53,7 @@
 
     @Mock private lateinit var pipeline: NotifPipeline
     @Mock private lateinit var assistantFeedbackController: AssistantFeedbackController
-    @Mock private lateinit var sectionClassifier: SectionClassifier
+    @Mock private lateinit var sectionStyleProvider: SectionStyleProvider
 
     @Mock private lateinit var section1: NotifSection
     @Mock private lateinit var section2: NotifSection
@@ -66,7 +66,7 @@
         coordinator = RowAppearanceCoordinator(
             mContext,
             assistantFeedbackController,
-            sectionClassifier
+            sectionStyleProvider
         )
         coordinator.attach(pipeline)
         beforeRenderListListener = withArgCaptor {
@@ -82,8 +82,8 @@
 
     @Test
     fun testSetSystemExpandedOnlyOnFirst() {
-        whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(false)
-        whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(false)
+        whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(false)
+        whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(false)
         beforeRenderListListener.onBeforeRenderList(listOf(entry1, entry2))
         afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
         verify(controller1).setSystemExpanded(eq(true))
@@ -93,8 +93,8 @@
 
     @Test
     fun testSetSystemExpandedNeverIfMinimized() {
-        whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(true)
-        whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(true)
+        whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(true)
+        whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(true)
         beforeRenderListListener.onBeforeRenderList(listOf(entry1, entry2))
         afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
         verify(controller1).setSystemExpanded(eq(false))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
index 0e18658..ff60193 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
@@ -19,7 +19,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
 import com.android.systemui.statusbar.notification.collection.ListEntry
@@ -28,6 +27,7 @@
 import com.android.systemui.statusbar.notification.collection.getAttachState
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
 import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
 import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
 import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 1ecb09b..3d57f66 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -144,10 +144,9 @@
                 mock(KeyguardBypassController.class),
                 mock(NotificationGroupManagerLegacy.class),
                 mock(VisualStabilityProvider.class),
-                mock(ConfigurationControllerImpl.class)
+                mock(ConfigurationControllerImpl.class),
+                new Handler(mTestLooper.getLooper())
         );
-        mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
-        mHeadsUpManager.mHandler = new Handler(mTestLooper.getLooper());
         mGroupMembershipManager.setHeadsUpManager(mHeadsUpManager);
         mIconManager = new IconManager(
                 mock(CommonNotifCollection.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index db5741c..b8c8b5f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
+import android.os.Handler;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.view.View;
@@ -76,7 +77,8 @@
                 VisualStabilityProvider visualStabilityProvider,
                 StatusBarStateController statusBarStateController,
                 KeyguardBypassController keyguardBypassController,
-                ConfigurationController configurationController
+                ConfigurationController configurationController,
+                Handler handler
         ) {
             super(
                     context,
@@ -85,7 +87,8 @@
                     keyguardBypassController,
                     groupManager,
                     visualStabilityProvider,
-                    configurationController
+                    configurationController,
+                    handler
             );
             mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
             mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
@@ -105,6 +108,8 @@
         when(mVSProvider.isReorderingAllowed()).thenReturn(true);
         mDependency.injectMockDependency(NotificationShadeWindowController.class);
         mDependency.injectMockDependency(ConfigurationController.class);
+        super.setUp();
+
         mHeadsUpManager = new TestableHeadsUpManagerPhone(
                 mContext,
                 mHeadsUpManagerLogger,
@@ -112,11 +117,9 @@
                 mVSProvider,
                 mStatusBarStateController,
                 mBypassController,
-                mConfigurationController
+                mConfigurationController,
+                mTestHandler
         );
-        super.setUp();
-        mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
-        mHeadsUpManager.mHandler = mTestHandler;
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
index 7070bc1..56dfb0c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.Notification;
+import android.os.Handler;
 import android.service.notification.StatusBarNotification;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -51,7 +52,6 @@
 import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
 import com.android.wm.shell.bubbles.Bubbles;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -89,7 +89,8 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        mHeadsUpManager = new HeadsUpManager(mContext, mock(HeadsUpManagerLogger.class)) {};
+        mHeadsUpManager = new HeadsUpManager(mContext, mock(HeadsUpManagerLogger.class),
+                mock(Handler.class)) {};
 
         when(mNotificationEntryManager.getPendingNotificationsIterator())
                 .thenReturn(mPendingEntries.values());
@@ -114,11 +115,6 @@
         mHeadsUpManager.addListener(mGroupAlertTransferHelper);
     }
 
-    @After
-    public void tearDown() {
-        mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
-    }
-
     private void mockHasHeadsUpContentView(NotificationEntry entry,
             boolean hasHeadsUpContentView) {
         RowContentBindParams params = new RowContentBindParams();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
index 424a40058..f39d687 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
@@ -36,6 +36,7 @@
 import android.app.Person;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Handler;
 import android.service.notification.StatusBarNotification;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -73,8 +74,8 @@
     @Mock private HeadsUpManagerLogger mLogger;
 
     private final class TestableHeadsUpManager extends HeadsUpManager {
-        TestableHeadsUpManager(Context context, HeadsUpManagerLogger logger) {
-            super(context, logger);
+        TestableHeadsUpManager(Context context, HeadsUpManagerLogger logger, Handler handler) {
+            super(context, logger, handler);
             mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
             mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
         }
@@ -91,10 +92,9 @@
         mDependency.injectTestDependency(UiEventLogger.class, mUiEventLoggerFake);
         when(mEntry.getSbn()).thenReturn(mSbn);
         when(mSbn.getNotification()).thenReturn(mNotification);
-        mHeadsUpManager = new TestableHeadsUpManager(mContext, mLogger);
+
         super.setUp();
-        mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
-        mHeadsUpManager.mHandler = mTestHandler;
+        mHeadsUpManager = new TestableHeadsUpManager(mContext, mLogger, mTestHandler);
     }
 
     @After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
index 799dafc..152815f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.policy
 
 import android.app.IActivityManager
+import android.app.NotificationManager
 import android.app.admin.DevicePolicyManager
 import android.content.Context
 import android.content.DialogInterface
@@ -28,6 +29,7 @@
 import android.os.Handler
 import android.os.UserHandle
 import android.os.UserManager
+import android.provider.Settings
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.ThreadedRenderer
@@ -36,7 +38,9 @@
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.util.LatencyTracker
 import com.android.internal.util.UserIcons
+import com.android.systemui.GuestResetOrExitSessionReceiver
 import com.android.systemui.GuestResumeSessionReceiver
+import com.android.systemui.GuestSessionNotification
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogLaunchAnimator
@@ -51,6 +55,7 @@
 import com.android.systemui.statusbar.phone.NotificationShadeWindowView
 import com.android.systemui.telephony.TelephonyListenerManager
 import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.settings.GlobalSettings
 import com.android.systemui.util.settings.SecureSettings
 import com.android.systemui.util.time.FakeSystemClock
 import org.junit.Assert.assertEquals
@@ -67,6 +72,7 @@
 import org.mockito.Mockito.any
 import org.mockito.Mockito.doNothing
 import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.eq
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
@@ -95,6 +101,12 @@
     @Mock private lateinit var notificationShadeWindowView: NotificationShadeWindowView
     @Mock private lateinit var threadedRenderer: ThreadedRenderer
     @Mock private lateinit var dialogLaunchAnimator: DialogLaunchAnimator
+    @Mock private lateinit var globalSettings: GlobalSettings
+    @Mock private lateinit var guestSessionNotification: GuestSessionNotification
+    @Mock private lateinit var guestResetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
+    private lateinit var resetSessionDialogFactory:
+                            GuestResumeSessionReceiver.ResetSessionDialog.Factory
+    private lateinit var guestResumeSessionReceiver: GuestResumeSessionReceiver
     private lateinit var testableLooper: TestableLooper
     private lateinit var bgExecutor: FakeExecutor
     private lateinit var longRunningExecutor: FakeExecutor
@@ -126,9 +138,28 @@
                 com.android.internal.R.bool.config_guestUserAutoCreated, false)
 
         mContext.addMockSystemService(Context.FACE_SERVICE, mock(FaceManager::class.java))
+        mContext.addMockSystemService(Context.NOTIFICATION_SERVICE,
+                mock(NotificationManager::class.java))
         mContext.addMockSystemService(Context.FINGERPRINT_SERVICE,
                 mock(FingerprintManager::class.java))
 
+        resetSessionDialogFactory = object : GuestResumeSessionReceiver.ResetSessionDialog.Factory {
+                override fun create(userId: Int): GuestResumeSessionReceiver.ResetSessionDialog {
+                    return GuestResumeSessionReceiver.ResetSessionDialog(
+                                mContext,
+                                mock(UserSwitcherController::class.java),
+                                uiEventLogger,
+                                userId
+                            )
+                }
+            }
+
+        guestResumeSessionReceiver = GuestResumeSessionReceiver(userTracker,
+                                        secureSettings,
+                                        broadcastDispatcher,
+                                        guestSessionNotification,
+                                        resetSessionDialogFactory)
+
         `when`(userManager.canAddMoreUsers(eq(UserManager.USER_TYPE_FULL_SECONDARY)))
                 .thenReturn(true)
         `when`(notificationShadeWindowView.context).thenReturn(context)
@@ -148,6 +179,22 @@
         `when`(userTracker.userId).thenReturn(ownerId)
         `when`(userTracker.userInfo).thenReturn(ownerInfo)
 
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.ADD_USERS_WHEN_LOCKED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(0)
+
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.USER_SWITCHER_ENABLED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(1)
+
         setupController()
     }
 
@@ -168,13 +215,16 @@
                 falsingManager,
                 telephonyListenerManager,
                 secureSettings,
+                globalSettings,
                 bgExecutor,
                 longRunningExecutor,
                 uiExecutor,
                 interactionJankMonitor,
                 latencyTracker,
                 dumpManager,
-                dialogLaunchAnimator)
+                dialogLaunchAnimator,
+                guestResumeSessionReceiver,
+                guestResetOrExitSessionReceiver)
         userSwitcherController.init(notificationShadeWindowView)
     }
 
@@ -264,7 +314,10 @@
                 .getButton(DialogInterface.BUTTON_POSITIVE).performClick()
         testableLooper.processAllMessages()
         assertEquals(1, uiEventLogger.numLogs())
-        assertEquals(QSUserSwitcherEvent.QS_USER_GUEST_REMOVE.id, uiEventLogger.eventId(0))
+        assertTrue(
+            QSUserSwitcherEvent.QS_USER_GUEST_REMOVE.id == uiEventLogger.eventId(0) ||
+            QSUserSwitcherEvent.QS_USER_SWITCH.id == uiEventLogger.eventId(0)
+        )
     }
 
     @Test
@@ -326,7 +379,7 @@
         userSwitcherController.onUserListItemClicked(currentGuestUserRecord, null)
         assertNotNull(userSwitcherController.mExitGuestDialog)
         userSwitcherController.mExitGuestDialog
-                .getButton(DialogInterface.BUTTON_NEGATIVE).performClick()
+                .getButton(DialogInterface.BUTTON_NEUTRAL).performClick()
         testableLooper.processAllMessages()
         assertEquals(0, uiEventLogger.numLogs())
     }
@@ -469,4 +522,43 @@
         // THEN a supervised user can NOT be constructed
         assertFalse(userSwitcherController.canCreateSupervisedUser())
     }
+
+    @Test
+    fun testCannotCreateUserWhenUserSwitcherDisabled() {
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.USER_SWITCHER_ENABLED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(0)
+        setupController()
+        assertFalse(userSwitcherController.canCreateUser())
+    }
+
+    @Test
+    fun testCannotCreateGuestUserWhenUserSwitcherDisabled() {
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.USER_SWITCHER_ENABLED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(0)
+        setupController()
+        assertFalse(userSwitcherController.canCreateGuest(false))
+    }
+
+    @Test
+    fun testCannotCreateSupervisedUserWhenUserSwitcherDisabled() {
+        `when`(
+            globalSettings.getIntForUser(
+                eq(Settings.Global.USER_SWITCHER_ENABLED),
+                anyInt(),
+                eq(UserHandle.USER_SYSTEM)
+            )
+        ).thenReturn(0)
+        setupController()
+        assertFalse(userSwitcherController.canCreateSupervisedUser())
+    }
 }
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index dfa34bb..4ca83dd 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -286,6 +286,11 @@
     // Package: android
     NOTE_MTE_OVERRIDE_ENABLED = 69;
 
+    // Notify the user that this is a guest session with information
+    // about first login and ephemeral state
+    // Package: android
+    NOTE_GUEST_SESSION = 70;
+
     // Inform the user of notification permissions changes.
     // Package: android
     NOTE_REVIEW_NOTIFICATION_PERMISSIONS = 71;
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index 2cf0e3e..9a257e5 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -45,6 +45,7 @@
 import android.graphics.Region;
 import android.os.Handler;
 import android.util.DisplayMetrics;
+import android.util.Log;
 import android.util.Slog;
 import android.view.Display;
 import android.view.InputDevice;
@@ -84,12 +85,14 @@
 public class TouchExplorer extends BaseEventStreamTransformation
         implements GestureManifold.Listener {
 
-    static final boolean DEBUG = false;
     private static final long LOGGING_FLAGS = FLAGS_GESTURE | FLAGS_INPUT_FILTER;
 
     // Tag for logging received events.
     private static final String LOG_TAG = "TouchExplorer";
 
+    // To enable these logs, run: 'adb shell setprop log.tag.TouchExplorer DEBUG' (requires restart)
+    static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
+
     // The maximum of the cosine between the vectors of two moving
     // pointers so they can be considered moving in the same direction.
     private static final float MAX_DRAGGING_ANGLE_COS = 0.525321989f; // cos(pi/4)
diff --git a/services/autofill/java/com/android/server/autofill/ClientSuggestionsSession.java b/services/autofill/java/com/android/server/autofill/ClientSuggestionsSession.java
new file mode 100644
index 0000000..715697d
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/ClientSuggestionsSession.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.autofill;
+
+import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
+
+import static com.android.server.autofill.Helper.sVerbose;
+
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.AppGlobals;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.ICancellationSignal;
+import android.os.RemoteException;
+import android.service.autofill.Dataset;
+import android.service.autofill.FillResponse;
+import android.service.autofill.IFillCallback;
+import android.service.autofill.SaveInfo;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.Slog;
+import android.view.autofill.AutofillId;
+import android.view.autofill.IAutoFillManagerClient;
+import android.view.inputmethod.InlineSuggestionsRequest;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.infra.AndroidFuture;
+
+import java.util.List;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Maintains a client suggestions session with the
+ * {@link android.view.autofill.AutofillRequestCallback} through the {@link IAutoFillManagerClient}.
+ *
+ */
+final class ClientSuggestionsSession {
+
+    private static final String TAG = "ClientSuggestionsSession";
+    private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 15 * DateUtils.SECOND_IN_MILLIS;
+
+    private final int mSessionId;
+    private final IAutoFillManagerClient mClient;
+    private final Handler mHandler;
+    private final ComponentName mComponentName;
+
+    private final RemoteFillService.FillServiceCallbacks mCallbacks;
+
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private AndroidFuture<FillResponse> mPendingFillRequest;
+    @GuardedBy("mLock")
+    private int mPendingFillRequestId = INVALID_REQUEST_ID;
+
+    ClientSuggestionsSession(int sessionId, IAutoFillManagerClient client, Handler handler,
+            ComponentName componentName, RemoteFillService.FillServiceCallbacks callbacks) {
+        mSessionId = sessionId;
+        mClient = client;
+        mHandler = handler;
+        mComponentName = componentName;
+        mCallbacks = callbacks;
+    }
+
+    void onFillRequest(int requestId, InlineSuggestionsRequest inlineRequest, int flags) {
+        final AtomicReference<ICancellationSignal> cancellationSink = new AtomicReference<>();
+        final AtomicReference<AndroidFuture<FillResponse>> futureRef = new AtomicReference<>();
+        final AndroidFuture<FillResponse> fillRequest = new AndroidFuture<>();
+
+        mHandler.post(() -> {
+            if (sVerbose) {
+                Slog.v(TAG, "calling onFillRequest() for id=" + requestId);
+            }
+
+            try {
+                mClient.requestFillFromClient(requestId, inlineRequest,
+                        new FillCallbackImpl(fillRequest, futureRef, cancellationSink));
+            } catch (RemoteException e) {
+                fillRequest.completeExceptionally(e);
+            }
+        });
+
+        fillRequest.orTimeout(TIMEOUT_REMOTE_REQUEST_MILLIS, TimeUnit.MILLISECONDS);
+        futureRef.set(fillRequest);
+
+        synchronized (mLock) {
+            mPendingFillRequest = fillRequest;
+            mPendingFillRequestId = requestId;
+        }
+
+        fillRequest.whenComplete((res, err) -> mHandler.post(() -> {
+            synchronized (mLock) {
+                mPendingFillRequest = null;
+                mPendingFillRequestId = INVALID_REQUEST_ID;
+            }
+            if (err == null) {
+                processAutofillId(res);
+                mCallbacks.onFillRequestSuccess(requestId, res,
+                        mComponentName.getPackageName(), flags);
+            } else {
+                Slog.e(TAG, "Error calling on  client fill request", err);
+                if (err instanceof TimeoutException) {
+                    dispatchCancellationSignal(cancellationSink.get());
+                    mCallbacks.onFillRequestTimeout(requestId);
+                } else if (err instanceof CancellationException) {
+                    dispatchCancellationSignal(cancellationSink.get());
+                } else {
+                    mCallbacks.onFillRequestFailure(requestId, err.getMessage());
+                }
+            }
+        }));
+    }
+
+    /**
+     * Gets the application info for the component.
+     */
+    @Nullable
+    static ApplicationInfo getAppInfo(ComponentName comp, @UserIdInt int userId) {
+        try {
+            ApplicationInfo si = AppGlobals.getPackageManager().getApplicationInfo(
+                    comp.getPackageName(),
+                    PackageManager.GET_META_DATA,
+                    userId);
+            if (si != null) {
+                return si;
+            }
+        } catch (RemoteException e) {
+        }
+        return null;
+    }
+
+    /**
+     * Gets the user-visible name of the application.
+     */
+    @Nullable
+    @GuardedBy("mLock")
+    static CharSequence getAppLabelLocked(Context context, ApplicationInfo appInfo) {
+        return appInfo == null ? null : appInfo.loadSafeLabel(
+                context.getPackageManager(), 0 /* do not ellipsize */,
+                TextUtils.SAFE_STRING_FLAG_FIRST_LINE | TextUtils.SAFE_STRING_FLAG_TRIM);
+    }
+
+    /**
+     * Gets the user-visible icon of the application.
+     */
+    @Nullable
+    @GuardedBy("mLock")
+    static Drawable getAppIconLocked(Context context, ApplicationInfo appInfo) {
+        return appInfo == null ? null : appInfo.loadIcon(context.getPackageManager());
+    }
+
+    int cancelCurrentRequest() {
+        synchronized (mLock) {
+            return mPendingFillRequest != null && mPendingFillRequest.cancel(false)
+                    ? mPendingFillRequestId
+                    : INVALID_REQUEST_ID;
+        }
+    }
+
+    /**
+     * The {@link AutofillId} which the client gets from its view is not contain the session id,
+     * but Autofill framework is using the {@link AutofillId} with a session id. So before using
+     * those ids in the Autofill framework, applies the current session id.
+     *
+     * @param res which response need to apply for a session id
+     */
+    private void processAutofillId(FillResponse res) {
+        if (res == null) {
+            return;
+        }
+
+        final List<Dataset> datasets = res.getDatasets();
+        if (datasets != null && !datasets.isEmpty()) {
+            for (int i = 0; i < datasets.size(); i++) {
+                final Dataset dataset = datasets.get(i);
+                if (dataset != null) {
+                    applySessionId(dataset.getFieldIds());
+                }
+            }
+        }
+
+        final SaveInfo saveInfo = res.getSaveInfo();
+        if (saveInfo != null) {
+            applySessionId(saveInfo.getOptionalIds());
+            applySessionId(saveInfo.getRequiredIds());
+            applySessionId(saveInfo.getSanitizerValues());
+            applySessionId(saveInfo.getTriggerId());
+        }
+    }
+
+    private void applySessionId(List<AutofillId> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return;
+        }
+
+        for (int i = 0; i < ids.size(); i++) {
+            applySessionId(ids.get(i));
+        }
+    }
+
+    private void applySessionId(AutofillId[][] ids) {
+        if (ids == null) {
+            return;
+        }
+        for (int i = 0; i < ids.length; i++) {
+            applySessionId(ids[i]);
+        }
+    }
+
+    private void applySessionId(AutofillId[] ids) {
+        if (ids == null) {
+            return;
+        }
+        for (int i = 0; i < ids.length; i++) {
+            applySessionId(ids[i]);
+        }
+    }
+
+    private void applySessionId(AutofillId id) {
+        if (id == null) {
+            return;
+        }
+        id.setSessionId(mSessionId);
+    }
+
+    private void dispatchCancellationSignal(@Nullable ICancellationSignal signal) {
+        if (signal == null) {
+            return;
+        }
+        try {
+            signal.cancel();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Error requesting a cancellation", e);
+        }
+    }
+
+    private class FillCallbackImpl extends IFillCallback.Stub {
+        final AndroidFuture<FillResponse> mFillRequest;
+        final AtomicReference<AndroidFuture<FillResponse>> mFutureRef;
+        final AtomicReference<ICancellationSignal> mCancellationSink;
+
+        FillCallbackImpl(AndroidFuture<FillResponse> fillRequest,
+                AtomicReference<AndroidFuture<FillResponse>> futureRef,
+                AtomicReference<ICancellationSignal> cancellationSink) {
+            mFillRequest = fillRequest;
+            mFutureRef = futureRef;
+            mCancellationSink = cancellationSink;
+        }
+
+        @Override
+        public void onCancellable(ICancellationSignal cancellation) {
+            AndroidFuture<FillResponse> future = mFutureRef.get();
+            if (future != null && future.isCancelled()) {
+                dispatchCancellationSignal(cancellation);
+            } else {
+                mCancellationSink.set(cancellation);
+            }
+        }
+
+        @Override
+        public void onSuccess(FillResponse response) {
+            mFillRequest.complete(response);
+        }
+
+        @Override
+        public void onFailure(int requestId, CharSequence message) {
+            String errorMessage = message == null ? "" : String.valueOf(message);
+            mFillRequest.completeExceptionally(
+                    new RuntimeException(errorMessage));
+        }
+    }
+}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 7e277ba..b0445ae 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -31,6 +31,7 @@
 import static android.view.autofill.AutofillManager.ACTION_VALUE_CHANGED;
 import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED;
 import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
+import static android.view.autofill.AutofillManager.FLAG_ENABLED_CLIENT_SUGGESTIONS;
 import static android.view.autofill.AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM;
 import static android.view.autofill.AutofillManager.getSmartSuggestionModeToString;
 
@@ -61,6 +62,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.IntentSender;
+import android.content.pm.ApplicationInfo;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -364,6 +366,9 @@
      */
     private final AssistDataReceiverImpl mAssistReceiver = new AssistDataReceiverImpl();
 
+    @Nullable
+    private ClientSuggestionsSession mClientSuggestionsSession;
+
     // TODO(b/216576510): Share one BroadcastReceiver between all Sessions instead of creating a
     // new one per Session.
     private final BroadcastReceiver mDelayedFillBroadcastReceiver =
@@ -456,6 +461,9 @@
         /** Whether the current {@link FillResponse} is expired. */
         private boolean mExpiredResponse;
 
+        /** Whether the client is using {@link android.view.autofill.AutofillRequestCallback}. */
+        private boolean mClientSuggestionsEnabled;
+
         /** Whether the fill dialog UI is disabled. */
         private boolean mFillDialogDisabled;
     }
@@ -486,14 +494,21 @@
                     }
                     mWaitForInlineRequest = inlineSuggestionsRequest != null;
                     mPendingInlineSuggestionsRequest = inlineSuggestionsRequest;
-                    maybeRequestFillLocked();
+                    mWaitForInlineRequest = inlineSuggestionsRequest != null;
+                    maybeRequestFillFromServiceLocked();
                     viewState.resetState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
                 }
             } : null;
         }
 
+        void newAutofillRequestLocked(@Nullable InlineSuggestionsRequest inlineRequest) {
+            mPendingFillRequest = null;
+            mWaitForInlineRequest = inlineRequest != null;
+            mPendingInlineSuggestionsRequest = inlineRequest;
+        }
+
         @GuardedBy("mLock")
-        void maybeRequestFillLocked() {
+        void maybeRequestFillFromServiceLocked() {
             if (mPendingFillRequest == null) {
                 return;
             }
@@ -503,10 +518,14 @@
                     return;
                 }
 
-                mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(),
-                        mPendingFillRequest.getFillContexts(), mPendingFillRequest.getClientState(),
-                        mPendingFillRequest.getFlags(), mPendingInlineSuggestionsRequest,
-                        mPendingFillRequest.getDelayedFillIntentSender());
+                if (mPendingInlineSuggestionsRequest.isServiceSupported()) {
+                    mPendingFillRequest = new FillRequest(mPendingFillRequest.getId(),
+                            mPendingFillRequest.getFillContexts(),
+                            mPendingFillRequest.getClientState(),
+                            mPendingFillRequest.getFlags(),
+                            mPendingInlineSuggestionsRequest,
+                            mPendingFillRequest.getDelayedFillIntentSender());
+                }
             }
             mLastFillRequest = mPendingFillRequest;
 
@@ -618,7 +637,7 @@
                             : mDelayedFillPendingIntent.getIntentSender());
 
                 mPendingFillRequest = request;
-                maybeRequestFillLocked();
+                maybeRequestFillFromServiceLocked();
             }
 
             if (mActivityToken != null) {
@@ -843,30 +862,39 @@
     }
 
     /**
-     * Cancels the last request sent to the {@link #mRemoteFillService}.
+     * Cancels the last request sent to the {@link #mRemoteFillService} or the
+     * {@link #mClientSuggestionsSession}.
      */
     @GuardedBy("mLock")
     private void cancelCurrentRequestLocked() {
-        if (mRemoteFillService == null) {
-            wtf(null, "cancelCurrentRequestLocked() called without a remote service. "
-                    + "mForAugmentedAutofillOnly: %s", mSessionFlags.mAugmentedAutofillOnly);
+        if (mRemoteFillService == null && mClientSuggestionsSession == null) {
+            wtf(null, "cancelCurrentRequestLocked() called without a remote service or a "
+                    + "client suggestions session.  mForAugmentedAutofillOnly: %s",
+                    mSessionFlags.mAugmentedAutofillOnly);
             return;
         }
-        final int canceledRequest = mRemoteFillService.cancelCurrentRequest();
 
-        // Remove the FillContext as there will never be a response for the service
-        if (canceledRequest != INVALID_REQUEST_ID && mContexts != null) {
-            final int numContexts = mContexts.size();
+        if (mRemoteFillService != null) {
+            final int canceledRequest = mRemoteFillService.cancelCurrentRequest();
 
-            // It is most likely the last context, hence search backwards
-            for (int i = numContexts - 1; i >= 0; i--) {
-                if (mContexts.get(i).getRequestId() == canceledRequest) {
-                    if (sDebug) Slog.d(TAG, "cancelCurrentRequest(): id = " + canceledRequest);
-                    mContexts.remove(i);
-                    break;
+            // Remove the FillContext as there will never be a response for the service
+            if (canceledRequest != INVALID_REQUEST_ID && mContexts != null) {
+                final int numContexts = mContexts.size();
+
+                // It is most likely the last context, hence search backwards
+                for (int i = numContexts - 1; i >= 0; i--) {
+                    if (mContexts.get(i).getRequestId() == canceledRequest) {
+                        if (sDebug) Slog.d(TAG, "cancelCurrentRequest(): id = " + canceledRequest);
+                        mContexts.remove(i);
+                        break;
+                    }
                 }
             }
         }
+
+        if (mClientSuggestionsSession != null) {
+            mClientSuggestionsSession.cancelCurrentRequest();
+        }
     }
 
     private boolean isViewFocusedLocked(int flags) {
@@ -931,17 +959,30 @@
         // structure is taken. This causes only one fill request per burst of focus changes.
         cancelCurrentRequestLocked();
 
-        // Only ask IME to create inline suggestions request if Autofill provider supports it and
-        // the render service is available except the autofill is triggered manually and the view
-        // is also not focused.
+        // Only ask IME to create inline suggestions request when
+        // 1. Autofill provider supports it or client enabled client suggestions.
+        // 2. The render service is available.
+        // 3. The view is focused. (The view may not be focused if the autofill is triggered
+        //    manually.)
         final RemoteInlineSuggestionRenderService remoteRenderService =
                 mService.getRemoteInlineSuggestionRenderServiceLocked();
-        if (mSessionFlags.mInlineSupportedByService
+        if ((mSessionFlags.mInlineSupportedByService || mSessionFlags.mClientSuggestionsEnabled)
                 && remoteRenderService != null
-                && (isViewFocusedLocked(flags) || isRequestSupportFillDialog(flags))) {
-            Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer =
-                    mAssistReceiver.newAutofillRequestLocked(viewState,
-                            /* isInlineRequest= */ true);
+                && (isViewFocusedLocked(flags) || (isRequestSupportFillDialog(flags)))) {
+            final Consumer<InlineSuggestionsRequest> inlineSuggestionsRequestConsumer;
+            if (mSessionFlags.mClientSuggestionsEnabled) {
+                final int finalRequestId = requestId;
+                inlineSuggestionsRequestConsumer = (inlineSuggestionsRequest) -> {
+                    // Using client suggestions
+                    synchronized (mLock) {
+                        onClientFillRequestLocked(finalRequestId, inlineSuggestionsRequest);
+                    }
+                    viewState.resetState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
+                };
+            } else {
+                inlineSuggestionsRequestConsumer = mAssistReceiver.newAutofillRequestLocked(
+                        viewState, /* isInlineRequest= */ true);
+            }
             if (inlineSuggestionsRequestConsumer != null) {
                 final AutofillId focusedId = mCurrentViewId;
                 final int requestIdCopy = requestId;
@@ -957,10 +998,18 @@
                 );
                 viewState.setState(ViewState.STATE_PENDING_CREATE_INLINE_REQUEST);
             }
+        } else if (mSessionFlags.mClientSuggestionsEnabled) {
+            // Request client suggestions for the dropdown mode
+            onClientFillRequestLocked(requestId, null);
         } else {
             mAssistReceiver.newAutofillRequestLocked(viewState, /* isInlineRequest= */ false);
         }
 
+        if (mSessionFlags.mClientSuggestionsEnabled) {
+            // Using client suggestions, unnecessary request AssistStructure
+            return;
+        }
+
         // Now request the assist structure data.
         requestAssistStructureLocked(requestId, flags);
     }
@@ -1020,10 +1069,13 @@
         mComponentName = componentName;
         mCompatMode = compatMode;
         mSessionState = STATE_ACTIVE;
+
         synchronized (mLock) {
             mSessionFlags = new SessionFlags();
             mSessionFlags.mAugmentedAutofillOnly = forAugmentedAutofillOnly;
             mSessionFlags.mInlineSupportedByService = mService.isInlineSuggestionsEnabledLocked();
+            mSessionFlags.mClientSuggestionsEnabled =
+                    (mFlags & FLAG_ENABLED_CLIENT_SUGGESTIONS) != 0;
             setClientLocked(client);
         }
 
@@ -1135,12 +1187,13 @@
                 if (requestLog != null) {
                     requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, -1);
                 }
-                processNullResponseLocked(requestId, requestFlags);
+                processNullResponseOrFallbackLocked(requestId, requestFlags);
                 return;
             }
 
             fieldClassificationIds = response.getFieldClassificationIds();
-            if (fieldClassificationIds != null && !mService.isFieldClassificationEnabledLocked()) {
+            if (!mSessionFlags.mClientSuggestionsEnabled && fieldClassificationIds != null
+                    && !mService.isFieldClassificationEnabledLocked()) {
                 Slog.w(TAG, "Ignoring " + response + " because field detection is disabled");
                 processNullResponseLocked(requestId, requestFlags);
                 return;
@@ -1225,6 +1278,26 @@
         }
     }
 
+    @GuardedBy("mLock")
+    private void processNullResponseOrFallbackLocked(int requestId, int flags) {
+        if (!mSessionFlags.mClientSuggestionsEnabled) {
+            processNullResponseLocked(requestId, flags);
+            return;
+        }
+
+        // fallback to the default platform password manager
+        mSessionFlags.mClientSuggestionsEnabled = false;
+
+        final InlineSuggestionsRequest inlineRequest =
+                (mLastInlineSuggestionsRequest != null
+                        && mLastInlineSuggestionsRequest.first == requestId)
+                        ? mLastInlineSuggestionsRequest.second : null;
+        mAssistReceiver.newAutofillRequestLocked(inlineRequest);
+        requestAssistStructureLocked(requestId,
+                flags & ~FLAG_ENABLED_CLIENT_SUGGESTIONS);
+        return;
+    }
+
     // FillServiceCallbacks
     @Override
     public void onFillRequestFailure(int requestId, @Nullable CharSequence message) {
@@ -3196,13 +3269,22 @@
             filterText = value.getTextValue().toString();
         }
 
-        final CharSequence serviceLabel;
-        final Drawable serviceIcon;
+        final CharSequence targetLabel;
+        final Drawable targetIcon;
         synchronized (mLock) {
-            serviceLabel = mService.getServiceLabelLocked();
-            serviceIcon = mService.getServiceIconLocked();
+            if (mSessionFlags.mClientSuggestionsEnabled) {
+                final ApplicationInfo appInfo = ClientSuggestionsSession.getAppInfo(mComponentName,
+                        mService.getUserId());
+                targetLabel = ClientSuggestionsSession.getAppLabelLocked(
+                        mService.getMaster().getContext(), appInfo);
+                targetIcon = ClientSuggestionsSession.getAppIconLocked(
+                        mService.getMaster().getContext(), appInfo);
+            } else {
+                targetLabel = mService.getServiceLabelLocked();
+                targetIcon = mService.getServiceIconLocked();
+            }
         }
-        if (serviceLabel == null || serviceIcon == null) {
+        if (targetLabel == null || targetIcon == null) {
             wtf(null, "onFillReady(): no service label or icon");
             return;
         }
@@ -3233,7 +3315,7 @@
 
         getUiForShowing().showFillUi(filledId, response, filterText,
                 mService.getServicePackageName(), mComponentName,
-                serviceLabel, serviceIcon, this, id, mCompatMode);
+                targetLabel, targetIcon, this, id, mCompatMode);
 
         synchronized (mLock) {
             mService.logDatasetShown(id, mClientState, UI_TYPE_MENU);
@@ -3362,6 +3444,17 @@
             return false;
         }
 
+        final InlineSuggestionsRequest request = inlineSuggestionsRequest.get();
+        if (mSessionFlags.mClientSuggestionsEnabled && !request.isClientSupported()
+                || !mSessionFlags.mClientSuggestionsEnabled && !request.isServiceSupported()) {
+            if (sDebug) {
+                Slog.d(TAG, "Inline suggestions not supported for "
+                        + (mSessionFlags.mClientSuggestionsEnabled ? "client" : "service")
+                        + ". Falling back to dropdown.");
+            }
+            return false;
+        }
+
         final RemoteInlineSuggestionRenderService remoteRenderService =
                 mService.getRemoteInlineSuggestionRenderServiceLocked();
         if (remoteRenderService == null) {
@@ -3370,7 +3463,7 @@
         }
 
         final InlineFillUi.InlineFillUiInfo inlineFillUiInfo =
-                new InlineFillUi.InlineFillUiInfo(inlineSuggestionsRequest.get(), focusedId,
+                new InlineFillUi.InlineFillUiInfo(request, focusedId,
                         filterText, remoteRenderService, userId, id);
         InlineFillUi inlineFillUi = InlineFillUi.forAutofill(inlineFillUiInfo, response,
                 new InlineFillUi.InlineSuggestionUiCallback() {
@@ -3980,6 +4073,25 @@
         }
     }
 
+    @GuardedBy("mLock")
+    private void onClientFillRequestLocked(int requestId,
+            InlineSuggestionsRequest inlineSuggestionsRequest) {
+        if (mClientSuggestionsSession == null) {
+            mClientSuggestionsSession = new ClientSuggestionsSession(id, mClient, mHandler,
+                    mComponentName, this);
+        }
+
+        if (mContexts == null) {
+            mContexts = new ArrayList<>(1);
+        }
+
+        if (inlineSuggestionsRequest != null && !inlineSuggestionsRequest.isClientSupported()) {
+            inlineSuggestionsRequest = null;
+        }
+
+        mClientSuggestionsSession.onFillRequest(requestId, inlineSuggestionsRequest, mFlags);
+    }
+
     /**
      * The result of checking whether to show the save dialog, when session can be saved.
      *
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index e80a6d9..9f0deea 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -235,60 +235,7 @@
             return;
         }
 
-        long homeVersion = 0;
-        ArrayList<byte[]> homeSigHashes = null;
-        PackageInfo homeInfo = null;
-        String homeInstaller = null;
-        ComponentName home = getPreferredHomeComponent();
-        if (home != null) {
-            try {
-                homeInfo = mPackageManager.getPackageInfoAsUser(home.getPackageName(),
-                        PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
-                homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName());
-                homeVersion = homeInfo.getLongVersionCode();
-                SigningInfo signingInfo = homeInfo.signingInfo;
-                if (signingInfo == null) {
-                    Slog.e(TAG, "Home app has no signing information");
-                } else {
-                    // retrieve the newest sigs to back up
-                    // TODO (b/73988180) use entire signing history in case of rollbacks
-                    Signature[] homeInfoSignatures = signingInfo.getApkContentsSigners();
-                    homeSigHashes = BackupUtils.hashSignatureArray(homeInfoSignatures);
-                }
-            } catch (NameNotFoundException e) {
-                Slog.w(TAG, "Can't access preferred home info");
-                // proceed as though there were no preferred home set
-                home = null;
-            }
-        }
-
         try {
-            // We need to push a new preferred-home-app record if:
-            //    1. the version of the home app has changed since our last backup;
-            //    2. the home app [or absence] we now use differs from the prior state,
-            // OR 3. it looks like we use the same home app + version as before, but
-            //       the signatures don't match so we treat them as different apps.
-            PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
-            final boolean needHomeBackup = (homeVersion != mStoredHomeVersion)
-                    || !Objects.equals(home, mStoredHomeComponent)
-                    || (home != null
-                        && !BackupUtils.signaturesMatch(mStoredHomeSigHashes, homeInfo, pmi));
-            if (needHomeBackup) {
-                if (DEBUG) {
-                    Slog.i(TAG, "Home preference changed; backing up new state " + home);
-                }
-                if (home != null) {
-                    outputBuffer.reset();
-                    outputBufferStream.writeUTF(home.flattenToString());
-                    outputBufferStream.writeLong(homeVersion);
-                    outputBufferStream.writeUTF(homeInstaller != null ? homeInstaller : "" );
-                    writeSignatureHashArray(outputBufferStream, homeSigHashes);
-                    writeEntity(data, DEFAULT_HOME_KEY, outputBuffer.toByteArray());
-                } else {
-                    data.writeEntityHeader(DEFAULT_HOME_KEY, -1);
-                }
-            }
-
             /*
              * Global metadata:
              *
@@ -403,7 +350,7 @@
         }
 
         // Finally, write the new state blob -- just the list of all apps we handled
-        writeStateFile(mAllPackages, home, homeVersion, homeSigHashes, newState);
+        writeStateFile(mAllPackages, newState);
     }
 
     private static void writeEntity(BackupDataOutput data, String key, byte[] bytes)
@@ -623,8 +570,7 @@
     }
 
     // Util: write out our new backup state file
-    private void writeStateFile(List<PackageInfo> pkgs, ComponentName preferredHome,
-            long homeVersion, ArrayList<byte[]> homeSigHashes, ParcelFileDescriptor stateFile) {
+    private void writeStateFile(List<PackageInfo> pkgs, ParcelFileDescriptor stateFile) {
         FileOutputStream outstream = new FileOutputStream(stateFile.getFileDescriptor());
         BufferedOutputStream outbuf = new BufferedOutputStream(outstream);
         DataOutputStream out = new DataOutputStream(outbuf);
@@ -635,14 +581,6 @@
             out.writeUTF(STATE_FILE_HEADER);
             out.writeInt(STATE_FILE_VERSION);
 
-            // If we remembered a preferred home app, record that
-            if (preferredHome != null) {
-                out.writeUTF(DEFAULT_HOME_KEY);
-                out.writeUTF(preferredHome.flattenToString());
-                out.writeLong(homeVersion);
-                writeSignatureHashArray(out, homeSigHashes);
-            }
-
             // Conclude with the metadata block
             out.writeUTF(GLOBAL_METADATA_KEY);
             out.writeInt(Build.VERSION.SDK_INT);
@@ -789,6 +727,8 @@
                                 + Build.VERSION.INCREMENTAL + ")");
                     }
                 } else if (key.equals(DEFAULT_HOME_KEY)) {
+                    // Default home app data is no longer backed up by this agent. This code is
+                    // kept to handle restore of old backups that still contain home app data.
                     String cn = inputBufferStream.readUTF();
                     mRestoredHome = ComponentName.unflattenFromString(cn);
                     mRestoredHomeVersion = inputBufferStream.readLong();
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 1af35af..e886ed0 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -85,7 +85,6 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SELinux;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
@@ -3986,7 +3985,7 @@
             String callerLogString = "BMS.filterAppsEligibleForBackup";
             TransportConnection transportConnection =
                     mTransportManager.getCurrentTransportClient(callerLogString);
-            List<String> eligibleApps = new LinkedList<>();
+            List<String> eligibleApps = new ArrayList<>();
             for (String packageName : packages) {
                 if (mScheduledBackupEligibility.appIsRunningAndEligibleForBackupWithTransport(
                         transportConnection, packageName)) {
@@ -3996,7 +3995,7 @@
             if (transportConnection != null) {
                 mTransportManager.disposeOfTransportClient(transportConnection, callerLogString);
             }
-            return eligibleApps.toArray(new String[eligibleApps.size()]);
+            return eligibleApps.toArray(new String[0]);
         } finally {
             Binder.restoreCallingIdentity(oldToken);
         }
@@ -4144,6 +4143,24 @@
                 pw.print(" : ");
                 pw.println(entry.packageName);
             }
+            pw.println(userPrefix + "Agent timeouts:");
+            pw.println("    KvBackupAgentTimeoutMillis: "
+                    + mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis());
+            pw.println("    FullBackupAgentTimeoutMillis: "
+                    + mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis());
+            pw.println("    SharedBackupAgentTimeoutMillis: "
+                    + mAgentTimeoutParameters.getSharedBackupAgentTimeoutMillis());
+            pw.println("    RestoreAgentTimeoutMillis (system): "
+                    + mAgentTimeoutParameters.getRestoreAgentTimeoutMillis(
+                    Process.FIRST_APPLICATION_UID - 1));
+            pw.println("    RestoreAgentTimeoutMillis: "
+                    + mAgentTimeoutParameters.getRestoreAgentTimeoutMillis(
+                    Process.FIRST_APPLICATION_UID));
+            pw.println("    RestoreAgentFinishedTimeoutMillis: "
+                    + mAgentTimeoutParameters.getRestoreAgentFinishedTimeoutMillis());
+            pw.println("    QuotaExceededTimeoutMillis: "
+                    + mAgentTimeoutParameters.getQuotaExceededTimeoutMillis());
+
         }
     }
 
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 76df8b9..e78c8d1 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -24,8 +24,10 @@
 import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 
+import android.annotation.NonNull;
 import android.app.ApplicationThreadConstants;
 import android.app.IBackupAgent;
+import android.app.backup.BackupAgent;
 import android.app.backup.BackupManager;
 import android.app.backup.FullBackup;
 import android.app.backup.IBackupManagerMonitor;
@@ -38,10 +40,12 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.provider.Settings;
+import android.system.OsConstants;
 import android.text.TextUtils;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.LocalServices;
 import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupRestoreTask;
@@ -57,6 +61,7 @@
 import com.android.server.backup.utils.RestoreUtils;
 import com.android.server.backup.utils.TarBackupReader;
 
+import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -135,6 +140,8 @@
     private boolean mPipesClosed;
     private final BackupEligibilityRules mBackupEligibilityRules;
 
+    private FileMetadata mReadOnlyParent = null;
+
     public FullRestoreEngine(
             UserBackupManagerService backupManagerService, OperationStorage operationStorage,
             BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
@@ -158,6 +165,22 @@
         mBackupEligibilityRules = backupEligibilityRules;
     }
 
+    @VisibleForTesting
+    FullRestoreEngine() {
+        mIsAdbRestore = false;
+        mAllowApks = false;
+        mEphemeralOpToken = 0;
+        mUserId = 0;
+        mBackupEligibilityRules = null;
+        mAgentTimeoutParameters = null;
+        mBuffer = null;
+        mBackupManagerService = null;
+        mOperationStorage = null;
+        mMonitor = null;
+        mMonitorTask = null;
+        mOnlyPackage = null;
+    }
+
     public IBackupAgent getAgent() {
         return mAgent;
     }
@@ -397,6 +420,11 @@
                         okay = false;
                     }
 
+                    if (shouldSkipReadOnlyDir(info)) {
+                        // b/194894879: We don't support restore of read-only dirs.
+                        okay = false;
+                    }
+
                     // At this point we have an agent ready to handle the full
                     // restore data as well as a pipe for sending data to
                     // that agent.  Tell the agent to start reading from the
@@ -573,6 +601,45 @@
         return (info != null);
     }
 
+    boolean shouldSkipReadOnlyDir(FileMetadata info) {
+        if (isValidParent(mReadOnlyParent, info)) {
+            // This file has a read-only parent directory, we shouldn't
+            // restore it.
+            return true;
+        } else {
+            // We're now in a different branch of the file tree, update the parent
+            // value.
+            if (isReadOnlyDir(info)) {
+                // Current directory is read-only. Remember it so that we can skip all
+                // of its contents.
+                mReadOnlyParent = info;
+                Slog.w(TAG, "Skipping restore of " + info.path + " and its contents as "
+                        + "read-only dirs are currently not supported.");
+                return true;
+            } else {
+                mReadOnlyParent = null;
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean isValidParent(FileMetadata parentDir, @NonNull FileMetadata childDir) {
+        return parentDir != null
+                && childDir.packageName.equals(parentDir.packageName)
+                && childDir.domain.equals(parentDir.domain)
+                && childDir.path.startsWith(getPathWithTrailingSeparator(parentDir.path));
+    }
+
+    private static String getPathWithTrailingSeparator(String path) {
+        return path.endsWith(File.separator) ? path : path + File.separator;
+    }
+
+    private static boolean isReadOnlyDir(FileMetadata file) {
+        // Check if owner has 'write' bit in the file's mode value (see 'man -7 inode' for details).
+        return file.type == BackupAgent.TYPE_DIRECTORY && (file.mode & OsConstants.S_IWUSR) == 0;
+    }
+
     private void setUpPipes() throws IOException {
         synchronized (mPipesLock) {
             mPipes = ParcelFileDescriptor.createPipe();
diff --git a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
index 7a5fa62..47d2640 100644
--- a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
+++ b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
@@ -26,6 +26,7 @@
 import static com.android.server.companion.PackageUtils.enforceUsesCompanionDeviceFeature;
 import static com.android.server.companion.PermissionsUtils.enforcePermissionsForAssociation;
 import static com.android.server.companion.RolesUtils.isRoleHolder;
+import static com.android.server.companion.Utils.prepareForIpc;
 
 import static java.util.Objects.requireNonNull;
 
@@ -47,7 +48,6 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.UserHandle;
@@ -413,20 +413,4 @@
 
         return requestingPackageSignatureAllowlisted;
     }
-
-    /**
-     * Convert an instance of a "locally-defined" ResultReceiver to an instance of
-     * {@link android.os.ResultReceiver} itself, which the receiving process will be able to
-     * unmarshall.
-     */
-    private static <T extends ResultReceiver> ResultReceiver prepareForIpc(T resultReceiver) {
-        final Parcel parcel = Parcel.obtain();
-        resultReceiver.writeToParcel(parcel, 0);
-        parcel.setDataPosition(0);
-
-        final ResultReceiver ipcFriendly = ResultReceiver.CREATOR.createFromParcel(parcel);
-        parcel.recycle();
-
-        return ipcFriendly;
-    }
 }
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index ac0944b..c362b8e 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -99,6 +99,8 @@
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.companion.datatransfer.SystemDataTransferProcessor;
+import com.android.server.companion.datatransfer.SystemDataTransferRequestStore;
 import com.android.server.companion.presence.CompanionDevicePresenceMonitor;
 import com.android.server.pm.UserManagerInternal;
 
@@ -130,7 +132,9 @@
     private final PersistUserStateHandler mUserPersistenceHandler;
 
     private final AssociationStoreImpl mAssociationStore;
+    private final SystemDataTransferRequestStore mSystemDataTransferRequestStore;
     private AssociationRequestsProcessor mAssociationRequestsProcessor;
+    private SystemDataTransferProcessor mSystemDataTransferProcessor;
     private CompanionDevicePresenceMonitor mDevicePresenceMonitor;
     private CompanionApplicationController mCompanionAppController;
 
@@ -164,6 +168,7 @@
 
         mUserPersistenceHandler = new PersistUserStateHandler();
         mAssociationStore = new AssociationStoreImpl();
+        mSystemDataTransferRequestStore = new SystemDataTransferRequestStore();
     }
 
     @Override
@@ -178,6 +183,8 @@
 
         mAssociationRequestsProcessor = new AssociationRequestsProcessor(
                 /* cdmService */this, mAssociationStore);
+        mSystemDataTransferProcessor = new SystemDataTransferProcessor(this, mAssociationStore,
+                mSystemDataTransferRequestStore);
 
         final Context context = getContext();
         mCompanionAppController = new CompanionApplicationController(
@@ -602,6 +609,18 @@
         }
 
         @Override
+        public PendingIntent buildPermissionTransferUserConsentIntent(String packageName,
+                int userId, int associationId) throws RemoteException {
+            return mSystemDataTransferProcessor.buildPermissionTransferUserConsentIntent(
+                    packageName, userId, associationId);
+        }
+
+        @Override
+        public void startSystemDataTransfer(int userId, int associationId) throws RemoteException {
+            // TODO(b/222121838)
+        }
+
+        @Override
         public void notifyDeviceAppeared(int associationId) {
             if (DEBUG) Log.i(TAG, "notifyDevice_Appeared() id=" + associationId);
 
@@ -860,6 +879,9 @@
         mAssociationStore.removeAssociation(associationId);
         logRemoveAssociation(deviceProfile);
 
+        // Remove all the system data transfer requests for the association.
+        mSystemDataTransferRequestStore.removeRequestsByAssociationId(userId, associationId);
+
         final List<AssociationInfo> otherAssociations =
                 mAssociationStore.getAssociationsForPackage(userId, packageName);
 
diff --git a/services/companion/java/com/android/server/companion/DataStoreUtils.java b/services/companion/java/com/android/server/companion/DataStoreUtils.java
index 8ac741a..73e68ec 100644
--- a/services/companion/java/com/android/server/companion/DataStoreUtils.java
+++ b/services/companion/java/com/android/server/companion/DataStoreUtils.java
@@ -33,15 +33,24 @@
 import java.io.File;
 import java.io.FileOutputStream;
 
-final class DataStoreUtils {
+/**
+ * Util class for CDM data stores
+ */
+public final class DataStoreUtils {
     private static final String TAG = "CompanionDevice_DataStoreUtils";
 
-    static boolean isStartOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
+    /**
+     * Check if the parser pointer is at the start of the tag
+     */
+    public static boolean isStartOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
             throws XmlPullParserException {
         return parser.getEventType() == START_TAG && tag.equals(parser.getName());
     }
 
-    static boolean isEndOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
+    /**
+     * Check if the parser pointer is at the end of the tag
+     */
+    public static boolean isEndOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
             throws XmlPullParserException {
         return parser.getEventType() == END_TAG && tag.equals(parser.getName());
     }
@@ -57,7 +66,7 @@
      * @return an AtomicFile for the user
      */
     @NonNull
-    static AtomicFile createStorageFileForUser(@UserIdInt int userId, String fileName) {
+    public static AtomicFile createStorageFileForUser(@UserIdInt int userId, String fileName) {
         return new AtomicFile(getBaseStorageFileForUser(userId, fileName));
     }
 
@@ -70,7 +79,7 @@
      * Writing to file could fail, for example, if the user has been recently removed and so was
      * their DE (/data/system_de/<user-id>/) directory.
      */
-    static void writeToFileSafely(
+    public static void writeToFileSafely(
             @NonNull AtomicFile file, @NonNull ThrowingConsumer<FileOutputStream> consumer) {
         try {
             file.write(consumer);
diff --git a/services/companion/java/com/android/server/companion/PackageUtils.java b/services/companion/java/com/android/server/companion/PackageUtils.java
index a2b2059..42c7687 100644
--- a/services/companion/java/com/android/server/companion/PackageUtils.java
+++ b/services/companion/java/com/android/server/companion/PackageUtils.java
@@ -41,8 +41,8 @@
 
 import com.android.internal.util.ArrayUtils;
 
+import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
@@ -87,7 +87,8 @@
         final List<ResolveInfo> companionServices = pm.queryIntentServicesAsUser(
                 COMPANION_SERVICE_INTENT, ResolveInfoFlags.of(0), userId);
 
-        final Map<String, List<ComponentName>> packageNameToServiceInfoList = new HashMap<>();
+        final Map<String, List<ComponentName>> packageNameToServiceInfoList =
+                new HashMap<>(companionServices.size());
 
         for (ResolveInfo resolveInfo : companionServices) {
             final ServiceInfo service = resolveInfo.serviceInfo;
@@ -101,19 +102,19 @@
                 continue;
             }
 
-            // Use LinkedList, because we'll need to prepend "primary" services, while appending the
-            // other (non-primary) services to the list.
-            final LinkedList<ComponentName> services =
-                    (LinkedList<ComponentName>) packageNameToServiceInfoList.computeIfAbsent(
-                            service.packageName, it -> new LinkedList<>());
+            // We'll need to prepend "primary" services, while appending the other (non-primary)
+            // services to the list.
+            final ArrayList<ComponentName> services =
+                    (ArrayList<ComponentName>) packageNameToServiceInfoList.computeIfAbsent(
+                            service.packageName, it -> new ArrayList<>(1));
 
             final ComponentName componentName = service.getComponentName();
 
             if (isPrimaryCompanionDeviceService(pm, componentName)) {
                 // "Primary" service should be at the head of the list.
-                services.addFirst(componentName);
+                services.add(0, componentName);
             } else {
-                services.addLast(componentName);
+                services.add(componentName);
             }
         }
 
diff --git a/services/companion/java/com/android/server/companion/PersistentDataStore.java b/services/companion/java/com/android/server/companion/PersistentDataStore.java
index 3639389..4d42838 100644
--- a/services/companion/java/com/android/server/companion/PersistentDataStore.java
+++ b/services/companion/java/com/android/server/companion/PersistentDataStore.java
@@ -103,7 +103,7 @@
  * Since Android T the data is stored to "companion_device_manager.xml" file in
  * {@link Environment#getDataSystemDeDirectory(int) /data/system_de/}.
  *
- * See {@link #getBaseStorageFileForUser(int) getBaseStorageFileForUser()}
+ * See {@link #getStorageFileForUser(int)}
  *
  * <p>
  * Since Android T the data is stored using the v1 schema.
diff --git a/services/companion/java/com/android/server/companion/SystemDataTransferRequestDataStore.java b/services/companion/java/com/android/server/companion/SystemDataTransferRequestDataStore.java
deleted file mode 100644
index 38e5d16..0000000
--- a/services/companion/java/com/android/server/companion/SystemDataTransferRequestDataStore.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.companion;
-
-import static com.android.internal.util.XmlUtils.readBooleanAttribute;
-import static com.android.internal.util.XmlUtils.readIntAttribute;
-import static com.android.internal.util.XmlUtils.readThisListXml;
-import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
-import static com.android.internal.util.XmlUtils.writeIntAttribute;
-import static com.android.internal.util.XmlUtils.writeListXml;
-import static com.android.server.companion.DataStoreUtils.createStorageFileForUser;
-import static com.android.server.companion.DataStoreUtils.isEndOfTag;
-import static com.android.server.companion.DataStoreUtils.isStartOfTag;
-import static com.android.server.companion.DataStoreUtils.writeToFileSafely;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
-import android.companion.SystemDataTransferRequest;
-import android.util.AtomicFile;
-import android.util.Slog;
-import android.util.TypedXmlPullParser;
-import android.util.TypedXmlSerializer;
-import android.util.Xml;
-
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * The class is responsible for reading/writing SystemDataTransferRequest records from/to the disk.
- *
- * The following snippet is a sample XML file stored in the disk.
- * <pre>{@code
- * <requests>
- *   <request
- *     association_id="1"
- *     is_permission_sync_all_packages="false">
- *     <list name="permission_sync_packages">
- *       <string>com.sample.app1</string>
- *       <string>com.sample.app2</string>
- *     </list>
- *   </request>
- * </requests>
- * }</pre>
- */
-public class SystemDataTransferRequestDataStore {
-
-    private static final String LOG_TAG = SystemDataTransferRequestDataStore.class.getSimpleName();
-
-    private static final String FILE_NAME = "companion_device_system_data_transfer_requests.xml";
-
-    private static final String XML_TAG_REQUESTS = "requests";
-    private static final String XML_TAG_REQUEST = "request";
-    private static final String XML_TAG_LIST = "list";
-
-    private static final String XML_ATTR_ASSOCIATION_ID = "association_id";
-    private static final String XML_ATTR_IS_PERMISSION_SYNC_ALL_PACKAGES =
-            "is_permission_sync_all_packages";
-    private static final String XML_ATTR_PERMISSION_SYNC_PACKAGES = "permission_sync_packages";
-
-    private final ConcurrentMap<Integer, AtomicFile> mUserIdToStorageFile =
-            new ConcurrentHashMap<>();
-
-    /**
-     * Reads previously persisted data for the given user
-     *
-     * @param userId Android UserID
-     * @return a list of SystemDataTransferRequest
-     */
-    @NonNull
-    List<SystemDataTransferRequest> readRequestsForUser(@UserIdInt int userId) {
-        final AtomicFile file = getStorageFileForUser(userId);
-        Slog.i(LOG_TAG, "Reading SystemDataTransferRequests for user " + userId + " from "
-                + "file=" + file.getBaseFile().getPath());
-
-        // getStorageFileForUser() ALWAYS returns the SAME OBJECT, which allows us to synchronize
-        // accesses to the file on the file system using this AtomicFile object.
-        synchronized (file) {
-            if (!file.getBaseFile().exists()) {
-                Slog.d(LOG_TAG, "File does not exist -> Abort");
-                return Collections.emptyList();
-            }
-            try (FileInputStream in = file.openRead()) {
-                final TypedXmlPullParser parser = Xml.resolvePullParser(in);
-                XmlUtils.beginDocument(parser, XML_TAG_REQUESTS);
-
-                return readRequests(parser);
-            } catch (XmlPullParserException | IOException e) {
-                Slog.e(LOG_TAG, "Error while reading requests file", e);
-                return Collections.emptyList();
-            }
-        }
-    }
-
-    @NonNull
-    private List<SystemDataTransferRequest> readRequests(@NonNull TypedXmlPullParser parser)
-            throws XmlPullParserException, IOException {
-        if (!isStartOfTag(parser, XML_TAG_REQUESTS)) {
-            throw new XmlPullParserException("The XML doesn't have start tag: " + XML_TAG_REQUESTS);
-        }
-
-        List<SystemDataTransferRequest> requests = new ArrayList<>();
-
-        while (true) {
-            parser.nextTag();
-            if (isEndOfTag(parser, XML_TAG_REQUESTS)) break;
-            if (isStartOfTag(parser, XML_TAG_REQUEST)) {
-                requests.add(readRequest(parser));
-            }
-        }
-
-        return requests;
-    }
-
-    private SystemDataTransferRequest readRequest(@NonNull TypedXmlPullParser parser)
-            throws XmlPullParserException, IOException {
-        if (!isStartOfTag(parser, XML_TAG_REQUEST)) {
-            throw new XmlPullParserException("XML doesn't have start tag: " + XML_TAG_REQUEST);
-        }
-
-        final int associationId = readIntAttribute(parser, XML_ATTR_ASSOCIATION_ID);
-        final boolean isPermissionSyncAllPackages = readBooleanAttribute(parser,
-                XML_ATTR_IS_PERMISSION_SYNC_ALL_PACKAGES);
-        parser.nextTag();
-        List<String> permissionSyncPackages = new ArrayList<>();
-        if (isStartOfTag(parser, XML_TAG_LIST)) {
-            parser.nextTag();
-            permissionSyncPackages = readThisListXml(parser, XML_TAG_LIST,
-                    new String[1]);
-        }
-
-        return new SystemDataTransferRequest(associationId, isPermissionSyncAllPackages,
-                permissionSyncPackages);
-    }
-
-    /**
-     * Persisted user's SystemDataTransferRequest data to the disk.
-     *
-     * @param userId   Android UserID
-     * @param requests a list of user's SystemDataTransferRequest.
-     */
-    void writeRequestsForUser(@UserIdInt int userId,
-            @NonNull List<SystemDataTransferRequest> requests) {
-        final AtomicFile file = getStorageFileForUser(userId);
-        Slog.i(LOG_TAG, "Writing SystemDataTransferRequests for user " + userId + " to file="
-                + file.getBaseFile().getPath());
-
-        // getStorageFileForUser() ALWAYS returns the SAME OBJECT, which allows us to synchronize
-        // accesses to the file on the file system using this AtomicFile object.
-        synchronized (file) {
-            writeToFileSafely(file, out -> {
-                final TypedXmlSerializer serializer = Xml.resolveSerializer(out);
-                serializer.setFeature(
-                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
-                serializer.startDocument(null, true);
-                writeRequests(serializer, requests);
-                serializer.endDocument();
-            });
-        }
-    }
-
-    private void writeRequests(@NonNull TypedXmlSerializer serializer,
-            @Nullable Collection<SystemDataTransferRequest> requests) throws IOException {
-        serializer.startTag(null, XML_TAG_REQUESTS);
-
-        for (SystemDataTransferRequest request : requests) {
-            writeRequest(serializer, request);
-        }
-
-        serializer.endTag(null, XML_TAG_REQUESTS);
-    }
-
-    private void writeRequest(@NonNull TypedXmlSerializer serializer,
-            @NonNull SystemDataTransferRequest request) throws IOException {
-        serializer.startTag(null, XML_TAG_REQUEST);
-
-        writeIntAttribute(serializer, XML_ATTR_ASSOCIATION_ID, request.getAssociationId());
-        writeBooleanAttribute(serializer, XML_ATTR_IS_PERMISSION_SYNC_ALL_PACKAGES,
-                request.isPermissionSyncAllPackages());
-        try {
-            writeListXml(request.getPermissionSyncPackages(), XML_ATTR_PERMISSION_SYNC_PACKAGES,
-                    serializer);
-        } catch (XmlPullParserException e) {
-            Slog.e(LOG_TAG, "Error writing permission sync packages into XML. "
-                    + request.getPermissionSyncPackages().toString());
-        }
-
-        serializer.endTag(null, XML_TAG_REQUEST);
-    }
-
-    /**
-     * Creates and caches {@link AtomicFile} object that represents the back-up file for the given
-     * user.
-     *
-     * IMPORTANT: the method will ALWAYS return the same {@link AtomicFile} object, which makes it
-     * possible to synchronize reads and writes to the file using the returned object.
-     */
-    private @NonNull AtomicFile getStorageFileForUser(@UserIdInt int userId) {
-        return mUserIdToStorageFile.computeIfAbsent(userId,
-                u -> createStorageFileForUser(userId, FILE_NAME));
-    }
-}
diff --git a/services/companion/java/com/android/server/companion/Utils.java b/services/companion/java/com/android/server/companion/Utils.java
new file mode 100644
index 0000000..b9f61ec
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/Utils.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion;
+
+import android.os.Parcel;
+import android.os.ResultReceiver;
+
+/**
+ * A miscellaneous util class for CDM
+ *
+ * @hide
+ */
+public final class Utils {
+
+    /**
+     * Convert an instance of a "locally-defined" ResultReceiver to an instance of
+     * {@link android.os.ResultReceiver} itself, which the receiving process will be able to
+     * unmarshall.
+     * @hide
+     */
+    public static <T extends ResultReceiver> ResultReceiver prepareForIpc(T resultReceiver) {
+        final Parcel parcel = Parcel.obtain();
+        resultReceiver.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+
+        final ResultReceiver ipcFriendly = ResultReceiver.CREATOR.createFromParcel(parcel);
+        parcel.recycle();
+
+        return ipcFriendly;
+    }
+
+    private Utils() {}
+}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
new file mode 100644
index 0000000..ca47453
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion.datatransfer;
+
+import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
+import static android.app.PendingIntent.FLAG_IMMUTABLE;
+import static android.app.PendingIntent.FLAG_ONE_SHOT;
+import static android.companion.CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME;
+import static android.content.ComponentName.createRelative;
+
+import static com.android.server.companion.Utils.prepareForIpc;
+
+import android.annotation.UserIdInt;
+import android.app.PendingIntent;
+import android.companion.AssociationInfo;
+import android.companion.DeviceNotAssociatedException;
+import android.companion.datatransfer.PermissionSyncRequest;
+import android.companion.datatransfer.SystemDataTransferRequest;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.util.Slog;
+
+import com.android.server.companion.AssociationStore;
+import com.android.server.companion.CompanionDeviceManagerService;
+
+import java.util.List;
+
+/**
+ * This processor builds user consent intent for a given SystemDataTransferRequest and processes the
+ * request when the system is ready (a secure channel is established between the handhold and the
+ * companion device).
+ */
+public class SystemDataTransferProcessor {
+
+    private static final String LOG_TAG = SystemDataTransferProcessor.class.getSimpleName();
+
+    // Values from UI to SystemDataTransferProcessor via ResultReceiver
+    private static final int RESULT_CODE_SYSTEM_DATA_TRANSFER_ALLOWED = 0;
+    private static final int RESULT_CODE_SYSTEM_DATA_TRANSFER_DISALLOWED = 1;
+    private static final String EXTRA_PERMISSION_SYNC_REQUEST = "permission_sync_request";
+    private static final String EXTRA_COMPANION_DEVICE_NAME = "companion_device_name";
+    private static final String EXTRA_SYSTEM_DATA_TRANSFER_RESULT_RECEIVER =
+            "system_data_transfer_result_receiver";
+    private static final ComponentName SYSTEM_DATA_TRANSFER_REQUEST_APPROVAL_ACTIVITY =
+            createRelative(COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
+                    ".CompanionDeviceDataTransferActivity");
+
+    private final Context mContext;
+    private final AssociationStore mAssociationStore;
+    private final SystemDataTransferRequestStore mSystemDataTransferRequestStore;
+
+    public SystemDataTransferProcessor(CompanionDeviceManagerService service,
+            AssociationStore associationStore,
+            SystemDataTransferRequestStore systemDataTransferRequestStore) {
+        mContext = service.getContext();
+        mAssociationStore = associationStore;
+        mSystemDataTransferRequestStore = systemDataTransferRequestStore;
+    }
+
+    /**
+     * Build a PendingIntent of permission sync user consent dialog
+     */
+    public PendingIntent buildPermissionTransferUserConsentIntent(String packageName,
+            @UserIdInt int userId, int associationId) throws RemoteException {
+        // The association must exist and either belong to the calling package,
+        // or the calling package must hold REQUEST_SYSTEM_DATA_TRANSFER permission.
+        AssociationInfo association = mAssociationStore.getAssociationById(associationId);
+        if (association == null) {
+            throw new RemoteException(new DeviceNotAssociatedException(
+                    "Association id: " + associationId + " doesn't exist."));
+        } else {
+            if (!association.getPackageName().equals(packageName)) {
+                Slog.e(LOG_TAG, "The calling package doesn't own the association.");
+                return null;
+            }
+
+            // Check if the request's data type has been requested before.
+            List<SystemDataTransferRequest> storedRequests =
+                    mSystemDataTransferRequestStore.readRequestsByAssociationId(userId,
+                            associationId);
+            for (SystemDataTransferRequest storedRequest : storedRequests) {
+                if (storedRequest instanceof PermissionSyncRequest) {
+                    Slog.e(LOG_TAG, "The request has been sent before, you can not send "
+                            + "the same request type again.");
+                    return null;
+                }
+            }
+        }
+
+        Slog.i(LOG_TAG, "Creating permission sync intent for userId=" + userId
+                + "associationId: " + associationId);
+
+        // Create an internal intent to launch the user consent dialog
+        final Bundle extras = new Bundle();
+        PermissionSyncRequest request = new PermissionSyncRequest(associationId);
+        request.setUserId(userId);
+        extras.putParcelable(EXTRA_PERMISSION_SYNC_REQUEST, request);
+        extras.putCharSequence(EXTRA_COMPANION_DEVICE_NAME, association.getDisplayName());
+        extras.putParcelable(EXTRA_SYSTEM_DATA_TRANSFER_RESULT_RECEIVER,
+                prepareForIpc(mOnSystemDataTransferRequestConfirmationReceiver));
+
+        final Intent intent = new Intent();
+        intent.setComponent(SYSTEM_DATA_TRANSFER_REQUEST_APPROVAL_ACTIVITY);
+        intent.putExtras(extras);
+
+        // Create a PendingIntent
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return PendingIntent.getActivity(mContext, /*requestCode */ associationId, intent,
+                    FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private final ResultReceiver mOnSystemDataTransferRequestConfirmationReceiver =
+            new ResultReceiver(Handler.getMain()) {
+                @Override
+                protected void onReceiveResult(int resultCode, Bundle data) {
+                    Slog.d(LOG_TAG, "onReceiveResult() code=" + resultCode + ", "
+                            + "data=" + data);
+
+                    if (resultCode == RESULT_CODE_SYSTEM_DATA_TRANSFER_ALLOWED
+                            || resultCode == RESULT_CODE_SYSTEM_DATA_TRANSFER_DISALLOWED) {
+                        final PermissionSyncRequest request =
+                                data.getParcelable(EXTRA_PERMISSION_SYNC_REQUEST,
+                                        PermissionSyncRequest.class);
+                        if (request != null) {
+                            request.setUserConsented(
+                                    resultCode == RESULT_CODE_SYSTEM_DATA_TRANSFER_ALLOWED);
+                            Slog.i(LOG_TAG, "Recording request: " + request);
+                            mSystemDataTransferRequestStore.writeRequest(request.getUserId(),
+                                    request);
+                        }
+
+                        return;
+                    }
+
+                    Slog.e(LOG_TAG, "Unknown result code:" + resultCode);
+                }
+            };
+}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferRequestStore.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferRequestStore.java
new file mode 100644
index 0000000..ab0a062
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferRequestStore.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion.datatransfer;
+
+import static android.companion.datatransfer.SystemDataTransferRequest.DATA_TYPE_PERMISSION_SYNC;
+
+import static com.android.internal.util.XmlUtils.readBooleanAttribute;
+import static com.android.internal.util.XmlUtils.readIntAttribute;
+import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
+import static com.android.internal.util.XmlUtils.writeIntAttribute;
+import static com.android.server.companion.DataStoreUtils.createStorageFileForUser;
+import static com.android.server.companion.DataStoreUtils.isEndOfTag;
+import static com.android.server.companion.DataStoreUtils.isStartOfTag;
+import static com.android.server.companion.DataStoreUtils.writeToFileSafely;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.companion.datatransfer.PermissionSyncRequest;
+import android.companion.datatransfer.SystemDataTransferRequest;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TypedXmlPullParser;
+import android.util.TypedXmlSerializer;
+import android.util.Xml;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * The class is responsible for reading/writing SystemDataTransferRequest records from/to the disk.
+ * <p>
+ * The following snippet is a sample XML file stored in the disk.
+ * <pre>{@code
+ * <requests>
+ *   <request
+ *     association_id="1"
+ *     data_type="1"
+ *     user_id="12"
+ *     is_user_consented="true"
+ *   </request>
+ * </requests>
+ * }</pre>
+ */
+public class SystemDataTransferRequestStore {
+
+    private static final String LOG_TAG = SystemDataTransferRequestStore.class.getSimpleName();
+
+    private static final String FILE_NAME = "companion_device_system_data_transfer_requests.xml";
+
+    private static final String XML_TAG_REQUESTS = "requests";
+    private static final String XML_TAG_REQUEST = "request";
+
+    private static final String XML_ATTR_ASSOCIATION_ID = "association_id";
+    private static final String XML_ATTR_DATA_TYPE = "data_type";
+    private static final String XML_ATTR_USER_ID = "user_id";
+    private static final String XML_ATTR_IS_USER_CONSENTED = "is_user_consented";
+
+    private static final int READ_FROM_DISK_TIMEOUT = 5; // in seconds
+
+    private final ExecutorService mExecutor;
+    private final ConcurrentMap<Integer, AtomicFile> mUserIdToStorageFile =
+            new ConcurrentHashMap<>();
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final SparseArray<ArrayList<SystemDataTransferRequest>> mCachedPerUser =
+            new SparseArray<>();
+
+    public SystemDataTransferRequestStore() {
+        mExecutor = Executors.newSingleThreadExecutor();
+    }
+
+    @NonNull
+    List<SystemDataTransferRequest> readRequestsByAssociationId(@UserIdInt int userId,
+            int associationId) {
+        List<SystemDataTransferRequest> cachedRequests;
+        synchronized (mLock) {
+            cachedRequests = readRequestsFromCache(userId);
+        }
+
+        List<SystemDataTransferRequest> requestsByAssociationId = new ArrayList<>();
+        for (SystemDataTransferRequest request : cachedRequests) {
+            if (request.getAssociationId() == associationId) {
+                requestsByAssociationId.add(request);
+            }
+        }
+        return requestsByAssociationId;
+    }
+
+    void writeRequest(@UserIdInt int userId, SystemDataTransferRequest request) {
+        Slog.i(LOG_TAG, "Writing request=" + request + " to store.");
+        ArrayList<SystemDataTransferRequest> cachedRequests;
+        synchronized (mLock) {
+            // Write to cache
+            cachedRequests = readRequestsFromCache(userId);
+            cachedRequests.add(request);
+            mCachedPerUser.set(userId, cachedRequests);
+        }
+        // Write to store
+        mExecutor.execute(() -> writeRequestsToStore(userId, cachedRequests));
+    }
+
+    /**
+     * Remove requests by association id. userId must be the one which owns the associationId.
+     */
+    public void removeRequestsByAssociationId(@UserIdInt int userId, int associationId) {
+        Slog.i(LOG_TAG, "Removing system data transfer requests for userId=" + userId
+                + ", associationId=" + associationId);
+        ArrayList<SystemDataTransferRequest> cachedRequests;
+        synchronized (mLock) {
+            // Remove requests from cache
+            cachedRequests = readRequestsFromCache(userId);
+            cachedRequests.removeIf(request -> request.getAssociationId() == associationId);
+            mCachedPerUser.set(userId, cachedRequests);
+        }
+        // Remove requests from store
+        mExecutor.execute(() -> writeRequestsToStore(userId, cachedRequests));
+    }
+
+    @GuardedBy("mLock")
+    private ArrayList<SystemDataTransferRequest> readRequestsFromCache(@UserIdInt int userId) {
+        ArrayList<SystemDataTransferRequest> cachedRequests = mCachedPerUser.get(userId);
+        if (cachedRequests == null) {
+            Future<ArrayList<SystemDataTransferRequest>> future =
+                    mExecutor.submit(() -> readRequestsFromStore(userId));
+            try {
+                cachedRequests = future.get(READ_FROM_DISK_TIMEOUT, TimeUnit.SECONDS);
+            } catch (InterruptedException e) {
+                Slog.e(LOG_TAG, "Thread reading SystemDataTransferRequest from disk is "
+                        + "interrupted.");
+            } catch (ExecutionException e) {
+                Slog.e(LOG_TAG, "Error occurred while reading SystemDataTransferRequest "
+                        + "from disk.");
+            } catch (TimeoutException e) {
+                Slog.e(LOG_TAG, "Reading SystemDataTransferRequest from disk timed out.");
+            }
+            mCachedPerUser.set(userId, cachedRequests);
+        }
+        return cachedRequests;
+    }
+
+    /**
+     * Reads previously persisted data for the given user
+     *
+     * @param userId Android UserID
+     * @return a list of SystemDataTransferRequest
+     */
+    @NonNull
+    private ArrayList<SystemDataTransferRequest> readRequestsFromStore(@UserIdInt int userId) {
+        final AtomicFile file = getStorageFileForUser(userId);
+        Slog.i(LOG_TAG, "Reading SystemDataTransferRequests for user " + userId + " from "
+                + "file=" + file.getBaseFile().getPath());
+
+        // getStorageFileForUser() ALWAYS returns the SAME OBJECT, which allows us to synchronize
+        // accesses to the file on the file system using this AtomicFile object.
+        synchronized (file) {
+            if (!file.getBaseFile().exists()) {
+                Slog.d(LOG_TAG, "File does not exist -> Abort");
+                return new ArrayList<>();
+            }
+            try (FileInputStream in = file.openRead()) {
+                final TypedXmlPullParser parser = Xml.resolvePullParser(in);
+                XmlUtils.beginDocument(parser, XML_TAG_REQUESTS);
+
+                return readRequestsFromXml(parser);
+            } catch (XmlPullParserException | IOException e) {
+                Slog.e(LOG_TAG, "Error while reading requests file", e);
+                return new ArrayList<>();
+            }
+        }
+    }
+
+    @NonNull
+    private ArrayList<SystemDataTransferRequest> readRequestsFromXml(
+            @NonNull TypedXmlPullParser parser) throws XmlPullParserException, IOException {
+        if (!isStartOfTag(parser, XML_TAG_REQUESTS)) {
+            throw new XmlPullParserException("The XML doesn't have start tag: " + XML_TAG_REQUESTS);
+        }
+
+        ArrayList<SystemDataTransferRequest> requests = new ArrayList<>();
+
+        while (true) {
+            parser.nextTag();
+            if (isEndOfTag(parser, XML_TAG_REQUESTS)) {
+                break;
+            }
+            if (isStartOfTag(parser, XML_TAG_REQUEST)) {
+                requests.add(readRequestFromXml(parser));
+            }
+        }
+
+        return requests;
+    }
+
+    private SystemDataTransferRequest readRequestFromXml(@NonNull TypedXmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        if (!isStartOfTag(parser, XML_TAG_REQUEST)) {
+            throw new XmlPullParserException("XML doesn't have start tag: " + XML_TAG_REQUEST);
+        }
+
+        final int associationId = readIntAttribute(parser, XML_ATTR_ASSOCIATION_ID);
+        final int dataType = readIntAttribute(parser, XML_ATTR_DATA_TYPE);
+        final int userId = readIntAttribute(parser, XML_ATTR_USER_ID);
+        final boolean isUserConsented = readBooleanAttribute(parser, XML_ATTR_IS_USER_CONSENTED);
+
+        switch (dataType) {
+            case DATA_TYPE_PERMISSION_SYNC:
+                PermissionSyncRequest request = new PermissionSyncRequest(associationId);
+                request.setUserId(userId);
+                request.setUserConsented(isUserConsented);
+                return request;
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Persisted user's SystemDataTransferRequest data to the disk.
+     *
+     * @param userId   Android UserID
+     * @param requests a list of user's SystemDataTransferRequest.
+     */
+    void writeRequestsToStore(@UserIdInt int userId,
+            @NonNull List<SystemDataTransferRequest> requests) {
+        final AtomicFile file = getStorageFileForUser(userId);
+        Slog.i(LOG_TAG, "Writing SystemDataTransferRequests for user " + userId + " to file="
+                + file.getBaseFile().getPath());
+
+        // getStorageFileForUser() ALWAYS returns the SAME OBJECT, which allows us to synchronize
+        // accesses to the file on the file system using this AtomicFile object.
+        synchronized (file) {
+            writeToFileSafely(file, out -> {
+                final TypedXmlSerializer serializer = Xml.resolveSerializer(out);
+                serializer.setFeature(
+                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
+                serializer.startDocument(null, true);
+                writeRequestsToXml(serializer, requests);
+                serializer.endDocument();
+            });
+        }
+    }
+
+    private void writeRequestsToXml(@NonNull TypedXmlSerializer serializer,
+            @Nullable Collection<SystemDataTransferRequest> requests) throws IOException {
+        serializer.startTag(null, XML_TAG_REQUESTS);
+
+        for (SystemDataTransferRequest request : requests) {
+            writeRequestToXml(serializer, request);
+        }
+
+        serializer.endTag(null, XML_TAG_REQUESTS);
+    }
+
+    private void writeRequestToXml(@NonNull TypedXmlSerializer serializer,
+            @NonNull SystemDataTransferRequest request) throws IOException {
+        serializer.startTag(null, XML_TAG_REQUEST);
+
+        writeIntAttribute(serializer, XML_ATTR_ASSOCIATION_ID, request.getAssociationId());
+        writeIntAttribute(serializer, XML_ATTR_DATA_TYPE, request.getDataType());
+        writeIntAttribute(serializer, XML_ATTR_USER_ID, request.getUserId());
+        writeBooleanAttribute(serializer, XML_ATTR_IS_USER_CONSENTED, request.isUserConsented());
+
+        serializer.endTag(null, XML_TAG_REQUEST);
+    }
+
+    /**
+     * Creates and caches {@link AtomicFile} object that represents the back-up file for the given
+     * user.
+     * <p>
+     * IMPORTANT: the method will ALWAYS return the same {@link AtomicFile} object, which makes it
+     * possible to synchronize reads and writes to the file using the returned object.
+     */
+    @NonNull
+    private AtomicFile getStorageFileForUser(@UserIdInt int userId) {
+        return mUserIdToStorageFile.computeIfAbsent(userId,
+                u -> createStorageFileForUser(userId, FILE_NAME));
+    }
+}
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 06f698e..58c22a75 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -552,18 +552,23 @@
     /**
      * Set which overlay to use for a package.
      * @param userId The user for which to update the overlays.
-     * @param targetPackageName The package name of the package for which to update the overlays.
-     * @param overlayPaths  The complete list of overlay paths that should be enabled for
+     * @param pendingChanges is a map to describe all overlay targets and their related overlay
+     *                      paths. Its key is the overlay target package and its value is the
+     *                      complete list of overlay paths that should be enabled for
      *                      the target. Previously enabled overlays not specified in the list
      *                      will be disabled. Pass in null or empty paths to disable all overlays.
      *                      The order of the items is significant if several overlays modify the
-     *                      same resource.
+     *                      same resource. To pass the concrete ArrayMap type is to reduce the
+     *                      overheads of system server.
      * @param outUpdatedPackageNames An output list that contains the package names of packages
      *                               affected by the update of enabled overlays.
-     * @return true if all packages names were known by the package manager, false otherwise
+     * @param outInvalidPackageNames An output list that contains the package names of packages
+     *                               are not valid.
      */
-    public abstract boolean setEnabledOverlayPackages(int userId, String targetPackageName,
-            @Nullable OverlayPaths overlayPaths, Set<String> outUpdatedPackageNames);
+    public abstract void setEnabledOverlayPackages(int userId,
+            @NonNull ArrayMap<String, OverlayPaths> pendingChanges,
+            @NonNull Set<String> outUpdatedPackageNames,
+            @NonNull Set<String> outInvalidPackageNames);
 
     /**
      * Resolves an activity intent, allowing instant apps to be resolved.
diff --git a/services/core/java/com/android/server/ConsumerIrService.java b/services/core/java/com/android/server/ConsumerIrService.java
index c4e84a4..a9bdf06 100644
--- a/services/core/java/com/android/server/ConsumerIrService.java
+++ b/services/core/java/com/android/server/ConsumerIrService.java
@@ -16,6 +16,10 @@
 
 package com.android.server;
 
+import static android.Manifest.permission.TRANSMIT_IR;
+
+import android.annotation.EnforcePermission;
+import android.annotation.RequiresNoPermission;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.hardware.IConsumerIrService;
@@ -60,6 +64,7 @@
     }
 
     @Override
+    @RequiresNoPermission
     public boolean hasIrEmitter() {
         return mHasNativeHal;
     }
@@ -85,12 +90,8 @@
 
 
     @Override
+    @EnforcePermission(TRANSMIT_IR)
     public void transmit(String packageName, int carrierFrequency, int[] pattern) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
-                != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Requires TRANSMIT_IR permission");
-        }
-
         long totalXmitTime = 0;
 
         for (int slice : pattern) {
@@ -125,12 +126,8 @@
     }
 
     @Override
+    @EnforcePermission(TRANSMIT_IR)
     public int[] getCarrierFrequencies() {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
-                != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Requires TRANSMIT_IR permission");
-        }
-
         throwIfNoIrEmitter();
 
         synchronized(mHalLock) {
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 78df983..a562afb 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
 import android.os.Environment;
 import android.os.SystemClock;
@@ -162,16 +163,17 @@
     /**
      * Returns true if the jar is in a test APEX.
      */
-    private static boolean isJarInTestApex(String pathStr) {
+    private boolean isJarInTestApex(String pathStr) {
         Path path = Paths.get(pathStr);
         if (path.getNameCount() >= 2 && path.getName(0).toString().equals("apex")) {
             String apexModuleName = path.getName(1).toString();
             ApexManager apexManager = ApexManager.getInstance();
             String packageName = apexManager.getActivePackageNameForApexModuleName(apexModuleName);
-            PackageInfo packageInfo = apexManager.getPackageInfo(
-                    packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
-            if (packageInfo != null) {
+            try {
+                PackageInfo packageInfo =  mContext.getPackageManager().getPackageInfo(packageName,
+                        PackageManager.PackageInfoFlags.of(PackageManager.MATCH_APEX));
                 return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0;
+            } catch (Exception ignore) {
             }
         }
         return false;
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index b059cc7..2c465f4 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1820,6 +1820,14 @@
         if (account == null) {
             return false;
         }
+        if (account.name != null && account.name.length() > 200) {
+            Log.w(TAG, "Account cannot be added - Name longer than 200 chars");
+            return false;
+        }
+        if (account.type != null && account.type.length() > 200) {
+            Log.w(TAG, "Account cannot be added - Name longer than 200 chars");
+            return false;
+        }
         if (!isLocalUnlockedUser(accounts.userId)) {
             Log.w(TAG, "Account " + account.toSafeString() + " cannot be added - user "
                     + accounts.userId + " is locked. callingUid=" + callingUid);
@@ -2065,6 +2073,10 @@
                 + ", pid " + Binder.getCallingPid());
         }
         if (accountToRename == null) throw new IllegalArgumentException("account is null");
+        if (newName != null && newName.length() > 200) {
+            Log.e(TAG, "renameAccount failed - account name longer than 200");
+            throw new IllegalArgumentException("account name longer than 200");
+        }
         int userId = UserHandle.getCallingUserId();
         if (!isAccountManagedByCaller(accountToRename.type, callingUid, userId)) {
             String msg = String.format(
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index efde2a5..52577ef 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8735,8 +8735,8 @@
             sb.append("Foreground: ")
                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
                     .append("\n");
-            if (process.getStartTime() > 0) {
-                long runtimeMillis = SystemClock.elapsedRealtime() - process.getStartTime();
+            if (process.getStartUptime() > 0) {
+                long runtimeMillis = SystemClock.uptimeMillis() - process.getStartUptime();
                 sb.append("Process-Runtime: ").append(runtimeMillis).append("\n");
             }
         }
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 361629b..f35d792 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2783,7 +2783,9 @@
             @Nullable IAppOpsCallback permissionPolicyCallback) {
         enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
         verifyIncomingOp(code);
-        verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+        if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+            return;
+        }
 
         ArraySet<ModeCallback> repCbs = null;
         code = AppOpsManager.opToSwitch(code);
@@ -3218,7 +3220,9 @@
     private int checkOperationImpl(int code, int uid, String packageName,
             @Nullable String attributionTag, boolean raw) {
         verifyIncomingOp(code);
-        verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+        if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+            return AppOpsManager.opToDefaultMode(code);
+        }
 
         String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
         if (resolvedPackageName == null) {
@@ -3330,8 +3334,7 @@
     }
 
     private boolean isPackageExisted(String packageName) {
-        return LocalServices.getService(PackageManagerInternal.class)
-                .getPackageStateInternal(packageName) != null;
+        return getPackageManagerInternal().getPackageStateInternal(packageName) != null;
     }
 
     /**
@@ -3366,8 +3369,11 @@
 
         verifyIncomingProxyUid(attributionSource);
         verifyIncomingOp(code);
-        verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid));
-        verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
+        if (!isIncomingPackageValid(proxiedPackageName, UserHandle.getUserId(proxiedUid))
+                || !isIncomingPackageValid(proxyPackageName, UserHandle.getUserId(proxyUid))) {
+            return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, proxiedAttributionTag,
+                    proxiedPackageName);
+        }
 
         skipProxyOperation = skipProxyOperation
                 && isCallerAndAttributionTrusted(attributionSource);
@@ -3424,7 +3430,10 @@
             @Nullable String message, boolean shouldCollectMessage) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
-        verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+        if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+            return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
+                    packageName);
+        }
 
         String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
         if (resolvedPackageName == null) {
@@ -3830,7 +3839,10 @@
             int attributionChainId) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
-        verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+        if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+            return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
+                    packageName);
+        }
 
         String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
         if (resolvedPackageName == null) {
@@ -3884,8 +3896,11 @@
 
         verifyIncomingProxyUid(attributionSource);
         verifyIncomingOp(code);
-        verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
-        verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid));
+        if (!isIncomingPackageValid(proxyPackageName, UserHandle.getUserId(proxyUid))
+                || !isIncomingPackageValid(proxiedPackageName, UserHandle.getUserId(proxiedUid))) {
+            return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, proxiedAttributionTag,
+                    proxiedPackageName);
+        }
 
         boolean isCallerTrusted = isCallerAndAttributionTrusted(attributionSource);
         skipProxyOperation = isCallerTrusted && skipProxyOperation;
@@ -4070,7 +4085,9 @@
             String attributionTag) {
         verifyIncomingUid(uid);
         verifyIncomingOp(code);
-        verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+        if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+            return;
+        }
 
         String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
         if (resolvedPackageName == null) {
@@ -4103,8 +4120,10 @@
 
         verifyIncomingProxyUid(attributionSource);
         verifyIncomingOp(code);
-        verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
-        verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid));
+        if (!isIncomingPackageValid(proxyPackageName, UserHandle.getUserId(proxyUid))
+                || !isIncomingPackageValid(proxiedPackageName, UserHandle.getUserId(proxiedUid))) {
+            return null;
+        }
 
         String resolvedProxyPackageName = AppOpsManager.resolvePackageName(proxyUid,
                 proxyPackageName);
@@ -4377,12 +4396,32 @@
         throw new IllegalArgumentException("Bad operation #" + op);
     }
 
-    private void verifyIncomingPackage(@Nullable String packageName, @UserIdInt int userId) {
-        if (packageName != null && getPackageManagerInternal().filterAppAccess(packageName,
-                Binder.getCallingUid(), userId)) {
-            throw new IllegalArgumentException(
-                    packageName + " not found from " + Binder.getCallingUid());
+    private boolean isIncomingPackageValid(@Nullable String packageName, @UserIdInt int userId) {
+        final int callingUid = Binder.getCallingUid();
+        // Handle the special UIDs that don't have actual packages (audioserver, cameraserver, etc).
+        if (packageName == null || isSpecialPackage(callingUid, packageName)) {
+            return true;
         }
+
+        // If the package doesn't exist, #verifyAndGetBypass would throw a SecurityException in
+        // the end. Although that exception would be caught and return, we could make it return
+        // early.
+        if (!isPackageExisted(packageName)) {
+            return false;
+        }
+
+        if (getPackageManagerInternal().filterAppAccess(packageName, callingUid, userId)) {
+            Slog.w(TAG, packageName + " not found from " + callingUid);
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean isSpecialPackage(int callingUid, @Nullable String packageName) {
+        final String resolvedPackage = AppOpsManager.resolvePackageName(callingUid, packageName);
+        return callingUid == Process.SYSTEM_UID
+                || resolveUid(resolvedPackage) != Process.INVALID_UID;
     }
 
     private boolean isCallerAndAttributionTrusted(@NonNull AttributionSource attributionSource) {
@@ -6672,7 +6711,9 @@
             }
         }
         verifyIncomingOp(code);
-        verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+        if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+            return false;
+        }
 
         final String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
         if (resolvedPackageName == null) {
@@ -7077,7 +7118,7 @@
 
     private static int resolveUid(String packageName)  {
         if (packageName == null) {
-            return -1;
+            return Process.INVALID_UID;
         }
         switch (packageName) {
             case "root":
@@ -7092,7 +7133,7 @@
             case "cameraserver":
                 return Process.CAMERASERVER_UID;
         }
-        return -1;
+        return Process.INVALID_UID;
     }
 
     private static String[] getPackagesForUid(int uid) {
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index aab6281..387e00f 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -20,9 +20,9 @@
 import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
 import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD;
 import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.os.Process.SYSTEM_UID;
 
+import android.annotation.EnforcePermission;
+import android.annotation.RequiresNoPermission;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.IActivityManager;
@@ -93,15 +93,15 @@
     }
 
     @Override
+    @EnforcePermission(LOG_COMPAT_CHANGE)
     public void reportChange(long changeId, ApplicationInfo appInfo) {
-        checkCompatChangeLogPermission();
         reportChangeInternal(changeId, appInfo.uid, ChangeReporter.STATE_LOGGED);
     }
 
     @Override
+    @EnforcePermission(LOG_COMPAT_CHANGE)
     public void reportChangeByPackageName(long changeId, String packageName,
             @UserIdInt int userId) {
-        checkCompatChangeLogPermission();
         ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
         if (appInfo != null) {
             reportChangeInternal(changeId, appInfo.uid, ChangeReporter.STATE_LOGGED);
@@ -109,8 +109,8 @@
     }
 
     @Override
+    @EnforcePermission(LOG_COMPAT_CHANGE)
     public void reportChangeByUid(long changeId, int uid) {
-        checkCompatChangeLogPermission();
         reportChangeInternal(changeId, uid, ChangeReporter.STATE_LOGGED);
     }
 
@@ -119,15 +119,15 @@
     }
 
     @Override
+    @EnforcePermission(allOf = {LOG_COMPAT_CHANGE, READ_COMPAT_CHANGE_CONFIG})
     public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
-        checkCompatChangeReadAndLogPermission();
         return isChangeEnabledInternal(changeId, appInfo);
     }
 
     @Override
+    @EnforcePermission(allOf = {LOG_COMPAT_CHANGE, READ_COMPAT_CHANGE_CONFIG})
     public boolean isChangeEnabledByPackageName(long changeId, String packageName,
             @UserIdInt int userId) {
-        checkCompatChangeReadAndLogPermission();
         ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
         if (appInfo == null) {
             return mCompatConfig.willChangeBeEnabled(changeId, packageName);
@@ -136,8 +136,8 @@
     }
 
     @Override
+    @EnforcePermission(allOf = {LOG_COMPAT_CHANGE, READ_COMPAT_CHANGE_CONFIG})
     public boolean isChangeEnabledByUid(long changeId, int uid) {
-        checkCompatChangeReadAndLogPermission();
         String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
         if (packages == null || packages.length == 0) {
             return mCompatConfig.defaultChangeIdValue(changeId);
@@ -197,8 +197,8 @@
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
     public void setOverrides(CompatibilityChangeConfig overrides, String packageName) {
-        checkCompatChangeOverridePermission();
         Map<Long, PackageOverride> overridesMap = new HashMap<>();
         for (long change : overrides.enabledChanges()) {
             overridesMap.put(change, new PackageOverride.Builder().setEnabled(true).build());
@@ -213,8 +213,8 @@
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
     public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName) {
-        checkCompatChangeOverridePermission();
         Map<Long, PackageOverride> overridesMap = new HashMap<>();
         for (long change : overrides.enabledChanges()) {
             overridesMap.put(change, new PackageOverride.Builder().setEnabled(true).build());
@@ -228,9 +228,9 @@
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
     public void putAllOverridesOnReleaseBuilds(
             CompatibilityOverridesByPackageConfig overridesByPackage) {
-        checkCompatChangeOverrideOverridablePermission();
         for (CompatibilityOverrideConfig overrides :
                 overridesByPackage.packageNameToOverrides.values()) {
             checkAllCompatOverridesAreOverridable(overrides.overrides.keySet());
@@ -239,16 +239,16 @@
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
     public void putOverridesOnReleaseBuilds(CompatibilityOverrideConfig overrides,
             String packageName) {
-        checkCompatChangeOverrideOverridablePermission();
         checkAllCompatOverridesAreOverridable(overrides.overrides.keySet());
         mCompatConfig.addPackageOverrides(overrides, packageName, /* skipUnknownChangeIds= */ true);
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
     public int enableTargetSdkChanges(String packageName, int targetSdkVersion) {
-        checkCompatChangeOverridePermission();
         int numChanges =
                 mCompatConfig.enableTargetSdkChangesForPackage(packageName, targetSdkVersion);
         killPackage(packageName);
@@ -256,8 +256,8 @@
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
     public int disableTargetSdkChanges(String packageName, int targetSdkVersion) {
-        checkCompatChangeOverridePermission();
         int numChanges =
                 mCompatConfig.disableTargetSdkChangesForPackage(packageName, targetSdkVersion);
         killPackage(packageName);
@@ -265,36 +265,36 @@
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
     public void clearOverrides(String packageName) {
-        checkCompatChangeOverridePermission();
         mCompatConfig.removePackageOverrides(packageName);
         killPackage(packageName);
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
     public void clearOverridesForTest(String packageName) {
-        checkCompatChangeOverridePermission();
         mCompatConfig.removePackageOverrides(packageName);
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
     public boolean clearOverride(long changeId, String packageName) {
-        checkCompatChangeOverridePermission();
         boolean existed = mCompatConfig.removeOverride(changeId, packageName);
         killPackage(packageName);
         return existed;
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
     public boolean clearOverrideForTest(long changeId, String packageName) {
-        checkCompatChangeOverridePermission();
         return mCompatConfig.removeOverride(changeId, packageName);
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
     public void removeAllOverridesOnReleaseBuilds(
             CompatibilityOverridesToRemoveByPackageConfig overridesToRemoveByPackage) {
-        checkCompatChangeOverrideOverridablePermission();
         for (CompatibilityOverridesToRemoveConfig overridesToRemove :
                 overridesToRemoveByPackage.packageNameToOverridesToRemove.values()) {
             checkAllCompatOverridesAreOverridable(overridesToRemove.changeIds);
@@ -303,27 +303,28 @@
     }
 
     @Override
+    @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
     public void removeOverridesOnReleaseBuilds(
             CompatibilityOverridesToRemoveConfig overridesToRemove,
             String packageName) {
-        checkCompatChangeOverrideOverridablePermission();
         checkAllCompatOverridesAreOverridable(overridesToRemove.changeIds);
         mCompatConfig.removePackageOverrides(overridesToRemove, packageName);
     }
 
     @Override
+    @EnforcePermission(allOf = {LOG_COMPAT_CHANGE, READ_COMPAT_CHANGE_CONFIG})
     public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
-        checkCompatChangeReadAndLogPermission();
         return mCompatConfig.getAppConfig(appInfo);
     }
 
     @Override
+    @EnforcePermission(READ_COMPAT_CHANGE_CONFIG)
     public CompatibilityChangeInfo[] listAllChanges() {
-        checkCompatChangeReadPermission();
         return mCompatConfig.dumpChanges();
     }
 
     @Override
+    @RequiresNoPermission
     public CompatibilityChangeInfo[] listUIChanges() {
         return Arrays.stream(listAllChanges()).filter(this::isShownInUI).toArray(
                 CompatibilityChangeInfo[]::new);
@@ -362,11 +363,15 @@
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) {
             return;
         }
-        checkCompatChangeReadAndLogPermission();
+        mContext.enforceCallingOrSelfPermission(
+                READ_COMPAT_CHANGE_CONFIG, "Cannot read compat change");
+        mContext.enforceCallingOrSelfPermission(
+                LOG_COMPAT_CHANGE, "Cannot read log compat change usage");
         mCompatConfig.dumpConfig(pw);
     }
 
     @Override
+    @RequiresNoPermission
     public IOverrideValidator getOverrideValidator() {
         return mCompatConfig.getOverrideValidator();
     }
@@ -414,49 +419,6 @@
         }
     }
 
-    private void checkCompatChangeLogPermission() throws SecurityException {
-        // Don't check for permissions within the system process
-        if (Binder.getCallingUid() == SYSTEM_UID) {
-            return;
-        }
-        if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE) != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot log compat change usage");
-        }
-    }
-
-    private void checkCompatChangeReadPermission() {
-        // Don't check for permissions within the system process
-        if (Binder.getCallingUid() == SYSTEM_UID) {
-            return;
-        }
-        if (mContext.checkCallingOrSelfPermission(READ_COMPAT_CHANGE_CONFIG)
-                != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot read compat change");
-        }
-    }
-
-    private void checkCompatChangeOverridePermission() {
-        // Don't check for permissions within the system process
-        if (Binder.getCallingUid() == SYSTEM_UID) {
-            return;
-        }
-        if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
-                != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot override compat change");
-        }
-    }
-
-    private void checkCompatChangeOverrideOverridablePermission() {
-        // Don't check for permissions within the system process
-        if (Binder.getCallingUid() == SYSTEM_UID) {
-            return;
-        }
-        if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD)
-                != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot override compat change");
-        }
-    }
-
     private void checkAllCompatOverridesAreOverridable(Collection<Long> changeIds) {
         for (Long changeId : changeIds) {
             if (isKnownChangeId(changeId) && !mCompatConfig.isOverridable(changeId)) {
@@ -466,11 +428,6 @@
         }
     }
 
-    private void checkCompatChangeReadAndLogPermission() {
-        checkCompatChangeReadPermission();
-        checkCompatChangeLogPermission();
-    }
-
     private boolean isShownInUI(CompatibilityChangeInfo change) {
         if (change.getLoggingOnly()) {
             return false;
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index edaa18a..a661358 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -173,7 +173,7 @@
     public static final int TOUCH_VIRTUAL = 3;
 
     /**
-     * Diff result: The {@link #state} fields differ.
+     * Diff result: The {@link #state} or {@link #committedState} fields differ.
      */
     public static final int DIFF_STATE = 1 << 0;
 
@@ -335,6 +335,13 @@
     public int state = Display.STATE_ON;
 
     /**
+     * Display committed state.
+     *
+     * This matches {@link DisplayDeviceInfo#state} only after the power state change finishes.
+     */
+    public int committedState = Display.STATE_UNKNOWN;
+
+    /**
      * The UID of the application that owns this display, or zero if it is owned by the system.
      * <p>
      * If the display is private, then only the owner can use it.
@@ -387,7 +394,7 @@
      */
     public int diff(DisplayDeviceInfo other) {
         int diff = 0;
-        if (state != other.state) {
+        if (state != other.state || committedState != other.committedState) {
             diff |= DIFF_STATE;
         }
         if (colorMode != other.colorMode) {
@@ -461,6 +468,7 @@
         address = other.address;
         deviceProductInfo = other.deviceProductInfo;
         state = other.state;
+        committedState = other.committedState;
         ownerUid = other.ownerUid;
         ownerPackageName = other.ownerPackageName;
         frameRateOverrides = other.frameRateOverrides;
@@ -501,6 +509,7 @@
         }
         sb.append(", deviceProductInfo ").append(deviceProductInfo);
         sb.append(", state ").append(Display.stateToString(state));
+        sb.append(", committedState ").append(Display.stateToString(committedState));
         if (ownerUid != 0 || ownerPackageName != null) {
             sb.append(", owner ").append(ownerPackageName);
             sb.append(" (uid ").append(ownerUid).append(")");
diff --git a/services/core/java/com/android/server/display/HighBrightnessModeController.java b/services/core/java/com/android/server/display/HighBrightnessModeController.java
index 0b9d4de..f98c7df 100644
--- a/services/core/java/com/android/server/display/HighBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/HighBrightnessModeController.java
@@ -42,8 +42,8 @@
 import com.android.server.display.DisplayManagerService.Clock;
 
 import java.io.PrintWriter;
+import java.util.ArrayDeque;
 import java.util.Iterator;
-import java.util.LinkedList;
 
 /**
  * Controls the status of high-brightness mode for devices that support it. This class assumes that
@@ -110,11 +110,11 @@
     private long mRunningStartTimeMillis = -1;
 
     /**
-     * List of previous HBM-events ordered from most recent to least recent.
+     * Queue of previous HBM-events ordered from most recent to least recent.
      * Meant to store only the events that fall into the most recent
-     * {@link mHbmData.timeWindowMillis}.
+     * {@link HighBrightnessModeData#timeWindowMillis mHbmData.timeWindowMillis}.
      */
-    private LinkedList<HbmEvent> mEvents = new LinkedList<>();
+    private final ArrayDeque<HbmEvent> mEvents = new ArrayDeque<>();
 
     HighBrightnessModeController(Handler handler, int width, int height, IBinder displayToken,
             String displayUniqueId, float brightnessMin, float brightnessMax,
@@ -234,7 +234,7 @@
                 mRunningStartTimeMillis = -1;
 
                 if (DEBUG) {
-                    Slog.d(TAG, "New HBM event: " + mEvents.getFirst());
+                    Slog.d(TAG, "New HBM event: " + mEvents.peekFirst());
                 }
             }
         }
@@ -433,7 +433,7 @@
             // window by at least minTime. Basically, we're calculating the soonest time we can
             // get {@code timeMinMillis} back to us.
             final long windowstartTimeMillis = currentTime - mHbmData.timeWindowMillis;
-            final HbmEvent lastEvent = mEvents.getLast();
+            final HbmEvent lastEvent = mEvents.peekLast();
             final long startTimePlusMinMillis =
                     Math.max(windowstartTimeMillis, lastEvent.startTimeMillis)
                     + mHbmData.timeMinMillis;
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index a155095..84bce80 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -195,6 +195,8 @@
         private DisplayDeviceInfo mInfo;
         private boolean mHavePendingChanges;
         private int mState = Display.STATE_UNKNOWN;
+        private int mCommittedState = Display.STATE_UNKNOWN;
+
         // This is only set in the runnable returned from requestDisplayStateLocked.
         private float mBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
         private float mSdrBrightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT;
@@ -635,6 +637,7 @@
                 mInfo.appVsyncOffsetNanos = mActiveSfDisplayMode.appVsyncOffsetNanos;
                 mInfo.presentationDeadlineNanos = mActiveSfDisplayMode.presentationDeadlineNanos;
                 mInfo.state = mState;
+                mInfo.committedState = mCommittedState;
                 mInfo.uniqueId = getUniqueId();
                 final DisplayAddress.Physical physicalAddress =
                         DisplayAddress.fromPhysicalDisplayId(mPhysicalDisplayId);
@@ -815,6 +818,7 @@
                         } finally {
                             Trace.traceEnd(Trace.TRACE_TAG_POWER);
                         }
+                        setCommittedState(state);
                         // If we're entering a suspended (but not OFF) power state and we
                         // have a sidekick available, tell it now that it can take control.
                         if (Display.isSuspendedState(state) && state != Display.STATE_OFF
@@ -829,6 +833,16 @@
                         }
                     }
 
+                    private void setCommittedState(int state) {
+                        // After the display state is set, let's update the committed state.
+                        getHandler().post(() -> {
+                            synchronized (getSyncRoot()) {
+                                mCommittedState = state;
+                                updateDeviceInfoLocked();
+                            }
+                        });
+                    }
+
                     private void setDisplayBrightness(float brightnessState,
                             float sdrBrightnessState) {
                         // brightnessState includes invalid, off and full range.
@@ -1094,6 +1108,7 @@
             pw.println("mDefaultModeId=" + mDefaultModeId);
             pw.println("mUserPreferredModeId=" + mUserPreferredModeId);
             pw.println("mState=" + Display.stateToString(mState));
+            pw.println("mCommittedState=" + Display.stateToString(mCommittedState));
             pw.println("mBrightnessState=" + mBrightnessState);
             pw.println("mBacklightAdapter=" + mBacklightAdapter);
             pw.println("mAllmSupported=" + mAllmSupported);
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index a640497..839555b 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -413,6 +413,7 @@
             mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
             mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
             mBaseDisplayInfo.state = deviceInfo.state;
+            mBaseDisplayInfo.committedState = deviceInfo.committedState;
             mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth;
             mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight;
             mBaseDisplayInfo.largestNominalAppWidth = maskedWidth;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 576a5ff..26e38bd 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -306,16 +306,23 @@
     @Override
     @ServiceThreadOnly
     protected void onInitializeCecComplete(int initiatedBy) {
-        if (initiatedBy == HdmiControlService.INITIATED_BY_SCREEN_ON) {
-            oneTouchPlay(new IHdmiControlCallback.Stub() {
-                @Override
-                public void onComplete(int result) {
-                    if (result != HdmiControlManager.RESULT_SUCCESS) {
-                        Slog.w(TAG, "Failed to complete One Touch Play. result=" + result);
-                    }
-                }
-            });
+        if (initiatedBy != HdmiControlService.INITIATED_BY_SCREEN_ON) {
+            return;
         }
+        @HdmiControlManager.PowerControlMode
+        String powerControlMode = mService.getHdmiCecConfig().getStringValue(
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE);
+        if (powerControlMode.equals(HdmiControlManager.POWER_CONTROL_MODE_NONE)) {
+            return;
+        }
+        oneTouchPlay(new IHdmiControlCallback.Stub() {
+            @Override
+            public void onComplete(int result) {
+                if (result != HdmiControlManager.RESULT_SUCCESS) {
+                    Slog.w(TAG, "Failed to complete One Touch Play. result=" + result);
+                }
+            }
+        });
     }
 
     @Override
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 8ab0b93..e433324 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.input;
 
+import static android.provider.DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT;
 import static android.view.KeyEvent.KEYCODE_UNKNOWN;
 
 import android.annotation.NonNull;
@@ -157,6 +158,8 @@
 
     // Feature flag name for the deep press feature
     private static final String DEEP_PRESS_ENABLED = "deep_press_enabled";
+    // Feature flag name for the strategy to be used in VelocityTracker
+    private static final String VELOCITYTRACKER_STRATEGY_PROPERTY = "velocitytracker_strategy";
 
     private static final int MSG_DELIVER_INPUT_DEVICES_CHANGED = 1;
     private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 2;
@@ -358,6 +361,8 @@
     public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER;
     public static final int SW_MUTE_DEVICE_BIT = 1 << SW_MUTE_DEVICE;
 
+    private final String mVelocityTrackerStrategy;
+
     /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
     final boolean mUseDevInputEventForAudioJack;
 
@@ -406,6 +411,8 @@
         mDoubleTouchGestureEnableFile = TextUtils.isEmpty(doubleTouchGestureEnablePath) ? null :
             new File(doubleTouchGestureEnablePath);
 
+        mVelocityTrackerStrategy = DeviceConfig.getProperty(
+                NAMESPACE_INPUT_NATIVE_BOOT, VELOCITYTRACKER_STRATEGY_PROPERTY);
         LocalServices.addService(InputManagerInternal.class, new LocalService());
     }
 
@@ -878,6 +885,11 @@
         return mNative.verifyInputEvent(event);
     }
 
+    @Override // Binder call
+    public String getVelocityTrackerStrategy() {
+        return mVelocityTrackerStrategy;
+    }
+
     /**
      * Gets information about the input device with the specified id.
      * @param deviceId The device id.
@@ -2343,7 +2355,7 @@
     public void removePortAssociation(@NonNull String inputPort) {
         if (!checkCallingPermission(
                 android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY,
-                "clearPortAssociations()")) {
+                "removePortAssociation()")) {
             throw new SecurityException(
                     "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission");
         }
@@ -2359,7 +2371,7 @@
     public void addUniqueIdAssociation(@NonNull String inputPort, @NonNull String displayUniqueId) {
         if (!checkCallingPermission(
                 android.Manifest.permission.ASSOCIATE_INPUT_DEVICE_TO_DISPLAY,
-                "addNameAssociation()")) {
+                "addUniqueIdAssociation()")) {
             throw new SecurityException(
                     "Requires ASSOCIATE_INPUT_DEVICE_TO_DISPLAY permission");
         }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 3c31405..8cf0ab74 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4734,7 +4734,8 @@
     }
 
     @BinderThread
-    private void hideMySoftInput(@NonNull IBinder token, int flags) {
+    private void hideMySoftInput(@NonNull IBinder token, int flags,
+            @SoftInputShowHideReason int reason) {
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideMySoftInput");
         synchronized (ImfLock.class) {
             if (!calledWithValidTokenLocked(token)) {
@@ -4742,10 +4743,7 @@
             }
             final long ident = Binder.clearCallingIdentity();
             try {
-                hideCurrentInputLocked(
-                        mLastImeTargetWindow, flags, null,
-                        SoftInputShowHideReason.HIDE_MY_SOFT_INPUT);
-
+                hideCurrentInputLocked(mLastImeTargetWindow, flags, null, reason);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -4763,7 +4761,7 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 showCurrentInputLocked(mLastImeTargetWindow, flags, null,
-                        SoftInputShowHideReason.SHOW_MY_SOFT_INPUT);
+                        SoftInputShowHideReason.SHOW_SOFT_INPUT_FROM_IME);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -6571,11 +6569,12 @@
 
         @BinderThread
         @Override
-        public void hideMySoftInput(int flags, AndroidFuture future /* T=Void */) {
+        public void hideMySoftInput(int flags, @SoftInputShowHideReason int reason,
+                AndroidFuture future /* T=Void */) {
             @SuppressWarnings("unchecked")
             final AndroidFuture<Void> typedFuture = future;
             try {
-                mImms.hideMySoftInput(mToken, flags);
+                mImms.hideMySoftInput(mToken, flags, reason);
                 typedFuture.complete(null);
             } catch (Throwable e) {
                 typedFuture.completeExceptionally(e);
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 42fed36..9e5da45 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -1179,8 +1179,15 @@
         @Override
         public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
                 String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
-            (new MediaShellCommand()).exec(this, in, out, err, args, callback,
-                    resultReceiver);
+            String[] packageNames =
+                    mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid());
+            String packageName = packageNames != null && packageNames.length > 0
+                    ? packageNames[0]
+                    : "com.android.shell"; // We should not need this branch, but defaulting to the
+                                           // current shell package name for robustness. See
+                                           // b/227109905.
+            new MediaShellCommand(packageName)
+                    .exec(this, in, out, err, args, callback, resultReceiver);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/media/MediaShellCommand.java b/services/core/java/com/android/server/media/MediaShellCommand.java
index 103cdd9..d175d87 100644
--- a/services/core/java/com/android/server/media/MediaShellCommand.java
+++ b/services/core/java/com/android/server/media/MediaShellCommand.java
@@ -47,15 +47,19 @@
  * ShellCommand for MediaSessionService.
  */
 public class MediaShellCommand extends ShellCommand {
-    // This doesn't belongs to any package. Setting the package name to empty string.
-    private static final String PACKAGE_NAME = "";
     private static ActivityThread sThread;
     private static MediaSessionManager sMediaSessionManager;
+
+    private final String mPackageName;
     private ISessionManager mSessionService;
     private PrintWriter mWriter;
     private PrintWriter mErrorWriter;
     private InputStream mInput;
 
+    public MediaShellCommand(String packageName) {
+        mPackageName = packageName;
+    }
+
     @Override
     public int onCommand(String cmd) {
         mWriter = getOutPrintWriter();
@@ -110,7 +114,7 @@
         mWriter.println();
         mWriter.println("media_session dispatch: dispatch a media key to the system.");
         mWriter.println("                KEY may be: play, pause, play-pause, mute, headsethook,");
-        mWriter.println("                stop, next, previous, rewind, record, fast-forword.");
+        mWriter.println("                stop, next, previous, rewind, record, fast-forward.");
         mWriter.println("media_session list-sessions: print a list of the current sessions.");
         mWriter.println("media_session monitor: monitor updates to the specified session.");
         mWriter.println("                       Use the tag from list-sessions.");
@@ -120,7 +124,8 @@
 
     private void sendMediaKey(KeyEvent event) {
         try {
-            mSessionService.dispatchMediaKeyEvent(PACKAGE_NAME, false, event, false);
+            mSessionService.dispatchMediaKeyEvent(
+                    mPackageName, /* asSystemService= */ false, event, /* needWakeLock= */ false);
         } catch (RemoteException e) {
         }
     }
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index a9b2570..e09f7b0 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -40,11 +40,12 @@
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 import java.util.Iterator;
-import java.util.LinkedList;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -76,7 +77,7 @@
     private final Handler mFileWriteHandler;
     @VisibleForTesting
     // List of files holding history information, sorted newest to oldest
-    final LinkedList<AtomicFile> mHistoryFiles;
+    final List<AtomicFile> mHistoryFiles;
     private final File mHistoryDir;
     private final File mVersionFile;
     // Current version of the database files schema
@@ -94,7 +95,7 @@
         mFileWriteHandler = fileWriteHandler;
         mVersionFile = new File(dir, "version");
         mHistoryDir = new File(dir, "history");
-        mHistoryFiles = new LinkedList<>();
+        mHistoryFiles = new ArrayList<>();
         mBuffer = new NotificationHistory();
         mWriteBufferRunnable = new WriteBufferRunnable();
 
@@ -133,7 +134,7 @@
                 safeParseLong(lhs.getName())));
 
         for (File file : files) {
-            mHistoryFiles.addLast(new AtomicFile(file));
+            mHistoryFiles.add(new AtomicFile(file));
         }
     }
 
@@ -411,7 +412,7 @@
                         + file.getBaseFile().getAbsolutePath());
                 try {
                     writeLocked(file, mBuffer);
-                    mHistoryFiles.addFirst(file);
+                    mHistoryFiles.add(0, file);
                     mBuffer = new NotificationHistory();
 
                     scheduleDeletion(file.getBaseFile(), time, HISTORY_RETENTION_DAYS);
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index 903d02a..f3cb7fb 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -19,6 +19,7 @@
 import static com.android.server.om.OverlayManagerService.DEBUG;
 import static com.android.server.om.OverlayManagerService.TAG;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.content.om.OverlayInfo;
 import android.content.om.OverlayableInfo;
@@ -33,6 +34,8 @@
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -56,6 +59,18 @@
         VENDOR_IS_Q_OR_LATER = isQOrLater;
     }
 
+    static final int IDMAP_NOT_EXIST = 0;
+    static final int IDMAP_IS_VERIFIED = 1;
+    static final int IDMAP_IS_MODIFIED = 1 << 1;
+
+    @IntDef(flag = true, prefix = { "IDMAP_" }, value = {
+            IDMAP_NOT_EXIST,
+            IDMAP_IS_VERIFIED,
+            IDMAP_IS_MODIFIED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface IdmapStatus {}
+
     private final IdmapDaemon mIdmapDaemon;
     private final PackageManagerHelper mPackageManager;
 
@@ -76,8 +91,14 @@
     /**
      * Creates the idmap for the target/overlay combination and returns whether the idmap file was
      * modified.
+     * @return the status of the specific idmap file. It's one of the following.<ul>
+     *     <li>{@link #IDMAP_NOT_EXIST} means the idmap file is not existed.</li>
+     *     <li>{@link #IDMAP_IS_VERIFIED} means the idmap file is verified by Idmap2d.</li>
+     *     <li>{@link #IDMAP_IS_MODIFIED | IDMAP_IS_VERIFIED } means the idmap file is modified and
+     *     verified by Idmap2d.</li>
+     * </ul>.
      */
-    boolean createIdmap(@NonNull final AndroidPackage targetPackage,
+    @IdmapStatus int createIdmap(@NonNull final AndroidPackage targetPackage,
             @NonNull final AndroidPackage overlayPackage, String overlayBasePath,
             String overlayName, int userId) {
         if (DEBUG) {
@@ -90,14 +111,15 @@
             boolean enforce = enforceOverlayable(overlayPackage);
             if (mIdmapDaemon.verifyIdmap(targetPath, overlayBasePath, overlayName, policies,
                     enforce, userId)) {
-                return false;
+                return IDMAP_IS_VERIFIED;
             }
-            return mIdmapDaemon.createIdmap(targetPath, overlayBasePath, overlayName, policies,
-                    enforce, userId) != null;
+            final boolean idmapCreated = mIdmapDaemon.createIdmap(targetPath, overlayBasePath,
+                    overlayName, policies, enforce, userId) != null;
+            return (idmapCreated) ? IDMAP_IS_MODIFIED | IDMAP_IS_VERIFIED : IDMAP_NOT_EXIST;
         } catch (Exception e) {
             Slog.w(TAG, "failed to generate idmap for " + targetPath + " and "
                     + overlayBasePath, e);
-            return false;
+            return IDMAP_NOT_EXIST;
         }
     }
 
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 8ecc607..9ba1552 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -1477,7 +1477,7 @@
                 targetPackageNames = pm.getTargetPackageNames(userId);
             }
 
-            final Map<String, OverlayPaths> pendingChanges =
+            final ArrayMap<String, OverlayPaths> pendingChanges =
                     new ArrayMap<>(targetPackageNames.size());
             synchronized (mLock) {
                 final OverlayPaths frameworkOverlays =
@@ -1493,6 +1493,9 @@
             }
 
             final HashSet<String> updatedPackages = new HashSet<>();
+            final HashSet<String> invalidPackages = new HashSet<>();
+            pm.setEnabledOverlayPackages(userId, pendingChanges, updatedPackages, invalidPackages);
+
             for (final String targetPackageName : targetPackageNames) {
                 if (DEBUG) {
                     Slog.d(TAG, "-> Updating overlay: target=" + targetPackageName + " overlays=["
@@ -1500,11 +1503,10 @@
                             + "] userId=" + userId);
                 }
 
-                if (!pm.setEnabledOverlayPackages(
-                        userId, targetPackageName, pendingChanges.get(targetPackageName),
-                        updatedPackages)) {
-                    Slog.e(TAG, String.format("Failed to change enabled overlays for %s user %d",
-                            targetPackageName, userId));
+                if (invalidPackages.contains(targetPackageName)) {
+                    Slog.e(TAG, TextUtils.formatSimple(
+                            "Failed to change enabled overlays for %s user %d", targetPackageName,
+                            userId));
                 }
             }
             return new ArrayList<>(updatedPackages);
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 38781fa..e15e65a 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -24,6 +24,9 @@
 import static android.content.om.OverlayInfo.STATE_TARGET_IS_BEING_REPLACED;
 import static android.os.UserHandle.USER_SYSTEM;
 
+import static com.android.server.om.IdmapManager.IDMAP_IS_MODIFIED;
+import static com.android.server.om.IdmapManager.IDMAP_IS_VERIFIED;
+import static com.android.server.om.IdmapManager.IDMAP_NOT_EXIST;
 import static com.android.server.om.OverlayManagerService.DEBUG;
 import static com.android.server.om.OverlayManagerService.TAG;
 
@@ -785,15 +788,18 @@
         // Immutable RROs targeting to "android", ie framework-res.apk, are handled by native
         // layers.
         final OverlayInfo updatedOverlayInfo = mSettings.getOverlayInfo(overlay, userId);
+        @IdmapManager.IdmapStatus int idmapStatus = IDMAP_NOT_EXIST;
         if (targetPackage != null && !("android".equals(info.getTargetPackageName())
                 && !isPackageConfiguredMutable(overlayPackage))) {
-            modified |= mIdmapManager.createIdmap(targetPackage, overlayPackage,
-                    updatedOverlayInfo.baseCodePath, overlay.getOverlayName(), userId);
+            idmapStatus = mIdmapManager.createIdmap(targetPackage,
+                    overlayPackage, updatedOverlayInfo.baseCodePath, overlay.getOverlayName(),
+                    userId);
+            modified |= (idmapStatus & IDMAP_IS_MODIFIED) != 0;
         }
 
         final @OverlayInfo.State int currentState = mSettings.getState(overlay, userId);
         final @OverlayInfo.State int newState = calculateNewState(updatedOverlayInfo, targetPackage,
-                userId, flags);
+                userId, flags, idmapStatus);
         if (currentState != newState) {
             if (DEBUG) {
                 Slog.d(TAG, String.format("%s:%d: %s -> %s",
@@ -808,7 +814,8 @@
     }
 
     private @OverlayInfo.State int calculateNewState(@NonNull final OverlayInfo info,
-            @Nullable final AndroidPackage targetPackage, final int userId, final int flags)
+            @Nullable final AndroidPackage targetPackage, final int userId, final int flags,
+            @IdmapManager.IdmapStatus final int idmapStatus)
             throws OverlayManagerSettings.BadKeyException {
         if ((flags & FLAG_TARGET_IS_BEING_REPLACED) != 0) {
             return STATE_TARGET_IS_BEING_REPLACED;
@@ -822,8 +829,10 @@
             return STATE_MISSING_TARGET;
         }
 
-        if (!mIdmapManager.idmapExists(info)) {
-            return STATE_NO_IDMAP;
+        if ((idmapStatus & IDMAP_IS_VERIFIED) == 0) {
+            if (!mIdmapManager.idmapExists(info)) {
+                return STATE_NO_IDMAP;
+            }
         }
 
         final boolean enabled = mSettings.getEnabled(info.getOverlayIdentifier(), userId);
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index a91c55f..e07e3c1 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -119,16 +119,18 @@
         @Nullable public final String apexModuleName;
         public final File apexDirectory;
         public final File preInstalledApexPath;
+        public final boolean isFactory;
 
         private ActiveApexInfo(File apexDirectory, File preInstalledApexPath) {
-            this(null, apexDirectory, preInstalledApexPath);
+            this(null, apexDirectory, preInstalledApexPath, true);
         }
 
         private ActiveApexInfo(@Nullable String apexModuleName, File apexDirectory,
-                File preInstalledApexPath) {
+                File preInstalledApexPath, boolean isFactory) {
             this.apexModuleName = apexModuleName;
             this.apexDirectory = apexDirectory;
             this.preInstalledApexPath = preInstalledApexPath;
+            this.isFactory = isFactory;
         }
 
         private ActiveApexInfo(ApexInfo apexInfo) {
@@ -136,7 +138,8 @@
                     apexInfo.moduleName,
                     new File(Environment.getApexDirectory() + File.separator
                             + apexInfo.moduleName),
-                    new File(apexInfo.preinstalledModulePath));
+                    new File(apexInfo.preinstalledModulePath),
+                    apexInfo.isFactory);
         }
     }
 
@@ -211,7 +214,7 @@
      * @return {@code true} if this package is pre-installed, {@code false} otherwise.
      */
     public static boolean isFactory(@NonNull PackageInfo packageInfo) {
-        return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+        return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 0;
     }
 
     /**
@@ -503,7 +506,7 @@
          * @return {@code true} if this package is active, {@code false} otherwise.
          */
         private static boolean isActive(PackageInfo packageInfo) {
-            return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0;
+            return packageInfo.isActiveApex;
         }
 
         /**
@@ -1150,7 +1153,7 @@
                 // Installation was successful, time to update mAllPackagesCache
                 synchronized (mLock) {
                     if (isFactory(existingApexPkg)) {
-                        existingApexPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
+                        existingApexPkg.isActiveApex = false;
                         mAllPackagesCache.add(finalApexPkg);
                     } else {
                         for (int i = 0, size = mAllPackagesCache.size(); i < size; i++) {
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 80d61b5..a548b72 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -540,8 +540,13 @@
                                 && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
                                 || (matchVisibleToInstantAppOnly && isCallerInstantApp
                                 && isTargetHiddenFromInstantApp));
+                final boolean resolveForStartNonExported = resolveForStart
+                                && !ai.exported
+                                && !isCallerSameApp(pkgName, filterCallingUid);
                 final boolean blockNormalResolution =
-                        !resolveForStart && !isTargetInstantApp && !isCallerInstantApp
+                        (!resolveForStart || resolveForStartNonExported)
+                                && !isTargetInstantApp
+                                && !isCallerInstantApp
                                 && shouldFilterApplication(
                                 getPackageStateInternal(ai.applicationInfo.packageName,
                                         Process.SYSTEM_UID), filterCallingUid, userId);
@@ -1835,9 +1840,6 @@
                 list.addAll(mApexManager.getFactoryPackages());
             } else {
                 list.addAll(mApexManager.getActivePackages());
-                if (listUninstalled) {
-                    list.addAll(mApexManager.getInactivePackages());
-                }
             }
         }
         return new ParceledListSlice<>(list);
@@ -4345,11 +4347,8 @@
 
     @Override
     public List<String> getAllPackages() {
-        // Allow iorapd to call this method.
-        if (Binder.getCallingUid() != Process.IORAPD_UID) {
-            PackageManagerServiceUtils.enforceSystemOrRootOrShell(
-                    "getAllPackages is limited to privileged callers");
-        }
+        PackageManagerServiceUtils.enforceSystemOrRootOrShell(
+                "getAllPackages is limited to privileged callers");
         final int callingUid = Binder.getCallingUid();
         final int callingUserId = UserHandle.getUserId(callingUid);
         if (canViewInstantApps(callingUid, callingUserId)) {
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index 7dae22a..52d4873 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -39,7 +39,6 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageDeleteObserver2;
-import android.content.pm.PackageChangeEvent;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.content.pm.SharedLibraryInfo;
@@ -762,7 +761,6 @@
             } catch (RemoteException e) {
                 Log.i(TAG, "Observer no longer exists.");
             } //end catch
-            notifyPackageChangeObserversOnDelete(packageName, versionCode);
 
             // Prune unused static shared libraries which have been cached a period of time
             mPm.schedulePruneUnusedStaticSharedLibraries(true /* delay */);
@@ -822,18 +820,6 @@
         return result;
     }
 
-    private void notifyPackageChangeObserversOnDelete(String packageName, long version) {
-        PackageChangeEvent pkgChangeEvent = new PackageChangeEvent();
-        pkgChangeEvent.packageName = packageName;
-        pkgChangeEvent.version = version;
-        pkgChangeEvent.lastUpdateTimeMillis = 0L;
-        pkgChangeEvent.newInstalled = false;
-        pkgChangeEvent.dataRemoved = false;
-        pkgChangeEvent.isDeleted = true;
-
-        mPm.notifyPackageChangeObservers(pkgChangeEvent);
-    }
-
     private static class TempUserState {
         public final int enabledState;
         @Nullable
diff --git a/services/core/java/com/android/server/pm/DistractingPackageHelper.java b/services/core/java/com/android/server/pm/DistractingPackageHelper.java
index 7dc45b5..b28b73e 100644
--- a/services/core/java/com/android/server/pm/DistractingPackageHelper.java
+++ b/services/core/java/com/android/server/pm/DistractingPackageHelper.java
@@ -17,6 +17,7 @@
 package com.android.server.pm;
 
 import static android.content.pm.PackageManager.RESTRICTION_NONE;
+import static android.os.Process.SYSTEM_UID;
 
 import android.annotation.NonNull;
 import android.content.Intent;
@@ -27,11 +28,13 @@
 import android.util.ArraySet;
 import android.util.IntArray;
 import android.util.Slog;
+import android.util.SparseArray;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.server.pm.pkg.PackageStateInternal;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -126,7 +129,7 @@
         if (!changedPackagesList.isEmpty()) {
             final String[] changedPackages = changedPackagesList.toArray(
                     new String[changedPackagesList.size()]);
-            sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
+            sendDistractingPackagesChanged(snapshot, changedPackages, changedUids.toArray(), userId,
                     restrictionFlags);
             mPm.scheduleWritePackageRestrictions(userId);
         }
@@ -168,7 +171,7 @@
         if (!changedPackages.isEmpty()) {
             final String[] packageArray = changedPackages.toArray(
                     new String[changedPackages.size()]);
-            sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId,
+            sendDistractingPackagesChanged(snapshot, packageArray, changedUids.toArray(), userId,
                     RESTRICTION_NONE);
             mPm.scheduleWritePackageRestrictions(userId);
         }
@@ -181,18 +184,53 @@
      * @param uidList The uids of packages which have suspension changes.
      * @param userId The user where packages reside.
      */
-    void sendDistractingPackagesChanged(@NonNull String[] pkgList,
+    void sendDistractingPackagesChanged(@NonNull Computer snapshot, @NonNull String[] pkgList,
             int[] uidList, int userId, int distractionFlags) {
-        final Bundle extras = new Bundle(3);
-        extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
-        extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
-        extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
+        final List<List<String>> pkgsToSend = new ArrayList(pkgList.length);
+        final List<IntArray> uidsToSend = new ArrayList(pkgList.length);
+        final List<SparseArray<int[]>> allowListsToSend = new ArrayList(pkgList.length);
+        final int[] userIds = new int[] {userId};
+        // Get allow lists for the pkg in the pkgList. Merge into the existed pkgs and uids if
+        // allow lists are the same.
+        for (int i = 0; i < pkgList.length; i++) {
+            final String pkgName = pkgList[i];
+            final int uid = uidList[i];
+            SparseArray<int[]> allowList = mInjector.getAppsFilter().getVisibilityAllowList(
+                    snapshot.getPackageStateInternal(pkgName, SYSTEM_UID),
+                    userIds, snapshot.getPackageStates());
+            if (allowList == null) {
+                allowList = new SparseArray<>(0);
+            }
+            boolean merged = false;
+            for (int j = 0; j < allowListsToSend.size(); j++) {
+                if (Arrays.equals(allowListsToSend.get(j).get(userId), allowList.get(userId))) {
+                    pkgsToSend.get(j).add(pkgName);
+                    uidsToSend.get(j).add(uid);
+                    merged = true;
+                    break;
+                }
+            }
+            if (!merged) {
+                pkgsToSend.add(new ArrayList<>(Arrays.asList(pkgName)));
+                uidsToSend.add(IntArray.wrap(new int[] {uid}));
+                allowListsToSend.add(allowList);
+            }
+        }
 
         final Handler handler = mInjector.getHandler();
-        handler.post(() -> mBroadcastHelper.sendPackageBroadcast(
-                Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */, extras,
-                Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */,
-                null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */,
-                null /* allowList */, null /* bOptions */));
+        for (int i = 0; i < pkgsToSend.size(); i++) {
+            final Bundle extras = new Bundle(3);
+            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST,
+                    pkgsToSend.get(i).toArray(new String[pkgsToSend.get(i).size()]));
+            extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidsToSend.get(i).toArray());
+            extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
+            final SparseArray<int[]> allowList = allowListsToSend.get(i).size() == 0
+                    ? null : allowListsToSend.get(i);
+            handler.post(() -> mBroadcastHelper.sendPackageBroadcast(
+                    Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null /* pkg */,
+                    extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */,
+                    null /* finishedReceiver */, userIds, null /* instantUserIds */,
+                    allowList, null /* bOptions */));
+        }
     }
 }
diff --git a/services/core/java/com/android/server/pm/InitAppsHelper.java b/services/core/java/com/android/server/pm/InitAppsHelper.java
index 154f32a..3dd0022 100644
--- a/services/core/java/com/android/server/pm/InitAppsHelper.java
+++ b/services/core/java/com/android/server/pm/InitAppsHelper.java
@@ -21,6 +21,7 @@
 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME;
 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME;
 import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX;
+import static com.android.server.pm.PackageManagerService.SCAN_AS_FACTORY;
 import static com.android.server.pm.PackageManagerService.SCAN_AS_PRIVILEGED;
 import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM;
 import static com.android.server.pm.PackageManagerService.SCAN_BOOTING;
@@ -31,6 +32,7 @@
 import static com.android.server.pm.PackageManagerService.SYSTEM_PARTITIONS;
 import static com.android.server.pm.PackageManagerService.TAG;
 import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_APK_IN_APEX;
+import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_FRAMEWORK_RES_SPLITS;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -167,7 +169,11 @@
                     sp.getFolder().getAbsolutePath())
                     || apexInfo.preInstalledApexPath.getAbsolutePath().startsWith(
                     sp.getFolder().getAbsolutePath() + File.separator)) {
-                return new ScanPartition(apexInfo.apexDirectory, sp, SCAN_AS_APK_IN_APEX);
+                int additionalScanFlag = SCAN_AS_APK_IN_APEX;
+                if (apexInfo.isFactory) {
+                    additionalScanFlag |= SCAN_AS_FACTORY;
+                }
+                return new ScanPartition(apexInfo.apexDirectory, sp, additionalScanFlag);
             }
         }
         return null;
@@ -317,8 +323,9 @@
                     packageParser, executorService);
         }
 
-        scanDirTracedLI(frameworkDir, null,
-                mSystemParseFlags,
+        List<File> frameworkSplits = getFrameworkResApkSplitFiles();
+        scanDirTracedLI(frameworkDir, frameworkSplits,
+                mSystemParseFlags | PARSE_FRAMEWORK_RES_SPLITS,
                 mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED,
                 packageParser, executorService);
         if (!mPm.mPackages.containsKey("android")) {
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 77d37dc..3b75947 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -60,6 +60,7 @@
 import static com.android.server.pm.PackageManagerService.POST_INSTALL;
 import static com.android.server.pm.PackageManagerService.PRECOMPILE_LAYOUTS;
 import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX;
+import static com.android.server.pm.PackageManagerService.SCAN_AS_FACTORY;
 import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP;
 import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
 import static com.android.server.pm.PackageManagerService.SCAN_AS_ODM;
@@ -101,7 +102,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.DataLoaderType;
 import android.content.pm.IPackageInstallObserver2;
-import android.content.pm.PackageChangeEvent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInfoLite;
 import android.content.pm.PackageInstaller;
@@ -315,6 +315,12 @@
             pkgSetting.setInstallSource(installSource);
         }
 
+        if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
+            boolean isFactory = (scanFlags & SCAN_AS_FACTORY) != 0;
+            pkgSetting.getPkgState().setApkInApex(true);
+            pkgSetting.getPkgState().setApkInUpdatedApex(!isFactory);
+        }
+
         // TODO(toddke): Consider a method specifically for modifying the Package object
         // post scan; or, moving this stuff out of the Package object since it has nothing
         // to do with the package on disk.
@@ -2341,29 +2347,11 @@
             // BackgroundDexOptService will remove it from its denylist.
             // TODO: Layering violation
             BackgroundDexOptService.getService().notifyPackageChanged(packageName);
-
-            notifyPackageChangeObserversOnUpdate(reconciledPkg);
         }
         PackageManagerServiceUtils.waitForNativeBinariesExtractionForIncremental(
                 incrementalStorages);
     }
 
-    private void notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg) {
-        final PackageSetting pkgSetting = reconciledPkg.mPkgSetting;
-        final PackageInstalledInfo pkgInstalledInfo = reconciledPkg.mInstallResult;
-        final PackageRemovedInfo pkgRemovedInfo = pkgInstalledInfo.mRemovedInfo;
-
-        PackageChangeEvent pkgChangeEvent = new PackageChangeEvent();
-        pkgChangeEvent.packageName = pkgSetting.getPkg().getPackageName();
-        pkgChangeEvent.version = pkgSetting.getVersionCode();
-        pkgChangeEvent.lastUpdateTimeMillis = pkgSetting.getLastUpdateTime();
-        pkgChangeEvent.newInstalled = (pkgRemovedInfo == null || !pkgRemovedInfo.mIsUpdate);
-        pkgChangeEvent.dataRemoved = (pkgRemovedInfo != null && pkgRemovedInfo.mDataRemoved);
-        pkgChangeEvent.isDeleted = false;
-
-        mPm.notifyPackageChangeObservers(pkgChangeEvent);
-    }
-
     public int installLocationPolicy(PackageInfoLite pkgLite, int installFlags) {
         String packageName = pkgLite.packageName;
         int installLocation = pkgLite.installLocation;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 7c900ef..3e314a4 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -299,6 +299,10 @@
     final SessionParams params;
     final long createdMillis;
 
+    /** Used for tracking whether user action was required for an install. */
+    @Nullable
+    private Boolean mUserActionRequired;
+
     /** Staging location where client data is written. */
     final File stageDir;
     final String stageCid;
@@ -2131,8 +2135,16 @@
          * in its belong session set. When the user answers the yes,
          * {@link #setPermissionsResult(boolean)} is called and then {@link #MSG_INSTALL} is
          * handled to come back here to check again.
+         *
+         * {@code mUserActionRequired} is used to track when user action is required for an
+         * install. Since control may come back here more than 1 time, we must ensure that it's
+         * value is not overwritten.
          */
-        if (sendPendingUserActionIntentIfNeeded()) {
+        boolean wasUserActionIntentSent = sendPendingUserActionIntentIfNeeded();
+        if (mUserActionRequired == null) {
+            mUserActionRequired = wasUserActionIntentSent;
+        }
+        if (wasUserActionIntentSent) {
             return;
         }
 
@@ -3323,6 +3335,18 @@
         }
     }
 
+    /**
+     * @return a boolean value indicating whether user action was requested for the install.
+     * Returns {@code false} if {@code mUserActionRequired} is {@code null}
+     */
+    public boolean getUserActionRequired() {
+        if (mUserActionRequired != null) {
+            return mUserActionRequired.booleanValue();
+        }
+        Slog.wtf(TAG, "mUserActionRequired should not be null.");
+        return false;
+    }
+
     private static String getRelativePath(File file, File base) throws IOException {
         final String pathStr = file.getAbsolutePath();
         final String baseStr = base.getAbsolutePath();
diff --git a/services/core/java/com/android/server/pm/PackageManagerNative.java b/services/core/java/com/android/server/pm/PackageManagerNative.java
index 9a43008..77d2ec9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerNative.java
+++ b/services/core/java/com/android/server/pm/PackageManagerNative.java
@@ -20,20 +20,16 @@
 
 import static com.android.server.pm.PackageManagerService.TAG;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageChangeObserver;
 import android.content.pm.IPackageManagerNative;
 import android.content.pm.IStagedApexObserver;
 import android.content.pm.PackageInfo;
 import android.content.pm.StagedApexInfo;
 import android.os.Binder;
-import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.Slog;
 
 import java.util.Arrays;
@@ -46,35 +42,6 @@
     }
 
     @Override
-    public void registerPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
-        synchronized (mPm.mPackageChangeObservers) {
-            try {
-                observer.asBinder().linkToDeath(
-                        new PackageChangeObserverDeathRecipient(observer), 0);
-            } catch (RemoteException e) {
-                Log.e(TAG, e.getMessage());
-            }
-            mPm.mPackageChangeObservers.add(observer);
-            Log.d(TAG, "Size of mPackageChangeObservers after registry is "
-                    + mPm.mPackageChangeObservers.size());
-        }
-    }
-
-    @Override
-    public void unregisterPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
-        synchronized (mPm.mPackageChangeObservers) {
-            mPm.mPackageChangeObservers.remove(observer);
-            Log.d(TAG, "Size of mPackageChangeObservers after unregistry is "
-                    + mPm.mPackageChangeObservers.size());
-        }
-    }
-
-    @Override
-    public String[] getAllPackages() {
-        return mPm.snapshotComputer().getAllPackages().toArray(new String[0]);
-    }
-
-    @Override
     public String[] getNamesForUids(int[] uids) throws RemoteException {
         String[] names = null;
         String[] results = null;
@@ -222,21 +189,4 @@
     public StagedApexInfo getStagedApexInfo(String moduleName) {
         return mPm.mInstallerService.getStagingManager().getStagedApexInfo(moduleName);
     }
-
-    private final class PackageChangeObserverDeathRecipient implements IBinder.DeathRecipient {
-        private final IPackageChangeObserver mObserver;
-
-        PackageChangeObserverDeathRecipient(IPackageChangeObserver observer) {
-            mObserver = observer;
-        }
-
-        @Override
-        public void binderDied() {
-            synchronized (mPm.mPackageChangeObservers) {
-                mPm.mPackageChangeObservers.remove(mObserver);
-                Log.d(TAG, "Size of mPackageChangeObservers after removing dead observer is "
-                        + mPm.mPackageChangeObservers.size());
-            }
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ce1ee70..d93334e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -80,7 +80,6 @@
 import android.content.pm.FeatureInfo;
 import android.content.pm.IDexModuleRegisterCallback;
 import android.content.pm.IOnChecksumsReadyListener;
-import android.content.pm.IPackageChangeObserver;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageDeleteObserver2;
 import android.content.pm.IPackageInstallObserver2;
@@ -92,7 +91,6 @@
 import android.content.pm.InstantAppInfo;
 import android.content.pm.InstantAppRequest;
 import android.content.pm.ModuleInfo;
-import android.content.pm.PackageChangeEvent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageInfoLite;
 import android.content.pm.PackageInstaller;
@@ -376,6 +374,7 @@
     static final int SCAN_AS_SYSTEM_EXT = 1 << 21;
     static final int SCAN_AS_ODM = 1 << 22;
     static final int SCAN_AS_APK_IN_APEX = 1 << 23;
+    static final int SCAN_AS_FACTORY = 1 << 24;
 
     @IntDef(flag = true, prefix = { "SCAN_" }, value = {
             SCAN_NO_DEX,
@@ -690,10 +689,6 @@
 
     private @NonNull final OverlayConfig mOverlayConfig;
 
-    @GuardedBy("itself")
-    final ArrayList<IPackageChangeObserver> mPackageChangeObservers =
-        new ArrayList<>();
-
     // Cached parsed flag value. Invalidated on each flag change.
     PerUidReadTimeouts[] mPerUidReadTimeoutsCache;
 
@@ -1842,10 +1837,10 @@
         mDexOptHelper = new DexOptHelper(this);
         mSuspendPackageHelper = new SuspendPackageHelper(this, mInjector, mBroadcastHelper,
                 mProtectedPackages);
-        mStorageEventHelper = new StorageEventHelper(this, mDeletePackageHelper,
-                mRemovePackageHelper);
         mDistractingPackageHelper = new DistractingPackageHelper(this, mInjector, mBroadcastHelper,
                 mSuspendPackageHelper);
+        mStorageEventHelper = new StorageEventHelper(this, mDeletePackageHelper,
+                mRemovePackageHelper);
 
         synchronized (mLock) {
             // Create the computer as soon as the state objects have been installed.  The
@@ -3142,23 +3137,6 @@
         });
     }
 
-    void notifyPackageChangeObservers(PackageChangeEvent event) {
-        try {
-            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "notifyPackageChangeObservers");
-            synchronized (mPackageChangeObservers) {
-                for (IPackageChangeObserver observer : mPackageChangeObservers) {
-                    try {
-                        observer.onPackageChanged(event);
-                    } catch (RemoteException e) {
-                        Log.wtf(TAG, e);
-                    }
-                }
-            }
-        } finally {
-            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-        }
-    }
-
     VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) {
         if (pkg.isExternalStorage()) {
             if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
@@ -4982,8 +4960,12 @@
         @Override
         public String getSplashScreenTheme(@NonNull String packageName, int userId) {
             final Computer snapshot = snapshotComputer();
+            final int callingUid = Binder.getCallingUid();
+            snapshot.enforceCrossUserPermission(
+                    callingUid, userId, false /* requireFullPermission */,
+                    false /* checkShell */, "getSplashScreenTheme");
             PackageStateInternal packageState = filterPackageStateForInstalledAndFiltered(snapshot,
-                    packageName, Binder.getCallingUid(), userId);
+                    packageName, callingUid, userId);
             return packageState == null ? null
                     : packageState.getUserStateOrDefault(userId).getSplashScreenTheme();
         }
@@ -6271,11 +6253,12 @@
         }
 
         @Override
-        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
-                @Nullable OverlayPaths overlayPaths,
-                @NonNull Set<String> outUpdatedPackageNames) {
-            return PackageManagerService.this.setEnabledOverlayPackages(userId, targetPackageName,
-                    overlayPaths, outUpdatedPackageNames);
+        public void setEnabledOverlayPackages(int userId,
+                @NonNull ArrayMap<String, OverlayPaths> pendingChanges,
+                @NonNull Set<String> outUpdatedPackageNames,
+                @NonNull Set<String> outInvalidPackageNames) {
+            PackageManagerService.this.setEnabledOverlayPackages(userId,
+                    pendingChanges, outUpdatedPackageNames, outInvalidPackageNames);
         }
 
         @Override
@@ -6483,85 +6466,119 @@
         }
     }
 
-    private boolean setEnabledOverlayPackages(@UserIdInt int userId,
-            @NonNull String targetPackageName, @Nullable OverlayPaths newOverlayPaths,
-            @NonNull Set<String> outUpdatedPackageNames) {
+    private void setEnabledOverlayPackages(@UserIdInt int userId,
+            @NonNull ArrayMap<String, OverlayPaths> pendingChanges,
+            @NonNull Set<String> outUpdatedPackageNames,
+            @NonNull Set<String> outInvalidPackageNames) {
+        final ArrayMap<String, ArrayMap<String, ArraySet<String>>>
+                targetPkgToLibNameToModifiedDependents = new ArrayMap<>();
+        final int numberOfPendingChanges = pendingChanges.size();
+
         synchronized (mOverlayPathsLock) {
-            final ArrayMap<String, ArraySet<String>> libNameToModifiedDependents = new ArrayMap<>();
             Computer computer = snapshotComputer();
-            final PackageStateInternal packageState = computer.getPackageStateInternal(
-                    targetPackageName);
-            final AndroidPackage targetPkg = packageState == null ? null : packageState.getPkg();
-            if (targetPackageName == null || targetPkg == null) {
-                Slog.e(TAG, "failed to find package " + targetPackageName);
-                return false;
-            }
+            for (int i = 0; i < numberOfPendingChanges; i++) {
+                final String targetPackageName = pendingChanges.keyAt(i);
+                final OverlayPaths newOverlayPaths = pendingChanges.valueAt(i);
+                final PackageStateInternal packageState = computer.getPackageStateInternal(
+                        targetPackageName);
+                final AndroidPackage targetPkg =
+                        packageState == null ? null : packageState.getPkg();
+                if (targetPackageName == null || targetPkg == null) {
+                    Slog.e(TAG, "failed to find package " + targetPackageName);
+                    outInvalidPackageNames.add(targetPackageName);
+                    continue;
+                }
 
-            if (Objects.equals(packageState.getUserStateOrDefault(userId).getOverlayPaths(),
-                    newOverlayPaths)) {
-                return true;
-            }
+                if (Objects.equals(packageState.getUserStateOrDefault(userId).getOverlayPaths(),
+                        newOverlayPaths)) {
+                    continue;
+                }
 
-            if (targetPkg.getLibraryNames() != null) {
-                // Set the overlay paths for dependencies of the shared library.
-                for (final String libName : targetPkg.getLibraryNames()) {
-                    ArraySet<String> modifiedDependents = null;
+                if (targetPkg.getLibraryNames() != null) {
+                    // Set the overlay paths for dependencies of the shared library.
+                    for (final String libName : targetPkg.getLibraryNames()) {
+                        ArraySet<String> modifiedDependents = null;
 
-                    final SharedLibraryInfo info = computer.getSharedLibraryInfo(libName,
-                            SharedLibraryInfo.VERSION_UNDEFINED);
-                    if (info == null) {
-                        continue;
-                    }
-                    final List<VersionedPackage> dependents = computer
-                            .getPackagesUsingSharedLibrary(info, 0, Process.SYSTEM_UID, userId);
-                    if (dependents == null) {
-                        continue;
-                    }
-                    for (final VersionedPackage dependent : dependents) {
-                        final PackageStateInternal dependentState =
-                                computer.getPackageStateInternal(dependent.getPackageName());
-                        if (dependentState == null) {
+                        final SharedLibraryInfo info = computer.getSharedLibraryInfo(libName,
+                                SharedLibraryInfo.VERSION_UNDEFINED);
+                        if (info == null) {
                             continue;
                         }
-                        if (!Objects.equals(dependentState.getUserStateOrDefault(userId)
-                                .getSharedLibraryOverlayPaths()
-                                .get(libName), newOverlayPaths)) {
-                            String dependentPackageName = dependent.getPackageName();
-                            modifiedDependents = ArrayUtils.add(modifiedDependents,
-                                    dependentPackageName);
-                            outUpdatedPackageNames.add(dependentPackageName);
+                        final List<VersionedPackage> dependents =
+                                computer.getPackagesUsingSharedLibrary(info, 0, Process.SYSTEM_UID,
+                                        userId);
+                        if (dependents == null) {
+                            continue;
+                        }
+                        for (final VersionedPackage dependent : dependents) {
+                            final PackageStateInternal dependentState =
+                                    computer.getPackageStateInternal(dependent.getPackageName());
+                            if (dependentState == null) {
+                                continue;
+                            }
+                            if (!Objects.equals(dependentState.getUserStateOrDefault(userId)
+                                    .getSharedLibraryOverlayPaths()
+                                    .get(libName), newOverlayPaths)) {
+                                String dependentPackageName = dependent.getPackageName();
+                                modifiedDependents = ArrayUtils.add(modifiedDependents,
+                                        dependentPackageName);
+                                outUpdatedPackageNames.add(dependentPackageName);
+                            }
+                        }
+
+                        if (modifiedDependents != null) {
+                            ArrayMap<String, ArraySet<String>> libNameToModifiedDependents =
+                                    targetPkgToLibNameToModifiedDependents.get(
+                                            targetPackageName);
+                            if (libNameToModifiedDependents == null) {
+                                libNameToModifiedDependents = new ArrayMap<>();
+                                targetPkgToLibNameToModifiedDependents.put(targetPackageName,
+                                        libNameToModifiedDependents);
+                            }
+                            libNameToModifiedDependents.put(libName, modifiedDependents);
                         }
                     }
-
-                    if (modifiedDependents != null) {
-                        libNameToModifiedDependents.put(libName, modifiedDependents);
-                    }
                 }
+
+                outUpdatedPackageNames.add(targetPackageName);
             }
 
-            outUpdatedPackageNames.add(targetPackageName);
-
             commitPackageStateMutation(null, mutator -> {
-                mutator.forPackage(targetPackageName)
-                        .userState(userId)
-                        .setOverlayPaths(newOverlayPaths);
+                for (int i = 0; i < numberOfPendingChanges; i++) {
+                    final String targetPackageName = pendingChanges.keyAt(i);
+                    final OverlayPaths newOverlayPaths = pendingChanges.valueAt(i);
 
-                for (int mapIndex = 0; mapIndex < libNameToModifiedDependents.size(); mapIndex++) {
-                    String libName = libNameToModifiedDependents.keyAt(mapIndex);
-                    ArraySet<String> modifiedDependents =
-                            libNameToModifiedDependents.valueAt(mapIndex);
-                    for (int setIndex = 0; setIndex < modifiedDependents.size(); setIndex++) {
-                        mutator.forPackage(modifiedDependents.valueAt(setIndex))
-                                .userState(userId)
-                                .setOverlayPathsForLibrary(libName, newOverlayPaths);
+                    if (!outUpdatedPackageNames.contains(targetPackageName)) {
+                        continue;
+                    }
+
+                    mutator.forPackage(targetPackageName)
+                            .userState(userId)
+                            .setOverlayPaths(newOverlayPaths);
+
+                    final ArrayMap<String, ArraySet<String>> libNameToModifiedDependents =
+                            targetPkgToLibNameToModifiedDependents.get(
+                                    targetPackageName);
+                    if (libNameToModifiedDependents == null) {
+                        continue;
+                    }
+
+                    for (int mapIndex = 0; mapIndex < libNameToModifiedDependents.size();
+                            mapIndex++) {
+                        String libName = libNameToModifiedDependents.keyAt(mapIndex);
+                        ArraySet<String> modifiedDependents =
+                                libNameToModifiedDependents.valueAt(mapIndex);
+                        for (int setIndex = 0; setIndex < modifiedDependents.size(); setIndex++) {
+                            mutator.forPackage(modifiedDependents.valueAt(setIndex))
+                                    .userState(userId)
+                                    .setOverlayPathsForLibrary(libName, newOverlayPaths);
+                        }
                     }
                 }
             });
         }
 
         invalidatePackageInfoCache();
-
-        return true;
     }
 
     private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java b/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java
index 16829e0e8..f44d922 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceTestParams.java
@@ -115,6 +115,6 @@
     public ResolveIntentHelper resolveIntentHelper;
     public DexOptHelper dexOptHelper;
     public SuspendPackageHelper suspendPackageHelper;
-    public StorageEventHelper storageEventHelper;
     public DistractingPackageHelper distractingPackageHelper;
+    public StorageEventHelper storageEventHelper;
 }
diff --git a/services/core/java/com/android/server/pm/PackageSessionVerifier.java b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
index 2016fc3..8302c2b 100644
--- a/services/core/java/com/android/server/pm/PackageSessionVerifier.java
+++ b/services/core/java/com/android/server/pm/PackageSessionVerifier.java
@@ -167,7 +167,7 @@
         }
         return new VerificationParams(user, session.stageDir, observer, session.params,
                 session.getInstallSource(), session.getInstallerUid(), session.getSigningDetails(),
-                session.sessionId, session.getPackageLite(), mPm);
+                session.sessionId, session.getPackageLite(), session.getUserActionRequired(), mPm);
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 2bae00f..f84db1f 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -1227,6 +1227,11 @@
         return pkgState.isUpdatedSystemApp();
     }
 
+    @Override
+    public boolean isApkInUpdatedApex() {
+        return pkgState.isApkInUpdatedApex();
+    }
+
     public PackageSetting setDomainSetId(@NonNull UUID domainSetId) {
         mDomainSetId = domainSetId;
         onChanged();
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index b53cfc5..383e4a5 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -799,7 +799,6 @@
         // always make sure the system package code and resource paths dont change
         if (dp == null && p.getPkg() != null && p.getPkg().isSystem()
                 && !p.getPkgState().isUpdatedSystemApp()) {
-            p.getPkgState().setUpdatedSystemApp(true);
             final PackageSetting disabled;
             if (replaced) {
                 // a little trick...  when we install the new package, we don't
@@ -810,6 +809,7 @@
             } else {
                 disabled = p;
             }
+            p.getPkgState().setUpdatedSystemApp(true);
             mDisabledSysPackages.put(name, disabled);
             SharedUserSetting sharedUserSetting = getSharedUserSettingLPr(disabled);
             if (sharedUserSetting != null) {
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index b3723fb..f57eaae 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -894,8 +894,12 @@
 
         // Get the list of all dynamic shortcuts in this package.
         final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
+        // Pass callingLauncher to ensure pinned flag marked by system ui, e.g. ShareSheet, are
+        // included in the result
         findAll(shortcuts, ShortcutInfo::isNonManifestVisible,
-                ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION);
+                ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION,
+                mShortcutUser.mService.mContext.getPackageName(),
+                0, /*getPinnedByAnyLauncher=*/ false);
 
         final List<ShortcutManager.ShareShortcutInfo> result = new ArrayList<>();
         for (int i = 0; i < shortcuts.size(); i++) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index ee0fdc0..b6e633c 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1873,6 +1873,44 @@
     }
 
     @Override
+    public boolean setUserEphemeral(@UserIdInt int userId, boolean enableEphemeral) {
+        checkCreateUsersPermission("update ephemeral user flag");
+        UserData userToUpdate = null;
+        synchronized (mPackagesLock) {
+            synchronized (mUsersLock) {
+                final UserData userData = mUsers.get(userId);
+                if (userData == null) {
+                    Slog.e(LOG_TAG, "User not found for setting ephemeral mode: u" + userId);
+                    return false;
+                }
+                boolean isEphemeralUser = (userData.info.flags & UserInfo.FLAG_EPHEMERAL) != 0;
+                boolean isEphemeralOnCreateUser =
+                        (userData.info.flags & UserInfo.FLAG_EPHEMERAL_ON_CREATE) != 0;
+                // when user is created in ephemeral mode via FLAG_EPHEMERAL
+                // its state cannot be changed to non ephemeral.
+                // FLAG_EPHEMERAL_ON_CREATE is used to keep track of this state
+                if (isEphemeralOnCreateUser && !enableEphemeral) {
+                    Slog.e(LOG_TAG, "Failed to change user state to non-ephemeral for user "
+                            + userId);
+                    return false;
+                }
+                if (isEphemeralUser != enableEphemeral) {
+                    if (enableEphemeral) {
+                        userData.info.flags |= UserInfo.FLAG_EPHEMERAL;
+                    } else {
+                        userData.info.flags &= ~UserInfo.FLAG_EPHEMERAL;
+                    }
+                    userToUpdate = userData;
+                }
+            }
+            if (userToUpdate != null) {
+                writeUserLP(userToUpdate);
+            }
+        }
+        return true;
+    }
+
+    @Override
     public void setUserIcon(@UserIdInt int userId, Bitmap bitmap) {
         try {
             checkManageUsersPermission("update users");
@@ -3979,6 +4017,10 @@
                         flags &= ~UserInfo.FLAG_EPHEMERAL;
                     }
 
+                    if ((flags & UserInfo.FLAG_EPHEMERAL) != 0) {
+                        flags |= UserInfo.FLAG_EPHEMERAL_ON_CREATE;
+                    }
+
                     userInfo = new UserInfo(userId, name, null, flags, userType);
                     userInfo.serialNumber = mNextSerialNumber++;
                     userInfo.creationTime = getCreationTime();
diff --git a/services/core/java/com/android/server/pm/VerificationParams.java b/services/core/java/com/android/server/pm/VerificationParams.java
index 7423bf6..a333560 100644
--- a/services/core/java/com/android/server/pm/VerificationParams.java
+++ b/services/core/java/com/android/server/pm/VerificationParams.java
@@ -123,6 +123,7 @@
     final long mRequiredInstalledVersionCode;
     final int mDataLoaderType;
     final int mSessionId;
+    final boolean mUserActionRequired;
 
     private boolean mWaitForVerificationToComplete;
     private boolean mWaitForIntegrityVerificationToComplete;
@@ -135,7 +136,7 @@
     VerificationParams(UserHandle user, File stagedDir, IPackageInstallObserver2 observer,
             PackageInstaller.SessionParams sessionParams, InstallSource installSource,
             int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite,
-            PackageManagerService pm) {
+            boolean userActionRequired, PackageManagerService pm) {
         super(user, pm);
         mOriginInfo = OriginInfo.fromStagedFile(stagedDir);
         mObserver = observer;
@@ -154,6 +155,7 @@
                 ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
         mSessionId = sessionId;
         mPackageLite = lite;
+        mUserActionRequired = userActionRequired;
     }
 
     @Override
@@ -430,6 +432,8 @@
 
         verification.putExtra(PackageInstaller.EXTRA_SESSION_ID, mSessionId);
 
+        verification.putExtra(PackageManager.EXTRA_USER_ACTION_REQUIRED, mUserActionRequired);
+
         populateInstallerExtras(verification);
 
         // Streaming installation timeout schema is enabled only for:
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 849f530..16cf721 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -1022,7 +1022,8 @@
         }
         for (String packageName : packageNames) {
             grantPermissionsToSystemPackage(NO_PM_CACHE, packageName, userId,
-                    PHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS, SMS_PERMISSIONS,
+                    PHONE_PERMISSIONS, ALWAYS_LOCATION_PERMISSIONS, SMS_PERMISSIONS);
+            grantPermissionsToPackage(NO_PM_CACHE, packageName, userId, false, false,
                     NOTIFICATION_PERMISSIONS);
         }
     }
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 5a05134b..5d6ebec 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -277,10 +277,6 @@
     }
 
     private boolean checkAutoRevokeAccess(AndroidPackage pkg, int callingUid) {
-        if (pkg == null) {
-            return false;
-        }
-
         final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
                 Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS)
                 == PackageManager.PERMISSION_GRANTED;
@@ -292,6 +288,12 @@
                     + Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS
                     + " or be the installer on record");
         }
+
+        if (pkg == null || mPackageManagerInt.filterAppAccess(pkg, callingUid,
+                UserHandle.getUserId(callingUid))) {
+            return false;
+        }
+
         return true;
     }
 
@@ -301,9 +303,6 @@
 
         final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
         final int callingUid = Binder.getCallingUid();
-        if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
-            return false;
-        }
 
         if (!checkAutoRevokeAccess(pkg, callingUid)) {
             return false;
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index c524fb7..a963280 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -47,7 +47,6 @@
 import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
 import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
 
-import static com.android.server.pm.ApexManager.MATCH_ACTIVE_PACKAGE;
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
 import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
 import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
@@ -3240,9 +3239,7 @@
         }
         // Only enforce the allowlist on boot
         if (!mSystemReady) {
-            final boolean isInUpdatedApex = containingApexPackageName != null
-                    && !apexManager.isFactory(apexManager.getPackageInfo(containingApexPackageName,
-                    MATCH_ACTIVE_PACKAGE));
+            final boolean isInUpdatedApex = packageSetting.isApkInUpdatedApex();
             // Apps that are in updated apexs' do not need to be allowlisted
             if (!isInUpdatedApex) {
                 Slog.w(TAG, "Privileged permission " + permissionName + " for package "
diff --git a/services/core/java/com/android/server/pm/pkg/PackageState.java b/services/core/java/com/android/server/pm/pkg/PackageState.java
index 7726d7f..b5e0e44 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageState.java
@@ -303,6 +303,11 @@
     boolean isUpdatedSystemApp();
 
     /**
+     * Whether this app is packaged in an updated apex.
+     */
+    boolean isApkInUpdatedApex();
+
+    /**
      * @see AndroidPackageApi#isVendor()
      */
     boolean isVendor();
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java
index 3170304..878a837 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java
@@ -71,6 +71,7 @@
                 INSTALL_PERMISSIONS_FIXED,
                 UPDATE_AVAILABLE,
                 UPDATED_SYSTEM_APP,
+                APK_IN_UPDATED_APEX,
         })
         public @interface Flags {
         }
@@ -89,6 +90,7 @@
         private static final int INSTALL_PERMISSIONS_FIXED = 1 << 11;
         private static final int UPDATE_AVAILABLE = 1 << 12;
         private static final int UPDATED_SYSTEM_APP = 1 << 13;
+        private static final int APK_IN_UPDATED_APEX = 1 << 14;
     }
 
     private int mBooleans;
@@ -187,6 +189,7 @@
         setBoolean(Booleans.UPDATE_AVAILABLE, pkgState.isUpdateAvailable());
         mLastPackageUsageTime = pkgState.getLastPackageUsageTime();
         setBoolean(Booleans.UPDATED_SYSTEM_APP, pkgState.isUpdatedSystemApp());
+        setBoolean(Booleans.APK_IN_UPDATED_APEX, pkgState.isApkInUpdatedApex());
         mSigningInfo = pkgState.getSigningInfo();
 
         SparseArray<? extends PackageUserState> userStates = pkgState.getUserStates();
@@ -264,6 +267,11 @@
     }
 
     @Override
+    public boolean isApkInUpdatedApex() {
+        return getBoolean(Booleans.APK_IN_UPDATED_APEX);
+    }
+
+    @Override
     public boolean isVendor() {
         return getBoolean(Booleans.VENDOR);
     }
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
index 7bd720a..fad2f85 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
@@ -52,6 +52,8 @@
     private List<String> usesLibraryFiles = emptyList();
 
     private boolean updatedSystemApp;
+    private boolean apkInApex;
+    private boolean apkInUpdatedApex;
 
     @NonNull
     private volatile long[] lastPackageUsageTimeInMills;
@@ -116,6 +118,8 @@
         }
 
         this.updatedSystemApp = other.updatedSystemApp;
+        this.apkInApex = other.apkInApex;
+        this.apkInUpdatedApex = other.apkInUpdatedApex;
         this.lastPackageUsageTimeInMills = other.lastPackageUsageTimeInMills;
         this.overrideSeInfo = other.overrideSeInfo;
         mPackageSetting.onChanged();
@@ -150,6 +154,18 @@
         return this;
     }
 
+    public PackageStateUnserialized setApkInApex(boolean value) {
+        apkInApex = value;
+        mPackageSetting.onChanged();
+        return this;
+    }
+
+    public PackageStateUnserialized setApkInUpdatedApex(boolean value) {
+        apkInUpdatedApex = value;
+        mPackageSetting.onChanged();
+        return this;
+    }
+
     public PackageStateUnserialized setLastPackageUsageTimeInMills(@NonNull long... value) {
         lastPackageUsageTimeInMills = value;
         mPackageSetting.onChanged();
@@ -198,6 +214,16 @@
     }
 
     @DataClass.Generated.Member
+    public boolean isApkInApex() {
+        return apkInApex;
+    }
+
+    @DataClass.Generated.Member
+    public boolean isApkInUpdatedApex() {
+        return apkInUpdatedApex;
+    }
+
+    @DataClass.Generated.Member
     public @NonNull long[] getLastPackageUsageTimeInMills() {
         long[] _lastPackageUsageTimeInMills = lastPackageUsageTimeInMills;
         if (_lastPackageUsageTimeInMills == null) {
@@ -222,10 +248,10 @@
     }
 
     @DataClass.Generated(
-            time = 1642554781099L,
+            time = 1646203523807L,
             codegenVersion = "1.0.23",
             sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java",
-            inputSignatures = "private  boolean hiddenUntilInstalled\nprivate @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> usesLibraryInfos\nprivate @android.annotation.NonNull java.util.List<java.lang.String> usesLibraryFiles\nprivate  boolean updatedSystemApp\nprivate volatile @android.annotation.NonNull long[] lastPackageUsageTimeInMills\nprivate @android.annotation.Nullable java.lang.String overrideSeInfo\nprivate @android.annotation.NonNull com.android.server.pm.PackageSetting mPackageSetting\nprivate  long[] lazyInitLastPackageUsageTimeInMills()\npublic  com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(int,long)\npublic  long getLatestPackageUseTimeInMills()\npublic  long getLatestForegroundPackageUseTimeInMills()\npublic  void updateFrom(com.android.server.pm.pkg.PackageStateUnserialized)\npublic @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> getNonNativeUsesLibraryInfos()\npublic  com.android.server.pm.pkg.PackageStateUnserialized setHiddenUntilInstalled(boolean)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryInfos(java.util.List<android.content.pm.SharedLibraryInfo>)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryFiles(java.util.List<java.lang.String>)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setUpdatedSystemApp(boolean)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(long)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setOverrideSeInfo(java.lang.String)\nclass PackageStateUnserialized extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genSetters=true, genConstructor=false, genBuilder=false)")
+            inputSignatures = "private  boolean hiddenUntilInstalled\nprivate @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> usesLibraryInfos\nprivate @android.annotation.NonNull java.util.List<java.lang.String> usesLibraryFiles\nprivate  boolean updatedSystemApp\nprivate  boolean apkInApex\nprivate  boolean apkInUpdatedApex\nprivate volatile @android.annotation.NonNull long[] lastPackageUsageTimeInMills\nprivate @android.annotation.Nullable java.lang.String overrideSeInfo\nprivate final @android.annotation.NonNull com.android.server.pm.PackageSetting mPackageSetting\nprivate  long[] lazyInitLastPackageUsageTimeInMills()\npublic  com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(int,long)\npublic  long getLatestPackageUseTimeInMills()\npublic  long getLatestForegroundPackageUseTimeInMills()\npublic  void updateFrom(com.android.server.pm.pkg.PackageStateUnserialized)\npublic @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> getNonNativeUsesLibraryInfos()\npublic  com.android.server.pm.pkg.PackageStateUnserialized setHiddenUntilInstalled(boolean)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryInfos(java.util.List<android.content.pm.SharedLibraryInfo>)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryFiles(java.util.List<java.lang.String>)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setUpdatedSystemApp(boolean)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setApkInApex(boolean)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setApkInUpdatedApex(boolean)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(long)\npublic  com.android.server.pm.pkg.PackageStateUnserialized setOverrideSeInfo(java.lang.String)\nclass PackageStateUnserialized extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genSetters=true, genConstructor=false, genBuilder=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/services/core/java/com/android/server/pm/pkg/parsing/PackageInfoWithoutStateUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/PackageInfoWithoutStateUtils.java
index 91d2010..8a64884 100644
--- a/services/core/java/com/android/server/pm/pkg/parsing/PackageInfoWithoutStateUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/parsing/PackageInfoWithoutStateUtils.java
@@ -321,19 +321,15 @@
 
             pi.applicationInfo.sourceDir = apexFile.getPath();
             pi.applicationInfo.publicSourceDir = apexFile.getPath();
+            pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
+            pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
             if (apexInfo.isFactory) {
-                pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
                 pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
             } else {
-                pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
                 pi.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
             }
-            if (apexInfo.isActive) {
-                pi.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
-            } else {
-                pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
-            }
             pi.isApex = true;
+            pi.isActiveApex = apexInfo.isActive;
         }
 
         final SigningDetails signingDetails = pkg.getSigningDetails();
diff --git a/services/core/java/com/android/server/power/ShutdownCheckPoints.java b/services/core/java/com/android/server/power/ShutdownCheckPoints.java
index 05ee7df..1a9eae6 100644
--- a/services/core/java/com/android/server/power/ShutdownCheckPoints.java
+++ b/services/core/java/com/android/server/power/ShutdownCheckPoints.java
@@ -36,7 +36,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
-import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -56,7 +55,7 @@
     private static final SimpleDateFormat DATE_FORMAT =
             new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS z");
 
-    private final LinkedList<CheckPoint> mCheckPoints;
+    private final ArrayList<CheckPoint> mCheckPoints;
     private final Injector mInjector;
 
     private ShutdownCheckPoints() {
@@ -85,7 +84,7 @@
 
     @VisibleForTesting
     ShutdownCheckPoints(Injector injector) {
-        mCheckPoints = new LinkedList<>();
+        mCheckPoints = new ArrayList<>();
         mInjector = injector;
     }
 
@@ -144,8 +143,8 @@
 
     private void recordCheckPointInternal(CheckPoint checkPoint) {
         synchronized (mCheckPoints) {
-            mCheckPoints.addLast(checkPoint);
-            if (mCheckPoints.size() > mInjector.maxCheckPoints()) mCheckPoints.removeFirst();
+            mCheckPoints.add(checkPoint);
+            if (mCheckPoints.size() > mInjector.maxCheckPoints()) mCheckPoints.remove(0);
         }
     }
 
diff --git a/services/core/java/com/android/server/security/AndroidKeystoreAttestationVerificationAttributes.java b/services/core/java/com/android/server/security/AndroidKeystoreAttestationVerificationAttributes.java
index 3543e93..928d128 100644
--- a/services/core/java/com/android/server/security/AndroidKeystoreAttestationVerificationAttributes.java
+++ b/services/core/java/com/android/server/security/AndroidKeystoreAttestationVerificationAttributes.java
@@ -32,6 +32,7 @@
 import com.android.internal.org.bouncycastle.asn1.ASN1TaggedObject;
 import com.android.internal.org.bouncycastle.asn1.x509.Certificate;
 
+import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
@@ -147,7 +148,7 @@
     @NonNull
     static AndroidKeystoreAttestationVerificationAttributes fromCertificate(
             @NonNull X509Certificate x509Certificate)
-            throws Exception {
+            throws CertificateEncodingException, IOException {
         return new AndroidKeystoreAttestationVerificationAttributes(x509Certificate);
     }
 
@@ -281,7 +282,7 @@
     }
 
     private AndroidKeystoreAttestationVerificationAttributes(X509Certificate x509Certificate)
-            throws Exception {
+            throws CertificateEncodingException, IOException {
         Certificate certificate = Certificate.getInstance(
                 new ASN1InputStream(x509Certificate.getEncoded()).readObject());
         ASN1Sequence keyAttributes = (ASN1Sequence) certificate.getTBSCertificate().getExtensions()
@@ -380,7 +381,7 @@
     }
 
     private void parseAttestationApplicationId(byte [] attestationApplicationId)
-            throws Exception {
+            throws IOException {
         ASN1Sequence outerSequence = ASN1Sequence.getInstance(
                 new ASN1InputStream(attestationApplicationId).readObject());
         Map<String, Long> packageNameVersion = new HashMap<>();
diff --git a/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java b/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java
index 0f8be5a..bcc39ba 100644
--- a/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java
+++ b/services/core/java/com/android/server/security/AttestationVerificationPeerDeviceVerifier.java
@@ -22,8 +22,10 @@
 import static android.security.attestationverification.AttestationVerificationManager.RESULT_SUCCESS;
 import static android.security.attestationverification.AttestationVerificationManager.TYPE_CHALLENGE;
 import static android.security.attestationverification.AttestationVerificationManager.TYPE_PUBLIC_KEY;
+import static android.security.attestationverification.AttestationVerificationManager.localBindingTypeToString;
 
 import static com.android.server.security.AndroidKeystoreAttestationVerificationAttributes.VerifiedBootState.VERIFIED;
+import static com.android.server.security.AndroidKeystoreAttestationVerificationAttributes.fromCertificate;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 
@@ -31,6 +33,7 @@
 import android.content.Context;
 import android.os.Build;
 import android.os.Bundle;
+import android.security.attestationverification.AttestationVerificationManager.LocalBindingType;
 import android.util.Log;
 import android.util.Slog;
 
@@ -40,8 +43,10 @@
 import org.json.JSONObject;
 
 import java.io.ByteArrayInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.security.InvalidAlgorithmParameterException;
 import java.security.cert.CertPath;
 import java.security.cert.CertPathValidator;
 import java.security.cert.CertPathValidatorException;
@@ -65,17 +70,26 @@
 import java.util.Set;
 
 /**
- * Verifies Android key attestation according to the {@code PROFILE_PEER_DEVICE} profile.
+ * Verifies Android key attestation according to the
+ * {@link android.security.attestationverification.AttestationVerificationManager#PROFILE_PEER_DEVICE PROFILE_PEER_DEVICE}
+ * profile.
  *
- * Trust anchors are vendor-defined via the vendor_required_attestation_certificates.xml resource.
+ * <p>
  * The profile is satisfied by checking all the following:
- * * TrustAnchor match
- * * Certificate validity
- * * Android OS 10 or higher
- * * Hardware backed key store
- * * Verified boot locked
- * * Remote Patch level must be within 1 year of local patch if local patch is less than 1 year old.
+ * <ul>
+ * <li> TrustAnchor match
+ * <li> Certificate validity
+ * <li> Android OS 10 or higher
+ * <li> Hardware backed key store
+ * <li> Verified boot locked
+ * <li> Remote Patch level must be within 1 year of local patch if local patch is less than 1 year
+ * old.
+ * </ul>
  *
+ * <p>
+ * Trust anchors are vendor-defined by populating
+ * {@link R.array#vendor_required_attestation_certificates} string array (defenined in
+ * {@code frameworks/base/core/res/res/values/vendor_required_attestation_certificates.xml}).
  */
 class AttestationVerificationPeerDeviceVerifier {
     private static final String TAG = "AVF";
@@ -87,20 +101,8 @@
     private final boolean mRevocationEnabled;
     private final LocalDate mTestSystemDate;
     private final LocalDate mTestLocalPatchDate;
-    private CertificateFactory mCertificateFactory;
-    private CertPathValidator mCertPathValidator;
-
-    private static void debugVerboseLog(String str, Throwable t) {
-        if (DEBUG) {
-            Slog.v(TAG, str, t);
-        }
-    }
-
-    private static void debugVerboseLog(String str) {
-        if (DEBUG) {
-            Slog.v(TAG, str);
-        }
-    }
+    private final CertificateFactory mCertificateFactory;
+    private final CertPathValidator mCertPathValidator;
 
     AttestationVerificationPeerDeviceVerifier(@NonNull Context context) throws Exception {
         mContext = Objects.requireNonNull(context);
@@ -128,53 +130,71 @@
 
     /**
      * Verifies attestation for public key or challenge local binding.
-     *
+     * <p>
      * The attestations must be suitable for {@link java.security.cert.CertificateFactory}
      * The certificates in the attestation provided must be DER-encoded and may be supplied in
      * binary or printable (Base64) encoding. If the certificate is provided in Base64 encoding,
-     * it must be bounded at the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at
-     * the end by -----END CERTIFICATE-----.
+     * it must be bounded at the beginning by {@code -----BEGIN CERTIFICATE-----}, and must be
+     * bounded at the end by {@code -----END CERTIFICATE-----}.
      *
      * @param localBindingType Only {@code TYPE_PUBLIC_KEY} and {@code TYPE_CHALLENGE} supported.
      * @param requirements Only {@code PARAM_PUBLIC_KEY} and {@code PARAM_CHALLENGE} supported.
      * @param attestation Certificates should be DER encoded with leaf certificate appended first.
      */
     int verifyAttestation(
-            int localBindingType, @NonNull Bundle requirements, @NonNull byte[] attestation) {
-        int status = RESULT_FAILURE;
-
+            @LocalBindingType int localBindingType,
+            @NonNull Bundle requirements,
+            @NonNull byte[] attestation) {
         if (mCertificateFactory == null) {
-            debugVerboseLog("Was unable to initialize CertificateFactory onCreate.");
-            return status;
+            debugVerboseLog("Unable to access CertificateFactory");
+            return RESULT_FAILURE;
         }
 
         if (mCertPathValidator == null) {
-            debugVerboseLog("Was unable to initialize CertPathValidator onCreate.");
-            return status;
+            debugVerboseLog("Unable to access CertPathValidator");
+            return RESULT_FAILURE;
         }
 
-        List<X509Certificate> certificates;
+        // Check if the provided local binding type is supported and if the provided requirements
+        // "match" the binding type.
+        if (!validateAttestationParameters(localBindingType, requirements)) {
+            return RESULT_FAILURE;
+        }
+
         try {
-            certificates = getCertificates(attestation);
-        } catch (CertificateException e) {
-            debugVerboseLog("Unable to parse attestation certificates.", e);
-            return status;
-        }
+            // First: parse and validate the certificate chain.
+            final List<X509Certificate> certificateChain = getCertificates(attestation);
+            // (returns void, but throws CertificateException and other similar Exceptions)
+            validateCertificateChain(certificateChain);
 
-        if (certificates.isEmpty()) {
-            debugVerboseLog("Attestation contains no certificates.");
-            return status;
-        }
+            final var leafCertificate = certificateChain.get(0);
+            final var attestationExtension = fromCertificate(leafCertificate);
 
-        X509Certificate leafNode = certificates.get(0);
-        if (validateRequirements(localBindingType, requirements)
-                && validateCertificateChain(certificates)
-                && checkCertificateAttributes(leafNode, localBindingType, requirements)) {
-            status = RESULT_SUCCESS;
-        } else {
-            status = RESULT_FAILURE;
+            // Second: verify if the attestation satisfies the "peer device" porfile.
+            if (!checkAttestationForPeerDeviceProfile(attestationExtension)) {
+                return RESULT_FAILURE;
+            }
+
+            // Third: check if the attestation satisfies local binding requirements.
+            if (!checkLocalBindingRequirements(
+                    leafCertificate, attestationExtension, localBindingType, requirements)) {
+                return RESULT_FAILURE;
+            }
+
+            return RESULT_SUCCESS;
+        } catch (CertificateException | CertPathValidatorException
+                | InvalidAlgorithmParameterException | IOException e) {
+            // Catch all non-RuntimeExpceptions (all of these are thrown by either getCertificates()
+            // or validateCertificateChain() or
+            // AndroidKeystoreAttestationVerificationAttributes.fromCertificate())
+            debugVerboseLog("Unable to parse/validate Android Attestation certificate(s)", e);
+            return RESULT_FAILURE;
+        } catch (RuntimeException e) {
+            // Catch everyting else (RuntimeExpcetions), since we don't want to throw any exceptions
+            // out of this class/method.
+            debugVerboseLog("Unexpected error", e);
+            return RESULT_FAILURE;
         }
-        return status;
     }
 
     @NonNull
@@ -189,14 +209,19 @@
         return certificates;
     }
 
-    private boolean validateRequirements(int localBindingType, Bundle requirements) {
-        if (requirements.size() != 1) {
-            debugVerboseLog("Requirements does not contain exactly 1 key.");
+    /**
+     * Check if the {@code localBindingType} is supported and if the {@code requirements} contains
+     * the required parameter for the given {@code @LocalBindingType}.
+     */
+    private boolean validateAttestationParameters(
+            @LocalBindingType int localBindingType, @NonNull Bundle requirements) {
+        if (localBindingType != TYPE_PUBLIC_KEY && localBindingType != TYPE_CHALLENGE) {
+            debugVerboseLog("Binding type is not supported: " + localBindingType);
             return false;
         }
 
-        if (localBindingType != TYPE_PUBLIC_KEY && localBindingType != TYPE_CHALLENGE) {
-            debugVerboseLog("Binding type is not supported: " + localBindingType);
+        if (requirements.size() != 1) {
+            debugVerboseLog("Requirements does not contain exactly 1 key.");
             return false;
         }
 
@@ -213,29 +238,25 @@
         return true;
     }
 
-    private boolean validateCertificateChain(List<X509Certificate> certificates) {
+    private void validateCertificateChain(List<X509Certificate> certificates)
+            throws CertificateException, CertPathValidatorException,
+            InvalidAlgorithmParameterException  {
         if (certificates.size() < 2) {
             debugVerboseLog("Certificate chain less than 2 in size.");
-            return false;
+            throw new CertificateException("Certificate chain less than 2 in size.");
         }
 
-        try {
-            CertPath certificatePath = mCertificateFactory.generateCertPath(certificates);
-            PKIXParameters validationParams = new PKIXParameters(mTrustAnchors);
-            if (mRevocationEnabled) {
-                // Checks Revocation Status List based on
-                // https://developer.android.com/training/articles/security-key-attestation#certificate_status
-                PKIXCertPathChecker checker = new AndroidRevocationStatusListChecker();
-                validationParams.addCertPathChecker(checker);
-            }
-            // Do not use built-in revocation status checker.
-            validationParams.setRevocationEnabled(false);
-            mCertPathValidator.validate(certificatePath, validationParams);
-        } catch (Throwable t) {
-            debugVerboseLog("Invalid certificate chain.", t);
-            return false;
+        CertPath certificatePath = mCertificateFactory.generateCertPath(certificates);
+        PKIXParameters validationParams = new PKIXParameters(mTrustAnchors);
+        if (mRevocationEnabled) {
+            // Checks Revocation Status List based on
+            // https://developer.android.com/training/articles/security-key-attestation#certificate_status
+            PKIXCertPathChecker checker = new AndroidRevocationStatusListChecker();
+            validationParams.addCertPathChecker(checker);
         }
-        return true;
+        // Do not use built-in revocation status checker.
+        validationParams.setRevocationEnabled(false);
+        mCertPathValidator.validate(certificatePath, validationParams);
     }
 
     private Set<TrustAnchor> getTrustAnchors() throws CertPathValidatorException {
@@ -267,18 +288,44 @@
                 R.array.vendor_required_attestation_certificates);
     }
 
-    private boolean checkCertificateAttributes(
-            X509Certificate leafCertificate, int localBindingType, Bundle requirements) {
-        AndroidKeystoreAttestationVerificationAttributes attestationAttributes;
-        try {
-            attestationAttributes =
-                    AndroidKeystoreAttestationVerificationAttributes.fromCertificate(
-                            leafCertificate);
-        } catch (Throwable t) {
-            debugVerboseLog("Could not get ParsedAttestationAttributes from Certificate.", t);
-            return false;
+    private boolean checkLocalBindingRequirements(
+            @NonNull X509Certificate leafCertificate,
+            @NonNull AndroidKeystoreAttestationVerificationAttributes attestationAttributes,
+            @LocalBindingType int localBindingType,
+            @NonNull Bundle requirements) {
+        switch (localBindingType) {
+            case TYPE_PUBLIC_KEY:
+                // Verify leaf public key matches provided public key.
+                final boolean publicKeyMatches = checkPublicKey(
+                        leafCertificate, requirements.getByteArray(PARAM_PUBLIC_KEY));
+                if (!publicKeyMatches) {
+                    debugVerboseLog(
+                            "Provided public key does not match leaf certificate public key.");
+                    return false;
+                }
+                break;
+
+            case TYPE_CHALLENGE:
+                // Verify challenge matches provided challenge.
+                final boolean attestationChallengeMatches = checkAttestationChallenge(
+                        attestationAttributes, requirements.getByteArray(PARAM_CHALLENGE));
+                if (!attestationChallengeMatches) {
+                    debugVerboseLog(
+                            "Provided challenge does not match leaf certificate challenge.");
+                    return false;
+                }
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unsupported local binding type "
+                        + localBindingTypeToString(localBindingType));
         }
 
+        return true;
+    }
+
+    private boolean checkAttestationForPeerDeviceProfile(
+            @NonNull AndroidKeystoreAttestationVerificationAttributes attestationAttributes) {
         // Checks for support of Keymaster 4.
         if (attestationAttributes.getAttestationVersion() < 3) {
             debugVerboseLog("Attestation version is not at least 3 (Keymaster 4).");
@@ -344,25 +391,22 @@
             return false;
         }
 
-        // Verify leaf public key matches provided public key.
-        if (localBindingType == TYPE_PUBLIC_KEY
-                && !Arrays.equals(requirements.getByteArray(PARAM_PUBLIC_KEY),
-                                  leafCertificate.getPublicKey().getEncoded())) {
-            debugVerboseLog("Provided public key does not match leaf certificate public key.");
-            return false;
-        }
-
-        // Verify challenge matches provided challenge.
-        if (localBindingType == TYPE_CHALLENGE
-                && !Arrays.equals(requirements.getByteArray(PARAM_CHALLENGE),
-                                  attestationAttributes.getAttestationChallenge().toByteArray())) {
-            debugVerboseLog("Provided challenge does not match leaf certificate challenge.");
-            return false;
-        }
-
         return true;
     }
 
+    private boolean checkPublicKey(
+            @NonNull Certificate certificate, @NonNull byte[] expectedPublicKey) {
+        final byte[] publicKey = certificate.getPublicKey().getEncoded();
+        return Arrays.equals(publicKey, expectedPublicKey);
+    }
+
+    private boolean checkAttestationChallenge(
+            @NonNull AndroidKeystoreAttestationVerificationAttributes attestationAttributes,
+            @NonNull byte[] expectedChallenge) {
+        final byte[] challenge = attestationAttributes.getAttestationChallenge().toByteArray();
+        return Arrays.equals(challenge, expectedChallenge);
+    }
+
     /**
      * Validates patchLevel passed is within range of the local device patch date if local patch is
      * not over one year old. Since the time can be changed on device, just checking the patch date
@@ -507,4 +551,16 @@
                     R.string.vendor_required_attestation_revocation_list_url);
         }
     }
+
+    private static void debugVerboseLog(String str, Throwable t) {
+        if (DEBUG) {
+            Slog.v(TAG, str, t);
+        }
+    }
+
+    private static void debugVerboseLog(String str) {
+        if (DEBUG) {
+            Slog.v(TAG, str);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index e3dcfd0..881bdbd 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -65,7 +65,6 @@
 import com.android.server.LocalServices;
 import com.android.server.ServiceThread;
 import com.android.server.SystemService;
-import com.android.server.SystemService.TargetUser;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -226,12 +225,18 @@
     }
 
     @Override
-    public int checkSlicePermission(Uri uri, String callingPkg, String pkg, int pid, int uid,
+    public int checkSlicePermission(Uri uri, String callingPkg, int pid, int uid,
             String[] autoGrantPermissions) {
+        return checkSlicePermissionInternal(uri, callingPkg, null /* pkg */, pid, uid,
+                autoGrantPermissions);
+    }
+
+    private int checkSlicePermissionInternal(Uri uri, String callingPkg, String pkg, int pid,
+            int uid, String[] autoGrantPermissions) {
         int userId = UserHandle.getUserId(uid);
         if (pkg == null) {
             for (String p : mContext.getPackageManager().getPackagesForUid(uid)) {
-                if (checkSlicePermission(uri, callingPkg, p, pid, uid, autoGrantPermissions)
+                if (checkSlicePermissionInternal(uri, callingPkg, p, pid, uid, autoGrantPermissions)
                         == PERMISSION_GRANTED) {
                     return PERMISSION_GRANTED;
                 }
@@ -395,7 +400,8 @@
     }
 
     protected int checkAccess(String pkg, Uri uri, int uid, int pid) {
-        return checkSlicePermission(uri, null, pkg, pid, uid, null);
+        return checkSlicePermissionInternal(uri, null /* callingPkg */, pkg, pid, uid,
+                null /* autoGrantPermissions */);
     }
 
     private String getProviderPkg(Uri uri, int user) {
@@ -404,7 +410,7 @@
             String providerName = getUriWithoutUserId(uri).getAuthority();
             ProviderInfo provider = mContext.getPackageManager().resolveContentProviderAsUser(
                     providerName, 0, getUserIdFromUri(uri, user));
-            return provider.packageName;
+            return provider == null ? null : provider.packageName;
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -629,7 +635,7 @@
                 .scheme(ContentResolver.SCHEME_CONTENT)
                 .authority(authority)
                 .build(), 0);
-        return mPermissions.getAllPackagesGranted(pkg);
+        return pkg == null ? new String[0] : mPermissions.getAllPackagesGranted(pkg);
     }
 
     /**
diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java
index 0772503..b6ab351 100644
--- a/services/core/java/com/android/server/tv/TvInputHal.java
+++ b/services/core/java/com/android/server/tv/TvInputHal.java
@@ -155,8 +155,6 @@
 
     // Handler.Callback implementation
 
-    private final Queue<Message> mPendingMessageQueue = new LinkedList<>();
-
     @Override
     public boolean handleMessage(Message msg) {
         switch (msg.what) {
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index f57a852..98dfb00 100755
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -69,7 +69,6 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
@@ -89,7 +88,7 @@
     private final TvInputHal mHal = new TvInputHal(this);
     private final SparseArray<Connection> mConnections = new SparseArray<>();
     private final List<TvInputHardwareInfo> mHardwareList = new ArrayList<>();
-    private final List<HdmiDeviceInfo> mHdmiDeviceList = new LinkedList<>();
+    private final List<HdmiDeviceInfo> mHdmiDeviceList = new ArrayList<>();
     /* A map from a device ID to the matching TV input ID. */
     private final SparseArray<String> mHardwareInputIdMap = new SparseArray<>();
     /* A map from a HDMI logical address to the matching TV input ID. */
@@ -112,9 +111,9 @@
     private int mCurrentMaxIndex = 0;
 
     private final SparseBooleanArray mHdmiStateMap = new SparseBooleanArray();
-    private final List<Message> mPendingHdmiDeviceEvents = new LinkedList<>();
+    private final List<Message> mPendingHdmiDeviceEvents = new ArrayList<>();
 
-    private final List<Message> mPendingTvinputInfoEvents = new LinkedList<>();
+    private final List<Message> mPendingTvinputInfoEvents = new ArrayList<>();
 
     // Calls to mListener should happen here.
     private final Handler mHandler = new ListenerHandler();
@@ -234,11 +233,7 @@
             } else {
                 Message msg = mHandler.obtainMessage(ListenerHandler.TVINPUT_INFO_ADDED,
                     deviceId, cableConnectionStatus, connection);
-                for (Iterator<Message> it = mPendingTvinputInfoEvents.iterator(); it.hasNext();) {
-                    if (it.next().arg1 == deviceId) {
-                    it.remove();
-                    }
-                }
+                mPendingTvinputInfoEvents.removeIf(message -> message.arg1 == deviceId);
                 mPendingTvinputInfoEvents.add(msg);
            }
             ITvInputHardwareCallback callback = connection.getCallbackLocked();
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 7f84f61..3b8677d 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -68,6 +68,7 @@
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
 import static com.android.server.wm.EventLogTags.WM_ACTIVITY_LAUNCH_TIME;
 
@@ -102,6 +103,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.util.FrameworkStatsLog;
+import com.android.internal.util.LatencyTracker;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
@@ -771,6 +773,12 @@
             info.mReason = activityToReason.valueAt(index);
             info.mLoggedTransitionStarting = true;
             if (info.mIsDrawn) {
+                if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
+                    final LatencyTracker latencyTracker = r.mWmService.mLatencyTracker;
+                    final int duration = info.mSourceEventDelayMs + info.mCurrentTransitionDelayMs;
+                    mLoggerHandler.post(() -> latencyTracker.logAction(
+                            LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration));
+                }
                 done(false /* abort */, info, "notifyTransitionStarting drawn", timestampNs);
             }
         }
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index cefc871..6f13f86 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -96,8 +96,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
 
@@ -854,7 +854,7 @@
             boolean visible) {
 
         // The candidates of animation targets, which might be able to promote to higher level.
-        final LinkedList<WindowContainer> candidates = new LinkedList<>();
+        final ArrayDeque<WindowContainer> candidates = new ArrayDeque<>();
         final ArraySet<ActivityRecord> apps = visible ? openingApps : closingApps;
         for (int i = 0; i < apps.size(); ++i) {
             final ActivityRecord app = apps.valueAt(i);
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 8a0ae65..70545c9 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -53,10 +53,10 @@
 import com.android.internal.util.ArrayUtils;
 
 import java.io.PrintWriter;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.WeakHashMap;
 import java.util.function.Consumer;
@@ -318,13 +318,13 @@
     private final WindowManagerGlobalLock mGlobalLock;
 
     // List of task organizers by priority
-    private final LinkedList<ITaskOrganizer> mTaskOrganizers = new LinkedList<>();
+    private final ArrayDeque<ITaskOrganizer> mTaskOrganizers = new ArrayDeque<>();
     private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
     private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
     // Pending task events due to layout deferred.
     private final ArrayList<PendingTaskEvent> mPendingTaskEvents = new ArrayList<>();
     // Set of organized tasks (by taskId) that dispatch back pressed to their organizers
-    private final HashSet<Integer> mInterceptBackPressedOnRootTasks = new HashSet();
+    private final HashSet<Integer> mInterceptBackPressedOnRootTasks = new HashSet<>();
 
     private RunningTaskInfo mTmpTaskInfo;
     private Consumer<Runnable> mDeferTaskOrgCallbacksConsumer;
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 4d0dfe2..4a0b343 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -52,6 +52,7 @@
 import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
 import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
 
+import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
 import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
 
@@ -670,8 +671,6 @@
 
         handleNonAppWindowsInTransition(dc, mType, mFlags);
 
-        reportStartReasonsToLogger();
-
         // The callback is only populated for custom activity-level client animations
         sendRemoteCallback(mClientAnimationStartCallback);
 
@@ -760,6 +759,8 @@
         }
         mSyncId = -1;
         mOverrideOptions = null;
+
+        reportStartReasonsToLogger();
     }
 
     /**
@@ -972,11 +973,15 @@
         for (int i = mParticipants.size() - 1; i >= 0; --i) {
             ActivityRecord r = mParticipants.valueAt(i).asActivityRecord();
             if (r == null || !r.mVisibleRequested) continue;
+            int transitionReason = APP_TRANSITION_WINDOWS_DRAWN;
             // At this point, r is "ready", but if it's not "ALL ready" then it is probably only
             // ready due to starting-window.
-            reasons.put(r, (r.mStartingData instanceof SplashScreenStartingData
-                    && !r.mLastAllReadyAtSync)
-                    ? APP_TRANSITION_SPLASH_SCREEN : APP_TRANSITION_WINDOWS_DRAWN);
+            if (r.mStartingData instanceof SplashScreenStartingData && !r.mLastAllReadyAtSync) {
+                transitionReason = APP_TRANSITION_SPLASH_SCREEN;
+            } else if (r.isActivityTypeHomeOrRecents() && isTransientLaunch(r)) {
+                transitionReason = APP_TRANSITION_RECENTS_ANIM;
+            }
+            reasons.put(r, transitionReason);
         }
         mController.mAtm.mTaskSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
                 reasons);
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 0d49f5f..cfcbc3a 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -185,6 +185,7 @@
         "android.system.suspend.control-V1-cpp",
         "android.system.suspend.control.internal-cpp",
         "android.system.suspend-V1-ndk",
+        "server_configurable_flags",
         "service.incremental",
     ],
 
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 3c5ebe7..ffda8be 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -50,6 +50,7 @@
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <server_configurable_flags/get_flags.h>
 #include <ui/Region.h>
 #include <utils/Log.h>
 #include <utils/Looper.h>
@@ -87,6 +88,13 @@
 // where the speed ranges from -7 to + 7 and is supplied by the user.
 static const float POINTER_SPEED_EXPONENT = 1.0f / 4;
 
+// Category (=namespace) name for the input settings that are applied at boot time
+static const char* INPUT_NATIVE_BOOT = "input_native_boot";
+/**
+ * Feature flag name. This flag determines which VelocityTracker strategy is used by default.
+ */
+static const char* VELOCITYTRACKER_STRATEGY = "velocitytracker_strategy";
+
 static struct {
     jclass clazz;
     jmethodID notifyConfigurationChanged;
@@ -2120,8 +2128,10 @@
 static std::string dumpInputProperties() {
     std::string out = "Input properties:\n";
     const std::string strategy =
-            sysprop::InputProperties::velocitytracker_strategy().value_or("default");
-    out += "  persist.input.velocitytracker.strategy = " + strategy + "\n";
+            server_configurable_flags::GetServerConfigurableFlag(INPUT_NATIVE_BOOT,
+                                                                 VELOCITYTRACKER_STRATEGY,
+                                                                 "default");
+    out += "  velocitytracker_strategy (flag value) = " + strategy + "\n";
     out += "\n";
     return out;
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 268d588..b7005a5 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11890,6 +11890,7 @@
                 ap = getParentOfAdminIfRequired(getOrganizationOwnedProfileOwnerLocked(caller),
                         parent);
             } else {
+                Preconditions.checkCallAuthorization(!isFinancedDeviceOwner(caller));
                 ap = getParentOfAdminIfRequired(getProfileOwnerOrDeviceOwnerLocked(caller), parent);
             }
 
diff --git a/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java
new file mode 100644
index 0000000..3f6199c
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/appenumeration/src/com/android/server/pm/test/appenumeration/CrossUserPackageVisibilityTests.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.test.appenumeration;
+
+import static org.junit.Assert.assertThrows;
+
+import android.app.AppGlobals;
+import android.app.Instrumentation;
+import android.content.pm.IPackageManager;
+import android.os.UserHandle;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CrossUserPackageVisibilityTests {
+
+    private Instrumentation mInstrumentation;
+    private IPackageManager mIPackageManager;
+
+    @Before
+    public void setup() {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mIPackageManager = AppGlobals.getPackageManager();
+    }
+
+    @Test
+    public void testGetSplashScreenTheme_withCrossUserId() {
+        final int crossUserId = UserHandle.myUserId() + 1;
+        assertThrows(SecurityException.class,
+                () -> mIPackageManager.getSplashScreenTheme(
+                        mInstrumentation.getContext().getPackageName(), crossUserId));
+    }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index a2e813a..82334f2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -59,6 +59,7 @@
 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
 import com.android.server.LocalServices;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.PackageStateInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -136,14 +137,17 @@
                 .spyStatic(Settings.Global.class)
                 .startMocking();
 
-        // Mock LocalServices.getService(PackageManagerInternal.class).getPackage dependency
-        // needed by AppOpsService
+        // Mock LocalServices.getService(PackageManagerInternal.class).getPackageStateInternal
+        // and getPackage dependency needed by AppOpsService
         PackageManagerInternal mockPackageManagerInternal = mock(PackageManagerInternal.class);
+        PackageStateInternal mockMyPSInternal = mock(PackageStateInternal.class);
         AndroidPackage mockMyPkg = mock(AndroidPackage.class);
         when(mockMyPkg.isPrivileged()).thenReturn(false);
         when(mockMyPkg.getUid()).thenReturn(mMyUid);
         when(mockMyPkg.getAttributions()).thenReturn(Collections.emptyList());
 
+        when(mockPackageManagerInternal.getPackageStateInternal(sMyPackageName))
+                .thenReturn(mockMyPSInternal);
         when(mockPackageManagerInternal.getPackage(sMyPackageName)).thenReturn(mockMyPkg);
         doReturn(mockPackageManagerInternal).when(
                 () -> LocalServices.getService(PackageManagerInternal.class));
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 617321b..7755552 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -558,6 +558,40 @@
     }
 
     @Test
+    public void testAfterDisplayStateChanges_committedSetAfterState() throws Exception {
+        FakeDisplay display = new FakeDisplay(PORT_A);
+        setUpDisplay(display);
+        updateAvailableDisplays();
+        mAdapter.registerLocked();
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+        assertThat(mListener.addedDisplays.size()).isEqualTo(1);
+        DisplayDevice displayDevice = mListener.addedDisplays.get(0);
+
+        // Turn off.
+        Runnable changeStateRunnable = displayDevice.requestDisplayStateLocked(Display.STATE_OFF, 0,
+                0);
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+        assertThat(mListener.changedDisplays.size()).isEqualTo(1);
+        mListener.changedDisplays.clear();
+        assertThat(displayDevice.getDisplayDeviceInfoLocked().state).isEqualTo(Display.STATE_OFF);
+        assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState).isNotEqualTo(
+                Display.STATE_OFF);
+        verify(mSurfaceControlProxy, never()).setDisplayPowerMode(display.token, Display.STATE_OFF);
+
+        // Execute powerstate change.
+        changeStateRunnable.run();
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+
+        // Verify that committed triggered a new change event and is set correctly.
+        verify(mSurfaceControlProxy, never()).setDisplayPowerMode(display.token, Display.STATE_OFF);
+        assertThat(mListener.changedDisplays.size()).isEqualTo(1);
+        assertThat(displayDevice.getDisplayDeviceInfoLocked().state).isEqualTo(Display.STATE_OFF);
+        assertThat(displayDevice.getDisplayDeviceInfoLocked().committedState).isEqualTo(
+                Display.STATE_OFF);
+    }
+
+    @Test
     public void testAfterDisplayChange_GameContentTypeSupportIsUpdated() throws Exception {
         FakeDisplay display = new FakeDisplay(PORT_A);
         display.dynamicInfo.gameContentTypeSupported = true;
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
index cf6c82f..0d2e666 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/DistractingPackageHelperTest.kt
@@ -29,6 +29,7 @@
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.never
+import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 
 @RunWith(JUnit4::class)
@@ -192,4 +193,70 @@
                 Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), nullable(), anyInt(),
                 nullable(), nullable(), any(), nullable(), nullable(), nullable())
     }
+
+    @Test
+    fun sendDistractingPackagesChanged_withSameVisibilityAllowList() {
+        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
+        mockAllowList(packageSetting2, allowList(10001, 10002, 10003))
+
+        distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(),
+                packagesToChange, uidsToChange, TEST_USER_ID,
+                PackageManager.RESTRICTION_HIDE_NOTIFICATIONS)
+        testHandler.flush()
+        verify(broadcastHelper).sendPackageBroadcast(eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED),
+                nullable(), bundleCaptor.capture(), anyInt(), nullable(), nullable(), any(),
+                nullable(), nullable(), nullable())
+
+        var changedPackages = bundleCaptor.value.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST)
+        var changedUids = bundleCaptor.value.getIntArray(Intent.EXTRA_CHANGED_UID_LIST)
+        assertThat(changedPackages).asList().containsExactly(TEST_PACKAGE_1, TEST_PACKAGE_2)
+        assertThat(changedUids).asList().containsExactly(
+                packageSetting1.appId, packageSetting2.appId)
+    }
+
+    @Test
+    fun sendDistractingPackagesChanged_withDifferentVisibilityAllowList() {
+        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
+        mockAllowList(packageSetting2, allowList(10001, 10002, 10004))
+
+        distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(),
+                packagesToChange, uidsToChange, TEST_USER_ID,
+                PackageManager.RESTRICTION_HIDE_NOTIFICATIONS)
+        testHandler.flush()
+        verify(broadcastHelper, times(2)).sendPackageBroadcast(
+                eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(),
+                anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable())
+
+        bundleCaptor.allValues.forEach {
+            var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST)
+            var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST)
+            assertThat(changedPackages?.size).isEqualTo(1)
+            assertThat(changedUids?.size).isEqualTo(1)
+            assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
+            assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId)
+        }
+    }
+
+    @Test
+    fun sendDistractingPackagesChanged_withNullVisibilityAllowList() {
+        mockAllowList(packageSetting1, allowList(10001, 10002, 10003))
+        mockAllowList(packageSetting2, null /* list */)
+
+        distractingPackageHelper.sendDistractingPackagesChanged(pms.snapshotComputer(),
+                packagesToChange, uidsToChange, TEST_USER_ID,
+                PackageManager.RESTRICTION_HIDE_NOTIFICATIONS)
+        testHandler.flush()
+        verify(broadcastHelper, times(2)).sendPackageBroadcast(
+                eq(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED), nullable(), bundleCaptor.capture(),
+                anyInt(), nullable(), nullable(), any(), nullable(), nullable(), nullable())
+
+        bundleCaptor.allValues.forEach {
+            var changedPackages = it.getStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST)
+            var changedUids = it.getIntArray(Intent.EXTRA_CHANGED_UID_LIST)
+            assertThat(changedPackages?.size).isEqualTo(1)
+            assertThat(changedUids?.size).isEqualTo(1)
+            assertThat(changedPackages?.get(0)).isAnyOf(TEST_PACKAGE_1, TEST_PACKAGE_2)
+            assertThat(changedUids?.get(0)).isAnyOf(packageSetting1.appId, packageSetting2.appId)
+        }
+    }
 }
\ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt b/services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt
index bd012fc..f48d16f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageHelperTestBase.kt
@@ -20,6 +20,8 @@
 import android.os.Bundle
 import android.os.UserHandle
 import android.os.UserManager
+import android.util.ArrayMap
+import android.util.SparseArray
 import com.android.server.pm.pkg.PackageStateInternal
 import com.android.server.testutils.TestHandler
 import com.android.server.testutils.any
@@ -31,6 +33,7 @@
 import org.mockito.Captor
 import org.mockito.Mock
 import org.mockito.Mockito
+import org.mockito.Mockito.argThat
 import org.mockito.Mockito.spy
 import org.mockito.MockitoAnnotations
 
@@ -138,4 +141,15 @@
         rule.system().validateFinalState()
         return pms
     }
+
+    protected fun allowList(vararg uids: Int) = SparseArray<IntArray>().apply {
+        this.put(TEST_USER_ID, uids)
+    }
+
+    protected fun mockAllowList(pkgSetting: PackageStateInternal, list: SparseArray<IntArray>?) {
+        whenever(rule.mocks().appsFilter.getVisibilityAllowList(
+                argThat { it?.packageName == pkgSetting.packageName }, any(IntArray::class.java),
+                any() as ArrayMap<String, out PackageStateInternal>
+        )).thenReturn(list)
+    }
 }
\ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
index 3ba9ca5..121cbe3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/SuspendPackageHelperTest.kt
@@ -20,19 +20,14 @@
 import android.content.pm.SuspendDialogInfo
 import android.os.Binder
 import android.os.PersistableBundle
-import android.util.ArrayMap
-import android.util.SparseArray
-import com.android.server.pm.pkg.PackageStateInternal
 import com.android.server.testutils.any
 import com.android.server.testutils.eq
 import com.android.server.testutils.nullable
-import com.android.server.testutils.whenever
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
 import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.Mockito.argThat
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 
@@ -382,16 +377,4 @@
         assertThat(modifiedUids).asList().containsExactly(
                 packageSetting1.appId, packageSetting2.appId)
     }
-
-    private fun allowList(vararg uids: Int) = SparseArray<IntArray>().apply {
-        this.put(TEST_USER_ID, uids)
-    }
-
-    private fun mockAllowList(pkgSetting: PackageStateInternal, list: SparseArray<IntArray>?) {
-        whenever(rule.mocks().appsFilter.getVisibilityAllowList(
-            argThat { it?.packageName == pkgSetting.packageName }, any(IntArray::class.java),
-            any() as ArrayMap<String, out PackageStateInternal>
-        ))
-            .thenReturn(list)
-    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index d5c5745..f28ad79 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -37,8 +37,8 @@
 import android.accounts.CantAddAccountActivity;
 import android.accounts.IAccountManagerResponse;
 import android.app.AppOpsManager;
-import android.app.PropertyInvalidatedCache;
 import android.app.INotificationManager;
+import android.app.PropertyInvalidatedCache;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.BroadcastReceiver;
@@ -253,6 +253,26 @@
     }
 
     @SmallTest
+    public void testCheckAddAccountLongName() throws Exception {
+        unlockSystemUser();
+        String longString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+                + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+                + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+                + "aaaaa";
+        Account a11 = new Account(longString, AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
+
+        mAms.addAccountExplicitly(
+                a11, /* password= */ "p11", /* extras= */ null, /* callerPackage= */ null);
+
+        String[] list = new String[]{AccountManagerServiceTestFixtures.CALLER_PACKAGE};
+        when(mMockPackageManager.getPackagesForUid(anyInt())).thenReturn(list);
+        Account[] accounts = mAms.getAccountsAsUser(null,
+                UserHandle.getCallingUserId(), mContext.getOpPackageName());
+        assertEquals(0, accounts.length);
+    }
+
+
+    @SmallTest
     public void testPasswords() throws Exception {
         unlockSystemUser();
         Account a11 = new Account("account1", AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1);
diff --git a/services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java b/services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java
new file mode 100644
index 0000000..049c745
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.backup.restore;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.backup.BackupAgent;
+import android.platform.test.annotations.Presubmit;
+import android.system.OsConstants;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.backup.FileMetadata;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class FullRestoreEngineTest {
+    private static final String DEFAULT_PACKAGE_NAME = "package";
+    private static final String DEFAULT_DOMAIN_NAME = "domain";
+    private static final String NEW_PACKAGE_NAME = "new_package";
+    private static final String NEW_DOMAIN_NAME = "new_domain";
+
+    private FullRestoreEngine mRestoreEngine;
+
+    @Before
+    public void setUp() {
+        mRestoreEngine = new FullRestoreEngine();
+    }
+
+    @Test
+    public void shouldSkipReadOnlyDir_skipsAllReadonlyDirsAndTheirChildren() {
+        // Create the file tree.
+        TestFile[] testFiles = new TestFile[] {
+                TestFile.dir("root"),
+                TestFile.file("root/auth_token"),
+                TestFile.dir("root/media"),
+                TestFile.file("root/media/picture1.png"),
+                TestFile.file("root/push_token.txt"),
+                TestFile.dir("root/read-only-dir-1").markReadOnly().expectSkipped(),
+                TestFile.dir("root/read-only-dir-1/writable-subdir").expectSkipped(),
+                TestFile.file("root/read-only-dir-1/writable-subdir/writable-file").expectSkipped(),
+                TestFile.dir("root/read-only-dir-1/writable-subdir/read-only-subdir-2")
+                        .markReadOnly().expectSkipped(),
+                TestFile.file("root/read-only-dir-1/writable-file").expectSkipped(),
+                TestFile.file("root/random-stuff.txt"),
+                TestFile.dir("root/database"),
+                TestFile.file("root/database/users.db"),
+                TestFile.dir("root/read-only-dir-2").markReadOnly().expectSkipped(),
+                TestFile.file("root/read-only-dir-2/writable-file-1").expectSkipped(),
+                TestFile.file("root/read-only-dir-2/writable-file-2").expectSkipped(),
+        };
+
+        assertCorrectItemsAreSkipped(testFiles);
+    }
+
+    @Test
+    public void shouldSkipReadOnlyDir_onlySkipsChildrenUnderTheSamePackage() {
+        TestFile[] testFiles = new TestFile[]{
+                TestFile.dir("read-only-dir").markReadOnly().expectSkipped(),
+                TestFile.file("read-only-dir/file").expectSkipped(),
+                TestFile.file("read-only-dir/file-from-different-package")
+                        .setPackage(NEW_PACKAGE_NAME),
+        };
+
+        assertCorrectItemsAreSkipped(testFiles);
+    }
+
+    @Test
+    public void shouldSkipReadOnlyDir_onlySkipsChildrenUnderTheSameDomain() {
+        TestFile[] testFiles = new TestFile[]{
+                TestFile.dir("read-only-dir").markReadOnly().expectSkipped(),
+                TestFile.file("read-only-dir/file").expectSkipped(),
+                TestFile.file("read-only-dir/file-from-different-domain")
+                        .setDomain(NEW_DOMAIN_NAME),
+        };
+
+        assertCorrectItemsAreSkipped(testFiles);
+    }
+
+    private void assertCorrectItemsAreSkipped(TestFile[] testFiles) {
+        // Verify all directories marked with .expectSkipped are skipped.
+        for (TestFile testFile : testFiles) {
+            boolean actualExcluded = mRestoreEngine.shouldSkipReadOnlyDir(testFile.mMetadata);
+            boolean expectedExcluded = testFile.mShouldSkip;
+            assertWithMessage(testFile.mMetadata.path).that(actualExcluded).isEqualTo(
+                    expectedExcluded);
+        }
+    }
+
+    private static class TestFile {
+        private final FileMetadata mMetadata;
+        private boolean mShouldSkip;
+
+        static TestFile dir(String path) {
+            return new TestFile(path, BackupAgent.TYPE_DIRECTORY);
+        }
+
+        static TestFile file(String path) {
+            return new TestFile(path, BackupAgent.TYPE_FILE);
+        }
+
+        TestFile markReadOnly() {
+            mMetadata.mode = 0;
+            return this;
+        }
+
+        TestFile expectSkipped() {
+            mShouldSkip = true;
+            return this;
+        }
+
+        TestFile setPackage(String packageName) {
+            mMetadata.packageName = packageName;
+            return this;
+        }
+
+        TestFile setDomain(String domain) {
+            mMetadata.domain = domain;
+            return this;
+        }
+
+        private TestFile(String path, int type) {
+            FileMetadata metadata = new FileMetadata();
+            metadata.path = path;
+            metadata.type = type;
+            metadata.packageName = DEFAULT_PACKAGE_NAME;
+            metadata.domain = DEFAULT_DOMAIN_NAME;
+            metadata.mode = OsConstants.S_IWUSR; // Mark as writable.
+            mMetadata = metadata;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index fe3034d..ce7b367 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -243,6 +243,7 @@
         assertEquals(info.currentState, DEFAULT_DEVICE_STATE.getIdentifier());
     }
 
+    @FlakyTest(bugId = 223153452)
     @Test
     public void registerCallback() throws RemoteException {
         TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 484b5a8..0f6addb 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -982,7 +982,11 @@
     }
 
     @Test
-    public void handleOnInitializeCecComplete_ByScreenOn() {
+    public void handleOnInitializeCecComplete_ByScreenOn_PowerControlModeTv() {
+        mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_TV);
+
         mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
                 mHdmiControlService.INITIATED_BY_SCREEN_ON);
         mTestLooper.dispatchAll();
@@ -999,6 +1003,27 @@
     }
 
     @Test
+    public void handleOnInitializeCecComplete_ByScreenOn_PowerControlModeNone() {
+        mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
+                HdmiControlManager.CEC_SETTING_NAME_POWER_CONTROL_MODE,
+                HdmiControlManager.POWER_CONTROL_MODE_NONE);
+
+        mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
+                mHdmiControlService.INITIATED_BY_SCREEN_ON);
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSource =
+                HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
+                        mPlaybackPhysicalAddress);
+        HdmiCecMessage textViewOn =
+                HdmiCecMessageBuilder.buildTextViewOn(mPlaybackLogicalAddress,
+                        ADDR_TV);
+
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(activeSource);
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(textViewOn);
+    }
+
+    @Test
     public void handleOnInitializeCecComplete_ByWakeUpMessage() {
         mHdmiCecLocalDevicePlayback.onInitializeCecComplete(
                 mHdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE);
diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
index c7a903b..11acfb7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -386,7 +386,8 @@
                 ApexManager.MATCH_ACTIVE_PACKAGE);
         assertThat(newInfo.applicationInfo.sourceDir).isEqualTo(finalApex.getAbsolutePath());
         assertThat(newInfo.applicationInfo.longVersionCode).isEqualTo(2);
-        assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+        assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)
+                .isEqualTo(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
         assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
             .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
 
@@ -396,7 +397,8 @@
         assertThat(factoryInfo.applicationInfo.longVersionCode).isEqualTo(1);
         assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
             .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
-        assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
+        assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+                .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
     }
 
     @Test
@@ -424,7 +426,8 @@
                 ApexManager.MATCH_ACTIVE_PACKAGE);
         assertThat(newInfo.applicationInfo.sourceDir).isEqualTo(finalApex.getAbsolutePath());
         assertThat(newInfo.applicationInfo.longVersionCode).isEqualTo(2);
-        assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+        assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)
+                .isEqualTo(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
         assertThat(newInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
             .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
 
@@ -434,7 +437,8 @@
         assertThat(factoryInfo.applicationInfo.longVersionCode).isEqualTo(1);
         assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
             .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
-        assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
+        assertThat(factoryInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+                .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index a79a52c..b91ff6b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -266,6 +266,11 @@
         public void sendIntentSender(IntentSender intent) {
             // Placeholder for spying.
         }
+
+        @Override
+        public String getPackageName() {
+            return SYSTEM_PACKAGE_NAME;
+        }
     }
 
     /** ShortcutService with injection override methods. */
@@ -698,6 +703,7 @@
 
     protected UriPermissionOwner mUriPermissionOwner;
 
+    protected static final String SYSTEM_PACKAGE_NAME = "android";
 
     protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
     protected static final int CALLING_UID_1 = 10001;
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
index 07cca0c..4d1c58d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/PackageParserLegacyCoreTest.java
@@ -610,7 +610,7 @@
         assertNotNull(pi.signingInfo);
         assertTrue(pi.signingInfo.getApkContentsSigners().length > 0);
         assertTrue(pi.isApex);
-        assertTrue((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0);
+        assertTrue((pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
         assertTrue((pi.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index c9721db..37792c5 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -911,27 +911,6 @@
     }
 
     @Test
-    public void testInattentiveSleep_dreamEnds_goesToSleepAfterTimeout() {
-        setMinimumScreenOffTimeoutConfig(5);
-        setAttentiveTimeout(30000);
-        createService();
-        startSystem();
-
-        advanceTime(10000);
-        forceDream();
-        advanceTime(10000);
-        final String pkg = mContextSpy.getOpPackageName();
-        mService.getBinderServiceInstance().wakeUp(mClock.now(),
-                PowerManager.WAKE_REASON_DREAM_FINISHED, "PowerManagerServiceTest:DREAM_FINISHED",
-                pkg);
-        advanceTime(10001);
-
-        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
-        assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo(
-                PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE);
-    }
-
-    @Test
     public void testInattentiveSleep_goesToSleepWithWakeLock() {
         final String pkg = mContextSpy.getOpPackageName();
         final Binder token = new Binder();
@@ -954,6 +933,27 @@
     }
 
     @Test
+    public void testInattentiveSleep_dreamEnds_goesToSleepAfterTimeout() {
+        setMinimumScreenOffTimeoutConfig(5);
+        setAttentiveTimeout(30000);
+        createService();
+        startSystem();
+
+        advanceTime(10000);
+        forceDream();
+        advanceTime(10000);
+        final String pkg = mContextSpy.getOpPackageName();
+        mService.getBinderServiceInstance().wakeUp(mClock.now(),
+                PowerManager.WAKE_REASON_DREAM_FINISHED, "PowerManagerServiceTest:DREAM_FINISHED",
+                pkg);
+        advanceTime(10001);
+
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+        assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo(
+                PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE);
+    }
+
+    @Test
     public void testInattentiveSleep_wakeLockOnAfterRelease_inattentiveSleepTimeoutNotAffected() {
         final DisplayInfo info = new DisplayInfo();
         info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
index bd7186e..a7d18ee 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
@@ -126,7 +126,7 @@
             when(file.getAbsolutePath()).thenReturn(String.valueOf(i));
             AtomicFile af = new AtomicFile(file);
             expectedFiles.add(af);
-            mDataBase.mHistoryFiles.addLast(af);
+            mDataBase.mHistoryFiles.add(af);
         }
 
         cal.add(Calendar.DATE, -1 * retainDays);
@@ -136,7 +136,7 @@
             when(file.getName()).thenReturn(String.valueOf(cal.getTimeInMillis() - i));
             when(file.getAbsolutePath()).thenReturn(String.valueOf(cal.getTimeInMillis() - i));
             AtomicFile af = new AtomicFile(file);
-            mDataBase.mHistoryFiles.addLast(af);
+            mDataBase.mHistoryFiles.add(af);
         }
 
         // back to today; trim everything a day + old
@@ -162,7 +162,7 @@
             when(file.getName()).thenReturn(i + ".bak");
             when(file.getAbsolutePath()).thenReturn(i + ".bak");
             AtomicFile af = new AtomicFile(file);
-            mDataBase.mHistoryFiles.addLast(af);
+            mDataBase.mHistoryFiles.add(af);
         }
 
         // trim everything a day+ old
@@ -224,7 +224,7 @@
     public void testReadNotificationHistory_readsAllFiles() throws Exception {
         for (long i = 10; i >= 5; i--) {
             AtomicFile af = mock(AtomicFile.class);
-            mDataBase.mHistoryFiles.addLast(af);
+            mDataBase.mHistoryFiles.add(af);
         }
 
         mDataBase.readNotificationHistory();
@@ -248,11 +248,11 @@
     public void testReadNotificationHistory_withNumFilterDoesNotReadExtraFiles() throws Exception {
         AtomicFile af = mock(AtomicFile.class);
         when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
-        mDataBase.mHistoryFiles.addLast(af);
+        mDataBase.mHistoryFiles.add(af);
 
         AtomicFile af2 = mock(AtomicFile.class);
         when(af2.getBaseFile()).thenReturn(new File(mRootDir, "af2"));
-        mDataBase.mHistoryFiles.addLast(af2);
+        mDataBase.mHistoryFiles.add(af2);
 
         mDataBase.readNotificationHistory(null, null, 0);
 
@@ -269,7 +269,7 @@
 
         AtomicFile af = mock(AtomicFile.class);
         when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
-        mDataBase.mHistoryFiles.addLast(af);
+        mDataBase.mHistoryFiles.add(af);
 
         when(nh.removeNotificationFromWrite("pkg", 123)).thenReturn(true);
 
@@ -292,7 +292,7 @@
 
         AtomicFile af = mock(AtomicFile.class);
         when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
-        mDataBase.mHistoryFiles.addLast(af);
+        mDataBase.mHistoryFiles.add(af);
 
         when(nh.removeNotificationFromWrite("pkg", 123)).thenReturn(false);
 
@@ -315,7 +315,7 @@
 
         AtomicFile af = mock(AtomicFile.class);
         when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
-        mDataBase.mHistoryFiles.addLast(af);
+        mDataBase.mHistoryFiles.add(af);
 
         when(nh.removeConversationsFromWrite("pkg", Set.of("convo", "another"))).thenReturn(true);
 
@@ -338,7 +338,7 @@
 
         AtomicFile af = mock(AtomicFile.class);
         when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
-        mDataBase.mHistoryFiles.addLast(af);
+        mDataBase.mHistoryFiles.add(af);
 
         when(nh.removeConversationsFromWrite("pkg", Set.of("convo"))).thenReturn(false);
 
@@ -361,7 +361,7 @@
 
         AtomicFile af = mock(AtomicFile.class);
         when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
-        mDataBase.mHistoryFiles.addLast(af);
+        mDataBase.mHistoryFiles.add(af);
 
         when(nh.removeChannelFromWrite("pkg", "channel")).thenReturn(true);
 
@@ -384,7 +384,7 @@
 
         AtomicFile af = mock(AtomicFile.class);
         when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
-        mDataBase.mHistoryFiles.addLast(af);
+        mDataBase.mHistoryFiles.add(af);
 
         when(nh.removeChannelFromWrite("pkg", "channel")).thenReturn(false);
 
@@ -424,7 +424,7 @@
         for (int i = 0; i < 5; i++) {
             AtomicFile af = mock(AtomicFile.class);
             when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
-            mDataBase.mHistoryFiles.addLast(af);
+            mDataBase.mHistoryFiles.add(af);
         }
         // Baseline size of history files
         assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(5);
@@ -440,7 +440,7 @@
         for (int i = 0; i < 5; i++) {
             AtomicFile af = mock(AtomicFile.class);
             when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
-            mDataBase.mHistoryFiles.addLast(af);
+            mDataBase.mHistoryFiles.add(af);
         }
         // Baseline size of history files
         assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(5);
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index dd0c162..a917c57 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -122,8 +122,7 @@
         when(mContextSpy.checkPermission("perm2", Process.myPid(), Process.myUid()))
                 .thenReturn(PERMISSION_GRANTED);
         mService.checkSlicePermission(TEST_URI, mContext.getPackageName(),
-                mContext.getPackageName(), Process.myPid(),
-                Process.myUid(), testPerms);
+                Process.myPid(), Process.myUid(), testPerms);
 
         verify(mContextSpy).checkPermission(eq("perm1"), eq(Process.myPid()), eq(Process.myUid()));
         verify(mContextSpy).checkPermission(eq("perm2"), eq(Process.myPid()), eq(Process.myUid()));
@@ -148,7 +147,7 @@
 
     private void grantSlicePermission() {
         doReturn(PERMISSION_GRANTED).when(mService).checkSlicePermission(
-                eq(TEST_URI), anyString(), anyString(), anyInt(), anyInt(), any());
+                eq(TEST_URI), anyString(), anyInt(), anyInt(), any());
         doReturn(PERMISSION_GRANTED).when(mService).checkAccess(
                 anyString(), eq(TEST_URI), anyInt(), anyInt());
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index 3beb7f2..88c7017 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -283,6 +283,21 @@
         verify(mTransaction).remove(dimLayer);
     }
 
+    @Test
+    public void testDimmerWithBlurUpdatesTransaction() {
+        TestWindowContainer child = new TestWindowContainer(mWm);
+        mHost.addChild(child, 0);
+
+        final int blurRadius = 50;
+        mDimmer.dimBelow(mTransaction, child, 0, blurRadius);
+        SurfaceControl dimLayer = getDimLayer();
+
+        assertNotNull("Dimmer should have created a surface", dimLayer);
+
+        verify(mTransaction).setBackgroundBlurRadius(dimLayer, blurRadius);
+        verify(mTransaction).setRelativeLayer(dimLayer, child.mControl, -1);
+    }
+
     private SurfaceControl getDimLayer() {
         return mDimmer.mDimState.mDimLayer;
     }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index ee2d235..3aa0ddd 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -84,9 +84,6 @@
 
     private static final int INVALID_VALUE = Integer.MIN_VALUE;
 
-    /** Maximum time to wait for a model stop confirmation before giving up. */
-    private static final long STOP_TIMEOUT_MS = 5000;
-
     /** The {@link ModuleProperties} for the system, or null if none exists. */
     final ModuleProperties mModuleProperties;
 
@@ -834,7 +831,7 @@
         }
 
         if (!event.recognitionStillActive) {
-            model.setStoppedLocked();
+            model.setStopped();
         }
 
         try {
@@ -921,7 +918,7 @@
         MetricsLogger.count(mContext, "sth_recognition_aborted", 1);
         ModelData modelData = getModelDataForLocked(event.soundModelHandle);
         if (modelData != null && modelData.isModelStarted()) {
-            modelData.setStoppedLocked();
+            modelData.setStopped();
             try {
                 IRecognitionStatusCallback callback = modelData.getCallback();
                 if (callback != null) {
@@ -978,7 +975,7 @@
         }
 
         if (!event.recognitionStillActive) {
-            modelData.setStoppedLocked();
+            modelData.setStopped();
         }
 
         try {
@@ -1206,7 +1203,7 @@
         if (modelData.isModelStarted()) {
             Slog.d(TAG, "Stopping previously started dangling model " + modelData.getHandle());
             if (mModule.stopRecognition(modelData.getHandle()) == STATUS_OK) {
-                modelData.setStoppedLocked();
+                modelData.setStopped();
                 modelData.setRequested(false);
             } else {
                 Slog.e(TAG, "Failed to stop model " + modelData.getHandle());
@@ -1255,7 +1252,7 @@
     private ModelData getOrCreateGenericModelDataLocked(UUID modelId) {
         ModelData modelData = mModelDataMap.get(modelId);
         if (modelData == null) {
-            modelData = createGenericModelData(modelId);
+            modelData = ModelData.createGenericModelData(modelId);
             mModelDataMap.put(modelId, modelData);
         } else if (!modelData.isGenericModel()) {
             Slog.e(TAG, "UUID already used for non-generic model.");
@@ -1287,7 +1284,7 @@
         mKeyphraseUuidMap.remove(keyphraseId);
         mModelDataMap.remove(modelId);
         mKeyphraseUuidMap.put(keyphraseId, modelId);
-        ModelData modelData = createKeyphraseModelData(modelId);
+        ModelData modelData = ModelData.createKeyphraseModelData(modelId);
         mModelDataMap.put(modelId, modelData);
         return modelData;
     }
@@ -1419,26 +1416,18 @@
                     Slog.w(TAG, "RemoteException in onError", e);
                 }
             }
-            return status;
-        }
-
-        // Wait for model to be stopped.
-        try {
-            modelData.waitStoppedLocked(STOP_TIMEOUT_MS);
-        } catch (InterruptedException e) {
-            Slog.e(TAG, "Didn't receive model stop callback");
-            return SoundTrigger.STATUS_ERROR;
-        }
-
-        MetricsLogger.count(mContext, "sth_stop_recognition_success", 1);
-        // Notify of pause if needed.
-        if (notify) {
-            try {
-                callback.onRecognitionPaused();
-            } catch (DeadObjectException e) {
-                forceStopAndUnloadModelLocked(modelData, e);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
+        } else {
+            modelData.setStopped();
+            MetricsLogger.count(mContext, "sth_stop_recognition_success", 1);
+            // Notify of pause if needed.
+            if (notify) {
+                try {
+                    callback.onRecognitionPaused();
+                } catch (DeadObjectException e) {
+                    forceStopAndUnloadModelLocked(modelData, e);
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "RemoteException in onRecognitionPaused", e);
+                }
             }
         }
         if (DBG) {
@@ -1473,7 +1462,7 @@
 
     // This class encapsulates the callbacks, state, handles and any other information that
     // represents a model.
-    private class ModelData {
+    private static class ModelData {
         // Model not loaded (and hence not started).
         static final int MODEL_NOTLOADED = 0;
 
@@ -1530,9 +1519,17 @@
             mModelType = modelType;
         }
 
+        static ModelData createKeyphraseModelData(UUID modelId) {
+            return new ModelData(modelId, SoundModel.TYPE_KEYPHRASE);
+        }
+
+        static ModelData createGenericModelData(UUID modelId) {
+            return new ModelData(modelId, SoundModel.TYPE_GENERIC_SOUND);
+        }
+
         // Note that most of the functionality in this Java class will not work for
         // SoundModel.TYPE_UNKNOWN nevertheless we have it since lower layers support it.
-        ModelData createModelDataOfUnknownType(UUID modelId) {
+        static ModelData createModelDataOfUnknownType(UUID modelId) {
             return new ModelData(modelId, SoundModel.TYPE_UNKNOWN);
         }
 
@@ -1556,20 +1553,8 @@
             mModelState = MODEL_STARTED;
         }
 
-        synchronized void setStoppedLocked() {
+        synchronized void setStopped() {
             mModelState = MODEL_LOADED;
-            mLock.notifyAll();
-        }
-
-        void waitStoppedLocked(long timeoutMs) throws InterruptedException {
-            long deadline = System.currentTimeMillis() + timeoutMs;
-            while (mModelState == MODEL_STARTED) {
-                long waitTime = deadline - System.currentTimeMillis();
-                if (waitTime <= 0) {
-                    throw new InterruptedException();
-                }
-                mLock.wait(waitTime);
-            }
         }
 
         synchronized void setLoaded() {
@@ -1589,7 +1574,6 @@
             mRecognitionConfig = null;
             mRequested = false;
             mCallback = null;
-            notifyAll();
         }
 
         synchronized void clearCallback() {
@@ -1694,12 +1678,4 @@
             return "Model type: " + type + "\n";
         }
     }
-
-    ModelData createKeyphraseModelData(UUID modelId) {
-        return new ModelData(modelId, SoundModel.TYPE_KEYPHRASE);
-    }
-
-    ModelData createGenericModelData(UUID modelId) {
-        return new ModelData(modelId, SoundModel.TYPE_GENERIC_SOUND);
-    }
 }
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 8d4a017..e6c2e04 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -506,6 +506,7 @@
                     if (mValidatingDspTrigger) {
                         mValidatingDspTrigger = false;
                         enforcePermissionsForDataDelivery();
+                        enforceExtraKeyphraseIdNotLeaked(result, recognitionEvent);
                         externalCallback.onKeyphraseDetected(recognitionEvent, result);
                         if (result != null) {
                             Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
@@ -581,6 +582,7 @@
                     mValidatingDspTrigger = false;
                     try {
                         enforcePermissionsForDataDelivery();
+                        enforceExtraKeyphraseIdNotLeaked(result, recognitionEvent);
                     } catch (SecurityException e) {
                         HotwordMetricsLogger.writeKeyphraseTriggerEvent(
                                 mDetectorType,
@@ -1130,6 +1132,19 @@
         }
     }
 
+    private static void enforceExtraKeyphraseIdNotLeaked(HotwordDetectedResult result,
+            SoundTrigger.KeyphraseRecognitionEvent recognitionEvent) {
+        // verify the phrase ID in HotwordDetectedResult is not exposing extra phrases
+        // the DSP did not detect
+        for (SoundTrigger.KeyphraseRecognitionExtra keyphrase : recognitionEvent.keyphraseExtras) {
+            if (keyphrase.getKeyphraseId() == result.getHotwordPhraseId()) {
+                return;
+            }
+        }
+        throw new SecurityException("Ignoring #onDetected due to trusted service "
+                + "sharing a keyphrase ID which the DSP did not detect");
+    }
+
     private static final String OP_MESSAGE =
             "Providing hotword detection result to VoiceInteractionService";
 };
diff --git a/telecomm/java/android/telecom/Logging/EventManager.java b/telecomm/java/android/telecom/Logging/EventManager.java
index 1342038..a74c0bb 100644
--- a/telecomm/java/android/telecom/Logging/EventManager.java
+++ b/telecomm/java/android/telecom/Logging/EventManager.java
@@ -180,7 +180,7 @@
             }
         }
 
-        private final List<Event> mEvents = Collections.synchronizedList(new LinkedList<>());
+        private final List<Event> mEvents = Collections.synchronizedList(new ArrayList<>());
         private final Loggable mRecordEntry;
 
         public EventRecord(Loggable recordEntry) {
@@ -197,7 +197,7 @@
         }
 
         public List<Event> getEvents() {
-            return new LinkedList<>(mEvents);
+            return new ArrayList<>(mEvents);
         }
 
         public List<EventTiming> extractEventTimings() {
@@ -205,7 +205,7 @@
                 return Collections.emptyList();
             }
 
-            LinkedList<EventTiming> result = new LinkedList<>();
+            ArrayList<EventTiming> result = new ArrayList<>();
             Map<String, PendingResponse> pendingResponses = new HashMap<>();
             synchronized (mEvents) {
                 for (Event event : mEvents) {
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
index b8ad9e2..ff87ab0 100644
--- a/telecomm/java/android/telecom/ParcelableCallAnalytics.java
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
@@ -359,7 +359,7 @@
         eventTimings = new ArrayList<>();
         in.readTypedList(eventTimings, EventTiming.CREATOR);
         isVideoCall = readByteAsBoolean(in);
-        videoEvents = new LinkedList<>();
+        videoEvents = new ArrayList<>();
         in.readTypedList(videoEvents, VideoEvent.CREATOR);
         callSource = in.readInt();
     }
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index e0f5b20..0f7dde5 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1179,7 +1179,7 @@
         if (service != null) {
             try {
                 return service.getSimCallManager(
-                        SubscriptionManager.getDefaultSubscriptionId());
+                        SubscriptionManager.getDefaultSubscriptionId(), mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getSimCallManager");
             }
@@ -1201,7 +1201,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getSimCallManager(subscriptionId);
+                return service.getSimCallManager(subscriptionId, mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getSimCallManager");
             }
@@ -1225,7 +1225,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getSimCallManagerForUser(userId);
+                return service.getSimCallManagerForUser(userId, mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#getSimCallManagerForUser");
             }
@@ -1500,7 +1500,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                service.registerPhoneAccount(account);
+                service.registerPhoneAccount(account, mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#registerPhoneAccount", e);
             }
@@ -1516,7 +1516,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                service.unregisterPhoneAccount(accountHandle);
+                service.unregisterPhoneAccount(accountHandle, mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#unregisterPhoneAccount", e);
             }
@@ -1597,7 +1597,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getDefaultDialerPackage();
+                return service.getDefaultDialerPackage(mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException attempting to get the default dialer package name.", e);
             }
@@ -1671,7 +1671,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                return service.getSystemDialerPackage();
+                return service.getSystemDialerPackage(mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException attempting to get the system dialer package name.", e);
             }
@@ -2076,7 +2076,8 @@
                             "acceptHandover for API > O-MR1");
                     return;
                 }
-                service.addNewIncomingCall(phoneAccount, extras == null ? new Bundle() : extras);
+                service.addNewIncomingCall(phoneAccount, extras == null ? new Bundle() : extras,
+                        mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException adding a new incoming call: " + phoneAccount, e);
             }
@@ -2118,7 +2119,8 @@
         if (service != null) {
             try {
                 service.addNewIncomingConference(
-                        phoneAccount, extras == null ? new Bundle() : extras);
+                        phoneAccount, extras == null ? new Bundle() : extras,
+                        mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException adding a new incoming conference: " + phoneAccount, e);
             }
@@ -2414,7 +2416,7 @@
         Intent result = null;
         if (service != null) {
             try {
-                result = service.createManageBlockedNumbersIntent();
+                result = service.createManageBlockedNumbersIntent(mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "Error calling ITelecomService#createManageBlockedNumbersIntent", e);
             }
@@ -2571,7 +2573,7 @@
         ITelecomService service = getTelecomService();
         if (service != null) {
             try {
-                service.acceptHandover(srcAddr, videoState, destAcct);
+                service.acceptHandover(srcAddr, videoState, destAcct, mContext.getPackageName());
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException acceptHandover: " + e);
             }
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 07e18d5..b3419e0 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -106,22 +106,22 @@
     /**
      * @see TelecomServiceImpl#getSimCallManager
      */
-    PhoneAccountHandle getSimCallManager(int subId);
+    PhoneAccountHandle getSimCallManager(int subId, String callingPackage);
 
     /**
      * @see TelecomServiceImpl#getSimCallManagerForUser
      */
-    PhoneAccountHandle getSimCallManagerForUser(int userId);
+    PhoneAccountHandle getSimCallManagerForUser(int userId, String callingPackage);
 
     /**
      * @see TelecomServiceImpl#registerPhoneAccount
      */
-    void registerPhoneAccount(in PhoneAccount metadata);
+    void registerPhoneAccount(in PhoneAccount metadata, String callingPackage);
 
     /**
      * @see TelecomServiceImpl#unregisterPhoneAccount
      */
-    void unregisterPhoneAccount(in PhoneAccountHandle account);
+    void unregisterPhoneAccount(in PhoneAccountHandle account, String callingPackage);
 
     /**
      * @see TelecomServiceImpl#clearAccounts
@@ -154,7 +154,7 @@
     /**
      * @see TelecomServiceImpl#getDefaultDialerPackage
      */
-    String getDefaultDialerPackage();
+    String getDefaultDialerPackage(String callingPackage);
 
     /**
      * @see TelecomServiceImpl#getDefaultDialerPackage
@@ -164,7 +164,7 @@
     /**
      * @see TelecomServiceImpl#getSystemDialerPackage
      */
-    String getSystemDialerPackage();
+    String getSystemDialerPackage(String callingPackage);
 
     /**
     * @see TelecomServiceImpl#dumpCallAnalytics
@@ -262,12 +262,15 @@
     /**
      * @see TelecomServiceImpl#addNewIncomingCall
      */
-    void addNewIncomingCall(in PhoneAccountHandle phoneAccount, in Bundle extras);
+    void addNewIncomingCall(in PhoneAccountHandle phoneAccount, in Bundle extras,
+            String callingPackage);
 
     /**
      * @see TelecomServiceImpl#addNewIncomingConference
      */
-    void addNewIncomingConference(in PhoneAccountHandle phoneAccount, in Bundle extras);
+    void addNewIncomingConference(in PhoneAccountHandle phoneAccount, in Bundle extras,
+            String callingPackage);
+
 
     /**
      * @see TelecomServiceImpl#addNewUnknownCall
@@ -303,7 +306,7 @@
     /**
     * @see TelecomServiceImpl#createManageBlockedNumbersIntent
     **/
-    Intent createManageBlockedNumbersIntent();
+    Intent createManageBlockedNumbersIntent(String callingPackage);
 
    /**
     * @see TelecomServiceImpl#createLaunchEmergencyDialerIntent
@@ -330,7 +333,8 @@
     /**
      * @see TelecomServiceImpl#acceptHandover
      */
-    void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct);
+    void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct,
+                String callingPackage);
 
     /**
      * @see TelecomServiceImpl#setTestEmergencyPhoneAccountPackageNameFilter
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a6a7c84..314104f 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -176,7 +176,7 @@
      * This flag specifies whether VoLTE availability is based on provisioning. By default this is
      * false.
      * Used for UCE to determine if EAB provisioning checks should be based on provisioning.
-     * @deprecated Use {@link Ims#KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE} instead.
+     * @deprecated Use {@link Ims#KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL} instead.
      */
     @Deprecated
     public static final String
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index efc2dec..c92f898 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -7744,7 +7744,7 @@
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
      *
      * TODO: remove this one. use {@link #rebootModem()} for reset type 1 and
-     * {@link #resetRadioConfig()} for reset type 3
+     * {@link #resetRadioConfig()} for reset type 3 (b/116476729)
      *
      * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
      * @return true on success; false on any failure.
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index 5bae1ad..f8048aa 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -539,7 +539,6 @@
      *     <li>The caller has carrier privileges (see
      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
      *     active subscription.</li>
-     *     <li>The caller is the default SMS app for the device.</li>
      * </ul>
      * <p>The profile owner is an app that owns a managed profile on the device; for more details
      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -601,7 +600,6 @@
      *     <li>The caller has carrier privileges (see
      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
      *     active subscription.</li>
-     *     <li>The caller is the default SMS app for the device.</li>
      * </ul>
      * <p>The profile owner is an app that owns a managed profile on the device; for more details
      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -649,7 +647,6 @@
      *     <li>The caller has carrier privileges (see
      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
      *     active subscription.</li>
-     *     <li>The caller is the default SMS app for the device.</li>
      * </ul>
      * <p>The profile owner is an app that owns a managed profile on the device; for more details
      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -862,7 +859,6 @@
      *     <li>The caller has carrier privileges (see
      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
      *     active subscription.</li>
-     *     <li>The caller is the default SMS app for the device.</li>
      * </ul>
      * <p>The profile owner is an app that owns a managed profile on the device; for more details
      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -937,7 +933,6 @@
      *     <li>The caller has carrier privileges (see
      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
      *     active subscription.</li>
-     *     <li>The caller is the default SMS app for the device.</li>
      * </ul>
      * <p>The profile owner is an app that owns a managed profile on the device; for more details
      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -1111,7 +1106,6 @@
      *     <li>The caller has carrier privileges (see
      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
      *     active subscription.</li>
-     *     <li>The caller is the default SMS app for the device.</li>
      * </ul>
      * <p>The profile owner is an app that owns a managed profile on the device; for more details
      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -1226,7 +1220,6 @@
      *     <li>The caller has carrier privileges (see
      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
      *     active subscription.</li>
-     *     <li>The caller is the default SMS app for the device.</li>
      * </ul>
      * <p>The profile owner is an app that owns a managed profile on the device; for more details
      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -1415,7 +1408,6 @@
      *     <li>The caller has carrier privileges (see
      *     {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
      *     active subscription.</li>
-     *     <li>The caller is the default SMS app for the device.</li>
      * </ul>
      * <p>The profile owner is an app that owns a managed profile on the device; for more details
      * see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 3415868..4439e5c 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -18,6 +18,7 @@
 
 import android.Manifest;
 import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
@@ -43,6 +44,8 @@
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.ITelephony;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
@@ -87,6 +90,46 @@
             "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
 
     /**
+     * This carrier supports User Capability Exchange as, defined by the framework using a
+     * presence server. If set, the RcsFeature should support capability exchange. If not set, this
+     * RcsFeature should not publish capabilities or service capability requests.
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "CAPABILITY_TYPE_", flag = true, value = {
+            CAPABILITY_TYPE_NONE,
+            CAPABILITY_TYPE_OPTIONS_UCE,
+            CAPABILITY_TYPE_PRESENCE_UCE
+    })
+    public @interface RcsImsCapabilityFlag {}
+
+    /**
+     * Undefined capability type for initialization
+     */
+    public static final int CAPABILITY_TYPE_NONE = 0;
+
+    /**
+     * This carrier supports User Capability Exchange using SIP OPTIONS as defined by the
+     * framework. If set, the RcsFeature should support capability exchange using SIP OPTIONS.
+     * If not set, this RcsFeature should not service capability requests.
+     */
+    public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0;
+
+    /**
+     * This carrier supports User Capability Exchange using a presence server as defined by the
+     * framework. If set, the RcsFeature should support capability exchange using a presence
+     * server. If not set, this RcsFeature should not publish capabilities or service capability
+     * requests using presence.
+     */
+    public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1;
+
+    /**
+     * This is used to check the upper range of RCS capability
+     * @hide
+     */
+    public static final int CAPABILITY_TYPE_MAX = CAPABILITY_TYPE_PRESENCE_UCE + 1;
+
+    /**
      * An application can use {@link #addOnAvailabilityChangedListener} to register a
      * {@link OnAvailabilityChangedListener}, which will notify the user when the RCS feature
      * availability status updates from the ImsService.
@@ -104,7 +147,7 @@
          *
          * @param capabilities The new availability of the capabilities.
          */
-        void onAvailabilityChanged(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities);
+        void onAvailabilityChanged(@RcsImsCapabilityFlag int capabilities);
     }
 
     /**
@@ -486,7 +529,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capability,
+    public boolean isCapable(@RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
         if (imsRcsController == null) {
@@ -497,6 +540,8 @@
 
         try {
             return imsRcsController.isCapable(mSubId, capability, radioTech);
+        } catch (ServiceSpecificException e) {
+            throw new ImsException(e.getMessage(), e.errorCode);
         } catch (RemoteException e) {
             Log.w(TAG, "Error calling IImsRcsController#isCapable", e);
             throw new ImsException("Remote IMS Service is not available",
@@ -522,7 +567,7 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    public boolean isAvailable(@RcsUceAdapter.RcsImsCapabilityFlag int capability,
+    public boolean isAvailable(@RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech)
             throws ImsException {
         IImsRcsController imsRcsController = getIImsRcsController();
@@ -534,6 +579,8 @@
 
         try {
             return imsRcsController.isAvailable(mSubId, capability, radioTech);
+        } catch (ServiceSpecificException e) {
+            throw new ImsException(e.getMessage(), e.errorCode);
         } catch (RemoteException e) {
             Log.w(TAG, "Error calling IImsRcsController#isAvailable", e);
             throw new ImsException("Remote IMS Service is not available",
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index be233b8..50fcdf8 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -52,6 +52,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
@@ -188,6 +189,7 @@
             new SparseArray<>();
 
     private IImsServiceControllerListener mListener;
+    private final Object mListenerLock = new Object();
     private Executor mExecutor;
 
     /**
@@ -225,7 +227,30 @@
     protected final IBinder mImsServiceController = new IImsServiceController.Stub() {
         @Override
         public void setListener(IImsServiceControllerListener l) {
-            mListener = l;
+            synchronized (mListenerLock) {
+                if (mListener != null && mListener.asBinder().isBinderAlive()) {
+                    try {
+                        mListener.asBinder().unlinkToDeath(mDeathRecipient, 0);
+                    } catch (NoSuchElementException e) {
+                        Log.w(LOG_TAG, "IImsServiceControllerListener does not exist");
+                    }
+                }
+
+                mListener = l;
+                if (mListener == null) {
+                    executeMethodAsync(() -> releaseResource(), "releaseResource");
+                    return;
+                }
+
+                try {
+                    mListener.asBinder().linkToDeath(mDeathRecipient, 0);
+                    Log.i(LOG_TAG, "setListener: register linkToDeath");
+                } catch (RemoteException e) {
+                    // RemoteException means target binder process was crashed
+                    // release resource
+                    executeMethodAsync(() -> releaseResource(), "releaseResource");
+                }
+            }
         }
 
         @Override
@@ -364,28 +389,15 @@
                     ImsService.this.disableImsForSubscription(slotId, subId), "disableIms");
         }
 
-        // Call the methods with a clean calling identity on the executor and wait indefinitely for
-        // the future to return.
-        private void executeMethodAsync(Runnable r, String errorLogName) {
-            try {
-                CompletableFuture.runAsync(
-                        () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor).join();
-            } catch (CancellationException | CompletionException e) {
-                Log.w(LOG_TAG, "ImsService Binder - " + errorLogName + " exception: "
-                        + e.getMessage());
-            }
-        }
 
-        private <T> T executeMethodAsyncForResult(Supplier<T> r, String errorLogName) {
-            CompletableFuture<T> future = CompletableFuture.supplyAsync(
-                    () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor);
-            try {
-                return future.get();
-            } catch (ExecutionException | InterruptedException e) {
-                Log.w(LOG_TAG, "ImsService Binder - " + errorLogName + " exception: "
-                        + e.getMessage());
-                return null;
-            }
+    };
+
+    private final IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
+        @Override
+        public void binderDied() {
+            Log.w(LOG_TAG,
+                    "IImsServiceControllerListener binder to framework has died. Cleaning up");
+            executeMethodAsync(() -> releaseResource(), "releaseResource");
         }
     };
 
@@ -490,6 +502,9 @@
     }
 
     private void removeImsFeature(int slotId, int featureType) {
+        // clear cached data
+        notifySubscriptionRemoved(slotId);
+
         synchronized (mFeaturesBySlot) {
             // get ImsFeature associated with the slot/feature
             SparseArray<ImsFeature> features = mFeaturesBySlot.get(slotId);
@@ -507,7 +522,6 @@
             f.onFeatureRemoved();
             features.remove(featureType);
         }
-
     }
 
     /**
@@ -552,6 +566,54 @@
         return createFlag;
     }
 
+    private void releaseResource() {
+        Log.w(LOG_TAG, "cleaning up features");
+        synchronized (mFeaturesBySlot) {
+            SparseArray<ImsFeature> features;
+            ImsFeature imsFeature;
+
+            for (int i = 0; i < mFeaturesBySlot.size(); i++) {
+                features = mFeaturesBySlot.valueAt(i);
+                if (features == null) {
+                    continue;
+                }
+
+                for (int index = 0; index < features.size(); index++) {
+                    imsFeature = features.valueAt(index);
+                    if (imsFeature != null) {
+                        imsFeature.onFeatureRemoved();
+                    }
+                }
+                features.clear();
+            }
+            mFeaturesBySlot.clear();
+        }
+    }
+
+    // Call the methods with a clean calling identity on the executor and wait indefinitely for
+    // the future to return.
+    private void executeMethodAsync(Runnable r, String errorLogName) {
+        try {
+            CompletableFuture.runAsync(
+                    () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor).join();
+        } catch (CancellationException | CompletionException e) {
+            Log.w(LOG_TAG, "ImsService Binder - " + errorLogName + " exception: "
+                    + e.getMessage());
+        }
+    }
+
+    private <T> T executeMethodAsyncForResult(Supplier<T> r, String errorLogName) {
+        CompletableFuture<T> future = CompletableFuture.supplyAsync(
+                () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor);
+        try {
+            return future.get();
+        } catch (ExecutionException | InterruptedException e) {
+            Log.w(LOG_TAG, "ImsService Binder - " + errorLogName + " exception: "
+                    + e.getMessage());
+            return null;
+        }
+    }
+
     /**
      * When called, provide the {@link ImsFeatureConfiguration} that this {@link ImsService}
      * currently supports. This will trigger the framework to set up the {@link ImsFeature}s that
@@ -574,10 +636,14 @@
      */
     public final void onUpdateSupportedImsFeatures(ImsFeatureConfiguration c)
             throws RemoteException {
-        if (mListener == null) {
-            throw new IllegalStateException("Framework is not ready");
+        IImsServiceControllerListener l;
+        synchronized (mListenerLock) {
+            if (mListener == null) {
+                throw new IllegalStateException("Framework is not ready");
+            }
+            l = mListener;
         }
-        mListener.onUpdateSupportedImsFeatures(c);
+        l.onUpdateSupportedImsFeatures(c);
     }
 
     /**
@@ -629,6 +695,24 @@
     }
 
     /**
+     * The subscription has removed. The ImsService should notify ImsRegistrationImplBase and
+     * ImsConfigImplBase the SIM state was changed.
+     * @param slotId The slot ID which has removed.
+     */
+    private void notifySubscriptionRemoved(int slotId) {
+        ImsRegistrationImplBase registrationImplBase =
+                getRegistration(slotId);
+        if (registrationImplBase != null) {
+            registrationImplBase.clearRegistrationCache();
+        }
+
+        ImsConfigImplBase imsConfigImplBase = getConfig(slotId);
+        if (imsConfigImplBase != null) {
+            imsConfigImplBase.clearConfigurationCache();
+        }
+    }
+
+    /**
      * The framework has enabled IMS for the slot specified, the ImsService should register for IMS
      * and perform all appropriate initialization to bring up all ImsFeatures.
      * @deprecated Use {@link #enableImsForSubscription} instead.
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 677c1a9..f2976f1 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -38,7 +38,6 @@
 import android.telephony.ims.aidl.IImsConfigCallback;
 import android.telephony.ims.aidl.IRcsConfigCallback;
 import android.telephony.ims.feature.MmTelFeature;
-import android.telephony.ims.feature.RcsFeature;
 import android.telephony.ims.stub.ImsConfigImplBase;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 
@@ -55,6 +54,9 @@
  * IMS provisioning keys are defined per carrier or OEM using OMA-DM or other provisioning
  * applications and may vary. It is up to the carrier and OEM applications to ensure that the
  * correct provisioning keys are being used when integrating with a vendor's ImsService.
+ *
+ * Use {@link android.telephony.ims.ImsManager#getProvisioningManager(int)} to get an instance of
+ * this manager.
  */
 @RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
 public class ProvisioningManager {
@@ -970,7 +972,7 @@
     /**
      * Callback for IMS provisioning feature changes.
      */
-    public static class FeatureProvisioningCallback {
+    public abstract static class FeatureProvisioningCallback {
 
         private static class CallbackBinder extends IFeatureProvisioningCallback.Stub {
 
@@ -1024,12 +1026,10 @@
          * specified, or {@code false} if the capability is not provisioned for the technology
          * specified.
          */
-        public void onFeatureProvisioningChanged(
+        public abstract void onFeatureProvisioningChanged(
                 @MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
                 @ImsRegistrationImplBase.ImsRegistrationTech int tech,
-                boolean isProvisioned) {
-            // Base Implementation
-        }
+                boolean isProvisioned);
 
         /**
          * The IMS RCS provisioning has changed for a specific capability and IMS
@@ -1041,12 +1041,10 @@
          * specified, or {@code false} if the capability is not provisioned for the technology
          * specified.
          */
-        public void onRcsFeatureProvisioningChanged(
-                @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+        public abstract void onRcsFeatureProvisioningChanged(
+                @ImsRcsManager.RcsImsCapabilityFlag int capability,
                 @ImsRegistrationImplBase.ImsRegistrationTech int tech,
-                boolean isProvisioned) {
-            // Base Implementation
-        }
+                boolean isProvisioned);
 
         /**@hide*/
         public final IFeatureProvisioningCallback getBinder() {
@@ -1505,7 +1503,7 @@
      * Get the provisioning status for the IMS RCS capability specified.
      *
      * If provisioning is not required for the queried
-     * {@link RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag} this method will always return
+     * {@link ImsRcsManager.RcsImsCapabilityFlag} this method will always return
      * {@code true}.
      *
      * @see CarrierConfigManager.Ims#KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL
@@ -1522,7 +1520,7 @@
     @WorkerThread
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public boolean getRcsProvisioningStatusForCapability(
-            @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
+            @ImsRcsManager.RcsImsCapabilityFlag int capability) {
         try {
             return getITelephony().getRcsProvisioningStatusForCapability(mSubId, capability,
             ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
@@ -1535,7 +1533,7 @@
      * Get the provisioning status for the IMS RCS capability specified.
      *
      * If provisioning is not required for the queried
-     * {@link RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag} this method
+     * {@link ImsRcsManager.RcsImsCapabilityFlag} this method
      * will always return {@code true}.
      *
      * <p> Requires Permission:
@@ -1553,7 +1551,7 @@
     @WorkerThread
     @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
     public boolean getRcsProvisioningStatusForCapability(
-            @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+            @ImsRcsManager.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int tech) {
         try {
             return getITelephony().getRcsProvisioningStatusForCapability(mSubId, capability, tech);
@@ -1590,7 +1588,7 @@
     @WorkerThread
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setRcsProvisioningStatusForCapability(
-            @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+            @ImsRcsManager.RcsImsCapabilityFlag int capability,
             boolean isProvisioned) {
         try {
             getITelephony().setRcsProvisioningStatusForCapability(mSubId, capability,
@@ -1622,7 +1620,7 @@
     @WorkerThread
     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
     public void setRcsProvisioningStatusForCapability(
-            @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+            @ImsRcsManager.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int tech, boolean isProvisioned) {
         try {
             getITelephony().setRcsProvisioningStatusForCapability(mSubId, capability,
@@ -1676,7 +1674,7 @@
      */
     @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
     public boolean isRcsProvisioningRequiredForCapability(
-            @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+            @ImsRcsManager.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int tech) {
         try {
             return getITelephony().isRcsProvisioningRequiredForCapability(mSubId, capability, tech);
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 154bb11..91dc38f 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -55,20 +55,28 @@
      * This carrier supports User Capability Exchange as, defined by the framework using
      * SIP OPTIONS. If set, the RcsFeature should support capability exchange. If not set, this
      * RcsFeature should not publish capabilities or service capability requests.
+     * @deprecated Use {@link ImsRcsManager#CAPABILITY_TYPE_OPTIONS_UCE} instead.
      * @hide
      */
+    @Deprecated
     public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0;
 
     /**
      * This carrier supports User Capability Exchange as, defined by the framework using a
      * presence server. If set, the RcsFeature should support capability exchange. If not set, this
      * RcsFeature should not publish capabilities or service capability requests.
+     * @deprecated Use {@link ImsRcsManager#CAPABILITY_TYPE_PRESENCE_UCE} instead.
      * @hide
      */
+    @Deprecated
     @SystemApi
     public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1;
 
-    /**@hide*/
+    /**
+     * @deprecated Use {@link ImsRcsManager.RcsImsCapabilityFlag} instead.
+     * @hide
+     */
+    @Deprecated
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = "CAPABILITY_TYPE_", value = {
             CAPABILITY_TYPE_OPTIONS_UCE,
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index ad2e9e1..fb0e659 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -396,7 +396,7 @@
         /**
          * Undefined capability type for initialization
          * This is used to check the upper range of MmTel capability
-         * {@hide}
+         * @hide
          */
         public static final int CAPABILITY_TYPE_NONE = 0;
 
@@ -427,7 +427,7 @@
 
         /**
          * This is used to check the upper range of MmTel capability
-         * {@hide}
+         * @hide
          */
         public static final int CAPABILITY_TYPE_MAX = CAPABILITY_TYPE_CALL_COMPOSER + 1;
 
@@ -738,7 +738,7 @@
      * Enabling/Disabling a capability here indicates that the capability should be registered or
      * deregistered (depending on the capability change) and become available or unavailable to
      * the framework.
-     * * @hide
+     * @hide
      */
     @Override
     @SystemApi
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index 70e4ef1..843827b 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -24,7 +24,7 @@
 import android.content.Context;
 import android.net.Uri;
 import android.os.RemoteException;
-import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.ImsRcsManager;
 import android.telephony.ims.aidl.CapabilityExchangeAidlWrapper;
 import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
@@ -59,7 +59,9 @@
 /**
  * Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend
  * this class and provide implementations of the RcsFeature methods that they support.
+ * @hide
  */
+@SystemApi
 public class RcsFeature extends ImsFeature {
 
     private static final String LOG_TAG = "RcsFeature";
@@ -184,18 +186,22 @@
      * Contains the capabilities defined and supported by a {@link RcsFeature} in the
      * form of a bitmask. The capabilities that are used in the RcsFeature are
      * defined as:
-     * {RcsUceAdapter.RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
-     * {RcsUceAdapter.RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
+     * {@link ImsRcsManager.RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
+     * {@link ImsRcsManager.RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
      *
      * The enabled capabilities of this RcsFeature will be set by the framework
-     * using {#changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}.
+     * using {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}.
      * After the capabilities have been set, the RcsFeature may then perform the necessary bring up
      * of the capability and notify the capability status as true using
-     * {#notifyCapabilitiesStatusChanged(RcsImsCapabilities)}. This will signal to the
+     * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}. This will signal to the
      * framework that the capability is available for usage.
      */
     public static class RcsImsCapabilities extends Capabilities {
-        /** @hide*/
+
+        /**
+         * Use {@link ImsRcsManager.RcsImsCapabilityFlag} instead in case used for public API
+         * @hide
+         */
         @Retention(RetentionPolicy.SOURCE)
         @IntDef(prefix = "CAPABILITY_TYPE_", flag = true, value = {
                 CAPABILITY_TYPE_NONE,
@@ -226,7 +232,7 @@
 
         /**
          * This is used to check the upper range of RCS capability
-         * {@hide}
+         * @hide
          */
         public static final int CAPABILITY_TYPE_MAX = CAPABILITY_TYPE_PRESENCE_UCE + 1;
 
@@ -234,10 +240,8 @@
          * Create a new {@link RcsImsCapabilities} instance with the provided capabilities.
          * @param capabilities The capabilities that are supported for RCS in the form of a
          * bitfield.
-         * @hide
          */
-        @SystemApi
-        public RcsImsCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
+        public RcsImsCapabilities(@ImsRcsManager.RcsImsCapabilityFlag int capabilities) {
             super(capabilities);
         }
 
@@ -249,30 +253,18 @@
             super(capabilities.getMask());
         }
 
-        /**
-         * @hide
-         */
         @Override
-        @SystemApi
-        public void addCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
+        public void addCapabilities(@ImsRcsManager.RcsImsCapabilityFlag int capabilities) {
             super.addCapabilities(capabilities);
         }
 
-        /**
-         * @hide
-         */
         @Override
-        @SystemApi
-        public void removeCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
+        public void removeCapabilities(@ImsRcsManager.RcsImsCapabilityFlag int capabilities) {
             super.removeCapabilities(capabilities);
         }
 
-        /**
-         * @hide
-         */
         @Override
-        @SystemApi
-        public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
+        public boolean isCapable(@ImsRcsManager.RcsImsCapabilityFlag int capabilities) {
             return super.isCapable(capabilities);
         }
     }
@@ -288,9 +280,7 @@
      * Method stubs called from the framework will be called asynchronously. To specify the
      * {@link Executor} that the methods stubs will be called, use
      * {@link RcsFeature#RcsFeature(Executor)} instead.
-     * @hide
      */
-    @SystemApi
     public RcsFeature() {
         super();
         // Run on the Binder threads that call them.
@@ -302,9 +292,7 @@
      * framework.
      * @param executor The executor for the framework to use when executing the methods overridden
      * by the implementation of RcsFeature.
-     * @hide
      */
-    @SystemApi
     public RcsFeature(@NonNull Executor executor) {
         super();
         if (executor == null) {
@@ -335,10 +323,8 @@
      * requests. To change the status of the capabilities
      * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)} should be called.
      * @return A copy of the current RcsFeature capability status.
-     * @hide
      */
     @Override
-    @SystemApi
     public @NonNull final RcsImsCapabilities queryCapabilityStatus() {
         return new RcsImsCapabilities(super.queryCapabilityStatus());
     }
@@ -348,9 +334,7 @@
      * this signals to the framework that the capability has been initialized and is ready.
      * Call {@link #queryCapabilityStatus()} to return the current capability status.
      * @param capabilities The current capability status of the RcsFeature.
-     * @hide
      */
-    @SystemApi
     public final void notifyCapabilitiesStatusChanged(@NonNull RcsImsCapabilities capabilities) {
         if (capabilities == null) {
             throw new IllegalArgumentException("RcsImsCapabilities must be non-null!");
@@ -367,11 +351,9 @@
      * @param capability The capability that we are querying the configuration for.
      * @param radioTech The radio technology type that we are querying.
      * @return true if the capability is enabled, false otherwise.
-     * @hide
      */
-    @SystemApi
     public boolean queryCapabilityConfiguration(
-            @RcsUceAdapter.RcsImsCapabilityFlag int capability,
+            @ImsRcsManager.RcsImsCapabilityFlag int capability,
             @ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
         // Base Implementation - Override to provide functionality
         return false;
@@ -392,10 +374,8 @@
      * be called for each capability change that resulted in an error.
      * @param request The request to change the capability.
      * @param callback To notify the framework that the result of the capability changes.
-     * @hide
      */
     @Override
-    @SystemApi
     public void changeEnabledCapabilities(@NonNull CapabilityChangeRequest request,
             @NonNull CapabilityCallbackProxy callback) {
         // Base Implementation - Override to provide functionality
@@ -415,9 +395,7 @@
      * event to the framework.
      * @return An instance of {@link RcsCapabilityExchangeImplBase} that implements capability
      * exchange if it is supported by the device.
-     * @hide
      */
-    @SystemApi
     public @NonNull RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(
             @NonNull CapabilityExchangeEventListener listener) {
         // Base Implementation, override to implement functionality
@@ -427,28 +405,20 @@
     /**
      * Remove the given CapabilityExchangeImplBase instance.
      * @param capExchangeImpl The {@link RcsCapabilityExchangeImplBase} instance to be destroyed.
-     * @hide
      */
-    @SystemApi
     public void destroyCapabilityExchangeImpl(
             @NonNull RcsCapabilityExchangeImplBase capExchangeImpl) {
         // Override to implement the process of destroying RcsCapabilityExchangeImplBase instance.
     }
 
-    /**{@inheritDoc}
-     * @hide
-     */
+    /**{@inheritDoc}*/
     @Override
-    @SystemApi
     public void onFeatureRemoved() {
 
     }
 
-    /**{@inheritDoc}
-     * @hide
-     */
+    /**{@inheritDoc}*/
     @Override
-    @SystemApi
     public void onFeatureReady() {
 
     }
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index f371ec3..897b57f 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -481,6 +481,17 @@
             }
         }
 
+        /**
+         * Clear cached configuration value.
+         */
+        public void clearCachedValue() {
+            Log.i(TAG, "clearCachedValue");
+            synchronized (mLock) {
+                mProvisionedIntValue.clear();
+                mProvisionedStringValue.clear();
+            }
+        }
+
         // Call the methods with a clean calling identity on the executor and wait indefinitely for
         // the future to return.
         private void executeMethodAsync(Runnable r, String errorLogName) throws RemoteException {
@@ -538,6 +549,7 @@
     private final RemoteCallbackListExt<IRcsConfigCallback> mRcsCallbacks =
             new RemoteCallbackListExt<>();
     private byte[] mRcsConfigData;
+    private final Object mRcsConfigDataLock = new Object();
     ImsConfigStub mImsConfigStub;
 
     /**
@@ -616,12 +628,20 @@
 
     private void addRcsConfigCallback(IRcsConfigCallback c) {
         mRcsCallbacks.register(c);
-        if (mRcsConfigData != null) {
-            try {
-                c.onConfigurationChanged(mRcsConfigData);
-            } catch (RemoteException e) {
-                Log.w(TAG, "dead binder to call onConfigurationChanged, skipping.");
+
+        // This is used to avoid calling the binder out of the synchronized scope.
+        byte[] cloneRcsConfigData;
+        synchronized (mRcsConfigDataLock) {
+            if (mRcsConfigData == null) {
+                return;
             }
+            cloneRcsConfigData = mRcsConfigData.clone();
+        }
+
+        try {
+            c.onConfigurationChanged(cloneRcsConfigData);
+        } catch (RemoteException e) {
+            Log.w(TAG, "dead binder to call onConfigurationChanged, skipping.");
         }
     }
 
@@ -631,18 +651,23 @@
 
     private void onNotifyRcsAutoConfigurationReceived(byte[] config, boolean isCompressed) {
         // cache uncompressed config
-        config = isCompressed ? RcsConfig.decompressGzip(config) : config;
-        if (Arrays.equals(mRcsConfigData, config)) {
-            return;
+        final byte[] rcsConfigData = isCompressed ? RcsConfig.decompressGzip(config) : config;
+
+        synchronized (mRcsConfigDataLock) {
+            if (Arrays.equals(mRcsConfigData, config)) {
+                return;
+            }
+            mRcsConfigData = rcsConfigData;
         }
-        mRcsConfigData = config;
 
         // can be null in testing
         if (mRcsCallbacks != null) {
             synchronized (mRcsCallbacks) {
                 mRcsCallbacks.broadcastAction(c -> {
                     try {
-                        c.onConfigurationChanged(mRcsConfigData);
+                        // config is cloned here so modifications to the config passed to the
+                        // vendor do not accidentally modify the cache.
+                        c.onConfigurationChanged(rcsConfigData.clone());
                     } catch (RemoteException e) {
                         Log.w(TAG, "dead binder in notifyRcsAutoConfigurationReceived, skipping.");
                     }
@@ -653,7 +678,9 @@
     }
 
     private void onNotifyRcsAutoConfigurationRemoved() {
-        mRcsConfigData = null;
+        synchronized (mRcsConfigDataLock) {
+            mRcsConfigData = null;
+        }
         if (mRcsCallbacks != null) {
             synchronized (mRcsCallbacks) {
                 mRcsCallbacks.broadcastAction(c -> {
@@ -857,4 +884,17 @@
             mImsConfigStub.mExecutor = executor;
         }
     }
+
+    /**
+     * Clear all cached config data. This will be called when the config data is no longer valid
+     * such as when the SIM was removed.
+     * @hide
+     */
+    public final void clearConfigurationCache() {
+        mImsConfigStub.clearCachedValue();
+
+        synchronized (mRcsConfigDataLock) {
+            mRcsConfigData = null;
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index ac5565b..6fc1cc8 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -93,7 +93,7 @@
 
     /**
      * This is used to check the upper range of registration tech
-     * {@hide}
+     * @hide
      */
     public static final int REGISTRATION_TECH_MAX = REGISTRATION_TECH_NR + 1;
 
@@ -517,4 +517,16 @@
             mExecutor = executor;
         }
     }
+
+    /**
+     * Clear the cached data when the subscription is no longer valid
+     * such as when a sim is removed.
+     * @hide
+     */
+    public final void clearRegistrationCache() {
+        synchronized (mLock) {
+            mUris = null;
+            mUrisSet = false;
+        }
+    }
 }
diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
index 7490d3f..ab83997 100644
--- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
@@ -114,6 +114,63 @@
         Uninstall.packages(TestApp.A, TestApp.B);
     }
 
+    private boolean isSystem(PackageInfo info) {
+        return (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+    }
+
+    private boolean isUpdatedSystem(PackageInfo info) {
+        return (info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
+    }
+
+    @Test
+    public void testUpdateSystemApp_InstallV2() throws Exception {
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+
+        PackageManager pm =
+                InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+        PackageInfo info;
+        // Check factory version
+        info = pm.getPackageInfo(TestApp.A,
+                PackageManager.PackageInfoFlags.of(PackageManager.MATCH_FACTORY_ONLY));
+        assertThat(isSystem(info)).isTrue();
+        assertThat(isUpdatedSystem(info)).isFalse();
+        // Check active version
+        info = pm.getPackageInfo(TestApp.A, PackageManager.PackageInfoFlags.of(0));
+        assertThat(isSystem(info)).isTrue();
+        assertThat(isUpdatedSystem(info)).isFalse();
+
+        Install.single(TestApp.A2).commit();
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+
+        // Check factory version
+        info = pm.getPackageInfo(TestApp.A,
+                PackageManager.PackageInfoFlags.of(PackageManager.MATCH_FACTORY_ONLY));
+        assertThat(isSystem(info)).isTrue();
+        assertThat(isUpdatedSystem(info)).isFalse();
+        // Check active version
+        info = pm.getPackageInfo(TestApp.A, PackageManager.PackageInfoFlags.of(0));
+        assertThat(isSystem(info)).isTrue();
+        assertThat(isUpdatedSystem(info)).isTrue();
+    }
+
+    @Test
+    public void testUpdateSystemApp_PostInstallV2() throws Exception {
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+
+        PackageManager pm =
+                InstrumentationRegistry.getInstrumentation().getContext().getPackageManager();
+        PackageInfo info;
+        // Check factory version
+        info = pm.getPackageInfo(TestApp.A,
+                PackageManager.PackageInfoFlags.of(PackageManager.MATCH_FACTORY_ONLY));
+        assertThat(isSystem(info)).isTrue();
+        assertThat(isUpdatedSystem(info)).isFalse();
+        // Check active version
+        info = pm.getPackageInfo(TestApp.A, PackageManager.PackageInfoFlags.of(0));
+        assertThat(isSystem(info)).isTrue();
+        assertThat(isUpdatedSystem(info)).isTrue();
+    }
+
     @Test
     public void testDuplicateApkInApexShouldFail_Commit() throws Exception {
         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
@@ -403,7 +460,8 @@
         {
             PackageInfo apex = pm.getPackageInfo("test.apex.rebootless", PackageManager.MATCH_APEX);
             assertThat(apex.getLongVersionCode()).isEqualTo(1);
-            assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+            assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)
+                    .isEqualTo(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
             assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
                     .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
             assertThat(apex.applicationInfo.sourceDir).startsWith("/data/apex/active");
@@ -414,7 +472,8 @@
             assertThat(apex.getLongVersionCode()).isEqualTo(1);
             assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
                     .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
-            assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
+            assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+                    .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
             assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
         }
 
@@ -425,7 +484,8 @@
         {
             PackageInfo apex = pm.getPackageInfo("test.apex.rebootless", PackageManager.MATCH_APEX);
             assertThat(apex.getLongVersionCode()).isEqualTo(2);
-            assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM).isEqualTo(0);
+            assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)
+                    .isEqualTo(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
             assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
                     .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
             assertThat(apex.applicationInfo.sourceDir).startsWith("/data/apex/active");
@@ -436,7 +496,8 @@
             assertThat(apex.getLongVersionCode()).isEqualTo(1);
             assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
                     .isEqualTo(ApplicationInfo.FLAG_SYSTEM);
-            assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED).isEqualTo(0);
+            assertThat(apex.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)
+                    .isEqualTo(ApplicationInfo.FLAG_INSTALLED);
             assertThat(apex.applicationInfo.sourceDir).startsWith("/system/apex");
         }
     }
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index f60b4d6..7e0a55f 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -95,6 +95,7 @@
                 "/data/apex/active/" + SHIM_APEX_PACKAGE_NAME + "*.apex",
                 "/system/apex/test.rebootless_apex_v*.apex",
                 "/data/apex/active/test.apex.rebootless*.apex",
+                "/system/app/TestApp/TestAppAv1.apk",
                 TEST_VENDOR_APEX_ALLOW_LIST);
     }
 
@@ -163,6 +164,25 @@
     }
 
     /**
+     * Tests app info flags are set correctly when updating a system app.
+     */
+    @Test
+    public void testUpdateSystemApp() throws Exception {
+        // Push TestAppAv1.apk to /system
+        final File apkFile = mHostUtils.getTestFile(APK_A);
+        if (!getDevice().isAdbRoot()) {
+            getDevice().enableAdbRoot();
+        }
+        getDevice().remountSystemWritable();
+        assertTrue(getDevice().pushFile(apkFile, "/system/app/TestApp/" + apkFile.getName()));
+        getDevice().reboot();
+
+        runPhase("testUpdateSystemApp_InstallV2");
+        getDevice().reboot();
+        runPhase("testUpdateSystemApp_PostInstallV2");
+    }
+
+    /**
      * Tests that duplicate packages in apk-in-apex and apk should fail to install.
      */
     @Test
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index b7f5b15..f183a9b 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -20,6 +20,7 @@
 import android.service.voice.AlwaysOnHotwordDetector;
 import android.service.voice.AlwaysOnHotwordDetector.Callback;
 import android.service.voice.AlwaysOnHotwordDetector.EventPayload;
+import android.service.voice.HotwordDetector;
 import android.service.voice.VoiceInteractionService;
 import android.util.Log;
 
@@ -83,16 +84,24 @@
                 break;
             case AlwaysOnHotwordDetector.STATE_KEYPHRASE_UNENROLLED:
                 Log.i(TAG, "STATE_KEYPHRASE_UNENROLLED");
-                Intent enroll = mHotwordDetector.createEnrollIntent();
-                Log.i(TAG, "Need to enroll with " + enroll);
+                try {
+                    Intent enroll = mHotwordDetector.createEnrollIntent();
+                    Log.i(TAG, "Need to enroll with " + enroll);
+                } catch (HotwordDetector.IllegalDetectorStateException e) {
+                    Log.e(TAG, "createEnrollIntent failed", e);
+                }
                 break;
             case AlwaysOnHotwordDetector.STATE_KEYPHRASE_ENROLLED:
                 Log.i(TAG, "STATE_KEYPHRASE_ENROLLED - starting recognition");
-                if (mHotwordDetector.startRecognition(
-                        AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE)) {
-                    Log.i(TAG, "startRecognition succeeded");
-                } else {
-                    Log.i(TAG, "startRecognition failed");
+                try {
+                    if (mHotwordDetector.startRecognition(
+                            AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE)) {
+                        Log.i(TAG, "startRecognition succeeded");
+                    } else {
+                        Log.i(TAG, "startRecognition failed");
+                    }
+                } catch (HotwordDetector.IllegalDetectorStateException e) {
+                    Log.e(TAG, "startRecognition failed", e);
                 }
                 break;
         }
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index bfb3285..0849600 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -36,6 +36,7 @@
 
 cc_defaults {
     name: "aapt2_defaults",
+    cpp_std: "gnu++2b",
     cflags: [
         "-Wall",
         "-Werror",
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index f47d66e..41896f6 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -273,7 +273,7 @@
     printer->Indent();
     for (const auto& type : package.types) {
       printer->Print("type ");
-      printer->Print(to_string(type.type));
+      printer->Print(type.named_type.to_string());
       if (type.id) {
         printer->Print(StringPrintf(" id=%02x", type.id.value()));
       }
@@ -287,7 +287,7 @@
         printer->Print(" ");
 
         // Write the name without the package (this is obvious and too verbose).
-        printer->Print(to_string(type.type));
+        printer->Print(type.named_type.to_string());
         printer->Print("/");
         printer->Print(entry.name);
 
@@ -547,7 +547,7 @@
           const auto policy_subsection = StringPrintf(R"(policies="%s")",
               android::idmap2::policy::PoliciesToDebugString(overlayable_item.policies).c_str());
           const auto value =
-            StringPrintf("%s/%s", to_string(type->type).data(), entry->name.c_str());
+              StringPrintf("%s/%s", type->named_type.to_string().data(), entry->name.c_str());
           items.push_back(DumpOverlayableEntry{overlayable_section, policy_subsection, value});
         }
       }
diff --git a/tools/aapt2/Resource.cpp b/tools/aapt2/Resource.cpp
index 0bb330e..df8c3b9 100644
--- a/tools/aapt2/Resource.cpp
+++ b/tools/aapt2/Resource.cpp
@@ -139,10 +139,10 @@
 }
 
 std::optional<ResourceNamedTypeRef> ParseResourceNamedType(const android::StringPiece& s) {
-  auto colon = std::find(s.begin(), s.end(), ':');
+  auto dot = std::find(s.begin(), s.end(), '.');
   const ResourceType* parsedType;
-  if (colon != s.end() && colon != std::prev(s.end())) {
-    parsedType = ParseResourceType(s.substr(s.begin(), colon));
+  if (dot != s.end() && dot != std::prev(s.end())) {
+    parsedType = ParseResourceType(s.substr(s.begin(), dot));
   } else {
     parsedType = ParseResourceType(s);
   }
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 8d35eee..a99e4b2 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -981,12 +981,14 @@
     return false;
   }
 
-  std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(maybe_type.value());
-  if (!parsed_type) {
+  std::optional<ResourceNamedTypeRef> maybe_parsed_type =
+      ParseResourceNamedType(maybe_type.value());
+  if (!maybe_parsed_type) {
     diag->Error(DiagMessage(out_resource->source)
                 << "invalid resource type '" << maybe_type.value() << "' in <" << tag_name << ">");
     return false;
   }
+  auto parsed_type = maybe_parsed_type->ToResourceNamedType();
 
   std::optional<StringPiece> maybe_id_str = xml::FindNonEmptyAttribute(parser, "first-id");
   if (!maybe_id_str) {
@@ -1046,7 +1048,7 @@
       }
 
       ParsedResource& entry_res = out_resource->child_resources.emplace_back(ParsedResource{
-          .name = ResourceName{{}, *parsed_type, maybe_name.value().to_string()},
+          .name = ResourceName{{}, parsed_type, maybe_name.value().to_string()},
           .source = item_source,
           .comment = std::move(comment),
       });
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 98cce26..0f5118d 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -43,8 +43,9 @@
 const char* Overlayable::kActorScheme = "overlay";
 
 namespace {
-bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs, ResourceType rhs) {
-  return lhs->type < rhs;
+bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs,
+                    const ResourceNamedTypeRef& rhs) {
+  return lhs->named_type < rhs;
 }
 
 template <typename T>
@@ -115,18 +116,24 @@
 }
 
 template <typename Func, typename Elements>
-static ResourceTableType* FindTypeRunAction(ResourceType type, Elements& entries, Func action) {
+static ResourceTableType* FindTypeRunAction(const ResourceNamedTypeRef& type, Elements& entries,
+                                            Func action) {
   const auto iter = std::lower_bound(entries.begin(), entries.end(), type, less_than_type);
-  const bool found = iter != entries.end() && type == (*iter)->type;
+  const bool found = iter != entries.end() && type == (*iter)->named_type;
   return action(found, iter);
 }
 
-ResourceTableType* ResourceTablePackage::FindType(ResourceType type) const {
+ResourceTableType* ResourceTablePackage::FindTypeWithDefaultName(const ResourceType type) const {
+  auto named_type = ResourceNamedTypeWithDefaultName(type);
+  return FindType(named_type);
+}
+
+ResourceTableType* ResourceTablePackage::FindType(const ResourceNamedTypeRef& type) const {
   return FindTypeRunAction(type, types,
                            [&](bool found, auto& iter) { return found ? iter->get() : nullptr; });
 }
 
-ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type) {
+ResourceTableType* ResourceTablePackage::FindOrCreateType(const ResourceNamedTypeRef& type) {
   return FindTypeRunAction(type, types, [&](bool found, auto& iter) {
     return found ? iter->get() : types.emplace(iter, new ResourceTableType(type))->get();
   });
@@ -329,7 +336,7 @@
 
 struct TypeViewComparer {
   bool operator()(const ResourceTableTypeView& lhs, const ResourceTableTypeView& rhs) {
-    return lhs.id != rhs.id ? lhs.id < rhs.id : lhs.type < rhs.type;
+    return lhs.id != rhs.id ? lhs.id < rhs.id : lhs.named_type < rhs.named_type;
   }
 };
 
@@ -355,7 +362,8 @@
                                        id ? id.value().package_id() : std::optional<uint8_t>{}};
   auto view_package = package_inserter.Insert(table.packages, std::move(new_package));
 
-  ResourceTableTypeView new_type{type->type, id ? id.value().type_id() : std::optional<uint8_t>{}};
+  ResourceTableTypeView new_type{type->named_type,
+                                 id ? id.value().type_id() : std::optional<uint8_t>{}};
   auto view_type = type_inserter.Insert(view_package->types, std::move(new_type));
 
   if (visibility.level == Visibility::Level::kPublic) {
@@ -420,13 +428,14 @@
     // we can reuse those packages for other types that need to be extracted from this package.
     // `start_index` is the index of the first newly created package that can be reused.
     const size_t start_index = new_packages.size();
-    std::map<ResourceType, size_t> type_new_package_index;
+    std::map<ResourceNamedType, size_t> type_new_package_index;
     for (auto type_it = package.types.begin(); type_it != package.types.end();) {
       auto& type = *type_it;
-      auto type_index_iter = type_new_package_index.find(type.type);
+      auto type_index_iter = type_new_package_index.find(type.named_type);
       if (type_index_iter == type_new_package_index.end()) {
         // First occurrence of the resource type in this package. Keep it in this package.
-        type_new_package_index.insert(type_index_iter, std::make_pair(type.type, start_index));
+        type_new_package_index.insert(type_index_iter,
+                                      std::make_pair(type.named_type, start_index));
         ++type_it;
         continue;
       }
@@ -440,7 +449,7 @@
 
       // Move the type into a new package
       auto& other_package = new_packages[index];
-      type_new_package_index[type.type] = index + 1;
+      type_new_package_index[type.named_type] = index + 1;
       type_inserter.Insert(other_package.types, std::move(type));
       type_it = package.types.erase(type_it);
     }
@@ -473,7 +482,7 @@
   }
 
   auto package = FindOrCreatePackage(res.name.package);
-  auto type = package->FindOrCreateType(res.name.type.type);
+  auto type = package->FindOrCreateType(res.name.type);
   auto entry_it = std::equal_range(type->entries.begin(), type->entries.end(), res.name.entry,
                                    NameEqualRange<ResourceEntry>{});
   const size_t entry_count = std::distance(entry_it.first, entry_it.second);
@@ -593,7 +602,7 @@
     return {};
   }
 
-  ResourceTableType* type = package->FindType(name.type.type);
+  ResourceTableType* type = package->FindType(name.type);
   if (type == nullptr) {
     return {};
   }
@@ -612,7 +621,7 @@
     return {};
   }
 
-  ResourceTableType* type = package->FindType(name.type.type);
+  ResourceTableType* type = package->FindType(name.type);
   if (type == nullptr) {
     return {};
   }
@@ -633,7 +642,7 @@
     return {};
   }
 
-  ResourceTableType* type = package->FindType(name.type.type);
+  ResourceTableType* type = package->FindType(name.type);
   if (type == nullptr) {
     return {};
   }
@@ -655,7 +664,7 @@
   for (const auto& pkg : packages) {
     ResourceTablePackage* new_pkg = new_table->FindOrCreatePackage(pkg->name);
     for (const auto& type : pkg->types) {
-      ResourceTableType* new_type = new_pkg->FindOrCreateType(type->type);
+      ResourceTableType* new_type = new_pkg->FindOrCreateType(type->named_type);
       new_type->visibility_level = type->visibility_level;
 
       for (const auto& entry : type->entries) {
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 2e17659..7aa8b0f 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -168,7 +168,7 @@
 class ResourceTableType {
  public:
   // The logical type of resource (string, drawable, layout, etc.).
-  const ResourceType type;
+  const ResourceNamedType named_type;
 
   // Whether this type is public (and must maintain the same type ID across builds).
   Visibility::Level visibility_level = Visibility::Level::kUndefined;
@@ -176,7 +176,9 @@
   // List of resources for this type.
   std::vector<std::unique_ptr<ResourceEntry>> entries;
 
-  explicit ResourceTableType(const ResourceType type) : type(type) {}
+  explicit ResourceTableType(const ResourceNamedTypeRef& type)
+      : named_type(type.ToResourceNamedType()) {
+  }
 
   ResourceEntry* CreateEntry(const android::StringPiece& name);
   ResourceEntry* FindEntry(const android::StringPiece& name) const;
@@ -196,8 +198,9 @@
   }
 
   ResourceTablePackage() = default;
-  ResourceTableType* FindType(ResourceType type) const;
-  ResourceTableType* FindOrCreateType(ResourceType type);
+  ResourceTableType* FindTypeWithDefaultName(const ResourceType type) const;
+  ResourceTableType* FindType(const ResourceNamedTypeRef& type) const;
+  ResourceTableType* FindOrCreateType(const ResourceNamedTypeRef& type);
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
@@ -217,7 +220,7 @@
 };
 
 struct ResourceTableTypeView {
-  ResourceType type;
+  ResourceNamedType named_type;
   std::optional<uint8_t> id;
   Visibility::Level visibility_level = Visibility::Level::kUndefined;
 
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 23f6c88..b4e79ca 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -40,6 +40,23 @@
 namespace aapt {
 namespace ResourceUtils {
 
+static std::optional<ResourceNamedType> ToResourceNamedType(const char16_t* type16,
+                                                            const char* type, size_t type_len) {
+  std::optional<ResourceNamedTypeRef> parsed_type;
+  if (type16) {
+    auto converted = util::Utf16ToUtf8(StringPiece16(type16, type_len));
+    parsed_type = ParseResourceNamedType(converted);
+  } else if (type) {
+    parsed_type = ParseResourceNamedType(StringPiece(type, type_len));
+  } else {
+    return {};
+  }
+  if (!parsed_type) {
+    return {};
+  }
+  return parsed_type->ToResourceNamedType();
+}
+
 std::optional<ResourceName> ToResourceName(const android::ResTable::resource_name& name_in) {
   // TODO: Remove this when ResTable and AssetManager(1) are removed from AAPT2
   ResourceName name_out;
@@ -50,20 +67,12 @@
   name_out.package =
       util::Utf16ToUtf8(StringPiece16(name_in.package, name_in.packageLen));
 
-  std::optional<ResourceNamedTypeRef> type;
-  if (name_in.type) {
-    type = ParseResourceNamedType(util::Utf16ToUtf8(StringPiece16(name_in.type, name_in.typeLen)));
-  } else if (name_in.type8) {
-    type = ParseResourceNamedType(StringPiece(name_in.type8, name_in.typeLen));
-  } else {
-    return {};
-  }
-
+  std::optional<ResourceNamedType> type =
+      ToResourceNamedType(name_in.type, name_in.name8, name_in.typeLen);
   if (!type) {
     return {};
   }
-
-  name_out.type = type->ToResourceNamedType();
+  name_out.type = *type;
 
   if (name_in.name) {
     name_out.entry =
@@ -84,21 +93,12 @@
 
   name_out.package = std::string(name_in.package, name_in.package_len);
 
-  std::optional<ResourceNamedTypeRef> type;
-  if (name_in.type16) {
-    type =
-        ParseResourceNamedType(util::Utf16ToUtf8(StringPiece16(name_in.type16, name_in.type_len)));
-  } else if (name_in.type) {
-    type = ParseResourceNamedType(StringPiece(name_in.type, name_in.type_len));
-  } else {
-    return {};
-  }
-
+  std::optional<ResourceNamedType> type =
+      ToResourceNamedType(name_in.type16, name_in.type, name_in.type_len);
   if (!type) {
     return {};
   }
-
-  name_out.type = type->ToResourceNamedType();
+  name_out.type = *type;
 
   if (name_in.entry16) {
     name_out.entry =
diff --git a/tools/aapt2/Resource_test.cpp b/tools/aapt2/Resource_test.cpp
index 2c55d1d..01d3c84 100644
--- a/tools/aapt2/Resource_test.cpp
+++ b/tools/aapt2/Resource_test.cpp
@@ -135,13 +135,13 @@
   type = ParseResourceNamedType("layout");
   EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout", ResourceType::kLayout))));
 
-  type = ParseResourceNamedType("layout:2");
-  EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout:2", ResourceType::kLayout))));
+  type = ParseResourceNamedType("layout.2");
+  EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout.2", ResourceType::kLayout))));
 
-  type = ParseResourceNamedType("layout:another");
-  EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout:another", ResourceType::kLayout))));
+  type = ParseResourceNamedType("layout.another");
+  EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout.another", ResourceType::kLayout))));
 
-  type = ParseResourceNamedType("layout:");
+  type = ParseResourceNamedType("layout.");
   EXPECT_THAT(type, Eq(std::nullopt));
 
   type = ParseResourceNamedType("layout2");
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index fe56018..e27b9aa 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -243,9 +243,9 @@
                 r_txt_printer.Print("private ");
             }
 
-            if (type->type != ResourceType::kStyleable) {
+            if (type->named_type.type != ResourceType::kStyleable) {
               r_txt_printer.Print("int ");
-              r_txt_printer.Print(to_string(type->type));
+              r_txt_printer.Print(type->named_type.to_string());
               r_txt_printer.Print(" ");
               r_txt_printer.Println(entry->name);
             } else {
diff --git a/tools/aapt2/cmd/Diff.cpp b/tools/aapt2/cmd/Diff.cpp
index d9e8c92..a854146 100644
--- a/tools/aapt2/cmd/Diff.cpp
+++ b/tools/aapt2/cmd/Diff.cpp
@@ -105,7 +105,7 @@
   Value* value_b = config_value_b->value.get();
   if (!value_a->Equals(value_b)) {
     std::stringstream str_stream;
-    str_stream << "value " << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
+    str_stream << "value " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                << " config=" << config_value_a->config << " does not match:\n";
     value_a->Print(&str_stream);
     str_stream << "\n vs \n";
@@ -128,7 +128,7 @@
     auto config_value_b = entry_b.FindValue(config_value_a->config);
     if (!config_value_b) {
       std::stringstream str_stream;
-      str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
+      str_stream << "missing " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                  << " config=" << config_value_a->config;
       EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
@@ -143,7 +143,7 @@
     auto config_value_a = entry_a.FindValue(config_value_b->config);
     if (!config_value_a) {
       std::stringstream str_stream;
-      str_stream << "new config " << pkg_b.name << ":" << type_b.type << "/" << entry_b.name
+      str_stream << "new config " << pkg_b.name << ":" << type_b.named_type << "/" << entry_b.name
                  << " config=" << config_value_b->config;
       EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
@@ -164,13 +164,15 @@
     if (entry_b_iter == type_b.entries.end()) {
       // Type A contains a type that type B does not have.
       std::stringstream str_stream;
-      str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a_iter->name;
+      str_stream << "missing " << pkg_a.name << ":" << type_a.named_type << "/"
+                 << entry_a_iter->name;
       EmitDiffLine(apk_a->GetSource(), str_stream.str());
       diff = true;
     } else if (entry_a_iter == type_a.entries.end()) {
       // Type B contains a type that type A does not have.
       std::stringstream str_stream;
-      str_stream << "new entry " << pkg_b.name << ":" << type_b.type << "/" << entry_b_iter->name;
+      str_stream << "new entry " << pkg_b.name << ":" << type_b.named_type << "/"
+                 << entry_b_iter->name;
       EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     } else {
@@ -178,7 +180,7 @@
       const auto& entry_b = *entry_b_iter;
       if (IsSymbolVisibilityDifferent(entry_a.visibility, entry_b.visibility)) {
         std::stringstream str_stream;
-        str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
+        str_stream << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                    << " has different visibility (";
         if (entry_b.visibility.staged_api) {
           str_stream << "STAGED ";
@@ -203,7 +205,7 @@
       } else if (IsIdDiff(entry_a.visibility.level, entry_a.id, entry_b.visibility.level,
                           entry_b.id)) {
         std::stringstream str_stream;
-        str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
+        str_stream << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                    << " has different public ID (";
         if (entry_b.id) {
           str_stream << "0x" << std::hex << entry_b.id.value();
@@ -243,13 +245,13 @@
     if (type_b_iter == pkg_b.types.end()) {
       // Type A contains a type that type B does not have.
       std::stringstream str_stream;
-      str_stream << "missing " << pkg_a.name << ":" << type_a_iter->type;
+      str_stream << "missing " << pkg_a.name << ":" << type_a_iter->named_type;
       EmitDiffLine(apk_a->GetSource(), str_stream.str());
       diff = true;
     } else if (type_a_iter == pkg_a.types.end()) {
       // Type B contains a type that type A does not have.
       std::stringstream str_stream;
-      str_stream << "new type " << pkg_b.name << ":" << type_b_iter->type;
+      str_stream << "new type " << pkg_b.name << ":" << type_b_iter->named_type;
       EmitDiffLine(apk_b->GetSource(), str_stream.str());
       diff = true;
     } else {
@@ -257,7 +259,7 @@
       const auto& type_b = *type_b_iter;
       if (type_a.visibility_level != type_b.visibility_level) {
         std::stringstream str_stream;
-        str_stream << pkg_a.name << ":" << type_a.type << " has different visibility (";
+        str_stream << pkg_a.name << ":" << type_a.named_type << " has different visibility (";
         if (type_b.visibility_level == Visibility::Level::kPublic) {
           str_stream << "PUBLIC";
         } else {
@@ -274,7 +276,7 @@
         diff = true;
       } else if (IsIdDiff(type_a.visibility_level, type_a.id, type_b.visibility_level, type_b.id)) {
         std::stringstream str_stream;
-        str_stream << pkg_a.name << ":" << type_a.type << " has different public ID (";
+        str_stream << pkg_a.name << ":" << type_a.named_type << " has different public ID (";
         if (type_b.id) {
           str_stream << "0x" << std::hex << type_b.id.value();
         } else {
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 790f2b3..bd74cc7 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -556,7 +556,7 @@
           file_op.config = config_value->config;
           file_op.file_to_copy = file;
 
-          if (type->type != ResourceType::kRaw &&
+          if (type->named_type.type != ResourceType::kRaw &&
               (file_ref->type == ResourceFile::Type::kBinaryXml ||
                file_ref->type == ResourceFile::Type::kProtoXml)) {
             std::unique_ptr<io::IData> data = file->OpenAsData();
@@ -596,7 +596,8 @@
 
             file_op.xml_to_flatten->file.config = config_value->config;
             file_op.xml_to_flatten->file.source = file_ref->GetSource();
-            file_op.xml_to_flatten->file.name = ResourceName(pkg->name, type->type, entry->name);
+            file_op.xml_to_flatten->file.name =
+                ResourceName(pkg->name, type->named_type, entry->name);
           }
 
           // NOTE(adamlesinski): Explicitly construct a StringPiece here, or
@@ -1009,7 +1010,7 @@
         // We have a package that is not related to the one we're building!
         for (const auto& type : package->types) {
           for (const auto& entry : type->entries) {
-            ResourceNameRef res_name(package->name, type->type, entry->name);
+            ResourceNameRef res_name(package->name, type->named_type, entry->name);
 
             for (const auto& config_value : entry->values) {
               // Special case the occurrence of an ID that is being generated
@@ -1046,7 +1047,7 @@
       for (const auto& type : package->types) {
         for (const auto& entry : type->entries) {
           if (entry->id) {
-            ResourceNameRef res_name(package->name, type->type, entry->name);
+            ResourceNameRef res_name(package->name, type->named_type, entry->name);
             context_->GetDiagnostics()->Error(DiagMessage() << "resource " << res_name << " has ID "
                                                             << entry->id.value() << " assigned");
             return false;
@@ -1057,6 +1058,83 @@
     return true;
   }
 
+  bool VerifyLocaleFormat(xml::XmlResource* manifest, IDiagnostics* diag) {
+    // Skip it if the Manifest doesn't declare the localeConfig attribute within the <application>
+    // element.
+    const xml::Element* application = manifest->root->FindChild("", "application");
+    if (!application) {
+      return true;
+    }
+    const xml::Attribute* localeConfig =
+        application->FindAttribute(xml::kSchemaAndroid, "localeConfig");
+    if (!localeConfig) {
+      return true;
+    }
+
+    if (localeConfig->compiled_value) {
+      const auto localeconfig_reference = ValueCast<Reference>(localeConfig->compiled_value.get());
+      const auto localeconfig_entry =
+          ResolveTableEntry(context_, &final_table_, localeconfig_reference);
+      if (!localeconfig_entry) {
+        return true;
+      }
+
+      for (const auto& value : localeconfig_entry->values) {
+        // Load an XML file which is linked from the localeConfig attribute.
+        const std::string& path = value->value->GetSource().path;
+        std::unique_ptr<xml::XmlResource> localeConfig_xml = LoadXml(path, diag);
+        if (!localeConfig_xml) {
+          diag->Error(DiagMessage(path) << "can't load the XML");
+          return false;
+        }
+
+        xml::Element* localeConfig_el = xml::FindRootElement(localeConfig_xml->root.get());
+        if (!localeConfig_el) {
+          diag->Error(DiagMessage(path) << "no root tag defined");
+          return false;
+        }
+        if (localeConfig_el->name != "locale-config") {
+          diag->Error(DiagMessage(path) << "invalid element name: " << localeConfig_el->name
+                                        << ", expected: locale-config");
+          return false;
+        }
+
+        for (const xml::Element* child_el : localeConfig_el->GetChildElements()) {
+          if (child_el->name == "locale") {
+            if (const xml::Attribute* locale_name_attr =
+                    child_el->FindAttribute(xml::kSchemaAndroid, "name")) {
+              const std::string& locale_name = locale_name_attr->value;
+              const std::string valid_name = ConvertToBCP47Tag(locale_name);
+
+              // Start to verify the locale format
+              ConfigDescription config;
+              if (!ConfigDescription::Parse(valid_name, &config)) {
+                diag->Error(DiagMessage(path) << "invalid configuration: " << locale_name);
+                return false;
+              }
+            } else {
+              diag->Error(DiagMessage(path) << "the attribute android:name is not found");
+              return false;
+            }
+          } else {
+            diag->Error(DiagMessage(path)
+                        << "invalid element name: " << child_el->name << ", expected: locale");
+            return false;
+          }
+        }
+      }
+    }
+    return true;
+  }
+
+  std::string ConvertToBCP47Tag(const std::string& locale) {
+    std::string bcp47tag = "b+";
+    bcp47tag += locale;
+    std::replace(bcp47tag.begin(), bcp47tag.end(), '-', '+');
+
+    return bcp47tag;
+  }
+
   std::unique_ptr<IArchiveWriter> MakeArchiveWriter(const StringPiece& out) {
     if (options_.output_to_directory) {
       return CreateDirectoryArchiveWriter(context_->GetDiagnostics(), out);
@@ -1939,7 +2017,7 @@
         for (auto& package : final_table_.packages) {
           for (auto& type : package->types) {
             for (auto& entry : type->entries) {
-              ResourceName name(package->name, type->type, entry->name);
+              ResourceName name(package->name, type->named_type, entry->name);
               // The IDs are guaranteed to exist.
               options_.stable_id_map[std::move(name)] = entry->id.value();
             }
@@ -2180,6 +2258,10 @@
       return 1;
     }
 
+    if (!VerifyLocaleFormat(manifest_xml.get(), context_->GetDiagnostics())) {
+      return 1;
+    };
+
     if (!WriteApk(archive_writer.get(), &proguard_keep_set, manifest_xml.get(), &final_table_)) {
       return 1;
     }
diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp
index 430c184..7b1236a 100644
--- a/tools/aapt2/cmd/Link_test.cpp
+++ b/tools/aapt2/cmd/Link_test.cpp
@@ -22,6 +22,7 @@
 #include "LoadedApk.h"
 #include "test/Test.h"
 
+using android::ConfigDescription;
 using testing::Eq;
 using testing::HasSubstr;
 using testing::IsNull;
@@ -783,4 +784,51 @@
   EXPECT_THAT(xml_attrs[1].value, Eq("Hello World!"));
 }
 
+TEST_F(LinkTest, ParseLocaleConfig) {
+  StdErrDiagnostics diag;
+  const std::string xml_values =
+      R"(<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
+            <locale android:name="pt"/>
+            <locale android:name="chr"/>
+            <locale android:name="chr-US"/>
+            <locale android:name="zh-Hant"/>
+            <locale android:name="es-419"/>
+            <locale android:name="en-US"/>
+            <locale android:name="zh-Hans-SG"/>
+        </locale-config>)";
+
+  const std::string res = GetTestPath("test-res");
+  ASSERT_TRUE(CompileFile(GetTestPath("res/xml/locale_config.xml"), xml_values, res, &diag));
+
+  const std::string out_apk = GetTestPath("out.apk");
+  auto link_args = LinkCommandBuilder(this)
+                       .SetManifestFile(ManifestBuilder(this).SetPackageName("com.test").Build())
+                       .AddCompiledResDir(res, &diag)
+                       .AddFlag("--no-auto-version")
+                       .Build(out_apk);
+  ASSERT_TRUE(Link(link_args, &diag));
+
+  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+  ASSERT_THAT(apk, Ne(nullptr));
+
+  auto xml = apk->LoadXml("res/xml/locale_config.xml", &diag);
+  ASSERT_THAT(xml, NotNull());
+  EXPECT_THAT(xml->root->name, Eq("locale-config"));
+  ASSERT_THAT(xml->root->children.size(), Eq(7));
+  for (auto& node : xml->root->children) {
+    const xml::Element* child_el = xml::NodeCast<xml::Element>(node.get());
+    ASSERT_THAT(child_el, NotNull());
+    EXPECT_THAT(child_el->name, Eq("locale"));
+
+    auto& xml_attrs = child_el->attributes;
+    for (auto& attr : xml_attrs) {
+      std::string locale = "b+";
+      locale += attr.value;
+      std::replace(locale.begin(), locale.end(), '-', '+');
+      ConfigDescription config;
+      ASSERT_TRUE(ConfigDescription::Parse(locale, &config));
+    }
+  }
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index caa3e60..e1370fd 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -254,7 +254,7 @@
             }
 
             if (file_ref->file == nullptr) {
-              ResourceNameRef name(pkg->name, type->type, entry->name);
+              ResourceNameRef name(pkg->name, type->named_type, entry->name);
               context_->GetDiagnostics()->Warn(DiagMessage(file_ref->GetSource())
                                                << "file for resource " << name << " with config '"
                                                << config_value->config << "' not found");
diff --git a/tools/aapt2/compile/IdAssigner.cpp b/tools/aapt2/compile/IdAssigner.cpp
index fa816be..29f9a08 100644
--- a/tools/aapt2/compile/IdAssigner.cpp
+++ b/tools/aapt2/compile/IdAssigner.cpp
@@ -128,7 +128,7 @@
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
-        const ResourceName name(package->name, type->type, entry->name);
+        const ResourceName name(package->name, type->named_type, entry->name);
         if (entry->id && !assigned_ids.ReserveId(name, entry->id.value(), entry->visibility,
                                                  context->GetDiagnostics())) {
           return false;
@@ -175,7 +175,7 @@
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
-        const ResourceName name(package->name, type->type, entry->name);
+        const ResourceName name(package->name, type->named_type, entry->name);
         if (entry->id) {
           continue;
         }
diff --git a/tools/aapt2/compile/IdAssigner_test.cpp b/tools/aapt2/compile/IdAssigner_test.cpp
index d357571..8911dad 100644
--- a/tools/aapt2/compile/IdAssigner_test.cpp
+++ b/tools/aapt2/compile/IdAssigner_test.cpp
@@ -191,12 +191,12 @@
       for (auto& entry : type->entries) {
         if (!entry->id) {
           return ::testing::AssertionFailure()
-                 << "resource " << ResourceNameRef(package->name, type->type, entry->name)
+                 << "resource " << ResourceNameRef(package->name, type->named_type, entry->name)
                  << " has no ID";
         }
         if (!seen_ids.insert(entry->id.value()).second) {
           return ::testing::AssertionFailure()
-                 << "resource " << ResourceNameRef(package->name, type->type, entry->name)
+                 << "resource " << ResourceNameRef(package->name, type->named_type, entry->name)
                  << " has a non-unique ID" << std::hex << entry->id.value() << std::dec;
         }
       }
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index c65c550..eea7efc 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -18,19 +18,19 @@
 
 #include <algorithm>
 #include <map>
+#include <optional>
 #include <string>
 
-#include "android-base/logging.h"
-#include "android-base/macros.h"
-#include "android-base/stringprintf.h"
-#include "androidfw/ResourceTypes.h"
-#include "androidfw/TypeWrappers.h"
-
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "Source.h"
 #include "ValueVisitor.h"
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+#include "android-base/stringprintf.h"
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/TypeWrappers.h"
 #include "format/binary/ResChunkPullParser.h"
 #include "util/Util.h"
 
@@ -364,7 +364,7 @@
   config.copyFromDtoH(type->config);
 
   const std::string type_str = util::GetString(type_pool_, type->id - 1);
-  const ResourceType* parsed_type = ParseResourceType(type_str);
+  std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(type_str);
   if (!parsed_type) {
     diag_->Warn(DiagMessage(source_)
                 << "invalid type name '" << type_str << "' for type with ID " << type->id);
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index a9192e8..b42e7d0 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -360,7 +360,7 @@
       if (!FlattenValue(&flat_entry, &values_buffer)) {
         diag_->Error(DiagMessage()
                      << "failed to flatten resource '"
-                     << ResourceNameRef(package_.name, type.type, flat_entry.entry->name)
+                     << ResourceNameRef(package_.name, type.named_type, flat_entry.entry->name)
                      << "' for configuration '" << config << "'");
         return false;
       }
@@ -447,7 +447,7 @@
         ResourceId id = android::make_resid(package_.id.value(), type.id.value(), entry.id.value());
         CHECK(seen_ids.find(id) == seen_ids.end())
             << "multiple overlayable definitions found for resource "
-            << ResourceName(package_.name, type.type, entry.name).to_string();
+            << ResourceName(package_.name, type.named_type, entry.name).to_string();
         seen_ids.insert(id);
 
         // Find the overlayable chunk with the specified name
@@ -592,7 +592,8 @@
   bool FlattenTypes(BigBuffer* buffer) {
     size_t expected_type_id = 1;
     for (const ResourceTableTypeView& type : package_.types) {
-      if (type.type == ResourceType::kStyleable || type.type == ResourceType::kMacro) {
+      if (type.named_type.type == ResourceType::kStyleable ||
+          type.named_type.type == ResourceType::kMacro) {
         // Styleables and macros are not real resource types.
         continue;
       }
@@ -606,7 +607,7 @@
         expected_type_id++;
       }
       expected_type_id++;
-      type_pool_.MakeRef(to_string(type.type));
+      type_pool_.MakeRef(type.named_type.to_string());
 
       if (!FlattenTypeSpec(type, type.entries, buffer)) {
         return false;
@@ -634,7 +635,7 @@
         }
 
         uint32_t local_key_index;
-        ResourceName resource_name({}, type.type, entry.name);
+        ResourceName resource_name({}, type.named_type, entry.name);
         if (!collapse_key_stringpool_ ||
             name_collapse_exemptions_.find(resource_name) != name_collapse_exemptions_.end()) {
           local_key_index = (uint32_t)key_pool_.MakeRef(entry.name).index();
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index cd1c0af..c73bbb5 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -837,4 +837,45 @@
   ASSERT_FALSE(Flatten(context_.get(), {}, table.get(), &output_table));
 }
 
+TEST_F(TableFlattenerTest, FlattenCustomResourceTypes) {
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .AddSimple("com.app.test:id/one", ResourceId(0x7f010000))
+          .AddSimple("com.app.test:id.2/two", ResourceId(0x7f020000))
+          .AddValue("com.app.test:integer/one", ResourceId(0x7f030000),
+                    util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 10u))
+          .AddValue("com.app.test:integer.1/one", ResourceId(0x7f040000),
+                    util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 1u))
+          .AddValue("com.app.test:integer.1/one", test::ParseConfigOrDie("v1"),
+                    ResourceId(0x7f040000),
+                    util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 2u))
+          .AddString("com.app.test:layout.custom/bar", ResourceId(0x7f050000), "res/layout/bar.xml")
+          .Build();
+
+  ResTable res_table;
+  ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &res_table));
+
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:id/one", ResourceId(0x7f010000), {},
+                     Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
+
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:id.2/two", ResourceId(0x7f020000), {},
+                     Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
+
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:integer/one", ResourceId(0x7f030000), {},
+                     Res_value::TYPE_INT_DEC, 10u, 0u));
+
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:integer.1/one", ResourceId(0x7f040000), {},
+                     Res_value::TYPE_INT_DEC, 1u, ResTable_config::CONFIG_VERSION));
+
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:integer.1/one", ResourceId(0x7f040000),
+                     test::ParseConfigOrDie("v1"), Res_value::TYPE_INT_DEC, 2u,
+                     ResTable_config::CONFIG_VERSION));
+
+  std::u16string bar_path = u"res/layout/bar.xml";
+  auto idx = res_table.getTableStringBlock(0)->indexOfString(bar_path.data(), bar_path.size());
+  ASSERT_TRUE(idx.has_value());
+  EXPECT_TRUE(Exists(&res_table, "com.app.test:layout.custom/bar", ResourceId(0x7f050000), {},
+                     Res_value::TYPE_STRING, (uint32_t)*idx, 0u));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 236c381..82c7248 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -429,8 +429,8 @@
 
   ResourceTablePackage* pkg = out_table->FindOrCreatePackage(pb_package.package_name());
   for (const pb::Type& pb_type : pb_package.type()) {
-    const ResourceType* res_type = ParseResourceType(pb_type.name());
-    if (res_type == nullptr) {
+    auto res_type = ParseResourceNamedType(pb_type.name());
+    if (!res_type) {
       std::ostringstream error;
       error << "unknown type '" << pb_type.name() << "'";
       *out_error = error.str();
@@ -515,7 +515,7 @@
       ResourceId resid(pb_package.package_id().id(), pb_type.type_id().id(),
                        pb_entry.entry_id().id());
       if (resid.is_valid()) {
-        id_index[resid] = ResourceNameRef(pkg->name, type->type, entry->name);
+        id_index[resid] = ResourceNameRef(pkg->name, type->named_type, entry->name);
       }
 
       for (const pb::ConfigValue& pb_config_value : pb_entry.config_value()) {
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index f3b7f75..bb8ea0c 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -358,7 +358,7 @@
       if (type.id) {
         pb_type->mutable_type_id()->set_id(type.id.value());
       }
-      pb_type->set_name(to_string(type.type).to_string());
+      pb_type->set_name(type.named_type.to_string());
 
       // hardcoded string uses characters which make it an invalid resource name
       static const char* obfuscated_resource_name = "0_resource_name_obfuscated";
@@ -367,7 +367,7 @@
         if (entry.id) {
           pb_entry->mutable_entry_id()->set_id(entry.id.value());
         }
-        ResourceName resource_name({}, type.type, entry.name);
+        ResourceName resource_name({}, type.named_type, entry.name);
         if (options.collapse_key_stringpool &&
             options.name_collapse_exemptions.find(resource_name) ==
             options.name_collapse_exemptions.end()) {
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index d1d72e0..0247021 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -951,4 +951,76 @@
   EXPECT_THAT(result.value().entry->staged_id.value().id, Eq(ResourceId(0x01ff0001)));
 }
 
+TEST(ProtoSerializeTest, CustomResourceTypes) {
+  const uint32_t id_one_id = 0x7f020000;
+  const uint32_t id_2_two_id = 0x7f030000;
+  const uint32_t integer_three_id = 0x7f030000;
+  const uint32_t integer_1_four_id = 0x7f030000;
+  const uint32_t layout_bar_id = 0x7f050000;
+  std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+  std::unique_ptr<ResourceTable> table =
+      test::ResourceTableBuilder()
+          .AddSimple("com.app.test:id/one", ResourceId(id_one_id))
+          .AddSimple("com.app.test:id.2/two", ResourceId(id_2_two_id))
+          .AddValue(
+              "com.app.test:integer/one", ResourceId(integer_three_id),
+              util::make_unique<BinaryPrimitive>(uint8_t(android::Res_value::TYPE_INT_DEC), 10u))
+          .AddValue(
+              "com.app.test:integer.1/one", ResourceId(integer_1_four_id),
+              util::make_unique<BinaryPrimitive>(uint8_t(android::Res_value::TYPE_INT_DEC), 1u))
+          .AddValue(
+              "com.app.test:integer.1/one", test::ParseConfigOrDie("v1"),
+              ResourceId(integer_1_four_id),
+              util::make_unique<BinaryPrimitive>(uint8_t(android::Res_value::TYPE_INT_DEC), 2u))
+          .AddFileReference("com.app.test:layout.custom/bar", ResourceId(layout_bar_id),
+                            "res/layout/bar.xml")
+          .Build();
+
+  test::TestFile file_a("res/layout/bar.xml");
+  MockFileCollection files;
+  EXPECT_CALL(files, FindFile(Eq("res/layout/bar.xml"))).WillRepeatedly(::testing::Return(&file_a));
+
+  ResourceTable new_table;
+  pb::ResourceTable pb_table;
+  std::string error;
+  SerializeTableToPb(*table, &pb_table, context->GetDiagnostics());
+  DeserializeTableFromPb(pb_table, &files, &new_table, &error);
+  ASSERT_THAT(error, IsEmpty());
+
+  auto bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(
+      &new_table, "com.app.test:integer.1/one", ConfigDescription::DefaultConfig(), "");
+  ASSERT_THAT(bp, NotNull());
+  EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC));
+  EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("1")->value.data));
+
+  bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "com.app.test:integer.1/one",
+                                                          test::ParseConfigOrDie("v1"), "");
+  ASSERT_THAT(bp, NotNull());
+  EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC));
+  EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("2")->value.data));
+
+  bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "com.app.test:integer/one",
+                                                          ConfigDescription::DefaultConfig(), "");
+  ASSERT_THAT(bp, NotNull());
+  EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC));
+  EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("10")->value.data));
+
+  bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "com.app.test:integer/one",
+                                                          test::ParseConfigOrDie("v1"), "");
+  ASSERT_THAT(bp, IsNull());
+
+  auto id = test::GetValueForConfigAndProduct<Id>(&new_table, "com.app.test:id/one",
+                                                  ConfigDescription::DefaultConfig(), "");
+  ASSERT_THAT(id, NotNull());
+
+  id = test::GetValueForConfigAndProduct<Id>(&new_table, "com.app.test:id.2/two",
+                                             ConfigDescription::DefaultConfig(), "");
+  ASSERT_THAT(id, NotNull());
+
+  auto custom_layout = test::GetValueForConfigAndProduct<FileReference>(
+      &new_table, "com.app.test:layout.custom/bar", ConfigDescription::DefaultConfig(), "");
+  ASSERT_THAT(custom_layout, NotNull());
+  EXPECT_THAT(*(custom_layout->path), Eq("res/layout/bar.xml"));
+}
+
 }  // namespace aapt
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index a963d98..a25ca22 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -548,10 +548,11 @@
     }
 
     // We need to make sure we hide the fact that we are generating kAttrPrivate attributes.
-    const ResourceNameRef resource_name(
-        package_name_to_generate,
-        type.type == ResourceType::kAttrPrivate ? ResourceType::kAttr : type.type,
-        unmangled_name.value());
+    const auto target_type = type.named_type.type == ResourceType::kAttrPrivate
+                                 ? ResourceNamedTypeWithDefaultName(ResourceType::kAttr)
+                                 : type.named_type;
+    const ResourceNameRef resource_name(package_name_to_generate, target_type,
+                                        unmangled_name.value());
 
     // Check to see if the unmangled name is a valid Java name (not a keyword).
     if (!IsValidSymbol(unmangled_name.value())) {
@@ -616,7 +617,8 @@
 
   for (const auto& package : table_->packages) {
     for (const auto& type : package->types) {
-      if (type->type == ResourceType::kAttrPrivate || type->type == ResourceType::kMacro) {
+      if (type->named_type.type == ResourceType::kAttrPrivate ||
+          type->named_type.type == ResourceType::kMacro) {
         // We generate kAttrPrivate as part of the kAttr type, so skip them here.
         // Macros are not actual resources, so skip them as well.
         continue;
@@ -628,7 +630,7 @@
       std::unique_ptr<ClassDefinition> class_def;
       if (out != nullptr) {
         class_def = util::make_unique<ClassDefinition>(
-            to_string(type->type), ClassQualifier::kStatic, force_creation_if_empty);
+            to_string(type->named_type.type), ClassQualifier::kStatic, force_creation_if_empty);
       }
 
       if (!ProcessType(package_name_to_generate, *package, *type, class_def.get(),
@@ -636,9 +638,10 @@
         return false;
       }
 
-      if (type->type == ResourceType::kAttr) {
+      if (type->named_type.type == ResourceType::kAttr) {
         // Also include private attributes in this same class.
-        if (const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate)) {
+        if (const ResourceTableType* priv_type =
+                package->FindTypeWithDefaultName(ResourceType::kAttrPrivate)) {
           if (!ProcessType(package_name_to_generate, *package, *priv_type, class_def.get(),
                            rewrite_method.get(), r_txt_printer.get())) {
             return false;
@@ -646,7 +649,7 @@
         }
       }
 
-      if (out != nullptr && type->type == ResourceType::kStyleable && is_public) {
+      if (out != nullptr && type->named_type.type == ResourceType::kStyleable && is_public) {
         // When generating a public R class, we don't want Styleable to be part
         // of the API. It is only emitted for documentation purposes.
         class_def->GetCommentBuilder()->AppendComment("@doconly");
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index e53e220..80a46d5 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -517,7 +517,7 @@
     for (auto& type : pkg->types) {
       for (auto& entry : type->entries) {
         for (auto& config_value : entry->values) {
-          ResourceName from(pkg->name, type->type, entry->name);
+          ResourceName from(pkg->name, type->named_type, entry->name);
           ReferenceVisitor visitor(context, from, keep_set);
           config_value->value->Accept(&visitor);
         }
diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp
index 328ac97..3dbd7e6 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -75,7 +75,7 @@
   CloningValueTransformer cloner(&table->string_pool);
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
-      if (type->type != ResourceType::kStyle) {
+      if (type->named_type.type != ResourceType::kStyle) {
         continue;
       }
 
diff --git a/tools/aapt2/link/NoDefaultResourceRemover.cpp b/tools/aapt2/link/NoDefaultResourceRemover.cpp
index 05990de..ab3c04e 100644
--- a/tools/aapt2/link/NoDefaultResourceRemover.cpp
+++ b/tools/aapt2/link/NoDefaultResourceRemover.cpp
@@ -76,7 +76,7 @@
       });
 
       for (auto iter = remove_iter; iter != end_iter; ++iter) {
-        const ResourceName name(pkg->name, type->type, (*iter)->name);
+        const ResourceName name(pkg->name, type->named_type, (*iter)->name);
         IDiagnostics* diag = context->GetDiagnostics();
         diag->Warn(DiagMessage() << "removing resource " << name
                                  << " without required default value");
diff --git a/tools/aapt2/link/PrivateAttributeMover.cpp b/tools/aapt2/link/PrivateAttributeMover.cpp
index 675b02a..8c6c743 100644
--- a/tools/aapt2/link/PrivateAttributeMover.cpp
+++ b/tools/aapt2/link/PrivateAttributeMover.cpp
@@ -57,7 +57,7 @@
 
 bool PrivateAttributeMover::Consume(IAaptContext* context, ResourceTable* table) {
   for (auto& package : table->packages) {
-    ResourceTableType* type = package->FindType(ResourceType::kAttr);
+    ResourceTableType* type = package->FindTypeWithDefaultName(ResourceType::kAttr);
     if (!type) {
       continue;
     }
@@ -80,7 +80,8 @@
       continue;
     }
 
-    ResourceTableType* priv_attr_type = package->FindOrCreateType(ResourceType::kAttrPrivate);
+    auto attr_private_type = ResourceNamedTypeWithDefaultName(ResourceType::kAttrPrivate);
+    ResourceTableType* priv_attr_type = package->FindOrCreateType(attr_private_type);
     CHECK(priv_attr_type->entries.empty());
     priv_attr_type->entries = std::move(private_attr_entries);
   }
diff --git a/tools/aapt2/link/PrivateAttributeMover_test.cpp b/tools/aapt2/link/PrivateAttributeMover_test.cpp
index 168234b..32335b7 100644
--- a/tools/aapt2/link/PrivateAttributeMover_test.cpp
+++ b/tools/aapt2/link/PrivateAttributeMover_test.cpp
@@ -41,13 +41,13 @@
   ResourceTablePackage* package = table->FindPackage("android");
   ASSERT_NE(package, nullptr);
 
-  ResourceTableType* type = package->FindType(ResourceType::kAttr);
+  ResourceTableType* type = package->FindTypeWithDefaultName(ResourceType::kAttr);
   ASSERT_NE(type, nullptr);
   ASSERT_EQ(type->entries.size(), 2u);
   EXPECT_NE(type->FindEntry("publicA"), nullptr);
   EXPECT_NE(type->FindEntry("publicB"), nullptr);
 
-  type = package->FindType(ResourceType::kAttrPrivate);
+  type = package->FindTypeWithDefaultName(ResourceType::kAttrPrivate);
   ASSERT_NE(type, nullptr);
   ASSERT_EQ(type->entries.size(), 2u);
   EXPECT_NE(type->FindEntry("privateA"), nullptr);
@@ -68,11 +68,11 @@
   ResourceTablePackage* package = table->FindPackage("android");
   ASSERT_NE(package, nullptr);
 
-  ResourceTableType* type = package->FindType(ResourceType::kAttr);
+  ResourceTableType* type = package->FindTypeWithDefaultName(ResourceType::kAttr);
   ASSERT_NE(type, nullptr);
   ASSERT_EQ(type->entries.size(), 2u);
 
-  type = package->FindType(ResourceType::kAttrPrivate);
+  type = package->FindTypeWithDefaultName(ResourceType::kAttrPrivate);
   ASSERT_EQ(type, nullptr);
 }
 
@@ -87,12 +87,12 @@
   ResourceTablePackage* package = table->FindPackage("android");
   ASSERT_NE(nullptr, package);
 
-  ASSERT_EQ(nullptr, package->FindType(ResourceType::kAttrPrivate));
+  ASSERT_EQ(nullptr, package->FindTypeWithDefaultName(ResourceType::kAttrPrivate));
 
   PrivateAttributeMover mover;
   ASSERT_TRUE(mover.Consume(context.get(), table.get()));
 
-  ASSERT_EQ(nullptr, package->FindType(ResourceType::kAttrPrivate));
+  ASSERT_EQ(nullptr, package->FindTypeWithDefaultName(ResourceType::kAttrPrivate));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/ProductFilter.cpp b/tools/aapt2/link/ProductFilter.cpp
index 793740a..0c54a73 100644
--- a/tools/aapt2/link/ProductFilter.cpp
+++ b/tools/aapt2/link/ProductFilter.cpp
@@ -98,7 +98,7 @@
             // End of the array, or we saw a different config,
             // so this must be the end of a range of products.
             // Select the product to keep from the set of products defined.
-            ResourceNameRef name(pkg->name, type->type, entry->name);
+            ResourceNameRef name(pkg->name, type->named_type, entry->name);
             auto value_to_keep = SelectProductToKeep(
                 name, start_range_iter, iter, context->GetDiagnostics());
             if (value_to_keep == iter) {
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 5372cf2..d1fbffa 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -468,7 +468,7 @@
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
         // First, unmangle the name if necessary.
-        ResourceName name(package->name, type->type, entry->name);
+        ResourceName name(package->name, type->named_type, entry->name);
         NameMangler::Unmangle(&name.entry, &name.package);
 
         // Symbol state information may be lost if there is no value for the resource.
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index d78f0ac..caaaba6 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -235,7 +235,7 @@
   bool error = false;
 
   for (auto& src_type : src_package->types) {
-    ResourceTableType* dst_type = main_package_->FindOrCreateType(src_type->type);
+    ResourceTableType* dst_type = main_package_->FindOrCreateType(src_type->named_type);
     if (!MergeType(context_, src, dst_type, src_type.get())) {
       error = true;
       continue;
@@ -254,7 +254,7 @@
         dst_entry = dst_type->FindEntry(entry_name);
       }
 
-      const ResourceNameRef res_name(src_package->name, src_type->type, src_entry->name);
+      const ResourceNameRef res_name(src_package->name, src_type->named_type, src_entry->name);
 
       if (!dst_entry) {
         context_->GetDiagnostics()->Error(DiagMessage(src)
@@ -349,7 +349,7 @@
   file_ref->file = file;
 
   ResourceTablePackage* pkg = table.FindOrCreatePackage(file_desc.name.package);
-  pkg->FindOrCreateType(file_desc.name.type.type)
+  pkg->FindOrCreateType(file_desc.name.type)
       ->FindOrCreateEntry(file_desc.name.entry)
       ->FindOrCreateValue(file_desc.config, {})
       ->value = std::move(file_ref);
diff --git a/tools/aapt2/optimize/ResourceFilter.cpp b/tools/aapt2/optimize/ResourceFilter.cpp
index 08c045b..db84b66 100644
--- a/tools/aapt2/optimize/ResourceFilter.cpp
+++ b/tools/aapt2/optimize/ResourceFilter.cpp
@@ -28,7 +28,7 @@
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       for (auto it = type->entries.begin(); it != type->entries.end(); ) {
-        ResourceName resource = ResourceName({}, type->type, (*it)->name);
+        ResourceName resource = ResourceName({}, type->named_type, (*it)->name);
         if (exclude_list_.find(resource) != exclude_list_.end()) {
           it = type->entries.erase(it);
         } else {
diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp
index 116b2ab9..85d150f 100644
--- a/tools/aapt2/split/TableSplitter.cpp
+++ b/tools/aapt2/split/TableSplitter.cpp
@@ -189,7 +189,7 @@
     }
 
     for (auto& type : pkg->types) {
-      if (type->type == ResourceType::kMipmap) {
+      if (type->named_type.type == ResourceType::kMipmap) {
         // Always keep mipmaps.
         continue;
       }
@@ -241,7 +241,7 @@
             // Create the same resource structure in the split. We do this lazily because we might
             // not have actual values for each type/entry.
             ResourceTablePackage* split_pkg = split_table->FindPackage(pkg->name);
-            ResourceTableType* split_type = split_pkg->FindOrCreateType(type->type);
+            ResourceTableType* split_type = split_pkg->FindOrCreateType(type->named_type);
             split_type->visibility_level = type->visibility_level;
 
             ResourceEntry* split_entry = split_type->FindOrCreateEntry(entry->name);
diff --git a/tools/lint/README.md b/tools/lint/README.md
index b534b62..c674d36 100644
--- a/tools/lint/README.md
+++ b/tools/lint/README.md
@@ -78,6 +78,7 @@
 ## Documentation
 
 - [Android Lint Docs](https://googlesamples.github.io/android-custom-lint-rules/)
+- [Lint Check Unit Testing](https://googlesamples.github.io/android-custom-lint-rules/api-guide/unit-testing.md.html)
 - [Android Lint source files](https://source.corp.google.com/studio-main/tools/base/lint/libs/lint-api/src/main/java/com/android/tools/lint/)
 - [PSI source files](https://github.com/JetBrains/intellij-community/tree/master/java/java-psi-api/src/com/intellij/psi)
 - [UAST source files](https://upsource.jetbrains.com/idea-ce/structure/idea-ce-7b9b8cc138bbd90aec26433f82cd2c6838694003/uast/uast-common/src/org/jetbrains/uast)
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
index a6fd9bb..859961a 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
@@ -19,6 +19,7 @@
 import com.android.tools.lint.client.api.IssueRegistry
 import com.android.tools.lint.client.api.Vendor
 import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.android.lint.parcel.SaferParcelChecker
 import com.google.auto.service.AutoService
 
 @AutoService(IssueRegistry::class)
@@ -33,7 +34,8 @@
             CallingIdentityTokenDetector.ISSUE_CLEAR_IDENTITY_CALL_NOT_FOLLOWED_BY_TRY_FINALLY,
             CallingSettingsNonUserGetterMethodsDetector.ISSUE_NON_USER_GETTER_CALLED,
             EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION,
-            EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION
+            EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION,
+            SaferParcelChecker.ISSUE_UNSAFE_API_USAGE,
     )
 
     override val api: Int
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/EnforcePermissionDetector.kt b/tools/lint/checks/src/main/java/com/google/android/lint/EnforcePermissionDetector.kt
index 8011b36..9f21618 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/EnforcePermissionDetector.kt
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/EnforcePermissionDetector.kt
@@ -16,6 +16,7 @@
 
 package com.google.android.lint
 
+import com.android.tools.lint.client.api.UElementHandler
 import com.android.tools.lint.detector.api.AnnotationInfo
 import com.android.tools.lint.detector.api.AnnotationOrigin
 import com.android.tools.lint.detector.api.AnnotationUsageInfo
@@ -32,22 +33,39 @@
 import com.intellij.psi.PsiAnnotation
 import com.intellij.psi.PsiClass
 import com.intellij.psi.PsiMethod
+import org.jetbrains.uast.UAnnotation
 import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UClass
+import org.jetbrains.uast.UMethod
 
 /**
  * Lint Detector that ensures that any method overriding a method annotated
  * with @EnforcePermission is also annotated with the exact same annotation.
  * The intent is to surface the effective permission checks to the service
  * implementations.
+ *
+ * This is done with 2 mechanisms:
+ *  1. Visit any annotation usage, to ensure that any derived class will have
+ *     the correct annotation on each methods. This is for the top to bottom
+ *     propagation.
+ *  2. Visit any annotation, to ensure that if a method is annotated, it has
+ *     its ancestor also annotated. This is to avoid having an annotation on a
+ *     Java method without the corresponding annotation on the AIDL interface.
  */
 class EnforcePermissionDetector : Detector(), SourceCodeScanner {
 
     val ENFORCE_PERMISSION = "android.annotation.EnforcePermission"
+    val BINDER_CLASS = "android.os.Binder"
+    val JAVA_OBJECT = "java.lang.Object"
 
     override fun applicableAnnotations(): List<String> {
         return listOf(ENFORCE_PERMISSION)
     }
 
+    override fun getApplicableUastTypes(): List<Class<out UElement>> {
+        return listOf(UAnnotation::class.java)
+    }
+
     private fun areAnnotationsEquivalent(
         context: JavaContext,
         anno1: PsiAnnotation,
@@ -74,6 +92,73 @@
         return true
     }
 
+    private fun compareMethods(
+        context: JavaContext,
+        element: UElement,
+        overridingMethod: PsiMethod,
+        overriddenMethod: PsiMethod,
+        checkEquivalence: Boolean = true
+    ) {
+        val overridingAnnotation = overridingMethod.getAnnotation(ENFORCE_PERMISSION)
+        val overriddenAnnotation = overriddenMethod.getAnnotation(ENFORCE_PERMISSION)
+        val location = context.getLocation(element)
+        val overridingClass = overridingMethod.parent as PsiClass
+        val overriddenClass = overriddenMethod.parent as PsiClass
+        val overridingName = "${overridingClass.name}.${overridingMethod.name}"
+        val overriddenName = "${overriddenClass.name}.${overriddenMethod.name}"
+        if (overridingAnnotation == null) {
+            val msg = "The method $overridingName overrides the method $overriddenName which " +
+                "is annotated with @EnforcePermission. The same annotation must be used " +
+                "on $overridingName"
+            context.report(ISSUE_MISSING_ENFORCE_PERMISSION, element, location, msg)
+        } else if (overriddenAnnotation == null) {
+            val msg = "The method $overridingName overrides the method $overriddenName which " +
+                "is not annotated with @EnforcePermission. The same annotation must be " +
+                "used on $overriddenName. Did you forget to annotate the AIDL definition?"
+            context.report(ISSUE_MISSING_ENFORCE_PERMISSION, element, location, msg)
+        } else if (checkEquivalence && !areAnnotationsEquivalent(
+                    context, overridingAnnotation, overriddenAnnotation)) {
+            val msg = "The method $overridingName is annotated with " +
+                "${overridingAnnotation.text} which differs from the overridden " +
+                "method $overriddenName: ${overriddenAnnotation.text}. The same " +
+                "annotation must be used for both methods."
+            context.report(ISSUE_MISMATCHING_ENFORCE_PERMISSION, element, location, msg)
+        }
+    }
+
+    private fun compareClasses(
+        context: JavaContext,
+        element: UElement,
+        newClass: PsiClass,
+        extendedClass: PsiClass,
+        checkEquivalence: Boolean = true
+    ) {
+        val newAnnotation = newClass.getAnnotation(ENFORCE_PERMISSION)
+        val extendedAnnotation = extendedClass.getAnnotation(ENFORCE_PERMISSION)
+
+        val location = context.getLocation(element)
+        val newClassName = newClass.qualifiedName
+        val extendedClassName = extendedClass.qualifiedName
+        if (newAnnotation == null) {
+            val msg = "The class $newClassName extends the class $extendedClassName which " +
+                "is annotated with @EnforcePermission. The same annotation must be used " +
+                "on $newClassName."
+            context.report(ISSUE_MISSING_ENFORCE_PERMISSION, element, location, msg)
+        } else if (extendedAnnotation == null) {
+            val msg = "The class $newClassName extends the class $extendedClassName which " +
+                "is not annotated with @EnforcePermission. The same annotation must be used " +
+                "on $extendedClassName. Did you forget to annotate the AIDL definition?"
+            context.report(ISSUE_MISSING_ENFORCE_PERMISSION, element, location, msg)
+        } else if (checkEquivalence && !areAnnotationsEquivalent(
+            context, newAnnotation, extendedAnnotation)) {
+            val msg = "The class $newClassName is annotated with ${newAnnotation.text} " +
+                "which differs from the parent class $extendedClassName: " +
+                "${extendedAnnotation.text}. The same annotation must be used for " +
+                "both classes."
+            context.report(ISSUE_MISMATCHING_ENFORCE_PERMISSION, element, location, msg)
+        }
+    }
+
     override fun visitAnnotationUsage(
         context: JavaContext,
         element: UElement,
@@ -83,48 +168,42 @@
         if (usageInfo.type == AnnotationUsageType.EXTENDS) {
             val newClass = element.sourcePsi?.parent?.parent as PsiClass
             val extendedClass: PsiClass = usageInfo.referenced as PsiClass
-            val newAnnotation = newClass.getAnnotation(ENFORCE_PERMISSION)
-            val extendedAnnotation = extendedClass.getAnnotation(ENFORCE_PERMISSION)!!
-
-            val location = context.getLocation(element)
-            val newClassName = newClass.qualifiedName
-            val extendedClassName = extendedClass.qualifiedName
-            if (newAnnotation == null) {
-                val msg = "The class $newClassName extends the class $extendedClassName which " +
-                    "is annotated with @EnforcePermission. The same annotation must be used " +
-                    "on $newClassName."
-                context.report(ISSUE_MISSING_ENFORCE_PERMISSION, element, location, msg)
-            } else if (!areAnnotationsEquivalent(context, newAnnotation, extendedAnnotation)) {
-                val msg = "The class $newClassName is annotated with ${newAnnotation.text} " +
-                    "which differs from the parent class $extendedClassName: " +
-                    "${extendedAnnotation.text}. The same annotation must be used for " +
-                    "both classes."
-                context.report(ISSUE_MISMATCHING_ENFORCE_PERMISSION, element, location, msg)
-            }
+            compareClasses(context, element, newClass, extendedClass)
         } else if (usageInfo.type == AnnotationUsageType.METHOD_OVERRIDE &&
             annotationInfo.origin == AnnotationOrigin.METHOD) {
             val overridingMethod = element.sourcePsi as PsiMethod
             val overriddenMethod = usageInfo.referenced as PsiMethod
-            val overridingAnnotation = overridingMethod.getAnnotation(ENFORCE_PERMISSION)
-            val overriddenAnnotation = overriddenMethod.getAnnotation(ENFORCE_PERMISSION)!!
+            compareMethods(context, element, overridingMethod, overriddenMethod)
+        }
+    }
 
-            val location = context.getLocation(element)
-            val overridingClass = overridingMethod.parent as PsiClass
-            val overriddenClass = overriddenMethod.parent as PsiClass
-            val overridingName = "${overridingClass.name}.${overridingMethod.name}"
-            val overriddenName = "${overriddenClass.name}.${overriddenMethod.name}"
-            if (overridingAnnotation == null) {
-                val msg = "The method $overridingName overrides the method $overriddenName which " +
-                    "is annotated with @EnforcePermission. The same annotation must be used " +
-                    "on $overridingName"
-                context.report(ISSUE_MISSING_ENFORCE_PERMISSION, element, location, msg)
-            } else if (!areAnnotationsEquivalent(
-                        context, overridingAnnotation, overriddenAnnotation)) {
-                val msg = "The method $overridingName is annotated with " +
-                    "${overridingAnnotation.text} which differs from the overridden " +
-                    "method $overriddenName: ${overriddenAnnotation.text}. The same " +
-                    "annotation must be used for both methods."
-                context.report(ISSUE_MISMATCHING_ENFORCE_PERMISSION, element, location, msg)
+    override fun createUastHandler(context: JavaContext): UElementHandler {
+        return object : UElementHandler() {
+            override fun visitAnnotation(node: UAnnotation) {
+                if (node.qualifiedName != ENFORCE_PERMISSION) {
+                    return
+                }
+                val method = node.uastParent as? UMethod
+                val klass = node.uastParent as? UClass
+                if (klass != null) {
+                    val newClass = klass as PsiClass
+                    val extendedClass = newClass.getSuperClass()
+                    if (extendedClass != null && extendedClass.qualifiedName != JAVA_OBJECT) {
+                        // The equivalence check can be skipped, if both classes are
+                        // annotated, it will be verified by visitAnnotationUsage.
+                        compareClasses(context, klass, newClass,
+                            extendedClass, checkEquivalence = false)
+                    }
+                } else if (method != null) {
+                    val overridingMethod = method as PsiMethod
+                    val parents = overridingMethod.findSuperMethods()
+                    for (overriddenMethod in parents) {
+                        // The equivalence check can be skipped, if both methods are
+                        // annotated, it will be verified by visitAnnotationUsage.
+                        compareMethods(context, method, overridingMethod,
+                            overriddenMethod, checkEquivalence = false)
+                    }
+                }
             }
         }
     }
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
new file mode 100644
index 0000000..cc2ab19
--- /dev/null
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2022 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.google.android.lint.parcel
+
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.LintFix
+import com.android.tools.lint.detector.api.Location
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiClassType
+import com.intellij.psi.PsiIntersectionType
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.PsiType
+import com.intellij.psi.PsiTypeParameter
+import com.intellij.psi.PsiWildcardType
+import org.jetbrains.kotlin.utils.addToStdlib.cast
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UExpression
+import org.jetbrains.uast.UVariable
+
+/**
+ * Subclass this class and override {@link #getBoundingClass} to report an unsafe Parcel API issue
+ * with a fix that migrates towards the new safer API by appending an argument in the form of
+ * {@code com.package.ItemType.class} coming from the result of the overridden method.
+ */
+abstract class CallMigrator(
+        val method: Method,
+        private val rejects: Set<String> = emptySet(),
+) {
+    open fun report(context: JavaContext, call: UCallExpression, method: PsiMethod) {
+        val location = context.getLocation(call)
+        val itemType = getBoundingClass(context, call, method)
+        val fix = (itemType as? PsiClassType)?.let { type ->
+            getParcelFix(location, this.method.name, getArgumentSuffix(type))
+        }
+        val message = "Unsafe `Parcel.${this.method.name}()` API usage"
+        context.report(SaferParcelChecker.ISSUE_UNSAFE_API_USAGE, call, location, message, fix)
+    }
+
+    protected open fun getArgumentSuffix(type: PsiClassType) =
+            ", ${type.rawType().canonicalText}.class"
+
+    protected open fun getBoundingClass(
+            context: JavaContext,
+            call: UCallExpression,
+            method: PsiMethod,
+    ): PsiType? = null
+
+    protected fun getItemType(type: PsiType, container: String): PsiClassType? {
+        val supers = getParentTypes(type).mapNotNull { it as? PsiClassType }
+        val containerType = supers.firstOrNull { it.rawType().canonicalText == container }
+                ?: return null
+        val itemType = containerType.parameters.getOrNull(0) ?: return null
+        // TODO: Expand to other types, see PsiTypeVisitor
+        return when (itemType) {
+            is PsiClassType -> itemType
+            is PsiWildcardType -> itemType.bound as PsiClassType
+            else -> null
+        }
+    }
+
+    /**
+     * Tries to obtain the type expected by the "receiving" end given a certain {@link UExpression}.
+     *
+     * This could be an assignment, an argument passed to a method call, to a constructor call, a
+     * type cast, etc. If no receiving end is found, the type of the UExpression itself is returned.
+     */
+    protected fun getReceivingType(expression: UExpression): PsiType? {
+        val parent = expression.uastParent
+        val type = when (parent) {
+            is UCallExpression -> {
+                val i = parent.valueArguments.indexOf(expression)
+                val psiCall = parent.sourcePsi as? PsiCallExpression ?: return null
+                val typeSubstitutor = psiCall.resolveMethodGenerics().substitutor
+                val method = psiCall.resolveMethod()!!
+                method.getSignature(typeSubstitutor).parameterTypes[i]
+            }
+            is UVariable -> parent.type
+            is UExpression -> parent.getExpressionType()
+            else -> null
+        }
+        return filter(type ?: expression.getExpressionType())
+    }
+
+    private fun filter(type: PsiType?): PsiType? {
+        // It's important that PsiIntersectionType case is above the one that check the type in
+        // rejects, because for intersect types, the canonicalText is one of the terms.
+        if (type is PsiIntersectionType) {
+            return type.conjuncts.mapNotNull(this::filter).firstOrNull()
+        }
+        if (type == null || type.canonicalText in rejects) {
+            return null
+        }
+        if (type is PsiClassType && type.resolve() is PsiTypeParameter) {
+            return null
+        }
+        return type
+    }
+
+    private fun getParentTypes(type: PsiType): Set<PsiType> =
+            type.superTypes.flatMap(::getParentTypes).toSet() + type
+
+    protected fun getParcelFix(location: Location, method: String, arguments: String) =
+            LintFix
+                    .create()
+                    .name("Migrate to safer Parcel.$method() API")
+                    .replace()
+                    .range(location)
+                    .pattern("$method\\s*\\(((?:.|\\n)*)\\)")
+                    .with("\\k<1>$arguments")
+                    .autoFix()
+                    .build()
+}
+
+/**
+ * This class derives the type to be appended by inferring the generic type of the {@code container}
+ * type (eg. "java.util.List") of the {@code argument}-th argument.
+ */
+class ContainerArgumentMigrator(
+        method: Method,
+        private val argument: Int,
+        private val container: String,
+        rejects: Set<String> = emptySet(),
+) : CallMigrator(method, rejects) {
+    override fun getBoundingClass(
+            context: JavaContext, call: UCallExpression, method: PsiMethod
+    ): PsiType? {
+        val firstParamType = call.valueArguments[argument].getExpressionType() ?: return null
+        return getItemType(firstParamType, container)!!
+    }
+
+    /**
+     * We need to insert a casting construct in the class parameter. For example:
+     *   (Class<Foo<Bar>>) (Class<?>) Foo.class.
+     * This is needed for when the arguments of the conflict (eg. when there is List<Foo<Bar>> and
+     * class type is Class<Foo?).
+     */
+    override fun getArgumentSuffix(type: PsiClassType): String {
+        if (type.parameters.isNotEmpty()) {
+            val rawType = type.rawType()
+            return ", (Class<${type.canonicalText}>) (Class<?>) ${rawType.canonicalText}.class"
+        }
+        return super.getArgumentSuffix(type)
+    }
+}
+
+/**
+ * This class derives the type to be appended by inferring the generic type of the {@code container}
+ * type (eg. "java.util.List") of the return type of the method.
+ */
+class ContainerReturnMigrator(
+        method: Method,
+        private val container: String,
+        rejects: Set<String> = emptySet(),
+) : CallMigrator(method, rejects) {
+    override fun getBoundingClass(
+            context: JavaContext, call: UCallExpression, method: PsiMethod
+    ): PsiType? {
+        val type = getReceivingType(call.uastParent as UExpression) ?: return null
+        return getItemType(type, container)
+    }
+}
+
+/**
+ * This class derives the type to be appended by inferring the expected type for the method result.
+ */
+class ReturnMigrator(
+        method: Method,
+        rejects: Set<String> = emptySet(),
+) : CallMigrator(method, rejects) {
+    override fun getBoundingClass(
+            context: JavaContext, call: UCallExpression, method: PsiMethod
+    ): PsiType? {
+        return getReceivingType(call.uastParent as UExpression)
+    }
+}
+
+/**
+ * This class appends the class loader and the class object by deriving the type from the method
+ * result.
+ */
+class ReturnMigratorWithClassLoader(
+        method: Method,
+        rejects: Set<String> = emptySet(),
+) : CallMigrator(method, rejects) {
+    override fun getBoundingClass(
+            context: JavaContext, call: UCallExpression, method: PsiMethod
+    ): PsiType? {
+        return getReceivingType(call.uastParent as UExpression)
+    }
+
+    override fun getArgumentSuffix(type: PsiClassType): String =
+            "${type.rawType().canonicalText}.class.getClassLoader(), " +
+                    "${type.rawType().canonicalText}.class"
+
+}
\ No newline at end of file
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt
new file mode 100644
index 0000000..c032fa2
--- /dev/null
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 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.google.android.lint.parcel
+
+data class Method(
+    val params: List<String>,
+    val clazz: String,
+    val name: String,
+    val parameters: List<String>
+) {
+    constructor(
+        clazz: String,
+        name: String,
+        parameters: List<String>
+    ) : this(
+            listOf(), clazz, name, parameters
+    )
+
+    val signature: String
+        get() {
+            val prefix = if (params.isEmpty()) "" else "${params.joinToString(", ", "<", ">")} "
+            return "$prefix$clazz.$name(${parameters.joinToString()})"
+        }
+}
\ No newline at end of file
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
new file mode 100644
index 0000000..89dbcae
--- /dev/null
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2022 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.google.android.lint.parcel
+
+import com.android.tools.lint.detector.api.*
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.PsiSubstitutor
+import com.intellij.psi.PsiType
+import com.intellij.psi.PsiTypeParameter
+import org.jetbrains.uast.UCallExpression
+import java.util.*
+
+class SaferParcelChecker : Detector(), SourceCodeScanner {
+    override fun getApplicableMethodNames(): List<String> =
+            MIGRATORS
+                    .map(CallMigrator::method)
+                    .map(Method::name)
+
+    override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+        if (!isAtLeastT(context)) return
+        val signature = getSignature(method)
+        val migrator = MIGRATORS.firstOrNull { it.method.signature == signature } ?: return
+        migrator.report(context, node, method)
+    }
+
+    private fun getSignature(method: PsiMethod): String {
+        val name = UastLintUtils.getQualifiedName(method)
+        val signature = method.getSignature(PsiSubstitutor.EMPTY)
+        val parameters =
+                signature.parameterTypes.joinToString(transform = PsiType::getCanonicalText)
+        val types = signature.typeParameters.map(PsiTypeParameter::getName)
+        val prefix = if (types.isEmpty()) "" else types.joinToString(", ", "<", ">") + " "
+        return "$prefix$name($parameters)"
+    }
+
+    /** Taken from androidx-main:core/core/src/main/java/androidx/core/os/BuildCompat.java */
+    private fun isAtLeastT(context: Context): Boolean {
+        val project = if (context.isGlobalAnalysis()) context.mainProject else context.project
+        return project.isAndroidProject
+                && project.minSdkVersion.featureLevel >= 32
+                && isAtLeastPreReleaseCodename("Tiramisu", project.minSdkVersion.codename)
+    }
+
+    /** Taken from androidx-main:core/core/src/main/java/androidx/core/os/BuildCompat.java */
+    private fun isAtLeastPreReleaseCodename(min: String, actual: String): Boolean {
+        if (actual == "REL") return false
+        return actual.uppercase(Locale.ROOT) >= min.uppercase(Locale.ROOT)
+    }
+
+    companion object {
+        @JvmField
+        val ISSUE_UNSAFE_API_USAGE: Issue = Issue.create(
+                id = "UnsafeParcelApi",
+                briefDescription = "Use of unsafe Parcel API",
+                explanation = """
+                    You are using a deprecated Parcel API that doesn't accept the expected class as\
+                     a parameter. This means that unexpected classes could be instantiated and\
+                     unexpected code executed.
+
+                    Please migrate to the safer alternative that takes an extra Class<T> parameter.
+                    """,
+                category = Category.SECURITY,
+                priority = 8,
+                severity = Severity.WARNING,
+
+                implementation = Implementation(
+                        SaferParcelChecker::class.java,
+                        Scope.JAVA_FILE_SCOPE
+                )
+        )
+
+        private val METHOD_READ_SERIALIZABLE = Method("android.os.Parcel", "readSerializable", listOf())
+        private val METHOD_READ_ARRAY_LIST = Method("android.os.Parcel", "readArrayList", listOf("java.lang.ClassLoader"))
+        private val METHOD_READ_LIST = Method("android.os.Parcel", "readList", listOf("java.util.List", "java.lang.ClassLoader"))
+        private val METHOD_READ_PARCELABLE = Method(listOf("T"), "android.os.Parcel", "readParcelable", listOf("java.lang.ClassLoader"))
+        private val METHOD_READ_PARCELABLE_LIST = Method(listOf("T"), "android.os.Parcel", "readParcelableList", listOf("java.util.List<T>", "java.lang.ClassLoader"))
+        private val METHOD_READ_SPARSE_ARRAY = Method(listOf("T"), "android.os.Parcel", "readSparseArray", listOf("java.lang.ClassLoader"))
+
+        // TODO: Write migrators for methods below
+        private val METHOD_READ_ARRAY = Method("android.os.Parcel", "readArray", listOf("java.lang.ClassLoader"))
+        private val METHOD_READ_PARCELABLE_ARRAY = Method("android.os.Parcel", "readParcelableArray", listOf("java.lang.ClassLoader"))
+        private val METHOD_READ_PARCELABLE_CREATOR = Method("android.os.Parcel", "readParcelableCreator", listOf("java.lang.ClassLoader"))
+
+        private val MIGRATORS = listOf(
+                ReturnMigrator(METHOD_READ_PARCELABLE, setOf("android.os.Parcelable")),
+                ContainerArgumentMigrator(METHOD_READ_LIST, 0, "java.util.List"),
+                ContainerReturnMigrator(METHOD_READ_ARRAY_LIST, "java.util.Collection"),
+                ContainerReturnMigrator(METHOD_READ_SPARSE_ARRAY, "android.util.SparseArray"),
+                ContainerArgumentMigrator(METHOD_READ_PARCELABLE_LIST, 0, "java.util.List"),
+                ReturnMigratorWithClassLoader(METHOD_READ_SERIALIZABLE),
+        )
+    }
+}
\ No newline at end of file
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/EnforcePermissionDetectorTest.kt b/tools/lint/checks/src/test/java/com/google/android/lint/EnforcePermissionDetectorTest.kt
index f5f4ebe..2cfc3fb 100644
--- a/tools/lint/checks/src/test/java/com/google/android/lint/EnforcePermissionDetectorTest.kt
+++ b/tools/lint/checks/src/test/java/com/google/android/lint/EnforcePermissionDetectorTest.kt
@@ -147,14 +147,57 @@
 1 errors, 0 warnings""".addLineContinuation())
     }
 
+    fun testDetectIssuesExtraAnnotationMethod() {
+        lint().files(java(
+            """
+            package test.pkg;
+            public class TestClass7 extends IBar.Stub {
+                @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET)
+                public void testMethod() {}
+            }
+            """).indented(),
+                *stubs
+        )
+        .run()
+        .expect("""src/test/pkg/TestClass7.java:4: Error: The method TestClass7.testMethod \
+overrides the method Stub.testMethod which is not annotated with @EnforcePermission. The same \
+annotation must be used on Stub.testMethod. Did you forget to annotate the AIDL definition? \
+[MissingEnforcePermissionAnnotation]
+    public void testMethod() {}
+                ~~~~~~~~~~
+1 errors, 0 warnings""".addLineContinuation())
+    }
+
+    fun testDetectIssuesExtraAnnotationInterface() {
+        lint().files(java(
+            """
+            package test.pkg;
+            @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET)
+            public class TestClass8 extends IBar.Stub {
+                public void testMethod() {}
+            }
+            """).indented(),
+                *stubs
+        )
+        .run()
+        .expect("""src/test/pkg/TestClass8.java:2: Error: The class test.pkg.TestClass8 \
+extends the class IBar.Stub which is not annotated with @EnforcePermission. The same annotation \
+must be used on IBar.Stub. Did you forget to annotate the AIDL definition? \
+[MissingEnforcePermissionAnnotation]
+@android.annotation.EnforcePermission(android.Manifest.permission.INTERNET)
+^
+1 errors, 0 warnings""".addLineContinuation())
+    }
+
     /* Stubs */
 
+    // A service with permission annotation on the class.
     private val interfaceIFooStub: TestFile = java(
         """
         @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
         public interface IFoo {
          @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
-         public static abstract class Stub implements IFoo {
+         public static abstract class Stub extends android.os.Binder implements IFoo {
            @Override
            public void testMethod() {}
          }
@@ -163,10 +206,11 @@
         """
     ).indented()
 
+    // A service with permission annotation on the method.
     private val interfaceIFooMethodStub: TestFile = java(
         """
         public interface IFooMethod {
-         public static abstract class Stub implements IFooMethod {
+         public static abstract class Stub extends android.os.Binder implements IFooMethod {
             @Override
             @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
             public void testMethod() {}
@@ -177,6 +221,19 @@
         """
     ).indented()
 
+    // A service without any permission annotation.
+    private val interfaceIBarStub: TestFile = java(
+        """
+        public interface IBar {
+         public static abstract class Stub extends android.os.Binder implements IBar {
+            @Override
+            public void testMethod() {}
+          }
+          public void testMethod();
+        }
+        """
+    ).indented()
+
     private val manifestPermissionStub: TestFile = java(
         """
         package android.Manifest;
@@ -194,7 +251,7 @@
         """
     ).indented()
 
-    private val stubs = arrayOf(interfaceIFooStub, interfaceIFooMethodStub,
+    private val stubs = arrayOf(interfaceIFooStub, interfaceIFooMethodStub, interfaceIBarStub,
             manifestPermissionStub, enforcePermissionAnnotationStub)
 
     // Substitutes "backslash + new line" with an empty string to imitate line continuation
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt b/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
new file mode 100644
index 0000000..05c7850
--- /dev/null
+++ b/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2022 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.google.android.lint.parcel
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.checks.infrastructure.TestMode
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+@Suppress("UnstableApiUsage")
+class SaferParcelCheckerTest : LintDetectorTest() {
+    override fun getDetector(): Detector = SaferParcelChecker()
+
+    override fun getIssues(): List<Issue> = listOf(
+            SaferParcelChecker.ISSUE_UNSAFE_API_USAGE
+    )
+
+    override fun lint(): TestLintTask =
+            super.lint()
+                    .allowMissingSdk(true)
+                    // We don't do partial analysis in the platform
+                    .skipTestModes(TestMode.PARTIAL)
+
+    fun testDetectUnsafeReadSerializable() {
+        lint()
+                .files(
+                        java(
+                                """
+                        package test.pkg;
+                        import android.os.Parcel;
+                        import java.io.Serializable;
+
+                        public class TestClass {
+                            private TestClass(Parcel p) {
+                                Serializable ans = p.readSerializable();
+                            }
+                        }
+                        """
+                        ).indented(),
+                        *includes
+                )
+                .expectIdenticalTestModeOutput(false)
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass.java:7: Warning: Unsafe Parcel.readSerializable() \
+                        API usage [UnsafeParcelApi]
+                                Serializable ans = p.readSerializable();
+                                                   ~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 1 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDoesNotDetectSafeReadSerializable() {
+        lint()
+                .files(
+                        java(
+                                """
+                        package test.pkg;
+                        import android.os.Parcel;
+                        import java.io.Serializable;
+
+                        public class TestClass {
+                            private TestClass(Parcel p) {
+                                String ans = p.readSerializable(null, String.class);
+                            }
+                        }
+                        """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect("No warnings.")
+    }
+
+    fun testDetectUnsafeReadArrayList() {
+        lint()
+                .files(
+                        java(
+                                """
+                        package test.pkg;
+                        import android.os.Parcel;
+
+                        public class TestClass {
+                            private TestClass(Parcel p) {
+                                ArrayList ans = p.readArrayList(null);
+                            }
+                        }
+                        """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass.java:6: Warning: Unsafe Parcel.readArrayList() API \
+                        usage [UnsafeParcelApi]
+                                ArrayList ans = p.readArrayList(null);
+                                                ~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 1 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDoesNotDetectSafeReadArrayList() {
+        lint()
+                .files(
+                        java(
+                                """
+                                package test.pkg;
+                                import android.content.Intent;
+                                import android.os.Parcel;
+
+                                public class TestClass {
+                                    private TestClass(Parcel p) {
+                                        ArrayList<Intent> ans = p.readArrayList(null, Intent.class);
+                                    }
+                                }
+                                """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect("No warnings.")
+    }
+
+    fun testDetectUnsafeReadList() {
+        lint()
+                .files(
+                        java(
+                                """
+                                package test.pkg;
+                                import android.content.Intent;
+                                import android.os.Parcel;
+                                import java.util.List;
+
+                                public class TestClass {
+                                    private TestClass(Parcel p) {
+                                        List<Intent> list = new ArrayList<Intent>();
+                                        p.readList(list, null);
+                                    }
+                                }
+                                """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass.java:9: Warning: Unsafe Parcel.readList() API usage \
+                        [UnsafeParcelApi]
+                                p.readList(list, null);
+                                ~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 1 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDoesNotDetectSafeReadList() {
+        lint()
+                .files(
+                        java(
+                                """
+                                package test.pkg;
+                                import android.content.Intent;
+                                import android.os.Parcel;
+                                import java.util.List;
+
+                                public class TestClass {
+                                    private TestClass(Parcel p) {
+                                        List<Intent> list = new ArrayList<Intent>();
+                                        p.readList(list, null, Intent.class);
+                                    }
+                                }
+                                """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect("No warnings.")
+    }
+
+    fun testDetectUnsafeReadParcelable() {
+        lint()
+                .files(
+                        java(
+                                """
+                                package test.pkg;
+                                import android.content.Intent;
+                                import android.os.Parcel;
+
+                                public class TestClass {
+                                    private TestClass(Parcel p) {
+                                        Intent ans = p.readParcelable(null);
+                                    }
+                                }
+                                """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass.java:7: Warning: Unsafe Parcel.readParcelable() API \
+                        usage [UnsafeParcelApi]
+                                Intent ans = p.readParcelable(null);
+                                             ~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 1 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDoesNotDetectSafeReadParcelable() {
+        lint()
+                .files(
+                        java(
+                                """
+                                package test.pkg;
+                                import android.content.Intent;
+                                import android.os.Parcel;
+
+                                public class TestClass {
+                                    private TestClass(Parcel p) {
+                                        Intent ans = p.readParcelable(null, Intent.class);
+                                    }
+                                }
+                                """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect("No warnings.")
+    }
+
+    fun testDetectUnsafeReadParcelableList() {
+        lint()
+                .files(
+                        java(
+                                """
+                                package test.pkg;
+                                import android.content.Intent;
+                                import android.os.Parcel;
+                                import java.util.List;
+
+                                public class TestClass {
+                                    private TestClass(Parcel p) {
+                                        List<Intent> list = new ArrayList<Intent>();
+                                        List<Intent> ans = p.readParcelableList(list, null);
+                                    }
+                                }
+                                """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass.java:9: Warning: Unsafe Parcel.readParcelableList() \
+                        API usage [UnsafeParcelApi]
+                                List<Intent> ans = p.readParcelableList(list, null);
+                                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 1 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDoesNotDetectSafeReadParcelableList() {
+        lint()
+                .files(
+                        java(
+                                """
+                                package test.pkg;
+                                import android.content.Intent;
+                                import android.os.Parcel;
+                                import java.util.List;
+
+                                public class TestClass {
+                                    private TestClass(Parcel p) {
+                                        List<Intent> list = new ArrayList<Intent>();
+                                        List<Intent> ans =
+                                                p.readParcelableList(list, null, Intent.class);
+                                    }
+                                }
+                                """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect("No warnings.")
+    }
+
+    fun testDetectUnsafeReadSparseArray() {
+        lint()
+                .files(
+                        java(
+                                """
+                                package test.pkg;
+                                import android.content.Intent;
+                                import android.os.Parcel;
+                                import android.util.SparseArray;
+
+                                public class TestClass {
+                                    private TestClass(Parcel p) {
+                                        SparseArray<Intent> ans = p.readSparseArray(null);
+                                    }
+                                }
+                                """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass.java:8: Warning: Unsafe Parcel.readSparseArray() API\
+                         usage [UnsafeParcelApi]
+                                SparseArray<Intent> ans = p.readSparseArray(null);
+                                                          ~~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 1 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDoesNotDetectSafeReadSparseArray() {
+        lint()
+                .files(
+                        java(
+                                """
+                                package test.pkg;
+                                import android.content.Intent;
+                                import android.os.Parcel;
+                                import android.util.SparseArray;
+
+                                public class TestClass {
+                                    private TestClass(Parcel p) {
+                                        SparseArray<Intent> ans =
+                                                p.readSparseArray(null, Intent.class);
+                                    }
+                                }
+                                """
+                        ).indented(),
+                        *includes
+                )
+                .run()
+                .expect("No warnings.")
+    }
+
+    /** Stubs for classes used for testing */
+
+
+    private val includes =
+            arrayOf(
+                manifest().minSdk("Tiramisu"),
+                java(
+                        """
+                        package android.os;
+                        import java.util.ArrayList;
+                        import java.util.List;
+                        import java.util.Map;
+                        import java.util.HashMap;
+
+                        public final class Parcel {
+                            // Deprecateds
+                            public Object[] readArray(ClassLoader loader) { return null; }
+                            public ArrayList readArrayList(ClassLoader loader) { return null; }
+                            public HashMap readHashMap(ClassLoader loader) { return null; }
+                            public void readList(List outVal, ClassLoader loader) {}
+                            public void readMap(Map outVal, ClassLoader loader) {}
+                            public <T extends Parcelable> T readParcelable(ClassLoader loader) { return null; }
+                            public Parcelable[] readParcelableArray(ClassLoader loader) { return null; }
+                            public Parcelable.Creator<?> readParcelableCreator(ClassLoader loader) { return null; }
+                            public <T extends Parcelable> List<T> readParcelableList(List<T> list, ClassLoader cl) { return null; }
+                            public Serializable readSerializable() { return null; }
+                            public <T> SparseArray<T> readSparseArray(ClassLoader loader) { return null; }
+
+                            // Replacements
+                            public <T> T[] readArray(ClassLoader loader, Class<T> clazz) { return null; }
+                            public <T> ArrayList<T> readArrayList(ClassLoader loader, Class<? extends T> clazz) { return null; }
+                            public <K, V> HashMap<K,V> readHashMap(ClassLoader loader, Class<? extends K> clazzKey, Class<? extends V> clazzValue) { return null; }
+                            public <T> void readList(List<? super T> outVal, ClassLoader loader, Class<T> clazz) {}
+                            public <K, V> void readMap(Map<? super K, ? super V> outVal, ClassLoader loader, Class<K> clazzKey, Class<V> clazzValue) {}
+                            public <T> T readParcelable(ClassLoader loader, Class<T> clazz) { return null; }
+                            public <T> T[] readParcelableArray(ClassLoader loader, Class<T> clazz) { return null; }
+                            public <T> Parcelable.Creator<T> readParcelableCreator(ClassLoader loader, Class<T> clazz) { return null; }
+                            public <T> List<T> readParcelableList(List<T> list, ClassLoader cl, Class<T> clazz) { return null; }
+                            public <T> T readSerializable(ClassLoader loader, Class<T> clazz) { return null; }
+                            public <T> SparseArray<T> readSparseArray(ClassLoader loader, Class<? extends T> clazz) { return null; }
+                        }
+                        """
+                ).indented(),
+                java(
+                        """
+                        package android.os;
+                        public interface Parcelable {}
+                        """
+                ).indented(),
+                java(
+                        """
+                        package android.content;
+                        public class Intent implements Parcelable, Cloneable {}
+                        """
+                ).indented(),
+                java(
+                        """
+                        package android.util;
+                        public class SparseArray<E> implements Cloneable {}
+                        """
+                ).indented(),
+            )
+
+    // Substitutes "backslash + new line" with an empty string to imitate line continuation
+    private fun String.addLineContinuation(): String = this.trimIndent().replace("\\\n", "")
+}
diff --git a/tools/preload-check/device/src/com/android/preload/check/Util.java b/tools/preload-check/device/src/com/android/preload/check/Util.java
index fccea0a0..f521c95 100644
--- a/tools/preload-check/device/src/com/android/preload/check/Util.java
+++ b/tools/preload-check/device/src/com/android/preload/check/Util.java
@@ -25,8 +25,8 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.LinkedList;
 import java.util.List;
 
 public class Util {
@@ -48,7 +48,7 @@
         Class<?> vmClassLoaderClass = Class.forName("java.lang.VMClassLoader");
         Method getResources = vmClassLoaderClass.getDeclaredMethod("getResources", String.class);
         getResources.setAccessible(true);
-        LinkedList<DexFile> res = new LinkedList<>();
+        ArrayList<DexFile> res = new ArrayList<>();
         for (int i = 1;; i++) {
             try {
                 String name = "classes" + (i > 1 ? String.valueOf(i) : "") + ".dex";