Merge "Fix for goat detection code" into rvc-dev
diff --git a/apex/Android.bp b/apex/Android.bp
index 51e030b..e8afa1d 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -63,6 +63,60 @@
     "--hide-annotation android.annotation.Hide " +
     "--hide InternalClasses " // com.android.* classes are okay in this interface
 
+// Defaults for mainline module provided java_sdk_library instances.
+java_defaults {
+    name: "framework-module-defaults",
+
+    // Additional annotations used for compiling both the implementation and the
+    // stubs libraries.
+    libs: ["framework-annotations-lib"],
+
+    // Enable api lint. This will eventually become the default for java_sdk_library
+    // but it cannot yet be turned on because some usages have not been cleaned up.
+    // TODO(b/156126315) - Remove when no longer needed.
+    api_lint: {
+        enabled: true,
+    },
+
+    // The API scope specific properties.
+    public: {
+        enabled: true,
+        sdk_version: "module_current",
+    },
+    system: {
+        enabled: true,
+        sdk_version: "module_current",
+    },
+    module_lib: {
+        enabled: true,
+        sdk_version: "module_current",
+    },
+
+    // The stub libraries must be visible to frameworks/base so they can be combined
+    // into API specific libraries.
+    stubs_library_visibility: [
+        "//frameworks/base", // Framework
+    ],
+
+    // Set the visibility of the modules creating the stubs source.
+    stubs_source_visibility: [
+        // Ignore any visibility rules specified on the java_sdk_library when
+        // setting the visibility of the stubs source modules.
+        "//visibility:override",
+
+        // Currently, the stub source is not required for anything other than building
+        // the stubs library so is private to avoid misuse.
+        "//visibility:private",
+    ],
+
+    // Collates API usages from each module for further analysis.
+    plugins: ["java_api_finder"],
+
+    // Mainline modules should only rely on 'module_lib' APIs provided by other modules
+    // and the non updatable parts of the platform.
+    sdk_version: "module_current",
+}
+
 stubs_defaults {
     name: "framework-module-stubs-defaults-publicapi",
     args: mainline_framework_stubs_args,
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
index 46d449a..372ec98 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
@@ -79,6 +79,12 @@
 
     private static final int STANDBY_BUCKET_UNKNOWN = -1;
 
+    /**
+     * The bucket beyond which apps are considered idle. Any apps in this bucket or lower are
+     * considered idle while those in higher buckets are not considered idle.
+     */
+    static final int IDLE_BUCKET_CUTOFF = STANDBY_BUCKET_RARE;
+
     @VisibleForTesting
     static final String APP_IDLE_FILENAME = "app_idle_stats.xml";
     private static final String TAG_PACKAGES = "packages";
@@ -350,7 +356,7 @@
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         AppUsageHistory appUsageHistory =
                 getPackageHistory(userHistory, packageName, elapsedRealtime, true);
-        return appUsageHistory.currentBucket >= STANDBY_BUCKET_RARE;
+        return appUsageHistory.currentBucket >= IDLE_BUCKET_CUTOFF;
     }
 
     public AppUsageHistory getAppUsageHistory(String packageName, int userId,
@@ -487,7 +493,7 @@
         final int newBucket;
         final int reason;
         if (idle) {
-            newBucket = STANDBY_BUCKET_RARE;
+            newBucket = IDLE_BUCKET_CUTOFF;
             reason = REASON_MAIN_FORCED_BY_USER;
         } else {
             newBucket = STANDBY_BUCKET_ACTIVE;
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 980372d..2834ab1 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -54,6 +54,7 @@
 import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.AppGlobals;
@@ -92,6 +93,7 @@
 import android.os.UserHandle;
 import android.provider.Settings.Global;
 import android.telephony.TelephonyManager;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.KeyValueListParser;
 import android.util.Slog;
@@ -227,6 +229,13 @@
     @GuardedBy("mActiveAdminApps")
     private final SparseArray<Set<String>> mActiveAdminApps = new SparseArray<>();
 
+    /**
+     * Set of system apps that are headless (don't have any declared activities, enabled or
+     * disabled). Presence in this map indicates that the app is a headless system app.
+     */
+    @GuardedBy("mAppIdleLock")
+    private final ArrayMap<String, Boolean> mHeadlessSystemApps = new ArrayMap<>();
+
     private final CountDownLatch mAdminDataAvailableLatch = new CountDownLatch(1);
 
     // Messages for the handler
@@ -667,20 +676,22 @@
                 return;
             }
         }
-        final boolean isSpecial = isAppSpecial(packageName,
+        final int minBucket = getAppMinBucket(packageName,
                 UserHandle.getAppId(uid),
                 userId);
         if (DEBUG) {
-            Slog.d(TAG, "   Checking idle state for " + packageName + " special=" +
-                    isSpecial);
+            Slog.d(TAG, "   Checking idle state for " + packageName
+                    + " minBucket=" + minBucket);
         }
-        if (isSpecial) {
+        if (minBucket <= STANDBY_BUCKET_ACTIVE) {
+            // No extra processing needed for ACTIVE or higher since apps can't drop into lower
+            // buckets.
             synchronized (mAppIdleLock) {
                 mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
-                        STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT);
+                        minBucket, REASON_MAIN_DEFAULT);
             }
             maybeInformListeners(packageName, userId, elapsedRealtime,
-                    STANDBY_BUCKET_EXEMPTED, REASON_MAIN_DEFAULT, false);
+                    minBucket, REASON_MAIN_DEFAULT, false);
         } else {
             synchronized (mAppIdleLock) {
                 final AppIdleHistory.AppUsageHistory app =
@@ -761,6 +772,14 @@
                         Slog.d(TAG, "Bringing up from RESTRICTED to RARE due to off switch");
                     }
                 }
+                if (newBucket > minBucket) {
+                    newBucket = minBucket;
+                    // Leave the reason alone.
+                    if (DEBUG) {
+                        Slog.d(TAG, "Bringing up from " + newBucket + " to " + minBucket
+                                + " due to min bucketing");
+                    }
+                }
                 if (DEBUG) {
                     Slog.d(TAG, "     Old bucket=" + oldBucket
                             + ", newBucket=" + newBucket);
@@ -1027,20 +1046,35 @@
         return isAppIdleFiltered(packageName, getAppId(packageName), userId, elapsedRealtime);
     }
 
-    private boolean isAppSpecial(String packageName, int appId, int userId) {
-        if (packageName == null) return false;
+    @StandbyBuckets
+    private int getAppMinBucket(String packageName, int userId) {
+        try {
+            final int uid = mPackageManager.getPackageUidAsUser(packageName, userId);
+            return getAppMinBucket(packageName, UserHandle.getAppId(uid), userId);
+        } catch (PackageManager.NameNotFoundException e) {
+            // Not a valid package for this user, nothing to do
+            return STANDBY_BUCKET_NEVER;
+        }
+    }
+
+    /**
+     * Return the lowest bucket this app should ever enter.
+     */
+    @StandbyBuckets
+    private int getAppMinBucket(String packageName, int appId, int userId) {
+        if (packageName == null) return STANDBY_BUCKET_NEVER;
         // If not enabled at all, of course nobody is ever idle.
         if (!mAppIdleEnabled) {
-            return true;
+            return STANDBY_BUCKET_EXEMPTED;
         }
         if (appId < Process.FIRST_APPLICATION_UID) {
             // System uids never go idle.
-            return true;
+            return STANDBY_BUCKET_EXEMPTED;
         }
         if (packageName.equals("android")) {
             // Nor does the framework (which should be redundant with the above, but for MR1 we will
             // retain this for safety).
-            return true;
+            return STANDBY_BUCKET_EXEMPTED;
         }
         if (mSystemServicesReady) {
             try {
@@ -1048,42 +1082,51 @@
                 // for idle mode, because app idle (aka app standby) is really not as big an issue
                 // for controlling who participates vs. doze mode.
                 if (mInjector.isNonIdleWhitelisted(packageName)) {
-                    return true;
+                    return STANDBY_BUCKET_EXEMPTED;
                 }
             } catch (RemoteException re) {
                 throw re.rethrowFromSystemServer();
             }
 
             if (isActiveDeviceAdmin(packageName, userId)) {
-                return true;
+                return STANDBY_BUCKET_EXEMPTED;
             }
 
             if (isActiveNetworkScorer(packageName)) {
-                return true;
+                return STANDBY_BUCKET_EXEMPTED;
             }
 
             if (mAppWidgetManager != null
                     && mInjector.isBoundWidgetPackage(mAppWidgetManager, packageName, userId)) {
-                return true;
+                // TODO: consider lowering to ACTIVE
+                return STANDBY_BUCKET_EXEMPTED;
             }
 
             if (isDeviceProvisioningPackage(packageName)) {
-                return true;
+                return STANDBY_BUCKET_EXEMPTED;
             }
         }
 
         // Check this last, as it can be the most expensive check
         if (isCarrierApp(packageName)) {
-            return true;
+            return STANDBY_BUCKET_EXEMPTED;
         }
 
-        return false;
+        if (isHeadlessSystemApp(packageName)) {
+            return STANDBY_BUCKET_ACTIVE;
+        }
+
+        return STANDBY_BUCKET_NEVER;
+    }
+
+    private boolean isHeadlessSystemApp(String packageName) {
+        return mHeadlessSystemApps.containsKey(packageName);
     }
 
     @Override
     public boolean isAppIdleFiltered(String packageName, int appId, int userId,
             long elapsedRealtime) {
-        if (isAppSpecial(packageName, appId, userId)) {
+        if (getAppMinBucket(packageName, appId, userId) < AppIdleHistory.IDLE_BUCKET_CUTOFF) {
             return false;
         } else {
             synchronized (mAppIdleLock) {
@@ -1423,6 +1466,8 @@
                 }
             }
 
+            // Make sure we don't put the app in a lower bucket than it's supposed to be in.
+            newBucket = Math.min(newBucket, getAppMinBucket(packageName, userId));
             mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket,
                     reason, resetTimeout);
         }
@@ -1617,14 +1662,16 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
+            final String pkgName = intent.getData().getSchemeSpecificPart();
+            final int userId = getSendingUserId();
             if (Intent.ACTION_PACKAGE_ADDED.equals(action)
                     || Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
                 clearCarrierPrivilegedApps();
+                // ACTION_PACKAGE_ADDED is called even for system app downgrades.
+                evaluateSystemAppException(pkgName, userId);
             }
             if ((Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
                     Intent.ACTION_PACKAGE_ADDED.equals(action))) {
-                final String pkgName = intent.getData().getSchemeSpecificPart();
-                final int userId = getSendingUserId();
                 if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                     maybeUnrestrictBuggyApp(pkgName, userId);
                 } else {
@@ -1634,6 +1681,34 @@
         }
     }
 
+    private void evaluateSystemAppException(String packageName, int userId) {
+        if (!mSystemServicesReady) {
+            // The app will be evaluated in initializeDefaultsForSystemApps() when possible.
+            return;
+        }
+        try {
+            PackageInfo pi = mPackageManager.getPackageInfoAsUser(packageName,
+                    PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS,
+                    userId);
+            evaluateSystemAppException(pi);
+        } catch (PackageManager.NameNotFoundException e) {
+            mHeadlessSystemApps.remove(packageName);
+        }
+    }
+
+    private void evaluateSystemAppException(@Nullable PackageInfo pkgInfo) {
+        if (pkgInfo.applicationInfo != null && pkgInfo.applicationInfo.isSystemApp()) {
+            synchronized (mAppIdleLock) {
+                if (pkgInfo.activities == null || pkgInfo.activities.length == 0) {
+                    // Headless system app.
+                    mHeadlessSystemApps.put(pkgInfo.packageName, true);
+                } else {
+                    mHeadlessSystemApps.remove(pkgInfo.packageName);
+                }
+            }
+        }
+    }
+
     @Override
     public void initializeDefaultsForSystemApps(int userId) {
         if (!mSystemServicesReady) {
@@ -1645,7 +1720,7 @@
                 + "appIdleEnabled=" + mAppIdleEnabled);
         final long elapsedRealtime = mInjector.elapsedRealtime();
         List<PackageInfo> packages = mPackageManager.getInstalledPackagesAsUser(
-                PackageManager.MATCH_DISABLED_COMPONENTS,
+                PackageManager.GET_ACTIVITIES | PackageManager.MATCH_DISABLED_COMPONENTS,
                 userId);
         final int packageCount = packages.size();
         synchronized (mAppIdleLock) {
@@ -1658,6 +1733,8 @@
                     mAppIdleHistory.reportUsage(packageName, userId, STANDBY_BUCKET_ACTIVE,
                             REASON_SUB_USAGE_SYSTEM_UPDATE, 0,
                             elapsedRealtime + mSystemUpdateUsageTimeoutMillis);
+
+                    evaluateSystemAppException(pi);
                 }
             }
             // Immediately persist defaults to disk
diff --git a/apex/media/framework/java/android/media/MediaParser.java b/apex/media/framework/java/android/media/MediaParser.java
index c3adf60..c1011ec 100644
--- a/apex/media/framework/java/android/media/MediaParser.java
+++ b/apex/media/framework/java/android/media/MediaParser.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.StringDef;
 import android.media.MediaCodec.CryptoInfo;
+import android.os.Build;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Pair;
@@ -467,7 +468,24 @@
     public @interface SampleFlags {}
     /** Indicates that the sample holds a synchronization sample. */
     public static final int SAMPLE_FLAG_KEY_FRAME = MediaCodec.BUFFER_FLAG_KEY_FRAME;
-    /** Indicates that the sample has supplemental data. */
+    /**
+     * Indicates that the sample has supplemental data.
+     *
+     * <p>Samples will not have this flag set unless the {@code
+     * "android.media.mediaparser.includeSupplementalData"} parameter is set to {@code true} via
+     * {@link #setParameter}.
+     *
+     * <p>Samples with supplemental data have the following sample data format:
+     *
+     * <ul>
+     *   <li>If the {@code "android.media.mediaparser.inBandCryptoInfo"} parameter is set, all
+     *       encryption information.
+     *   <li>(4 bytes) {@code sample_data_size}: The size of the actual sample data, not including
+     *       supplemental data or encryption information.
+     *   <li>({@code sample_data_size} bytes): The media sample data.
+     *   <li>(remaining bytes) The supplemental data.
+     * </ul>
+     */
     public static final int SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA = 1 << 28;
     /** Indicates that the sample is known to contain the last media sample of the stream. */
     public static final int SAMPLE_FLAG_LAST_SAMPLE = 1 << 29;
@@ -578,7 +596,9 @@
                 PARAMETER_TS_IGNORE_AVC_STREAM,
                 PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM,
                 PARAMETER_TS_DETECT_ACCESS_UNITS,
-                PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS
+                PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS,
+                PARAMETER_IN_BAND_CRYPTO_INFO,
+                PARAMETER_INCLUDE_SUPPLEMENTAL_DATA
             })
     public @interface ParameterName {}
 
@@ -740,6 +760,16 @@
     public static final String PARAMETER_IN_BAND_CRYPTO_INFO =
             "android.media.mediaparser.inBandCryptoInfo";
 
+    /**
+     * Sets whether supplemental data should be included as part of the sample data. {@code boolean}
+     * expected. Default value is {@code false}. See {@link #SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA} for
+     * information about the sample data format.
+     *
+     * @hide
+     */
+    public static final String PARAMETER_INCLUDE_SUPPLEMENTAL_DATA =
+            "android.media.mediaparser.includeSupplementalData";
+
     // Private constants.
 
     private static final String TAG = "MediaParser";
@@ -899,6 +929,7 @@
     private final ParsableByteArrayAdapter mScratchParsableByteArrayAdapter;
     @Nullable private final Constructor<DrmInitData.SchemeInitData> mSchemeInitDataConstructor;
     private boolean mInBandCryptoInfo;
+    private boolean mIncludeSupplementalData;
     private String mParserName;
     private Extractor mExtractor;
     private ExtractorInput mExtractorInput;
@@ -949,6 +980,9 @@
         if (PARAMETER_IN_BAND_CRYPTO_INFO.equals(parameterName)) {
             mInBandCryptoInfo = (boolean) value;
         }
+        if (PARAMETER_INCLUDE_SUPPLEMENTAL_DATA.equals(parameterName)) {
+            mIncludeSupplementalData = (boolean) value;
+        }
         mParserParameters.put(parameterName, value);
         return this;
     }
@@ -1099,6 +1133,9 @@
     // Private methods.
 
     private MediaParser(OutputConsumer outputConsumer, boolean sniff, String... parserNamesPool) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            throw new UnsupportedOperationException("Android version must be R or greater.");
+        }
         mParserParameters = new HashMap<>();
         mOutputConsumer = outputConsumer;
         mParserNamesPool = parserNamesPool;
@@ -1330,6 +1367,7 @@
         private int mEncryptionVectorSize;
         private boolean mHasSubsampleEncryptionData;
         private CryptoInfo.Pattern mEncryptionPattern;
+        private int mSkippedSupplementalDataBytes;
 
         private TrackOutputAdapter(int trackIndex) {
             mTrackIndex = trackIndex;
@@ -1419,6 +1457,10 @@
                             throw new IllegalStateException();
                     }
                 }
+            } else if (sampleDataPart == SAMPLE_DATA_PART_SUPPLEMENTAL
+                    && !mIncludeSupplementalData) {
+                mSkippedSupplementalDataBytes += length;
+                data.skipBytes(length);
             } else {
                 outputSampleData(data, length);
             }
@@ -1427,6 +1469,8 @@
         @Override
         public void sampleMetadata(
                 long timeUs, int flags, int size, int offset, @Nullable CryptoData cryptoData) {
+            size -= mSkippedSupplementalDataBytes;
+            mSkippedSupplementalDataBytes = 0;
             mOutputConsumer.onSampleCompleted(
                     mTrackIndex,
                     timeUs,
@@ -1686,13 +1730,13 @@
         }
     }
 
-    private static int getMediaParserFlags(int flags) {
+    private int getMediaParserFlags(int flags) {
         @SampleFlags int result = 0;
         result |= (flags & C.BUFFER_FLAG_ENCRYPTED) != 0 ? SAMPLE_FLAG_ENCRYPTED : 0;
         result |= (flags & C.BUFFER_FLAG_KEY_FRAME) != 0 ? SAMPLE_FLAG_KEY_FRAME : 0;
         result |= (flags & C.BUFFER_FLAG_DECODE_ONLY) != 0 ? SAMPLE_FLAG_DECODE_ONLY : 0;
         result |=
-                (flags & C.BUFFER_FLAG_HAS_SUPPLEMENTAL_DATA) != 0
+                (flags & C.BUFFER_FLAG_HAS_SUPPLEMENTAL_DATA) != 0 && mIncludeSupplementalData
                         ? SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA
                         : 0;
         result |= (flags & C.BUFFER_FLAG_LAST_SAMPLE) != 0 ? SAMPLE_FLAG_LAST_SAMPLE : 0;
@@ -1755,6 +1799,7 @@
         expectedTypeByParameterName.put(PARAMETER_TS_DETECT_ACCESS_UNITS, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS, Boolean.class);
         expectedTypeByParameterName.put(PARAMETER_IN_BAND_CRYPTO_INFO, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_INCLUDE_SUPPLEMENTAL_DATA, Boolean.class);
         EXPECTED_TYPE_BY_PARAMETER_NAME = Collections.unmodifiableMap(expectedTypeByParameterName);
     }
 }
diff --git a/apex/sdkextensions/Android.bp b/apex/sdkextensions/Android.bp
index dbb5bd3d..fdb078e 100644
--- a/apex/sdkextensions/Android.bp
+++ b/apex/sdkextensions/Android.bp
@@ -39,7 +39,7 @@
 
 sdk {
     name: "sdkextensions-sdk",
-    java_header_libs: [ "framework-sdkextensions-stubs-systemapi" ],
+    java_sdk_libs: [ "framework-sdkextensions" ],
 }
 
 apex_key {
diff --git a/apex/sdkextensions/framework/Android.bp b/apex/sdkextensions/framework/Android.bp
index 14e23ed..b8aad7d 100644
--- a/apex/sdkextensions/framework/Android.bp
+++ b/apex/sdkextensions/framework/Android.bp
@@ -25,14 +25,18 @@
     visibility: [ "//frameworks/base" ] // For the "global" stubs.
 }
 
-java_library {
+java_sdk_library {
     name: "framework-sdkextensions",
     srcs: [ ":framework-sdkextensions-sources" ],
-    sdk_version: "system_current",
-    libs: [ "framework-annotations-lib" ],
+    defaults: ["framework-module-defaults"],
+
+    // TODO(b/155480189) - Remove naming_scheme once references have been resolved.
+    // Temporary java_sdk_library component naming scheme to use to ease the transition from separate
+    // modules to java_sdk_library.
+    naming_scheme: "framework-modules",
+
     permitted_packages: [ "android.os.ext" ],
     installable: true,
-    plugins: ["java_api_finder"],
     visibility: [
         "//frameworks/base/apex/sdkextensions",
         "//frameworks/base/apex/sdkextensions/testing",
@@ -43,102 +47,3 @@
         "test_com.android.sdkext",
     ],
 }
-
-stubs_defaults {
-    name: "framework-sdkextensions-stubs-defaults",
-    srcs: [ ":framework-sdkextensions-sources" ],
-    libs: [ "framework-annotations-lib" ],
-    dist: { dest: "framework-sdkextensions.txt" },
-}
-
-droidstubs {
-    name: "framework-sdkextensions-stubs-srcs-publicapi",
-    defaults: [
-        "framework-module-stubs-defaults-publicapi",
-        "framework-sdkextensions-stubs-defaults",
-    ],
-    check_api: {
-        last_released: {
-            api_file: ":framework-sdkextensions.api.public.latest",
-            removed_api_file: ":framework-sdkextensions-removed.api.public.latest",
-        },
-        api_lint: {
-            new_since: ":framework-sdkextensions.api.public.latest",
-        },
-    },
-}
-
-droidstubs {
-    name: "framework-sdkextensions-stubs-srcs-systemapi",
-    defaults: [
-        "framework-module-stubs-defaults-systemapi",
-        "framework-sdkextensions-stubs-defaults",
-    ],
-    check_api: {
-        last_released: {
-            api_file: ":framework-sdkextensions.api.system.latest",
-            removed_api_file: ":framework-sdkextensions-removed.api.system.latest",
-        },
-        api_lint: {
-            new_since: ":framework-sdkextensions.api.system.latest",
-        },
-    },
-}
-
-droidstubs {
-    name: "framework-sdkextensions-api-module_libs_api",
-    defaults: [
-        "framework-module-api-defaults-module_libs_api",
-        "framework-sdkextensions-stubs-defaults",
-    ],
-    check_api: {
-        last_released: {
-            api_file: ":framework-sdkextensions.api.module-lib.latest",
-            removed_api_file: ":framework-sdkextensions-removed.api.module-lib.latest",
-        },
-        api_lint: {
-            new_since: ":framework-sdkextensions.api.module-lib.latest",
-        },
-    },
-}
-
-droidstubs {
-    name: "framework-sdkextensions-stubs-srcs-module_libs_api",
-    defaults: [
-        "framework-module-stubs-defaults-module_libs_api",
-        "framework-sdkextensions-stubs-defaults",
-    ],
-}
-
-java_library {
-    name: "framework-sdkextensions-stubs-publicapi",
-    srcs: [":framework-sdkextensions-stubs-srcs-publicapi"],
-    defaults: ["framework-module-stubs-lib-defaults-publicapi"],
-    visibility: [
-        "//frameworks/base", // Framework
-        "//frameworks/base/apex/sdkextensions", // sdkextensions SDK
-    ],
-    dist: { dest: "framework-sdkextensions.jar" },
-}
-
-java_library {
-    name: "framework-sdkextensions-stubs-systemapi",
-    srcs: [":framework-sdkextensions-stubs-srcs-systemapi"],
-    defaults: ["framework-module-stubs-lib-defaults-systemapi"],
-    visibility: [
-        "//frameworks/base", // Framework
-        "//frameworks/base/apex/sdkextensions", // sdkextensions SDK
-    ],
-    dist: { dest: "framework-sdkextensions.jar" },
-}
-
-java_library {
-    name: "framework-sdkextensions-stubs-module_libs_api",
-    srcs: [":framework-sdkextensions-stubs-srcs-module_libs_api"],
-    defaults: ["framework-module-stubs-lib-defaults-module_libs_api"],
-    visibility: [
-        "//frameworks/base", // Framework
-        "//frameworks/base/apex/sdkextensions", // sdkextensions SDK
-    ],
-    dist: { dest: "framework-sdkextensions.jar" },
-}
diff --git a/api/current.txt b/api/current.txt
index 41a74cf..952ccda 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -12097,6 +12097,7 @@
     field public static final String FEATURE_COMPANION_DEVICE_SETUP = "android.software.companion_device_setup";
     field public static final String FEATURE_CONNECTION_SERVICE = "android.software.connectionservice";
     field public static final String FEATURE_CONSUMER_IR = "android.hardware.consumerir";
+    field public static final String FEATURE_CONTROLS = "android.software.controls";
     field public static final String FEATURE_DEVICE_ADMIN = "android.software.device_admin";
     field public static final String FEATURE_EMBEDDED = "android.hardware.type.embedded";
     field public static final String FEATURE_ETHERNET = "android.hardware.ethernet";
diff --git a/api/test-current.txt b/api/test-current.txt
index 46049bd..5dc7bdb 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1811,6 +1811,7 @@
   }
 
   public class ConnectivityManager {
+    method @RequiresPermission(anyOf={"android.permission.MANAGE_TEST_NETWORKS", android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
     field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
     field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index 9e6d0a2..dc16125 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -351,9 +351,9 @@
 
 Status IncidentService::registerSection(const int id, const String16& name16,
         const sp<IIncidentDumpCallback>& callback) {
-    const char* name = String8(name16).c_str();
+    const String8 name = String8(name16);
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    ALOGI("Uid %d registers section %d '%s'", callingUid, id, name);
+    ALOGI("Uid %d registers section %d '%s'", callingUid, id, name.c_str());
     if (callback == nullptr) {
         return Status::fromExceptionCode(Status::EX_NULL_POINTER);
     }
@@ -363,11 +363,11 @@
                 ALOGW("Error registering section %d: calling uid does not match", id);
                 return Status::fromExceptionCode(Status::EX_SECURITY);
             }
-            mRegisteredSections.at(i) = new BringYourOwnSection(id, name, callingUid, callback);
+            mRegisteredSections.at(i) = new BringYourOwnSection(id, name.c_str(), callingUid, callback);
             return Status::ok();
         }
     }
-    mRegisteredSections.push_back(new BringYourOwnSection(id, name, callingUid, callback));
+    mRegisteredSections.push_back(new BringYourOwnSection(id, name.c_str(), callingUid, callback));
     return Status::ok();
 }
 
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 114cbb8..61e5eb0 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -876,7 +876,9 @@
 
 status_t BringYourOwnSection::BlockingCall(unique_fd& pipeWriteFd) const {
     android::os::ParcelFileDescriptor pfd(std::move(pipeWriteFd));
-    mCallback->onDumpSection(pfd);
+    if(mCallback != nullptr) {
+        mCallback->onDumpSection(pfd);
+    }
     return NO_ERROR;
 }
 
diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h
index 2ce45ed..bc4909d 100644
--- a/cmds/incidentd/src/Section.h
+++ b/cmds/incidentd/src/Section.h
@@ -207,7 +207,7 @@
     virtual status_t BlockingCall(unique_fd& pipeWriteFd) const;
 
 private:
-    const sp<IIncidentDumpCallback>& mCallback;
+    const sp<IIncidentDumpCallback> mCallback;
 };
 
 
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index a65f5f7..4ffa040 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -826,7 +826,7 @@
         uids.push_back(AID_SYSTEM);
     }
     vector<shared_ptr<LogEvent>> stats;
-    if (mPullerManager->Pull(s, uids, &stats)) {
+    if (mPullerManager->Pull(s, uids, getElapsedRealtimeNs(), &stats)) {
         for (const auto& it : stats) {
             dprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str());
         }
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 1d9f20e..f00a35d 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -447,7 +447,7 @@
     }
 
     // Pulled events will start at field 10000.
-    // Next: 10080
+    // Next: 10082
     oneof pulled {
         WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"];
         WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"];
@@ -538,6 +538,7 @@
         SimSlotState sim_slot_state = 10078 [(module) = "telephony"];
         SupportedRadioAccessFamily supported_radio_access_family = 10079 [(module) = "telephony"];
         SettingSnapshot setting_snapshot = 10080 [(module) = "framework"];
+        DisplayWakeReason display_wake_reason = 10081 [(module) = "framework"];
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP.
@@ -1256,7 +1257,8 @@
  */
 message ChargingStateChanged {
     // State of the battery, from frameworks/base/core/proto/android/os/enums.proto.
-    optional android.os.BatteryStatusEnum state = 1;
+    optional android.os.BatteryStatusEnum state = 1
+            [(state_field_option).exclusive_state = true, (state_field_option).nested = false];
 }
 
 /**
@@ -9460,9 +9462,6 @@
 
     /** The ID of the entry that the users actioned on */
     optional android.app.tvsettings.ItemId item_id = 2;
-
-    /** Additional information (e.g., navigation direction on page focused) */
-    optional string additional_info = 3;
 }
 
 /**
@@ -9634,6 +9633,17 @@
     optional android.stats.accessibility.ServiceStatus service_status = 2;
 }
 
+message DisplayWakeReason {
+    // Wake_up_reason code
+    // If LOWORD(wake_up_reason) = 0
+    //     reference to HIWORD(wake_up_reason) PowerManager.WAKE_REASON_XXX
+    //     else reference wake_up_reason to
+    //     frameworks/base/services/core/java/com/android/server/power/Notifier.java#DispWakeupReason
+    optional int32 wake_up_reason = 1;
+    // Count of wake up by reason
+    optional int32 wake_times = 2;
+}
+
 /**
  * Logs app usage events.
  */
diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp
index 829a603..9df4d1f 100644
--- a/cmds/statsd/src/external/StatsPuller.cpp
+++ b/cmds/statsd/src/external/StatsPuller.cpp
@@ -38,14 +38,16 @@
       mPullTimeoutNs(pullTimeoutNs),
       mCoolDownNs(coolDownNs),
       mAdditiveFields(additiveFields),
-      mLastPullTimeNs(0) {
+      mLastPullTimeNs(0),
+      mLastEventTimeNs(0) {
 }
 
-bool StatsPuller::Pull(std::vector<std::shared_ptr<LogEvent>>* data) {
+bool StatsPuller::Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data) {
     lock_guard<std::mutex> lock(mLock);
     int64_t elapsedTimeNs = getElapsedRealtimeNs();
     StatsdStats::getInstance().notePull(mTagId);
-    const bool shouldUseCache = elapsedTimeNs - mLastPullTimeNs < mCoolDownNs;
+    const bool shouldUseCache =
+            (mLastEventTimeNs == eventTimeNs) || (elapsedTimeNs - mLastPullTimeNs < mCoolDownNs);
     if (shouldUseCache) {
         if (mHasGoodData) {
             (*data) = mCachedData;
@@ -54,13 +56,13 @@
         }
         return mHasGoodData;
     }
-
     if (mLastPullTimeNs > 0) {
         StatsdStats::getInstance().updateMinPullIntervalSec(
                 mTagId, (elapsedTimeNs - mLastPullTimeNs) / NS_PER_SEC);
     }
     mCachedData.clear();
     mLastPullTimeNs = elapsedTimeNs;
+    mLastEventTimeNs = eventTimeNs;
     mHasGoodData = PullInternal(&mCachedData);
     if (!mHasGoodData) {
         return mHasGoodData;
@@ -70,7 +72,7 @@
     const bool pullTimeOut = pullDurationNs > mPullTimeoutNs;
     if (pullTimeOut) {
         // Something went wrong. Discard the data.
-        clearCacheLocked();
+        mCachedData.clear();
         mHasGoodData = false;
         StatsdStats::getInstance().notePullTimeout(mTagId);
         ALOGW("Pull for atom %d exceeds timeout %lld nano seconds.", mTagId,
@@ -104,6 +106,7 @@
     int ret = mCachedData.size();
     mCachedData.clear();
     mLastPullTimeNs = 0;
+    mLastEventTimeNs = 0;
     return ret;
 }
 
diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h
index fee571c..470d15e 100644
--- a/cmds/statsd/src/external/StatsPuller.h
+++ b/cmds/statsd/src/external/StatsPuller.h
@@ -51,7 +51,7 @@
     //   2) pull takes longer than mPullTimeoutNs (intrinsic to puller)
     // If a metric wants to make any change to the data, like timestamps, it
     // should make a copy as this data may be shared with multiple metrics.
-    bool Pull(std::vector<std::shared_ptr<LogEvent>>* data);
+    bool Pull(const int64_t eventTimeNs, std::vector<std::shared_ptr<LogEvent>>* data);
 
     // Clear cache immediately
     int ForceClearCache();
@@ -94,6 +94,11 @@
 
     int64_t mLastPullTimeNs;
 
+    // All pulls happen due to an event (app upgrade, bucket boundary, condition change, etc).
+    // If multiple pulls need to be done at the same event time, we will always use the cache after
+    // the first pull.
+    int64_t mLastEventTimeNs;
+
     // Cache of data from last pull. If next request comes before cool down finishes,
     // cached data will be returned.
     // Cached data is cleared when
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index 1a52eb9..8a9ec74 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -91,20 +91,21 @@
       mPullAtomCallbackDeathRecipient(AIBinder_DeathRecipient_new(pullAtomCallbackDied)) {
 }
 
-bool StatsPullerManager::Pull(int tagId, const ConfigKey& configKey,
+bool StatsPullerManager::Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
                               vector<shared_ptr<LogEvent>>* data, bool useUids) {
     std::lock_guard<std::mutex> _l(mLock);
-    return PullLocked(tagId, configKey, data, useUids);
+    return PullLocked(tagId, configKey, eventTimeNs, data, useUids);
 }
 
-bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids,
+bool StatsPullerManager::Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
                               vector<std::shared_ptr<LogEvent>>* data, bool useUids) {
     std::lock_guard<std::mutex> _l(mLock);
-    return PullLocked(tagId, uids, data, useUids);
+    return PullLocked(tagId, uids, eventTimeNs, data, useUids);
 }
 
 bool StatsPullerManager::PullLocked(int tagId, const ConfigKey& configKey,
-                                    vector<shared_ptr<LogEvent>>* data, bool useUids) {
+                                    const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
+                                    bool useUids) {
     vector<int32_t> uids;
     if (useUids) {
         auto uidProviderIt = mPullUidProviders.find(configKey);
@@ -123,18 +124,19 @@
         }
         uids = pullUidProvider->getPullAtomUids(tagId);
     }
-    return PullLocked(tagId, uids, data, useUids);
+    return PullLocked(tagId, uids, eventTimeNs, data, useUids);
 }
 
 bool StatsPullerManager::PullLocked(int tagId, const vector<int32_t>& uids,
-                                    vector<shared_ptr<LogEvent>>* data, bool useUids) {
+                                    const int64_t eventTimeNs, vector<shared_ptr<LogEvent>>* data,
+                                    bool useUids) {
     VLOG("Initiating pulling %d", tagId);
     if (useUids) {
         for (int32_t uid : uids) {
             PullerKey key = {.atomTag = tagId, .uid = uid};
             auto pullerIt = kAllPullAtomInfo.find(key);
             if (pullerIt != kAllPullAtomInfo.end()) {
-                bool ret = pullerIt->second->Pull(data);
+                bool ret = pullerIt->second->Pull(eventTimeNs, data);
                 VLOG("pulled %zu items", data->size());
                 if (!ret) {
                     StatsdStats::getInstance().notePullFailed(tagId);
@@ -149,7 +151,7 @@
         PullerKey key = {.atomTag = tagId, .uid = -1};
         auto pullerIt = kAllPullAtomInfo.find(key);
         if (pullerIt != kAllPullAtomInfo.end()) {
-            bool ret = pullerIt->second->Pull(data);
+            bool ret = pullerIt->second->Pull(eventTimeNs, data);
             VLOG("pulled %zu items", data->size());
             if (!ret) {
                 StatsdStats::getInstance().notePullFailed(tagId);
@@ -290,7 +292,8 @@
     }
     for (const auto& pullInfo : needToPull) {
         vector<shared_ptr<LogEvent>> data;
-        bool pullSuccess = PullLocked(pullInfo.first->atomTag, pullInfo.first->configKey, &data);
+        bool pullSuccess = PullLocked(pullInfo.first->atomTag, pullInfo.first->configKey,
+                                      elapsedTimeNs, &data);
         if (!pullSuccess) {
             VLOG("pull failed at %lld, will try again later", (long long)elapsedTimeNs);
         }
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 5e18aaa..194a0f5 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -101,11 +101,11 @@
     //      registered for any of the uids for this atom.
     // If the metric wants to make any change to the data, like timestamps, they
     // should make a copy as this data may be shared with multiple metrics.
-    virtual bool Pull(int tagId, const ConfigKey& configKey,
+    virtual bool Pull(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
                       vector<std::shared_ptr<LogEvent>>* data, bool useUids = true);
 
     // Same as above, but directly specify the allowed uids to pull from.
-    virtual bool Pull(int tagId, const vector<int32_t>& uids,
+    virtual bool Pull(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
                       vector<std::shared_ptr<LogEvent>>* data, bool useUids = true);
 
     // Clear pull data cache immediately.
@@ -152,11 +152,11 @@
     // mapping from Config Key to the PullUidProvider for that config
     std::map<ConfigKey, wp<PullUidProvider>> mPullUidProviders;
 
-    bool PullLocked(int tagId, const ConfigKey& configKey, vector<std::shared_ptr<LogEvent>>* data,
-                    bool useUids = true);
+    bool PullLocked(int tagId, const ConfigKey& configKey, const int64_t eventTimeNs,
+                    vector<std::shared_ptr<LogEvent>>* data, bool useUids = true);
 
-    bool PullLocked(int tagId, const vector<int32_t>& uids, vector<std::shared_ptr<LogEvent>>* data,
-                    bool useUids);
+    bool PullLocked(int tagId, const vector<int32_t>& uids, const int64_t eventTimeNs,
+                    vector<std::shared_ptr<LogEvent>>* data, bool useUids);
 
     // locks for data receiver and StatsCompanionService changes
     std::mutex mLock;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index cc4c565..1d4d0b3 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -321,7 +321,7 @@
         return;
     }
     vector<std::shared_ptr<LogEvent>> allData;
-    if (!mPullerManager->Pull(mPullTagId, mConfigKey, &allData)) {
+    if (!mPullerManager->Pull(mPullTagId, mConfigKey, timestampNs, &allData)) {
         ALOGE("Gauge Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
         return;
     }
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index d7ad27b..e8c575a 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -71,6 +71,8 @@
       mLastReportTimeNs(currentTimeNs),
       mLastReportWallClockNs(getWallClockNs()),
       mPullerManager(pullerManager),
+      mWhitelistedAtomIds(config.whitelisted_atom_ids().begin(),
+                          config.whitelisted_atom_ids().end()),
       mShouldPersistHistory(config.persist_locally()) {
     // Init the ttl end timestamp.
     refreshTtl(timeBaseNs);
@@ -366,11 +368,16 @@
 
 
 bool MetricsManager::checkLogCredentials(const LogEvent& event) {
+    // TODO(b/154856835): Remove this check once we get whitelist from the config.
     if (android::util::AtomsInfo::kWhitelistedAtoms.find(event.GetTagId()) !=
       android::util::AtomsInfo::kWhitelistedAtoms.end())
     {
         return true;
     }
+
+    if (mWhitelistedAtomIds.find(event.GetTagId()) != mWhitelistedAtomIds.end()) {
+        return true;
+    }
     std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
     if (mAllowedLogSources.find(event.GetUid()) == mAllowedLogSources.end()) {
         VLOG("log source %d not on the whitelist", event.GetUid());
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index ef03d20..c30532a 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -189,6 +189,8 @@
     // To guard access to mAllowedLogSources
     mutable std::mutex mAllowedLogSourcesMutex;
 
+    const std::set<int32_t> mWhitelistedAtomIds;
+
     // We can pull any atom from these uids.
     std::set<int32_t> mDefaultPullUids;
 
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index e5ec72e..bf636a4 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -508,7 +508,7 @@
 
 void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
     vector<std::shared_ptr<LogEvent>> allData;
-    if (!mPullerManager->Pull(mPullTagId, mConfigKey, &allData)) {
+    if (!mPullerManager->Pull(mPullTagId, mConfigKey, timestampNs, &allData)) {
         ALOGE("Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
         invalidateCurrentBucket(timestampNs, BucketDropReason::PULL_FAILED);
         return;
diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp
index 7b68721..361b161 100644
--- a/cmds/statsd/src/shell/ShellSubscriber.cpp
+++ b/cmds/statsd/src/shell/ShellSubscriber.cpp
@@ -152,6 +152,7 @@
             }
 
             int64_t nowMillis = getElapsedRealtimeMillis();
+            int64_t nowNanos = getElapsedRealtimeNs();
             for (PullInfo& pullInfo : mSubscriptionInfo->mPulledInfo) {
                 if (pullInfo.mPrevPullElapsedRealtimeMs + pullInfo.mInterval >= nowMillis) {
                     continue;
@@ -161,7 +162,7 @@
                 getUidsForPullAtom(&uids, pullInfo);
 
                 vector<std::shared_ptr<LogEvent>> data;
-                mPullerMgr->Pull(pullInfo.mPullerMatcher.atom_id(), uids, &data);
+                mPullerMgr->Pull(pullInfo.mPullerMatcher.atom_id(), uids, nowNanos, &data);
                 VLOG("Pulled %zu atoms with id %d", data.size(), pullInfo.mPullerMatcher.atom_id());
                 writePulledAtomsLocked(data, pullInfo.mPullerMatcher);
 
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index c7407bd..7c0057d 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -489,6 +489,8 @@
 
   repeated PullAtomPackages pull_atom_packages = 23;
 
+  repeated int32 whitelisted_atom_ids = 24;
+
   // Field number 1000 is reserved for later use.
   reserved 1000;
 }
diff --git a/cmds/statsd/tests/AlarmMonitor_test.cpp b/cmds/statsd/tests/AlarmMonitor_test.cpp
index edbf8b5..1dc9795 100644
--- a/cmds/statsd/tests/AlarmMonitor_test.cpp
+++ b/cmds/statsd/tests/AlarmMonitor_test.cpp
@@ -49,19 +49,19 @@
     EXPECT_TRUE(set.empty());
 
     set = am.popSoonerThan(30);
-    EXPECT_EQ(4u, set.size());
+    ASSERT_EQ(4u, set.size());
     EXPECT_EQ(1u, set.count(a));
     EXPECT_EQ(1u, set.count(b));
     EXPECT_EQ(1u, set.count(c));
     EXPECT_EQ(1u, set.count(d));
 
     set = am.popSoonerThan(60);
-    EXPECT_EQ(2u, set.size());
+    ASSERT_EQ(2u, set.size());
     EXPECT_EQ(1u, set.count(e));
     EXPECT_EQ(1u, set.count(f));
 
     set = am.popSoonerThan(80);
-    EXPECT_EQ(0u, set.size());
+    ASSERT_EQ(0u, set.size());
 }
 
 #else
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
index f5ba8fd..23f8ca4 100644
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -74,7 +74,7 @@
     vector<Matcher> output;
     translateFieldMatcher(matcher1, &output);
 
-    EXPECT_EQ((size_t)1, output.size());
+    ASSERT_EQ((size_t)1, output.size());
 
     const auto& matcher12 = output[0];
     EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
@@ -95,7 +95,7 @@
     vector<Matcher> output;
     translateFieldMatcher(matcher1, &output);
 
-    EXPECT_EQ((size_t)1, output.size());
+    ASSERT_EQ((size_t)1, output.size());
 
     const auto& matcher12 = output[0];
     EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
@@ -128,7 +128,7 @@
 
     filterValues(matchers, event.getValues(), &output);
 
-    EXPECT_EQ((size_t)7, output.getValues().size());
+    ASSERT_EQ((size_t)7, output.getValues().size());
     EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
     EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
     EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
@@ -218,12 +218,12 @@
     translateFieldMatcher(whatMatcher, &link.metricFields);
     translateFieldMatcher(conditionMatcher, &link.conditionFields);
 
-    EXPECT_EQ((size_t)1, link.metricFields.size());
+    ASSERT_EQ((size_t)1, link.metricFields.size());
     EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
     EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
     EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
 
-    EXPECT_EQ((size_t)1, link.conditionFields.size());
+    ASSERT_EQ((size_t)1, link.conditionFields.size());
     EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
     EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
     EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
@@ -264,15 +264,15 @@
         }
 
         DimensionsValue result;
-        EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
+        ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
 
         EXPECT_EQ(10, result.field());
         EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
-        EXPECT_EQ(3, result.value_tuple().dimensions_value_size());
+        ASSERT_EQ(3, result.value_tuple().dimensions_value_size());
 
         const auto& dim1 = result.value_tuple().dimensions_value(0);
         EXPECT_EQ(2, dim1.field());
-        EXPECT_EQ(2, dim1.value_tuple().dimensions_value_size());
+        ASSERT_EQ(2, dim1.value_tuple().dimensions_value_size());
 
         const auto& dim11 = dim1.value_tuple().dimensions_value(0);
         EXPECT_EQ(1, dim11.field());
@@ -285,7 +285,7 @@
 
         const auto& dim3 = result.value_tuple().dimensions_value(2);
         EXPECT_EQ(6, dim3.field());
-        EXPECT_EQ(1, dim3.value_tuple().dimensions_value_size());
+        ASSERT_EQ(1, dim3.value_tuple().dimensions_value_size());
         const auto& dim31 = dim3.value_tuple().dimensions_value(0);
         EXPECT_EQ(2, dim31.field());
     }
@@ -356,14 +356,14 @@
     }
 
     DimensionsValue result;
-    EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
+    ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
     EXPECT_EQ(10, result.field());
     EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
-    EXPECT_EQ(2, result.value_tuple().dimensions_value_size());
+    ASSERT_EQ(2, result.value_tuple().dimensions_value_size());
 
     const auto& dim1 = result.value_tuple().dimensions_value(0);
     EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
-    EXPECT_EQ(3, dim1.value_tuple().dimensions_value_size());
+    ASSERT_EQ(3, dim1.value_tuple().dimensions_value_size());
 
     const auto& dim11 = dim1.value_tuple().dimensions_value(0);
     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
@@ -418,8 +418,8 @@
     }
 
     DimensionsValueTuple result;
-    EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
-    EXPECT_EQ(4, result.dimensions_value_size());
+    ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
+    ASSERT_EQ(4, result.dimensions_value_size());
 
     const auto& dim1 = result.dimensions_value(0);
     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim1.value_case());
@@ -460,10 +460,10 @@
     }
 
     Atom result;
-    EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
+    ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
     EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
     const auto& atom = result.ble_scan_result_received();
-    EXPECT_EQ(2, atom.attribution_node_size());
+    ASSERT_EQ(2, atom.attribution_node_size());
     EXPECT_EQ(1111, atom.attribution_node(0).uid());
     EXPECT_EQ("location1", atom.attribution_node(0).tag());
     EXPECT_EQ(2222, atom.attribution_node(1).uid());
@@ -488,7 +488,7 @@
 
     vector<Matcher> matchers1;
     translateFieldMatcher(matcher1, &matchers1);
-    EXPECT_EQ(2, matchers1.size());
+    ASSERT_EQ(2, matchers1.size());
 
     // Initialize second set of matchers
     FieldMatcher matcher2;
@@ -501,7 +501,7 @@
 
     vector<Matcher> matchers2;
     translateFieldMatcher(matcher2, &matchers2);
-    EXPECT_EQ(1, matchers2.size());
+    ASSERT_EQ(1, matchers2.size());
 
     EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
     EXPECT_TRUE(subsetDimensions(matchers2, matchers1));
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index 00f336a..5c170c0 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -98,7 +98,7 @@
     EXPECT_FALSE(logEvent.hasAttributionChain());
 
     const vector<FieldValue>& values = logEvent.getValues();
-    EXPECT_EQ(4, values.size());
+    ASSERT_EQ(4, values.size());
 
     const FieldValue& int32Item = values[0];
     Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
@@ -147,7 +147,7 @@
     EXPECT_FALSE(logEvent.hasAttributionChain());
 
     const vector<FieldValue>& values = logEvent.getValues();
-    EXPECT_EQ(2, values.size());
+    ASSERT_EQ(2, values.size());
 
     const FieldValue& stringItem = values[0];
     Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
@@ -184,7 +184,7 @@
     EXPECT_FALSE(logEvent.hasAttributionChain());
 
     const vector<FieldValue>& values = logEvent.getValues();
-    EXPECT_EQ(1, values.size());
+    ASSERT_EQ(1, values.size());
 
     const FieldValue& item = values[0];
     Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
@@ -213,7 +213,7 @@
     EXPECT_EQ(1001, logEvent.GetPid());
 
     const vector<FieldValue>& values = logEvent.getValues();
-    EXPECT_EQ(1, values.size());
+    ASSERT_EQ(1, values.size());
 
     const FieldValue& item = values[0];
     Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
@@ -249,7 +249,7 @@
     EXPECT_EQ(1001, logEvent.GetPid());
 
     const vector<FieldValue>& values = logEvent.getValues();
-    EXPECT_EQ(4, values.size());  // 2 per attribution node
+    ASSERT_EQ(4, values.size());  // 2 per attribution node
 
     std::pair<int, int> attrIndexRange;
     EXPECT_TRUE(logEvent.hasAttributionChain(&attrIndexRange));
@@ -290,7 +290,7 @@
     createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_IS_UID, true);
 
     const vector<FieldValue>& values = event.getValues();
-    EXPECT_EQ(values.size(), 1);
+    ASSERT_EQ(values.size(), 1);
     EXPECT_EQ(event.getUidFieldIndex(), 0);
 }
 
@@ -299,7 +299,7 @@
     createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_STATE_NESTED, true);
 
     const vector<FieldValue>& values = event.getValues();
-    EXPECT_EQ(values.size(), 1);
+    ASSERT_EQ(values.size(), 1);
     EXPECT_TRUE(values[0].mAnnotations.isNested());
 }
 
@@ -308,7 +308,7 @@
     createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_PRIMARY_FIELD, true);
 
     const vector<FieldValue>& values = event.getValues();
-    EXPECT_EQ(values.size(), 1);
+    ASSERT_EQ(values.size(), 1);
     EXPECT_TRUE(values[0].mAnnotations.isPrimaryField());
 }
 
@@ -317,7 +317,7 @@
     createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_EXCLUSIVE_STATE, true);
 
     const vector<FieldValue>& values = event.getValues();
-    EXPECT_EQ(values.size(), 1);
+    ASSERT_EQ(values.size(), 1);
     EXPECT_TRUE(values[0].mAnnotations.isExclusiveState());
 }
 
@@ -349,7 +349,7 @@
 
     // Check annotation
     const vector<FieldValue>& values = logEvent.getValues();
-    EXPECT_EQ(values.size(), numInts + 4);
+    ASSERT_EQ(values.size(), numInts + 4);
     EXPECT_TRUE(values[firstUidInChainIndex].mAnnotations.isPrimaryField());
 }
 
@@ -359,7 +359,7 @@
     createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_TRIGGER_STATE_RESET, resetState);
 
     const vector<FieldValue>& values = event.getValues();
-    EXPECT_EQ(values.size(), 1);
+    ASSERT_EQ(values.size(), 1);
     EXPECT_EQ(event.getResetState(), resetState);
 }
 
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index a44541d..5c54392 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -309,10 +309,10 @@
                                  activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
                                  alertTrackerMap, metricsWithActivation,
                                  noReportMetricIds));
-    EXPECT_EQ(1u, allMetricProducers.size());
-    EXPECT_EQ(1u, allAnomalyTrackers.size());
-    EXPECT_EQ(1u, noReportMetricIds.size());
-    EXPECT_EQ(1u, alertTrackerMap.size());
+    ASSERT_EQ(1u, allMetricProducers.size());
+    ASSERT_EQ(1u, allAnomalyTrackers.size());
+    ASSERT_EQ(1u, noReportMetricIds.size());
+    ASSERT_EQ(1u, alertTrackerMap.size());
     EXPECT_NE(alertTrackerMap.find(kAlertId), alertTrackerMap.end());
     EXPECT_EQ(alertTrackerMap.find(kAlertId)->second, 0);
 }
@@ -591,6 +591,30 @@
     EXPECT_TRUE(isSubset(defaultPullUids, set<int32_t>(atom3Uids.begin(), atom3Uids.end())));
 }
 
+TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) {
+    sp<UidMap> uidMap;
+    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
+    sp<AlarmMonitor> anomalyAlarmMonitor;
+    sp<AlarmMonitor> periodicAlarmMonitor;
+
+    StatsdConfig config = buildGoodConfig();
+    config.add_whitelisted_atom_ids(3);
+    config.add_whitelisted_atom_ids(4);
+
+    MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
+                                  pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
+
+    LogEvent event(0 /* uid */, 0 /* pid */);
+    CreateNoValuesLogEvent(&event, 10 /* atom id */, 0 /* timestamp */);
+    EXPECT_FALSE(metricsManager.checkLogCredentials(event));
+
+    CreateNoValuesLogEvent(&event, 3 /* atom id */, 0 /* timestamp */);
+    EXPECT_TRUE(metricsManager.checkLogCredentials(event));
+
+    CreateNoValuesLogEvent(&event, 4 /* atom id */, 0 /* timestamp */);
+    EXPECT_TRUE(metricsManager.checkLogCredentials(event));
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index e6144c5..076f327 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -187,7 +187,7 @@
     EXPECT_TRUE(output.reports_size() > 0);
     auto uidmap = output.reports(0).uid_map();
     EXPECT_TRUE(uidmap.snapshots_size() > 0);
-    EXPECT_EQ(2, uidmap.snapshots(0).package_info_size());
+    ASSERT_EQ(2, uidmap.snapshots(0).package_info_size());
 }
 
 TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) {
@@ -248,7 +248,7 @@
     output.ParseFromArray(bytes.data(), bytes.size());
     EXPECT_TRUE(output.reports_size() > 0);
     auto report = output.reports(0);
-    EXPECT_EQ(1, report.annotation_size());
+    ASSERT_EQ(1, report.annotation_size());
     EXPECT_EQ(1, report.annotation(0).field_int64());
     EXPECT_EQ(2, report.annotation(0).field_int32());
 }
@@ -281,16 +281,16 @@
     processor->onDumpReport(cfgKey, 3, true, false /* Do NOT erase data. */, ADB_DUMP, FAST,
                             &bytes);
     output.ParseFromArray(bytes.data(), bytes.size());
-    EXPECT_EQ(output.reports_size(), 1);
-    EXPECT_EQ(output.reports(0).metrics_size(), 1);
-    EXPECT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
+    ASSERT_EQ(output.reports_size(), 1);
+    ASSERT_EQ(output.reports(0).metrics_size(), 1);
+    ASSERT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
 
     // Dump report WITH erasing data. There should be data since we didn't previously erase it.
     processor->onDumpReport(cfgKey, 4, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes);
     output.ParseFromArray(bytes.data(), bytes.size());
-    EXPECT_EQ(output.reports_size(), 1);
-    EXPECT_EQ(output.reports(0).metrics_size(), 1);
-    EXPECT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
+    ASSERT_EQ(output.reports_size(), 1);
+    ASSERT_EQ(output.reports(0).metrics_size(), 1);
+    ASSERT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1);
 
     // Dump report again. There should be no data since we erased it.
     processor->onDumpReport(cfgKey, 5, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes);
@@ -438,7 +438,7 @@
     processor.OnConfigUpdated(2, cfgKey2, config2);
     processor.OnConfigUpdated(3, cfgKey3, config3);
 
-    EXPECT_EQ(3, processor.mMetricsManagers.size());
+    ASSERT_EQ(3, processor.mMetricsManagers.size());
 
     // Expect the first config and both metrics in it to be active.
     auto it = processor.mMetricsManagers.find(cfgKey1);
@@ -535,7 +535,7 @@
 
     // A broadcast should have happened, and all 3 configs should be active in the broadcast.
     EXPECT_EQ(broadcastCount, 1);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 3);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 3);
     EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId1) !=
                 activeConfigsBroadcast.end());
     EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId2) !=
@@ -560,7 +560,7 @@
     processor2->OnConfigUpdated(timeBase2, cfgKey2, config2);
     processor2->OnConfigUpdated(timeBase2, cfgKey3, config3);
 
-    EXPECT_EQ(3, processor2->mMetricsManagers.size());
+    ASSERT_EQ(3, processor2->mMetricsManagers.size());
 
     // First config and both metrics are active.
     it = processor2->mMetricsManagers.find(cfgKey1);
@@ -619,7 +619,7 @@
     EXPECT_TRUE(it != processor2->mMetricsManagers.end());
     auto& metricsManager1003 = it->second;
     EXPECT_FALSE(metricsManager1003->isActive());
-    EXPECT_EQ(2, metricsManager1003->mAllMetricProducers.size());
+    ASSERT_EQ(2, metricsManager1003->mAllMetricProducers.size());
 
     metricIt = metricsManager1003->mAllMetricProducers.begin();
     for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
@@ -702,7 +702,7 @@
     sp<StatsLogProcessor> processor =
             CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
 
-    EXPECT_EQ(1, processor->mMetricsManagers.size());
+    ASSERT_EQ(1, processor->mMetricsManagers.size());
     auto it = processor->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor->mMetricsManagers.end());
     auto& metricsManager1 = it->second;
@@ -752,7 +752,7 @@
     sp<StatsLogProcessor> processor2 =
             CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
 
-    EXPECT_EQ(1, processor2->mMetricsManagers.size());
+    ASSERT_EQ(1, processor2->mMetricsManagers.size());
     it = processor2->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor2->mMetricsManagers.end());
     auto& metricsManager1001 = it->second;
@@ -835,7 +835,7 @@
     // Metric 1 is not active.
     // Metric 2 is active.
     // {{{---------------------------------------------------------------------------
-    EXPECT_EQ(1, processor->mMetricsManagers.size());
+    ASSERT_EQ(1, processor->mMetricsManagers.size());
     auto it = processor->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor->mMetricsManagers.end());
     auto& metricsManager1 = it->second;
@@ -920,7 +920,7 @@
     // Metric 1 is not active.
     // Metric 2 is active.
     // {{{---------------------------------------------------------------------------
-    EXPECT_EQ(1, processor2->mMetricsManagers.size());
+    ASSERT_EQ(1, processor2->mMetricsManagers.size());
     it = processor2->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor2->mMetricsManagers.end());
     auto& metricsManager1001 = it->second;
@@ -1021,7 +1021,7 @@
     // Metric 1 is not active.
     // Metric 2 is active.
     // {{{---------------------------------------------------------------------------
-    EXPECT_EQ(1, processor3->mMetricsManagers.size());
+    ASSERT_EQ(1, processor3->mMetricsManagers.size());
     it = processor3->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor3->mMetricsManagers.end());
     auto& metricsManagerTimeBase3 = it->second;
@@ -1123,7 +1123,7 @@
     // Metric 1 is not active.
     // Metric 2 is active.
     // {{{---------------------------------------------------------------------------
-    EXPECT_EQ(1, processor4->mMetricsManagers.size());
+    ASSERT_EQ(1, processor4->mMetricsManagers.size());
     it = processor4->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor4->mMetricsManagers.end());
     auto& metricsManagerTimeBase4 = it->second;
@@ -1237,13 +1237,13 @@
     // Metric 1 is not active.
     // Metric 2 is active.
     // {{{---------------------------------------------------------------------------
-    EXPECT_EQ(1, processor1->mMetricsManagers.size());
+    ASSERT_EQ(1, processor1->mMetricsManagers.size());
     auto it = processor1->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor1->mMetricsManagers.end());
     auto& metricsManager1 = it->second;
     EXPECT_TRUE(metricsManager1->isActive());
 
-    EXPECT_EQ(metricsManager1->mAllMetricProducers.size(), 2);
+    ASSERT_EQ(metricsManager1->mAllMetricProducers.size(), 2);
     // We assume that the index of a MetricProducer within the mAllMetricProducers
     // array follows the order in which metrics are added to the config.
     auto& metricProducer1_1 = metricsManager1->mAllMetricProducers[0];
@@ -1254,7 +1254,7 @@
     EXPECT_EQ(metricProducer1_2->getMetricId(), metricId2);
     EXPECT_TRUE(metricProducer1_2->isActive());
 
-    EXPECT_EQ(metricProducer1_1->mEventActivationMap.size(), 2);
+    ASSERT_EQ(metricProducer1_1->mEventActivationMap.size(), 2);
     // The key in mEventActivationMap is the index of the associated atom matcher. We assume
     // that matchers are indexed in the order that they are added to the config.
     const auto& activation1_1_1 = metricProducer1_1->mEventActivationMap.at(0);
@@ -1303,13 +1303,13 @@
     // Metric 1 is not active.
     // Metric 2 is active.
     // {{{---------------------------------------------------------------------------
-    EXPECT_EQ(1, processor2->mMetricsManagers.size());
+    ASSERT_EQ(1, processor2->mMetricsManagers.size());
     it = processor2->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor2->mMetricsManagers.end());
     auto& metricsManager2 = it->second;
     EXPECT_TRUE(metricsManager2->isActive());
 
-    EXPECT_EQ(metricsManager2->mAllMetricProducers.size(), 2);
+    ASSERT_EQ(metricsManager2->mAllMetricProducers.size(), 2);
     // We assume that the index of a MetricProducer within the mAllMetricProducers
     // array follows the order in which metrics are added to the config.
     auto& metricProducer2_1 = metricsManager2->mAllMetricProducers[0];
@@ -1320,7 +1320,7 @@
     EXPECT_EQ(metricProducer2_2->getMetricId(), metricId2);
     EXPECT_TRUE(metricProducer2_2->isActive());
 
-    EXPECT_EQ(metricProducer2_1->mEventActivationMap.size(), 2);
+    ASSERT_EQ(metricProducer2_1->mEventActivationMap.size(), 2);
     // The key in mEventActivationMap is the index of the associated atom matcher. We assume
     // that matchers are indexed in the order that they are added to the config.
     const auto& activation2_1_1 = metricProducer2_1->mEventActivationMap.at(0);
@@ -1387,13 +1387,13 @@
     // Metric 1 is not active.
     // Metric 2 is active.
     // {{{---------------------------------------------------------------------------
-    EXPECT_EQ(1, processor3->mMetricsManagers.size());
+    ASSERT_EQ(1, processor3->mMetricsManagers.size());
     it = processor3->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor3->mMetricsManagers.end());
     auto& metricsManager3 = it->second;
     EXPECT_TRUE(metricsManager3->isActive());
 
-    EXPECT_EQ(metricsManager3->mAllMetricProducers.size(), 2);
+    ASSERT_EQ(metricsManager3->mAllMetricProducers.size(), 2);
     // We assume that the index of a MetricProducer within the mAllMetricProducers
     // array follows the order in which metrics are added to the config.
     auto& metricProducer3_1 = metricsManager3->mAllMetricProducers[0];
@@ -1404,7 +1404,7 @@
     EXPECT_EQ(metricProducer3_2->getMetricId(), metricId2);
     EXPECT_TRUE(metricProducer3_2->isActive());
 
-    EXPECT_EQ(metricProducer3_1->mEventActivationMap.size(), 2);
+    ASSERT_EQ(metricProducer3_1->mEventActivationMap.size(), 2);
     // The key in mEventActivationMap is the index of the associated atom matcher. We assume
     // that matchers are indexed in the order that they are added to the config.
     const auto& activation3_1_1 = metricProducer3_1->mEventActivationMap.at(0);
@@ -1531,12 +1531,12 @@
     // Metric 3 is active.
     // {{{---------------------------------------------------------------------------
     sp<StatsLogProcessor> processor = service->mProcessor;
-    EXPECT_EQ(1, processor->mMetricsManagers.size());
+    ASSERT_EQ(1, processor->mMetricsManagers.size());
     auto it = processor->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor->mMetricsManagers.end());
     auto& metricsManager1 = it->second;
     EXPECT_TRUE(metricsManager1->isActive());
-    EXPECT_EQ(3, metricsManager1->mAllMetricProducers.size());
+    ASSERT_EQ(3, metricsManager1->mAllMetricProducers.size());
 
     auto& metricProducer1 = metricsManager1->mAllMetricProducers[0];
     EXPECT_EQ(metricId1, metricProducer1->getMetricId());
@@ -1551,7 +1551,7 @@
     EXPECT_TRUE(metricProducer3->isActive());
 
     // Check event activations.
-    EXPECT_EQ(metricsManager1->mAllAtomMatchers.size(), 4);
+    ASSERT_EQ(metricsManager1->mAllAtomMatchers.size(), 4);
     EXPECT_EQ(metricsManager1->mAllAtomMatchers[0]->getId(),
               metric1ActivationTrigger1->atom_matcher_id());
     const auto& activation1 = metricProducer1->mEventActivationMap.at(0);
@@ -1628,12 +1628,12 @@
 
     // We should have a new metrics manager. Lets get it and ensure activation status is restored.
     // {{{---------------------------------------------------------------------------
-    EXPECT_EQ(1, processor->mMetricsManagers.size());
+    ASSERT_EQ(1, processor->mMetricsManagers.size());
     it = processor->mMetricsManagers.find(cfgKey1);
     EXPECT_TRUE(it != processor->mMetricsManagers.end());
     auto& metricsManager2 = it->second;
     EXPECT_TRUE(metricsManager2->isActive());
-    EXPECT_EQ(3, metricsManager2->mAllMetricProducers.size());
+    ASSERT_EQ(3, metricsManager2->mAllMetricProducers.size());
 
     auto& metricProducer1001 = metricsManager2->mAllMetricProducers[0];
     EXPECT_EQ(metricId1, metricProducer1001->getMetricId());
@@ -1651,7 +1651,7 @@
     // Activation 1 is kActiveOnBoot.
     // Activation 2 and 3 are not active.
     // Activation 4 is active.
-    EXPECT_EQ(metricsManager2->mAllAtomMatchers.size(), 4);
+    ASSERT_EQ(metricsManager2->mAllAtomMatchers.size(), 4);
     EXPECT_EQ(metricsManager2->mAllAtomMatchers[0]->getId(),
               metric1ActivationTrigger1->atom_matcher_id());
     const auto& activation1001 = metricProducer1001->mEventActivationMap.at(0);
@@ -1709,7 +1709,7 @@
     processor->OnLogEvent(logEvent.get());
 
     const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
-    EXPECT_EQ(3, actualFieldValues->size());
+    ASSERT_EQ(3, actualFieldValues->size());
     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
     EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value);
     EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value);
@@ -1734,7 +1734,7 @@
     processor->OnLogEvent(logEvent.get());
 
     const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
-    EXPECT_EQ(3, actualFieldValues->size());
+    ASSERT_EQ(3, actualFieldValues->size());
     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
     EXPECT_EQ(field1, actualFieldValues->at(1).mValue.int_value);
     EXPECT_EQ(field2, actualFieldValues->at(2).mValue.int_value);
@@ -1759,7 +1759,7 @@
     processor->OnLogEvent(logEvent.get());
 
     const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
-    EXPECT_EQ(6, actualFieldValues->size());
+    ASSERT_EQ(6, actualFieldValues->size());
     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
     EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value);
@@ -1787,7 +1787,7 @@
     processor->OnLogEvent(logEvent.get());
 
     const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
-    EXPECT_EQ(6, actualFieldValues->size());
+    ASSERT_EQ(6, actualFieldValues->size());
     EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
     EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value);
     EXPECT_EQ(200, actualFieldValues->at(2).mValue.int_value);
diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp
index 29005a2..293e8ed 100644
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ b/cmds/statsd/tests/UidMap_test.cpp
@@ -86,7 +86,7 @@
     EXPECT_FALSE(m.hasApp(1000, "not.app"));
 
     std::set<string> name_set = m.getAppNamesFromUid(1000u, true /* returnNormalized */);
-    EXPECT_EQ(name_set.size(), 2u);
+    ASSERT_EQ(name_set.size(), 2u);
     EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
     EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
@@ -115,7 +115,7 @@
     m.updateMap(1, uids, versions, versionStrings, apps, installers);
 
     std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_EQ(name_set.size(), 2u);
+    ASSERT_EQ(name_set.size(), 2u);
     EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
     EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
@@ -124,7 +124,7 @@
     EXPECT_EQ(40, m.getAppVersion(1000, kApp1));
 
     name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_EQ(name_set.size(), 2u);
+    ASSERT_EQ(name_set.size(), 2u);
     EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
     EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
@@ -132,7 +132,7 @@
     EXPECT_FALSE(m.hasApp(1000, kApp1));
     EXPECT_TRUE(m.hasApp(1000, kApp2));
     name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_EQ(name_set.size(), 1u);
+    ASSERT_EQ(name_set.size(), 1u);
     EXPECT_TRUE(name_set.find(kApp1) == name_set.end());
     EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
@@ -149,14 +149,14 @@
     m.updateMap(1, {1000, 1000}, {4, 5}, {String16("v4"), String16("v5")},
                 {String16(kApp1.c_str()), String16(kApp2.c_str())}, {String16(""), String16("")});
     std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_EQ(name_set.size(), 2u);
+    ASSERT_EQ(name_set.size(), 2u);
     EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
     EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
     // Adds a new name for uid 1000.
     m.updateApp(2, String16("NeW_aPP1_NAmE"), 1000, 40, String16("v40"), String16(""));
     name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_EQ(name_set.size(), 3u);
+    ASSERT_EQ(name_set.size(), 3u);
     EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
     EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
     EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
@@ -165,7 +165,7 @@
     // This name is also reused by another uid 2000.
     m.updateApp(3, String16("NeW_aPP1_NAmE"), 2000, 1, String16("v1"), String16(""));
     name_set = m.getAppNamesFromUid(2000, true /* returnNormalized */);
-    EXPECT_EQ(name_set.size(), 1u);
+    ASSERT_EQ(name_set.size(), 1u);
     EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
     EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
 }
@@ -212,7 +212,7 @@
     // Check there's still a uidmap attached this one.
     UidMapping results;
     protoOutputStreamToUidMapping(&proto, &results);
-    EXPECT_EQ(1, results.snapshots_size());
+    ASSERT_EQ(1, results.snapshots_size());
     EXPECT_EQ("v1", results.snapshots(0).package_info(0).version_string());
 }
 
@@ -240,7 +240,7 @@
     // Snapshot should still contain this item as deleted.
     UidMapping results;
     protoOutputStreamToUidMapping(&proto, &results);
-    EXPECT_EQ(1, results.snapshots(0).package_info_size());
+    ASSERT_EQ(1, results.snapshots(0).package_info_size());
     EXPECT_EQ(true, results.snapshots(0).package_info(0).deleted());
 }
 
@@ -269,7 +269,7 @@
     ProtoOutputStream proto;
     m.appendUidMap(3, config1, nullptr, true, true, &proto);
     protoOutputStreamToUidMapping(&proto, &results);
-    EXPECT_EQ(maxDeletedApps + 10, results.snapshots(0).package_info_size());
+    ASSERT_EQ(maxDeletedApps + 10, results.snapshots(0).package_info_size());
 
     // Now remove all the apps.
     m.updateMap(1, uids, versions, versionStrings, apps, installers);
@@ -281,7 +281,7 @@
     m.appendUidMap(5, config1, nullptr, true, true, &proto);
     // Snapshot drops the first nine items.
     protoOutputStreamToUidMapping(&proto, &results);
-    EXPECT_EQ(maxDeletedApps, results.snapshots(0).package_info_size());
+    ASSERT_EQ(maxDeletedApps, results.snapshots(0).package_info_size());
 }
 
 TEST(UidMapTest, TestClearingOutput) {
@@ -313,44 +313,44 @@
     m.appendUidMap(2, config1, nullptr, true, true, &proto);
     UidMapping results;
     protoOutputStreamToUidMapping(&proto, &results);
-    EXPECT_EQ(1, results.snapshots_size());
+    ASSERT_EQ(1, results.snapshots_size());
 
     // We have to keep at least one snapshot in memory at all times.
     proto.clear();
     m.appendUidMap(2, config1, nullptr, true, true, &proto);
     protoOutputStreamToUidMapping(&proto, &results);
-    EXPECT_EQ(1, results.snapshots_size());
+    ASSERT_EQ(1, results.snapshots_size());
 
     // Now add another configuration.
     m.OnConfigUpdated(config2);
     m.updateApp(5, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""));
-    EXPECT_EQ(1U, m.mChanges.size());
+    ASSERT_EQ(1U, m.mChanges.size());
     proto.clear();
     m.appendUidMap(6, config1, nullptr, true, true, &proto);
     protoOutputStreamToUidMapping(&proto, &results);
-    EXPECT_EQ(1, results.snapshots_size());
-    EXPECT_EQ(1, results.changes_size());
-    EXPECT_EQ(1U, m.mChanges.size());
+    ASSERT_EQ(1, results.snapshots_size());
+    ASSERT_EQ(1, results.changes_size());
+    ASSERT_EQ(1U, m.mChanges.size());
 
     // Add another delta update.
     m.updateApp(7, String16(kApp2.c_str()), 1001, 41, String16("v41"), String16(""));
-    EXPECT_EQ(2U, m.mChanges.size());
+    ASSERT_EQ(2U, m.mChanges.size());
 
     // We still can't remove anything.
     proto.clear();
     m.appendUidMap(8, config1, nullptr, true, true, &proto);
     protoOutputStreamToUidMapping(&proto, &results);
-    EXPECT_EQ(1, results.snapshots_size());
-    EXPECT_EQ(1, results.changes_size());
-    EXPECT_EQ(2U, m.mChanges.size());
+    ASSERT_EQ(1, results.snapshots_size());
+    ASSERT_EQ(1, results.changes_size());
+    ASSERT_EQ(2U, m.mChanges.size());
 
     proto.clear();
     m.appendUidMap(9, config2, nullptr, true, true, &proto);
     protoOutputStreamToUidMapping(&proto, &results);
-    EXPECT_EQ(1, results.snapshots_size());
-    EXPECT_EQ(2, results.changes_size());
+    ASSERT_EQ(1, results.snapshots_size());
+    ASSERT_EQ(2, results.changes_size());
     // At this point both should be cleared.
-    EXPECT_EQ(0U, m.mChanges.size());
+    ASSERT_EQ(0U, m.mChanges.size());
 }
 
 TEST(UidMapTest, TestMemoryComputed) {
@@ -408,13 +408,13 @@
 
     m.updateApp(3, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 2,
                 String16("v2"), String16(""));
-    EXPECT_EQ(1U, m.mChanges.size());
+    ASSERT_EQ(1U, m.mChanges.size());
 
     // Now force deletion by limiting the memory to hold one delta change.
     m.maxBytesOverride = 120; // Since the app string alone requires >45 characters.
     m.updateApp(5, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 4,
                 String16("v4"), String16(""));
-    EXPECT_EQ(1U, m.mChanges.size());
+    ASSERT_EQ(1U, m.mChanges.size());
 }
 
 #else
diff --git a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
index 90ffcd0..322cfaf 100644
--- a/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AlarmTracker_test.cpp
@@ -56,7 +56,7 @@
 
     currentTimeSec = startMillis / MS_PER_SEC + 7000;
     firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
-    EXPECT_EQ(firedAlarmSet.size(), 1u);
+    ASSERT_EQ(firedAlarmSet.size(), 1u);
     tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
     EXPECT_TRUE(firedAlarmSet.empty());
     EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15 + 2 * 60 * 60));
diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
index 6bde79f..0cc8af1 100644
--- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
@@ -149,7 +149,7 @@
     std::shared_ptr<DimToValMap> bucket6 = MockBucket({{keyA, 2}});
 
     // Start time with no events.
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0u);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0u);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, -1LL);
 
     // Event from bucket #0 occurs.
@@ -160,7 +160,7 @@
 
     // Adds past bucket #0
     anomalyTracker.addPastBucket(bucket0, 0);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
@@ -174,7 +174,7 @@
 
     // Adds past bucket #0 again. The sum does not change.
     anomalyTracker.addPastBucket(bucket0, 0);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3u);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
@@ -187,7 +187,7 @@
     // Adds past bucket #1.
     anomalyTracker.addPastBucket(bucket1, 1);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 1L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
@@ -201,7 +201,7 @@
     // Adds past bucket #1 again. Nothing changes.
     anomalyTracker.addPastBucket(bucket1, 1);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 1L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
@@ -214,7 +214,7 @@
     // Adds past bucket #2.
     anomalyTracker.addPastBucket(bucket2, 2);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 2L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
 
@@ -227,7 +227,7 @@
     // Adds bucket #3.
     anomalyTracker.addPastBucket(bucket3, 3L);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 3L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
 
@@ -240,7 +240,7 @@
     // Adds bucket #4.
     anomalyTracker.addPastBucket(bucket4, 4);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 4L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 5LL);
 
@@ -253,7 +253,7 @@
     // Adds bucket #5.
     anomalyTracker.addPastBucket(bucket5, 5);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 5L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 5LL);
 
@@ -294,7 +294,7 @@
     int64_t eventTimestamp6 = bucketSizeNs * 27 + 3;
 
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, -1LL);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
     EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 9, bucket9, {}, {keyA, keyB, keyC, keyD}));
     detectAndDeclareAnomalies(anomalyTracker, 9, bucket9, eventTimestamp1);
     checkRefractoryTimes(anomalyTracker, eventTimestamp1, refractoryPeriodSec,
@@ -303,15 +303,15 @@
     // Add past bucket #9
     anomalyTracker.addPastBucket(bucket9, 9);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 9L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 3UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyA), 1LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
     EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 16, bucket16, {keyB}, {keyA, keyC, keyD}));
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
     detectAndDeclareAnomalies(anomalyTracker, 16, bucket16, eventTimestamp2);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
     checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
             {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
@@ -319,27 +319,27 @@
     // Add past bucket #16
     anomalyTracker.addPastBucket(bucket16, 16);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 16L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
     EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 18, bucket18, {keyB}, {keyA, keyC, keyD}));
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
     // Within refractory period.
     detectAndDeclareAnomalies(anomalyTracker, 18, bucket18, eventTimestamp3);
     checkRefractoryTimes(anomalyTracker, eventTimestamp3, refractoryPeriodSec,
             {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 4LL);
 
     // Add past bucket #18
     anomalyTracker.addPastBucket(bucket18, 18);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 18L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
     EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 20, bucket20, {keyB}, {keyA, keyC, keyD}));
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 19L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
     detectAndDeclareAnomalies(anomalyTracker, 20, bucket20, eventTimestamp4);
@@ -349,11 +349,11 @@
     // Add bucket #18 again. Nothing changes.
     anomalyTracker.addPastBucket(bucket18, 18);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 19L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
     EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 20, bucket20, {keyB}, {keyA, keyC, keyD}));
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 1LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
     detectAndDeclareAnomalies(anomalyTracker, 20, bucket20, eventTimestamp4 + 1);
@@ -364,12 +364,12 @@
     // Add past bucket #20
     anomalyTracker.addPastBucket(bucket20, 20);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 20L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 2UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 3LL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
     EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 25, bucket25, {}, {keyA, keyB, keyC, keyD}));
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 24L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
     detectAndDeclareAnomalies(anomalyTracker, 25, bucket25, eventTimestamp5);
     checkRefractoryTimes(anomalyTracker, eventTimestamp5, refractoryPeriodSec,
             {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
@@ -377,14 +377,14 @@
     // Add past bucket #25
     anomalyTracker.addPastBucket(bucket25, 25);
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 25L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
     EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyD), 1LL);
     EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {},
             {keyA, keyB, keyC, keyD, keyE}));
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
     detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
     checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
             {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
 
@@ -393,9 +393,9 @@
     EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {keyE},
             {keyA, keyB, keyC, keyD}));
     EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
     detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6 + 7);
-    EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+    ASSERT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
     checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
             {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, eventTimestamp6 + 7}});
 }
diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
index ba5b032..86e24fb 100644
--- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
+++ b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp
@@ -306,13 +306,13 @@
                                            changedCache);
 
         if (position == Position::FIRST || position == Position::LAST) {
-            EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
         } else {
-            EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
         }
         EXPECT_TRUE(changedCache[0]);
         if (position == Position::FIRST || position == Position::LAST) {
-            EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), 1u);
+            ASSERT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(), 1u);
             EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
         } else {
             EXPECT_EQ(conditionTracker.getChangedToTrueDimensions(allConditions)->size(),
@@ -338,9 +338,9 @@
                                            changedCache);
         EXPECT_FALSE(changedCache[0]);
         if (position == Position::FIRST || position == Position::LAST) {
-            EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
         } else {
-            EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
         }
         EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
         EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
@@ -359,9 +359,9 @@
         // nothing changes, because wake lock 2 is still held for this uid
         EXPECT_FALSE(changedCache[0]);
         if (position == Position::FIRST || position == Position::LAST) {
-            EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
         } else {
-            EXPECT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(uids.size(), conditionTracker.mSlicedConditionState.size());
         }
         EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
         EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
@@ -375,10 +375,10 @@
         changedCache[0] = false;
         conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
                                            changedCache);
-        EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
+        ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
         EXPECT_TRUE(changedCache[0]);
         if (position == Position::FIRST || position == Position::LAST) {
-            EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), 1u);
+            ASSERT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(), 1u);
             EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
         } else {
             EXPECT_EQ(conditionTracker.getChangedToFalseDimensions(allConditions)->size(),
@@ -432,7 +432,7 @@
     conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
                                        changedCache);
 
-    EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
+    ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
     EXPECT_TRUE(changedCache[0]);
 
     // Now test query
@@ -480,7 +480,7 @@
     changedCache[0] = false;
     conditionTracker.evaluateCondition(event4, matcherState, allPredicates, conditionCache,
                                        changedCache);
-    EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
+    ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
     EXPECT_TRUE(changedCache[0]);
 
     // query again
@@ -524,14 +524,14 @@
         conditionTracker.evaluateCondition(event1, matcherState, allPredicates, conditionCache,
                                            changedCache);
         if (position == Position::FIRST || position == Position::LAST) {
-            EXPECT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(1UL, conditionTracker.mSlicedConditionState.size());
         } else {
-            EXPECT_EQ(uids1.size(), conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(uids1.size(), conditionTracker.mSlicedConditionState.size());
         }
         EXPECT_TRUE(changedCache[0]);
         {
             if (position == Position::FIRST || position == Position::LAST) {
-                EXPECT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
+                ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
                 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
             } else {
                 EXPECT_EQ(uids1.size(),
@@ -560,14 +560,14 @@
         conditionTracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache,
                                            changedCache);
         if (position == Position::FIRST || position == Position::LAST) {
-            EXPECT_EQ(2UL, conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(2UL, conditionTracker.mSlicedConditionState.size());
         } else {
-            EXPECT_EQ(uids1.size() + uids2.size(), conditionTracker.mSlicedConditionState.size());
+            ASSERT_EQ(uids1.size() + uids2.size(), conditionTracker.mSlicedConditionState.size());
         }
         EXPECT_TRUE(changedCache[0]);
         {
             if (position == Position::FIRST || position == Position::LAST) {
-                EXPECT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
+                ASSERT_EQ(1UL, conditionTracker.getChangedToTrueDimensions(allConditions)->size());
                 EXPECT_TRUE(conditionTracker.getChangedToFalseDimensions(allConditions)->empty());
             } else {
                 EXPECT_EQ(uids2.size(),
@@ -597,10 +597,10 @@
         conditionTracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache,
                                            changedCache);
         EXPECT_TRUE(changedCache[0]);
-        EXPECT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
+        ASSERT_EQ(0UL, conditionTracker.mSlicedConditionState.size());
         {
             if (position == Position::FIRST || position == Position::LAST) {
-                EXPECT_EQ(2UL, conditionTracker.getChangedToFalseDimensions(allConditions)->size());
+                ASSERT_EQ(2UL, conditionTracker.getChangedToFalseDimensions(allConditions)->size());
                 EXPECT_TRUE(conditionTracker.getChangedToTrueDimensions(allConditions)->empty());
             } else {
                 EXPECT_EQ(uids1.size() + uids2.size(),
diff --git a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp b/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
index 9ea0b81..93b2783 100644
--- a/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Alarm_e2e_test.cpp
@@ -52,9 +52,9 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    EXPECT_EQ(2u, processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers.size());
+    ASSERT_EQ(2u, processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers.size());
 
     auto alarmTracker1 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[0];
     auto alarmTracker2 = processor->mMetricsManagers.begin()->second->mAllPeriodicAlarmTrackers[1];
@@ -68,7 +68,7 @@
     const int64_t alarmFiredTimestampSec0 = alarmTimestampSec1 + 5;
     auto alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
             static_cast<uint32_t>(alarmFiredTimestampSec0));
-    EXPECT_EQ(1u, alarmSet.size());
+    ASSERT_EQ(1u, alarmSet.size());
     processor->onPeriodicAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
     EXPECT_EQ(alarmTimestampSec0, alarmTracker1->getAlarmTimestampSec());
     EXPECT_EQ(alarmTimestampSec1 + 30 * 60, alarmTracker2->getAlarmTimestampSec());
@@ -77,7 +77,7 @@
     const int64_t alarmFiredTimestampSec1 = alarmTimestampSec0 + 2 * 60 * 60 + 125;
     alarmSet = processor->getPeriodicAlarmMonitor()->popSoonerThan(
             static_cast<uint32_t>(alarmFiredTimestampSec1));
-    EXPECT_EQ(2u, alarmSet.size());
+    ASSERT_EQ(2u, alarmSet.size());
     processor->onPeriodicAlarmFired(alarmFiredTimestampSec1 * NS_PER_SEC, alarmSet);
     EXPECT_EQ(alarmTimestampSec0 + 60 * 60 * 3, alarmTracker1->getAlarmTimestampSec());
     EXPECT_EQ(alarmTimestampSec1 + 30 * 60 * 5, alarmTracker2->getAlarmTimestampSec());
diff --git a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
index c2d7043..af9436b 100644
--- a/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Anomaly_count_e2e_test.cpp
@@ -66,9 +66,9 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
 
     sp<AnomalyTracker> anomalyTracker =
             processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -183,9 +183,9 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
 
     sp<AnomalyTracker> anomalyTracker =
             processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -254,16 +254,16 @@
     int64_t configId = 1000;
     ConfigKey cfgKey(configUid, configId);
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
 
     metadata::StatsMetadataList result;
     int64_t mockWallClockNs = 1584991200 * NS_PER_SEC;
     int64_t mockElapsedTimeNs = bucketStartTimeNs + 5000 * NS_PER_SEC;
     processor->WriteMetadataToProto(mockWallClockNs, mockElapsedTimeNs, &result);
 
-    EXPECT_EQ(result.stats_metadata_size(), 0);
+    ASSERT_EQ(result.stats_metadata_size(), 0);
 }
 
 TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk) {
@@ -279,9 +279,9 @@
     int64_t configId = 1000;
     ConfigKey cfgKey(configUid, configId);
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
 
     sp<AnomalyTracker> anomalyTracker =
             processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -308,15 +308,15 @@
     processor->WriteMetadataToProto(mockWallClockNs, mockElapsedTimeNs, &result);
 
     metadata::StatsMetadata statsMetadata = result.stats_metadata(0);
-    EXPECT_EQ(result.stats_metadata_size(), 1);
+    ASSERT_EQ(result.stats_metadata_size(), 1);
     EXPECT_EQ(statsMetadata.config_key().config_id(), configId);
     EXPECT_EQ(statsMetadata.config_key().uid(), configUid);
 
     metadata::AlertMetadata alertMetadata = statsMetadata.alert_metadata(0);
-    EXPECT_EQ(statsMetadata.alert_metadata_size(), 1);
+    ASSERT_EQ(statsMetadata.alert_metadata_size(), 1);
     EXPECT_EQ(alertMetadata.alert_id(), alert_id);
     metadata::AlertDimensionKeyedData keyedData = alertMetadata.alert_dim_keyed_data(0);
-    EXPECT_EQ(alertMetadata.alert_dim_keyed_data_size(), 1);
+    ASSERT_EQ(alertMetadata.alert_dim_keyed_data_size(), 1);
     EXPECT_EQ(keyedData.last_refractory_ends_sec(),
               anomalyTracker->getRefractoryPeriodEndsSec(dimensionKey1) -
               mockElapsedTimeNs / NS_PER_SEC +
@@ -342,9 +342,9 @@
     int64_t configId = 1000;
     ConfigKey cfgKey(configUid, configId);
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
 
     sp<AnomalyTracker> anomalyTracker =
             processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
diff --git a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
index 4f9f315..95e3010 100644
--- a/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
@@ -104,9 +104,9 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
 
     sp<AnomalyTracker> anomalyTracker =
             processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -162,7 +162,7 @@
     // Anomaly alarm fired.
     auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
             static_cast<uint32_t>(alarmFiredTimestampSec0));
-    EXPECT_EQ(1u, alarmSet.size());
+    ASSERT_EQ(1u, alarmSet.size());
     processor->onAnomalyAlarmFired(alarmFiredTimestampSec0 * NS_PER_SEC, alarmSet);
     EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
     EXPECT_EQ(refractory_period_sec + alarmFiredTimestampSec0,
@@ -199,7 +199,7 @@
 
     alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
             static_cast<uint32_t>(alarmFiredTimestampSec1));
-    EXPECT_EQ(0u, alarmSet.size());
+    ASSERT_EQ(0u, alarmSet.size());
 
     // Acquire wakelock wl1 near the end of bucket #0.
     acquire_event = CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs - 2,
@@ -285,9 +285,9 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
 
     sp<AnomalyTracker> anomalyTracker =
             processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -406,9 +406,9 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
-    EXPECT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
+    ASSERT_EQ(1u, processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers.size());
 
     sp<AnomalyTracker> anomalyTracker =
             processor->mMetricsManagers.begin()->second->mAllAnomalyTrackers[0];
@@ -439,7 +439,7 @@
     const int64_t firedAlarmTimestampNs = bucketStartTimeNs + 2 * bucketSizeNs - NS_PER_SEC;
     auto alarmSet = processor->getAnomalyAlarmMonitor()->popSoonerThan(
             static_cast<uint32_t>(firedAlarmTimestampNs / NS_PER_SEC));
-    EXPECT_EQ(1u, alarmSet.size());
+    ASSERT_EQ(1u, alarmSet.size());
     processor->onAnomalyAlarmFired(firedAlarmTimestampNs, alarmSet);
     EXPECT_EQ(0u, anomalyTracker->getAlarmTimestampSec(dimensionKey1));
     EXPECT_EQ(refractory_period_sec + firedAlarmTimestampNs / NS_PER_SEC,
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
index 52229e2..4c2caa9 100644
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
@@ -101,7 +101,7 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
 
     // Here it assumes that GMS core has two uids.
@@ -155,17 +155,17 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(reports.reports_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
+    ASSERT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(countMetrics.data_size(), 4);
+    ASSERT_EQ(countMetrics.data_size(), 4);
 
     auto data = countMetrics.data(0);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
                                           util::WAKELOCK_STATE_CHANGED, 111, "App1");
-    EXPECT_EQ(data.bucket_info_size(), 2);
+    ASSERT_EQ(data.bucket_info_size(), 2);
     EXPECT_EQ(data.bucket_info(0).count(), 2);
     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
     EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
@@ -178,7 +178,7 @@
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
                                           util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
-    EXPECT_EQ(data.bucket_info_size(), 2);
+    ASSERT_EQ(data.bucket_info_size(), 2);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
     EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
@@ -190,7 +190,7 @@
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
                                           util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule3");
-    EXPECT_EQ(data.bucket_info_size(), 1);
+    ASSERT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
               bucketStartTimeNs + 3 * bucketSizeNs);
@@ -200,7 +200,7 @@
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
                                           util::WAKELOCK_STATE_CHANGED, 444,
                                           "GMSCoreModule2");
-    EXPECT_EQ(data.bucket_info_size(), 1);
+    ASSERT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(),
               bucketStartTimeNs + 2 * bucketSizeNs);
@@ -214,7 +214,7 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
 
     // Here it assumes that GMS core has two uids.
@@ -268,18 +268,18 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(reports.reports_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
+    ASSERT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(countMetrics.data_size(), 6);
+    ASSERT_EQ(countMetrics.data_size(), 6);
 
     auto data = countMetrics.data(0);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(),
                                           util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -296,7 +296,7 @@
     ValidateUidDimension(data.dimensions_in_what(), 1, util::WAKELOCK_STATE_CHANGED, 333);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
                                           util::WAKELOCK_STATE_CHANGED, 333, "App3");
-    EXPECT_EQ(data.bucket_info_size(), 1);
+    ASSERT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(data.bucket_info(0).start_bucket_elapsed_nanos(), bucketStartTimeNs);
     EXPECT_EQ(data.bucket_info(0).end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
@@ -310,7 +310,7 @@
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 1,
                                           util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
-    EXPECT_EQ(data.bucket_info_size(), 1);
+    ASSERT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -327,7 +327,7 @@
     ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
                                           util::WAKELOCK_STATE_CHANGED, 333, "App3");
-    EXPECT_EQ(data.bucket_info_size(), 1);
+    ASSERT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -343,7 +343,7 @@
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
                                           util::WAKELOCK_STATE_CHANGED, 222,
                                           "GMSCoreModule1");
-    EXPECT_EQ(data.bucket_info_size(), 1);
+    ASSERT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -359,7 +359,7 @@
     ValidateUidDimension(data.dimensions_in_what(), 2, util::WAKELOCK_STATE_CHANGED, 333);
     ValidateAttributionUidAndTagDimension(data.dimensions_in_what(), 2,
                                           util::WAKELOCK_STATE_CHANGED, 333, "App3");
-    EXPECT_EQ(data.bucket_info_size(), 1);
+    ASSERT_EQ(data.bucket_info_size(), 1);
     EXPECT_EQ(data.bucket_info(0).count(), 1);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
diff --git a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp b/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
index 16adbdd..0bce0ba 100644
--- a/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ConfigTtl_e2e_test.cpp
@@ -68,7 +68,7 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
 
     std::vector<int> attributionUids1 = {111};
diff --git a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
index b1461a1..1a7cd55 100644
--- a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
@@ -65,14 +65,14 @@
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
 
     // Check that CountMetricProducer was initialized correctly.
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
+    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    EXPECT_EQ(metricProducer->mStateGroupMap.size(), 0);
+    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
 
     // Check that StateTrackers were initialized correctly.
     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
@@ -132,23 +132,23 @@
     ConfigMetricsReportList reports;
     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
                             FAST, &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(3, countMetrics.data_size());
+    ASSERT_EQ(3, countMetrics.data_size());
 
     // For each CountMetricData, check StateValue info is correct and buckets
     // have correct counts.
     auto data = countMetrics.data(0);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN,
@@ -157,7 +157,7 @@
     EXPECT_EQ(1, data.bucket_info(0).count());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
@@ -166,7 +166,7 @@
     EXPECT_EQ(2, data.bucket_info(1).count());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
@@ -220,14 +220,14 @@
     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
 
     // Check that CountMetricProducer was initialized correctly.
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
+    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    EXPECT_EQ(metricProducer->mStateGroupMap.size(), 1);
+    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
 
     StateMap map = state.map();
     for (auto group : map.group()) {
@@ -316,44 +316,44 @@
     ConfigMetricsReportList reports;
     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
                             FAST, &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(3, countMetrics.data_size());
+    ASSERT_EQ(3, countMetrics.data_size());
 
     // For each CountMetricData, check StateValue info is correct and buckets
     // have correct counts.
     auto data = countMetrics.data(0);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(1, data.bucket_info(1).count());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(4, data.bucket_info(0).count());
     EXPECT_EQ(2, data.bucket_info(1).count());
 }
@@ -405,15 +405,15 @@
     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
 
     // Check that CountMetricProducer was initialized correctly.
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
+    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
-    EXPECT_EQ(metricProducer->mStateGroupMap.size(), 0);
-    EXPECT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
+    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
+    ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
 
     /*
     NOTE: "1" or "2" represents the uid associated with the state/app crash event
@@ -496,23 +496,23 @@
     ConfigMetricsReportList reports;
     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
                             FAST, &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(5, countMetrics.data_size());
+    ASSERT_EQ(5, countMetrics.data_size());
 
     // For each CountMetricData, check StateValue info is correct and buckets
     // have correct counts.
     auto data = countMetrics.data(0);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
@@ -520,7 +520,7 @@
     EXPECT_EQ(1, data.bucket_info(0).count());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(0).value());
@@ -528,7 +528,7 @@
     EXPECT_EQ(2, data.bucket_info(0).count());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(0).value());
@@ -537,7 +537,7 @@
     EXPECT_EQ(2, data.bucket_info(1).count());
 
     data = countMetrics.data(3);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(0).value());
@@ -545,7 +545,7 @@
     EXPECT_EQ(2, data.bucket_info(0).count());
 
     data = countMetrics.data(4);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(0).value());
@@ -600,16 +600,16 @@
     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
 
     // Check that CountMetricProducer was initialized correctly.
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 2);
+    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 2);
     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(1), UID_PROCESS_STATE_ATOM_ID);
-    EXPECT_EQ(metricProducer->mStateGroupMap.size(), 1);
-    EXPECT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
+    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
+    ASSERT_EQ(metricProducer->mMetric2StateLinks.size(), 1);
 
     StateMap map = state1.map();
     for (auto group : map.group()) {
@@ -726,23 +726,23 @@
     ConfigMetricsReportList reports;
     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
                             FAST, &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(6, countMetrics.data_size());
+    ASSERT_EQ(6, countMetrics.data_size());
 
     // For each CountMetricData, check StateValue info is correct and buckets
     // have correct counts.
     auto data = countMetrics.data(0);
-    EXPECT_EQ(2, data.slice_by_state_size());
+    ASSERT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(-1, data.slice_by_state(0).value());
@@ -753,7 +753,7 @@
     EXPECT_EQ(1, data.bucket_info(0).count());
 
     data = countMetrics.data(1);
-    EXPECT_EQ(2, data.slice_by_state_size());
+    ASSERT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
@@ -764,7 +764,7 @@
     EXPECT_EQ(1, data.bucket_info(0).count());
 
     data = countMetrics.data(2);
-    EXPECT_EQ(2, data.slice_by_state_size());
+    ASSERT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
@@ -775,7 +775,7 @@
     EXPECT_EQ(1, data.bucket_info(0).count());
 
     data = countMetrics.data(3);
-    EXPECT_EQ(2, data.slice_by_state_size());
+    ASSERT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
@@ -786,7 +786,7 @@
     EXPECT_EQ(2, data.bucket_info(0).count());
 
     data = countMetrics.data(4);
-    EXPECT_EQ(2, data.slice_by_state_size());
+    ASSERT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
@@ -797,7 +797,7 @@
     EXPECT_EQ(1, data.bucket_info(0).count());
 
     data = countMetrics.data(5);
-    EXPECT_EQ(2, data.slice_by_state_size());
+    ASSERT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
diff --git a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
index d59ec3e..4efb038 100644
--- a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
@@ -57,10 +57,10 @@
 
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
 
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
@@ -93,18 +93,18 @@
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
 
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(1, durationMetrics.data_size());
+    ASSERT_EQ(1, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(durationEndNs - durationStartNs, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -140,10 +140,10 @@
 
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
 
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
@@ -176,18 +176,18 @@
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
 
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(1, durationMetrics.data_size());
+    ASSERT_EQ(1, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
 
     auto bucketInfo = data.bucket_info(0);
     EXPECT_EQ(0, bucketInfo.bucket_num());
@@ -253,16 +253,16 @@
 
     processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);  // 0:00
 
-    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     auto& eventActivationMap = metricProducer->mEventActivationMap;
 
     EXPECT_FALSE(metricsManager->isActive());
     EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap.size(), 1u);
+    ASSERT_EQ(eventActivationMap.size(), 1u);
     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
@@ -289,7 +289,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 1);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
@@ -302,8 +302,8 @@
     EXPECT_FALSE(metricsManager->isActive());
     EXPECT_FALSE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 2);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
-    EXPECT_EQ(eventActivationMap.size(), 1u);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(eventActivationMap.size(), 1u);
     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
@@ -333,7 +333,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, activation2StartNs);
@@ -347,18 +347,18 @@
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
 
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(1, durationMetrics.data_size());
+    ASSERT_EQ(1, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
 
     auto bucketInfo = data.bucket_info(0);
     EXPECT_EQ(0, bucketInfo.bucket_num());
@@ -393,10 +393,10 @@
     uint64_t bucketSizeNs =
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     auto& eventActivationMap = metricProducer->mEventActivationMap;
     EXPECT_TRUE(metricsManager->isActive());
@@ -428,23 +428,23 @@
     ConfigMetricsReportList reports;
     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
                             FAST, &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(1, durationMetrics.data_size());
+    ASSERT_EQ(1, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
 
     // Validate bucket info.
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
 
     auto bucketInfo = data.bucket_info(0);
     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
@@ -497,10 +497,10 @@
     uint64_t bucketSizeNs =
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     auto& eventActivationMap = metricProducer->mEventActivationMap;
     EXPECT_TRUE(metricsManager->isActive());
@@ -530,25 +530,25 @@
     ConfigMetricsReportList reports;
     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
                             FAST, &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(1, durationMetrics.data_size());
+    ASSERT_EQ(1, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
                                     util::WAKELOCK_STATE_CHANGED, appUid);
     // Validate bucket info.
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
 
     auto bucketInfo = data.bucket_info(0);
     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
@@ -608,15 +608,15 @@
     uint64_t bucketSizeNs =
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     auto& eventActivationMap = metricProducer->mEventActivationMap;
     EXPECT_FALSE(metricsManager->isActive());
     EXPECT_FALSE(metricProducer->mIsActive);
-    EXPECT_EQ(eventActivationMap.size(), 1u);
+    ASSERT_EQ(eventActivationMap.size(), 1u);
     EXPECT_TRUE(eventActivationMap.find(4) != eventActivationMap.end());
     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
@@ -691,25 +691,25 @@
     ConfigMetricsReportList reports;
     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
                             FAST, &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(1, durationMetrics.data_size());
+    ASSERT_EQ(1, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
                                     util::WAKELOCK_STATE_CHANGED, appUid);
     // Validate bucket info.
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
 
     auto bucketInfo = data.bucket_info(0);
     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
@@ -753,16 +753,16 @@
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
 
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     EXPECT_TRUE(metricsManager->isActive());
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
+    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    EXPECT_EQ(metricProducer->mStateGroupMap.size(), 0);
+    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
 
     // Check that StateTrackers were initialized correctly.
     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
@@ -814,26 +814,26 @@
     processor->onDumpReport(cfgKey, bucketStartTimeNs + 360 * NS_PER_SEC,
                             true /* include current partial bucket */, true, ADB_DUMP, FAST,
                             &buffer);  // 6:10
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(3, durationMetrics.data_size());
+    ASSERT_EQ(3, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -842,11 +842,11 @@
     EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
     data = durationMetrics.data(1);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(110 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -855,11 +855,11 @@
     EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
     data = durationMetrics.data(2);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -902,16 +902,16 @@
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
 
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     EXPECT_TRUE(metricsManager->isActive());
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
+    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    EXPECT_EQ(metricProducer->mStateGroupMap.size(), 0);
+    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
 
     // Check that StateTrackers were initialized correctly.
     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
@@ -976,26 +976,26 @@
     processor->onDumpReport(cfgKey, bucketStartTimeNs + 410 * NS_PER_SEC,
                             true /* include current partial bucket */, true, ADB_DUMP, FAST,
                             &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(3, durationMetrics.data_size());
+    ASSERT_EQ(3, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -1004,11 +1004,11 @@
     EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
     data = durationMetrics.data(1);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -1017,11 +1017,11 @@
     EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
     data = durationMetrics.data(2);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -1060,16 +1060,16 @@
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
 
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     EXPECT_TRUE(metricsManager->isActive());
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
+    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
-    EXPECT_EQ(metricProducer->mStateGroupMap.size(), 1);
+    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
 
     // Check that StateTrackers were initialized correctly.
     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
@@ -1134,26 +1134,26 @@
     processor->onDumpReport(cfgKey, bucketStartTimeNs + 490 * NS_PER_SEC,
                             true /* include current partial bucket */, true, ADB_DUMP, FAST,
                             &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(2, durationMetrics.data_size());
+    ASSERT_EQ(2, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(130 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -1162,11 +1162,11 @@
     EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
     data = durationMetrics.data(1);
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -1216,7 +1216,7 @@
 
     // This config is rejected because the dimension in what fields are not a superset of the sliced
     // state primary fields.
-    EXPECT_EQ(processor->mMetricsManagers.size(), 0);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 0);
 }
 
 TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset) {
@@ -1261,16 +1261,16 @@
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
 
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     EXPECT_TRUE(metricsManager->isActive());
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     EXPECT_TRUE(metricProducer->mIsActive);
-    EXPECT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
+    ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
-    EXPECT_EQ(metricProducer->mStateGroupMap.size(), 0);
+    ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
 
     // Check that StateTrackers were initialized correctly.
     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
@@ -1328,24 +1328,24 @@
     processor->onDumpReport(cfgKey, bucketStartTimeNs + 320 * NS_PER_SEC,
                             true /* include current partial bucket */, true, ADB_DUMP, FAST,
                             &buffer);
-    EXPECT_GT(buffer.size(), 0);
+    ASSERT_GT(buffer.size(), 0);
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
     StatsLogReport::DurationMetricDataWrapper durationMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
                                     &durationMetrics);
-    EXPECT_EQ(9, durationMetrics.data_size());
+    ASSERT_EQ(9, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
                                                   "wakelock1");
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
@@ -1358,7 +1358,7 @@
     data = durationMetrics.data(1);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
                                                   "wakelock1");
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
@@ -1374,7 +1374,7 @@
     data = durationMetrics.data(2);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
                                                   "wakelock2");
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
@@ -1387,7 +1387,7 @@
     data = durationMetrics.data(3);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
                                                   "wakelock2");
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
@@ -1400,7 +1400,7 @@
     data = durationMetrics.data(4);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
                                                   "wakelock1");
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
@@ -1412,7 +1412,7 @@
     data = durationMetrics.data(5);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
                                                   "wakelock1");
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
@@ -1425,7 +1425,7 @@
     data = durationMetrics.data(6);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
                                                   "wakelock2");
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
@@ -1437,7 +1437,7 @@
     data = durationMetrics.data(7);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
                                                   "wakelock2");
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
@@ -1453,7 +1453,7 @@
     data = durationMetrics.data(8);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
                                                   "wakelock2");
-    EXPECT_EQ(1, data.slice_by_state_size());
+    ASSERT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index c234b14..1be2612 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -76,7 +76,7 @@
     auto processor =
             CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                     SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
 
@@ -87,7 +87,7 @@
 
     // When creating the config, the gauge metric producer should register the alarm at the
     // end of the current bucket.
-    EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
+    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
     EXPECT_EQ(bucketSizeNs,
               processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
     int64_t& nextPullTimeNs =
@@ -141,30 +141,30 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    EXPECT_GT((int)gaugeMetrics.data_size(), 1);
+    ASSERT_GT((int)gaugeMetrics.data_size(), 1);
 
     auto data = gaugeMetrics.data(0);
     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    EXPECT_EQ(6, data.bucket_info_size());
+    ASSERT_EQ(6, data.bucket_info_size());
 
-    EXPECT_EQ(1, data.bucket_info(0).atom_size());
-    EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(0).atom_size());
+    ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
     EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
+    ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(1).atom_size());
+    ASSERT_EQ(1, data.bucket_info(1).atom_size());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
@@ -172,32 +172,32 @@
     EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(2).atom_size());
-    EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(2).atom_size());
+    ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(2).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(3).atom_size());
-    EXPECT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(3).atom_size());
+    ASSERT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 1, data.bucket_info(3).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(3).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(3).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(4).atom_size());
-    EXPECT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(4).atom_size());
+    ASSERT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(4).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(4).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(4).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(5).atom_size());
-    EXPECT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(5).atom_size());
+    ASSERT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs + 2, data.bucket_info(5).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos());
@@ -215,7 +215,7 @@
     auto processor =
             CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                     SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
 
@@ -259,30 +259,30 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    EXPECT_GT((int)gaugeMetrics.data_size(), 1);
+    ASSERT_GT((int)gaugeMetrics.data_size(), 1);
 
     auto data = gaugeMetrics.data(0);
     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    EXPECT_EQ(3, data.bucket_info_size());
+    ASSERT_EQ(3, data.bucket_info_size());
 
-    EXPECT_EQ(1, data.bucket_info(0).atom_size());
-    EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(0).atom_size());
+    ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
     EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
+    ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(1).atom_size());
+    ASSERT_EQ(1, data.bucket_info(1).atom_size());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100, data.bucket_info(1).elapsed_timestamp_nanos(0));
     EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
@@ -290,8 +290,8 @@
     EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(2, data.bucket_info(2).atom_size());
-    EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(2, data.bucket_info(2).atom_size());
+    ASSERT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 1, data.bucket_info(2).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs + 10, data.bucket_info(2).elapsed_timestamp_nanos(1));
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
@@ -312,7 +312,7 @@
     auto processor =
             CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                     SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
 
@@ -323,7 +323,7 @@
 
     // When creating the config, the gauge metric producer should register the alarm at the
     // end of the current bucket.
-    EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
+    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
     EXPECT_EQ(bucketSizeNs,
               processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
     int64_t& nextPullTimeNs =
@@ -359,29 +359,29 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    EXPECT_GT((int)gaugeMetrics.data_size(), 1);
+    ASSERT_GT((int)gaugeMetrics.data_size(), 1);
 
     auto data = gaugeMetrics.data(0);
     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    EXPECT_EQ(3, data.bucket_info_size());
+    ASSERT_EQ(3, data.bucket_info_size());
 
-    EXPECT_EQ(1, data.bucket_info(0).atom_size());
-    EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(0).atom_size());
+    ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
     EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(1).atom_size());
+    ASSERT_EQ(1, data.bucket_info(1).atom_size());
     EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11,
               data.bucket_info(1).elapsed_timestamp_nanos(0));
     EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
@@ -390,8 +390,8 @@
     EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(2).atom_size());
-    EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(2).atom_size());
+    ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs + 12, data.bucket_info(2).elapsed_timestamp_nanos(0));
     EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
@@ -420,7 +420,7 @@
     auto processor =
             CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                     SharedRefBase::make<FakeSubsystemSleepCallback>(), ATOM_TAG);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
 
@@ -432,7 +432,7 @@
 
     // When creating the config, the gauge metric producer should register the alarm at the
     // end of the current bucket.
-    EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
+    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
     EXPECT_EQ(bucketSizeNs,
               processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
     int64_t& nextPullTimeNs =
@@ -479,45 +479,45 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    EXPECT_GT((int)gaugeMetrics.data_size(), 0);
+    ASSERT_GT((int)gaugeMetrics.data_size(), 0);
 
     auto data = gaugeMetrics.data(0);
     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    EXPECT_EQ(3, data.bucket_info_size());
+    ASSERT_EQ(3, data.bucket_info_size());
 
     auto bucketInfo = data.bucket_info(0);
-    EXPECT_EQ(1, bucketInfo.atom_size());
-    EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, bucketInfo.atom_size());
+    ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
     EXPECT_EQ(activationNs, bucketInfo.elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
+    ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
     EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
 
     bucketInfo = data.bucket_info(1);
-    EXPECT_EQ(1, bucketInfo.atom_size());
-    EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, bucketInfo.atom_size());
+    ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 1, bucketInfo.elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
+    ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
     EXPECT_TRUE(bucketInfo.atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(bucketInfo.atom(0).subsystem_sleep_state().time_millis(), 0);
 
     bucketInfo = data.bucket_info(2);
-    EXPECT_EQ(1, bucketInfo.atom_size());
-    EXPECT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, bucketInfo.atom_size());
+    ASSERT_EQ(1, bucketInfo.elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs + 2, bucketInfo.elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
+    ASSERT_EQ(0, bucketInfo.wall_clock_timestamp_nanos_size());
     EXPECT_EQ(MillisToNano(NanoToMillis(baseTimeNs + 5 * bucketSizeNs)),
               bucketInfo.start_bucket_elapsed_nanos());
     EXPECT_EQ(MillisToNano(NanoToMillis(activationNs + ttlNs + 1)),
@@ -538,7 +538,7 @@
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                              SharedRefBase::make<FakeSubsystemSleepCallback>(),
                                              ATOM_TAG);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
 
@@ -548,7 +548,7 @@
 
     // When creating the config, the gauge metric producer should register the alarm at the
     // end of the current bucket.
-    EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
+    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
     EXPECT_EQ(bucketSizeNs,
               processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
     int64_t& nextPullTimeNs =
@@ -572,43 +572,43 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
     sortMetricDataByDimensionsValue(
             reports.reports(0).metrics(0).gauge_metrics(), &gaugeMetrics);
-    EXPECT_GT((int)gaugeMetrics.data_size(), 0);
+    ASSERT_GT((int)gaugeMetrics.data_size(), 0);
 
     auto data = gaugeMetrics.data(0);
     EXPECT_EQ(ATOM_TAG, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    EXPECT_EQ(3, data.bucket_info_size());
+    ASSERT_EQ(3, data.bucket_info_size());
 
-    EXPECT_EQ(1, data.bucket_info(0).atom_size());
-    EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(0).atom_size());
+    ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
     EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
+    ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(0).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(1).atom_size());
-    EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(1).atom_size());
+    ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1, data.bucket_info(1).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, data.bucket_info(1).wall_clock_timestamp_nanos_size());
+    ASSERT_EQ(0, data.bucket_info(1).wall_clock_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(1).atom(0).subsystem_sleep_state().subsystem_name().empty());
     EXPECT_GT(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 0);
 
-    EXPECT_EQ(1, data.bucket_info(2).atom_size());
-    EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
+    ASSERT_EQ(1, data.bucket_info(2).atom_size());
+    ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs + 4, data.bucket_info(2).elapsed_timestamp_nanos(0));
-    EXPECT_EQ(0, data.bucket_info(2).wall_clock_timestamp_nanos_size());
+    ASSERT_EQ(0, data.bucket_info(2).wall_clock_timestamp_nanos_size());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(2).atom(0).subsystem_sleep_state().subsystem_name().empty());
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
index 60403f2..a40a948 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
@@ -103,7 +103,7 @@
         ConfigKey cfgKey;
         auto processor =
                 CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-        EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+        ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
         EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
 
         int appUid1 = 123;
@@ -160,24 +160,24 @@
         backfillDimensionPath(&reports);
         backfillStringInReport(&reports);
         backfillStartEndTimestamp(&reports);
-        EXPECT_EQ(1, reports.reports_size());
-        EXPECT_EQ(1, reports.reports(0).metrics_size());
+        ASSERT_EQ(1, reports.reports_size());
+        ASSERT_EQ(1, reports.reports(0).metrics_size());
         StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
         sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(),
                                         &gaugeMetrics);
-        EXPECT_EQ(2, gaugeMetrics.data_size());
+        ASSERT_EQ(2, gaugeMetrics.data_size());
 
         auto data = gaugeMetrics.data(0);
         EXPECT_EQ(util::APP_START_OCCURRED, data.dimensions_in_what().field());
-        EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+        ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
         EXPECT_EQ(1 /* uid field */,
                   data.dimensions_in_what().value_tuple().dimensions_value(0).field());
         EXPECT_EQ(appUid1, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-        EXPECT_EQ(3, data.bucket_info_size());
+        ASSERT_EQ(3, data.bucket_info_size());
         if (sampling_type == GaugeMetric::FIRST_N_SAMPLES) {
-            EXPECT_EQ(2, data.bucket_info(0).atom_size());
-            EXPECT_EQ(2, data.bucket_info(0).elapsed_timestamp_nanos_size());
-            EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
+            ASSERT_EQ(2, data.bucket_info(0).atom_size());
+            ASSERT_EQ(2, data.bucket_info(0).elapsed_timestamp_nanos_size());
+            ASSERT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
             EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
             EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
                       data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -194,8 +194,8 @@
             EXPECT_EQ(103L,
                       data.bucket_info(0).atom(1).app_start_occurred().activity_start_millis());
 
-            EXPECT_EQ(1, data.bucket_info(1).atom_size());
-            EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
+            ASSERT_EQ(1, data.bucket_info(1).atom_size());
+            ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
             EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
                       data.bucket_info(1).start_bucket_elapsed_nanos());
             EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
@@ -207,8 +207,8 @@
             EXPECT_EQ(104L,
                       data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
 
-            EXPECT_EQ(2, data.bucket_info(2).atom_size());
-            EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
+            ASSERT_EQ(2, data.bucket_info(2).atom_size());
+            ASSERT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
             EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
                       data.bucket_info(2).start_bucket_elapsed_nanos());
             EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
@@ -226,8 +226,8 @@
             EXPECT_EQ(106L,
                       data.bucket_info(2).atom(1).app_start_occurred().activity_start_millis());
         } else {
-            EXPECT_EQ(1, data.bucket_info(0).atom_size());
-            EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
+            ASSERT_EQ(1, data.bucket_info(0).atom_size());
+            ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
             EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
             EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
                       data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -238,8 +238,8 @@
             EXPECT_EQ(102L,
                       data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis());
 
-            EXPECT_EQ(1, data.bucket_info(1).atom_size());
-            EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
+            ASSERT_EQ(1, data.bucket_info(1).atom_size());
+            ASSERT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
             EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
                       data.bucket_info(1).start_bucket_elapsed_nanos());
             EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
@@ -251,8 +251,8 @@
             EXPECT_EQ(104L,
                       data.bucket_info(1).atom(0).app_start_occurred().activity_start_millis());
 
-            EXPECT_EQ(1, data.bucket_info(2).atom_size());
-            EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
+            ASSERT_EQ(1, data.bucket_info(2).atom_size());
+            ASSERT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
             EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
                       data.bucket_info(2).start_bucket_elapsed_nanos());
             EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
@@ -268,13 +268,13 @@
         data = gaugeMetrics.data(1);
 
         EXPECT_EQ(data.dimensions_in_what().field(), util::APP_START_OCCURRED);
-        EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
+        ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
         EXPECT_EQ(1 /* uid field */,
                   data.dimensions_in_what().value_tuple().dimensions_value(0).field());
         EXPECT_EQ(appUid2, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-        EXPECT_EQ(1, data.bucket_info_size());
-        EXPECT_EQ(1, data.bucket_info(0).atom_size());
-        EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
+        ASSERT_EQ(1, data.bucket_info_size());
+        ASSERT_EQ(1, data.bucket_info(0).atom_size());
+        ASSERT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
         EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
                   data.bucket_info(0).start_bucket_elapsed_nanos());
         EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
index ba8d283..e320419 100644
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
@@ -267,10 +267,10 @@
 
     processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
 
-    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     auto& eventActivationMap = metricProducer->mEventActivationMap;
 
@@ -278,7 +278,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
     // triggered by screen on event (tracker index 2).
-    EXPECT_EQ(eventActivationMap.size(), 2u);
+    ASSERT_EQ(eventActivationMap.size(), 2u);
     EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
@@ -302,7 +302,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 1);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
@@ -353,7 +353,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // New broadcast since the config is no longer active.
     EXPECT_EQ(broadcastCount, 2);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
     EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
@@ -368,7 +368,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
@@ -389,42 +389,42 @@
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(4, countMetrics.data_size());
+    ASSERT_EQ(4, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     // Partial bucket as metric is deactivated.
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -433,11 +433,11 @@
 
     data = countMetrics.data(3);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -478,10 +478,10 @@
 
     processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
 
-    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     auto& eventActivationMap = metricProducer->mEventActivationMap;
     auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
@@ -490,7 +490,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
     // triggered by screen on event (tracker index 2).
-    EXPECT_EQ(eventActivationMap.size(), 2u);
+    ASSERT_EQ(eventActivationMap.size(), 2u);
     EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
@@ -499,9 +499,9 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap.size(), 1u);
+    ASSERT_EQ(eventDeactivationMap.size(), 1u);
     EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
-    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
+    ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
     EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
 
     std::unique_ptr<LogEvent> event;
@@ -518,7 +518,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 1);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
@@ -572,7 +572,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // New broadcast since the config is no longer active.
     EXPECT_EQ(broadcastCount, 2);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
     EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
@@ -588,7 +588,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
@@ -608,7 +608,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -628,7 +628,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -645,7 +645,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // New broadcast since the config is no longer active.
     EXPECT_EQ(broadcastCount, 4);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
     EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
@@ -663,7 +663,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 5);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
@@ -679,7 +679,7 @@
     EXPECT_FALSE(metricsManager->isActive());
     EXPECT_FALSE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 6);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
     EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
@@ -696,42 +696,42 @@
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(5, countMetrics.data_size());
+    ASSERT_EQ(5, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     // Partial bucket as metric is deactivated.
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -740,11 +740,11 @@
 
     data = countMetrics.data(3);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -753,11 +753,11 @@
 
     data = countMetrics.data(4);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -799,10 +799,10 @@
 
     processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
 
-    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     auto& eventActivationMap = metricProducer->mEventActivationMap;
     auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
@@ -811,7 +811,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
     // triggered by screen on event (tracker index 2).
-    EXPECT_EQ(eventActivationMap.size(), 2u);
+    ASSERT_EQ(eventActivationMap.size(), 2u);
     EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
@@ -820,11 +820,11 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap.size(), 2u);
+    ASSERT_EQ(eventDeactivationMap.size(), 2u);
     EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
     EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
-    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
-    EXPECT_EQ(eventDeactivationMap[4].size(), 1u);
+    ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
+    ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
     EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
     EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
@@ -842,7 +842,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 1);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
@@ -899,7 +899,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // New broadcast since the config is no longer active.
     EXPECT_EQ(broadcastCount, 2);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
     EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
@@ -916,7 +916,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
@@ -937,7 +937,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -959,7 +959,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // New broadcast since the config is no longer active.
     EXPECT_EQ(broadcastCount, 4);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
     EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
@@ -975,7 +975,7 @@
     EXPECT_FALSE(metricsManager->isActive());
     EXPECT_FALSE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 4);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
     EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
@@ -994,7 +994,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 5);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
@@ -1011,7 +1011,7 @@
     EXPECT_FALSE(metricsManager->isActive());
     EXPECT_FALSE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 6);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
     EXPECT_EQ(eventActivationMap[0]->ttl_ns, 60 * 6 * NS_PER_SEC);
@@ -1029,42 +1029,42 @@
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(5, countMetrics.data_size());
+    ASSERT_EQ(5, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     // Partial bucket as metric is deactivated.
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1073,11 +1073,11 @@
 
     data = countMetrics.data(3);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1086,11 +1086,11 @@
 
     data = countMetrics.data(4);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1132,10 +1132,10 @@
 
     processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
 
-    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 1);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     auto& eventActivationMap = metricProducer->mEventActivationMap;
     auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
@@ -1144,7 +1144,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
     // triggered by screen on event (tracker index 2).
-    EXPECT_EQ(eventActivationMap.size(), 2u);
+    ASSERT_EQ(eventActivationMap.size(), 2u);
     EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
@@ -1153,9 +1153,9 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap.size(), 1u);
+    ASSERT_EQ(eventDeactivationMap.size(), 1u);
     EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
-    EXPECT_EQ(eventDeactivationMap[3].size(), 2u);
+    ASSERT_EQ(eventDeactivationMap[3].size(), 2u);
     EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
     EXPECT_EQ(eventDeactivationMap[3][1], eventActivationMap[2]);
     EXPECT_EQ(broadcastCount, 0);
@@ -1172,7 +1172,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 1);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
@@ -1205,7 +1205,7 @@
     EXPECT_FALSE(metricProducer->mIsActive);
     // New broadcast since the config is no longer active.
     EXPECT_EQ(broadcastCount, 2);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
 
@@ -1219,7 +1219,7 @@
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 15);
@@ -1236,7 +1236,7 @@
     EXPECT_FALSE(metricsManager->isActive());
     EXPECT_FALSE(metricProducer->mIsActive);
     EXPECT_EQ(broadcastCount, 4);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
 
@@ -1252,42 +1252,42 @@
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(3, countMetrics.data_size());
+    ASSERT_EQ(3, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(firstDeactivation, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(555, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     // Partial bucket as metric is deactivated.
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
@@ -1329,10 +1329,10 @@
 
     processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);
 
-    EXPECT_EQ(processor.mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
     sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(metricsManager->mAllMetricProducers.size(), 2);
+    ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 2);
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
     auto& eventActivationMap = metricProducer->mEventActivationMap;
     auto& eventDeactivationMap = metricProducer->mEventDeactivationMap;
@@ -1345,7 +1345,7 @@
     EXPECT_FALSE(metricProducer2->mIsActive);
     // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
     // triggered by screen on event (tracker index 2).
-    EXPECT_EQ(eventActivationMap.size(), 2u);
+    ASSERT_EQ(eventActivationMap.size(), 2u);
     EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
@@ -1354,15 +1354,15 @@
     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap.size(), 2u);
+    ASSERT_EQ(eventDeactivationMap.size(), 2u);
     EXPECT_TRUE(eventDeactivationMap.find(3) != eventDeactivationMap.end());
     EXPECT_TRUE(eventDeactivationMap.find(4) != eventDeactivationMap.end());
-    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
-    EXPECT_EQ(eventDeactivationMap[4].size(), 1u);
+    ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
+    ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
     EXPECT_EQ(eventDeactivationMap[3][0], eventActivationMap[0]);
     EXPECT_EQ(eventDeactivationMap[4][0], eventActivationMap[2]);
 
-    EXPECT_EQ(eventActivationMap2.size(), 2u);
+    ASSERT_EQ(eventActivationMap2.size(), 2u);
     EXPECT_TRUE(eventActivationMap2.find(0) != eventActivationMap2.end());
     EXPECT_TRUE(eventActivationMap2.find(2) != eventActivationMap2.end());
     EXPECT_EQ(eventActivationMap2[0]->state, ActivationState::kNotActive);
@@ -1371,11 +1371,11 @@
     EXPECT_EQ(eventActivationMap2[2]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap2[2]->start_ns, 0);
     EXPECT_EQ(eventActivationMap2[2]->ttl_ns, 60 * 2 * NS_PER_SEC);
-    EXPECT_EQ(eventDeactivationMap2.size(), 2u);
+    ASSERT_EQ(eventDeactivationMap2.size(), 2u);
     EXPECT_TRUE(eventDeactivationMap2.find(3) != eventDeactivationMap2.end());
     EXPECT_TRUE(eventDeactivationMap2.find(4) != eventDeactivationMap2.end());
-    EXPECT_EQ(eventDeactivationMap[3].size(), 1u);
-    EXPECT_EQ(eventDeactivationMap[4].size(), 1u);
+    ASSERT_EQ(eventDeactivationMap[3].size(), 1u);
+    ASSERT_EQ(eventDeactivationMap[4].size(), 1u);
     EXPECT_EQ(eventDeactivationMap2[3][0], eventActivationMap2[0]);
     EXPECT_EQ(eventDeactivationMap2[4][0], eventActivationMap2[2]);
 
@@ -1395,7 +1395,7 @@
     processor.OnLogEvent(event.get(), bucketStartTimeNs + 10);
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_EQ(broadcastCount, 1);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
@@ -1487,7 +1487,7 @@
     EXPECT_FALSE(metricsManager->isActive());
     // New broadcast since the config is no longer active.
     EXPECT_EQ(broadcastCount, 2);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_FALSE(metricProducer->mIsActive);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + 10);
@@ -1513,7 +1513,7 @@
     processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
@@ -1545,7 +1545,7 @@
     processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_EQ(broadcastCount, 3);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
@@ -1578,7 +1578,7 @@
     EXPECT_FALSE(metricsManager->isActive());
     // New broadcast since the config is no longer active.
     EXPECT_EQ(broadcastCount, 4);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_FALSE(metricProducer->mIsActive);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -1605,7 +1605,7 @@
     processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 13);
     EXPECT_FALSE(metricsManager->isActive());
     EXPECT_EQ(broadcastCount, 4);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_FALSE(metricProducer->mIsActive);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 15);
@@ -1635,7 +1635,7 @@
     processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
     EXPECT_TRUE(metricsManager->isActive());
     EXPECT_EQ(broadcastCount, 5);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 1);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 1);
     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
     EXPECT_TRUE(metricProducer->mIsActive);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kActive);
@@ -1661,7 +1661,7 @@
     processor.OnLogEvent(event.get(), bucketStartTimeNs + NS_PER_SEC * 60 * 16);
     EXPECT_FALSE(metricsManager->isActive());
     EXPECT_EQ(broadcastCount, 6);
-    EXPECT_EQ(activeConfigsBroadcast.size(), 0);
+    ASSERT_EQ(activeConfigsBroadcast.size(), 0);
     EXPECT_FALSE(metricProducer->mIsActive);
     EXPECT_EQ(eventActivationMap[0]->state, ActivationState::kNotActive);
     EXPECT_EQ(eventActivationMap[0]->start_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 15);
@@ -1689,43 +1689,43 @@
     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
     backfillDimensionPath(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(2, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(2, reports.reports(0).metrics_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
 
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    EXPECT_EQ(5, countMetrics.data_size());
+    ASSERT_EQ(5, countMetrics.data_size());
 
     auto data = countMetrics.data(0);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     // Partial bucket as metric is deactivated.
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1734,11 +1734,11 @@
 
     data = countMetrics.data(3);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1747,11 +1747,11 @@
 
     data = countMetrics.data(4);
     EXPECT_EQ(util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1760,37 +1760,37 @@
 
     countMetrics.clear_data();
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(1).count_metrics(), &countMetrics);
-    EXPECT_EQ(5, countMetrics.data_size());
+    ASSERT_EQ(5, countMetrics.data_size());
 
     data = countMetrics.data(0);
     EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(2222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(1);
     EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(3333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
 
     data = countMetrics.data(2);
     EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(4444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     // Partial bucket as metric is deactivated.
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1799,11 +1799,11 @@
 
     data = countMetrics.data(3);
     EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(6666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1812,11 +1812,11 @@
 
     data = countMetrics.data(4);
     EXPECT_EQ(util::ACTIVITY_FOREGROUND_STATE_CHANGED, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* uid field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_EQ(7777, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
               data.bucket_info(0).start_bucket_elapsed_nanos());
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index f0df2c6..5e77ee0 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -107,7 +107,7 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
 
     int appUid = 123;
@@ -204,15 +204,15 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(reports.reports_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
+    ASSERT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 1);
     EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
     auto data = reports.reports(0).metrics(0).count_metrics().data(0);
     // Validate dimension value.
     EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
+    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
     // Uid field.
     EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
     EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
@@ -226,7 +226,7 @@
 
     ConfigKey cfgKey;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
 
     int appUid = 123;
@@ -324,16 +324,16 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(reports.reports_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 2);
+    ASSERT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info_size(), 2);
     EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(0).count(), 1);
     EXPECT_EQ(reports.reports(0).metrics(0).count_metrics().data(0).bucket_info(1).count(), 3);
     auto data = reports.reports(0).metrics(0).count_metrics().data(0);
     // Validate dimension value.
     EXPECT_EQ(data.dimensions_in_what().field(), util::PROCESS_LIFE_CYCLE_STATE_CHANGED);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
+    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
     // Uid field.
     EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 1);
     EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), appUid);
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index 9117623..783f31c 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -127,8 +127,8 @@
 
     ConfigMetricsReport report = GetReports(service->mProcessor, start + 3);
     // Expect no metrics since the bucket has not finished yet.
-    EXPECT_EQ(1, report.metrics_size());
-    EXPECT_EQ(0, report.metrics(0).count_metrics().data_size());
+    ASSERT_EQ(1, report.metrics_size());
+    ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
@@ -147,8 +147,8 @@
     service->mProcessor->OnLogEvent(CreateAppCrashEvent(start + 3, 100).get());
 
     ConfigMetricsReport report = GetReports(service->mProcessor, start + 4);
-    EXPECT_EQ(1, report.metrics_size());
-    EXPECT_EQ(0, report.metrics(0).count_metrics().data_size());
+    ASSERT_EQ(1, report.metrics_size());
+    ASSERT_EQ(0, report.metrics(0).count_metrics().data_size());
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
@@ -267,8 +267,8 @@
             GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100 * NS_PER_SEC);
     backfillStartEndTimestamp(&report);
 
-    EXPECT_EQ(1, report.metrics_size());
-    EXPECT_EQ(0, report.metrics(0).value_metrics().skipped_size());
+    ASSERT_EQ(1, report.metrics_size());
+    ASSERT_EQ(0, report.metrics(0).value_metrics().skipped_size());
 
     // The fake subsystem state sleep puller returns two atoms.
     ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
@@ -305,7 +305,7 @@
               report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
 
     ASSERT_EQ(2, report.metrics(0).value_metrics().data_size());
-    EXPECT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
+    ASSERT_EQ(1, report.metrics(0).value_metrics().data(0).bucket_info_size());
 }
 
 TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket) {
@@ -329,7 +329,7 @@
 
     // First bucket is dropped due to the initial pull failing
     ASSERT_EQ(1, report.metrics_size());
-    EXPECT_EQ(1, report.metrics(0).value_metrics().skipped_size());
+    ASSERT_EQ(1, report.metrics(0).value_metrics().skipped_size());
     EXPECT_EQ(MillisToNano(NanoToMillis(bootCompleteTimeNs)),
               report.metrics(0).value_metrics().skipped(0).end_bucket_elapsed_nanos());
 
@@ -359,10 +359,10 @@
     ConfigMetricsReport report = GetReports(service->mProcessor, 5 * 60 * NS_PER_SEC + start + 100);
     backfillStartEndTimestamp(&report);
     ASSERT_EQ(1, report.metrics_size());
-    EXPECT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
+    ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
     // The fake subsystem state sleep puller returns two atoms.
     ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
-    EXPECT_EQ(2, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
+    ASSERT_EQ(2, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
 }
 
 TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) {
@@ -391,7 +391,7 @@
     EXPECT_EQ(MillisToNano(NanoToMillis(endSkipped)),
               report.metrics(0).gauge_metrics().skipped(0).end_bucket_elapsed_nanos());
     ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
-    EXPECT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
+    ASSERT_EQ(1, report.metrics(0).gauge_metrics().data(0).bucket_info_size());
 }
 
 TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket) {
@@ -414,7 +414,7 @@
     backfillStartEndTimestamp(&report);
 
     ASSERT_EQ(1, report.metrics_size());
-    EXPECT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
+    ASSERT_EQ(0, report.metrics(0).gauge_metrics().skipped_size());
     // The fake subsystem state sleep puller returns two atoms.
     ASSERT_EQ(2, report.metrics(0).gauge_metrics().data_size());
     // No data in the first bucket, so nothing is reported
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index 0c4a7c6..e595f29 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -75,7 +75,7 @@
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                              SharedRefBase::make<FakeSubsystemSleepCallback>(),
                                              util::SUBSYSTEM_SLEEP_STATE);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
 
@@ -86,7 +86,7 @@
 
     // When creating the config, the value metric producer should register the alarm at the
     // end of the current bucket.
-    EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
+    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
     EXPECT_EQ(bucketSizeNs,
               processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
     int64_t& expectedPullTimeNs =
@@ -136,36 +136,36 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::ValueMetricDataWrapper valueMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
-    EXPECT_GT((int)valueMetrics.data_size(), 1);
+    ASSERT_GT((int)valueMetrics.data_size(), 1);
 
     auto data = valueMetrics.data(0);
     EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
     // We have 4 buckets, the first one was incomplete since the condition was unknown.
-    EXPECT_EQ(4, data.bucket_info_size());
+    ASSERT_EQ(4, data.bucket_info_size());
 
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(0).values_size());
+    ASSERT_EQ(1, data.bucket_info(0).values_size());
 
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(1).values_size());
+    ASSERT_EQ(1, data.bucket_info(1).values_size());
 
     EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(2).values_size());
+    ASSERT_EQ(1, data.bucket_info(2).values_size());
 
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(3).values_size());
+    ASSERT_EQ(1, data.bucket_info(3).values_size());
 }
 
 TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
@@ -179,7 +179,7 @@
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                              SharedRefBase::make<FakeSubsystemSleepCallback>(),
                                              util::SUBSYSTEM_SLEEP_STATE);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
 
@@ -190,7 +190,7 @@
 
     // When creating the config, the value metric producer should register the alarm at the
     // end of the current bucket.
-    EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
+    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
     EXPECT_EQ(bucketSizeNs,
               processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
     int64_t& expectedPullTimeNs =
@@ -244,31 +244,31 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::ValueMetricDataWrapper valueMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
-    EXPECT_GT((int)valueMetrics.data_size(), 1);
+    ASSERT_GT((int)valueMetrics.data_size(), 1);
 
     auto data = valueMetrics.data(0);
     EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
-    EXPECT_EQ(3, data.bucket_info_size());
+    ASSERT_EQ(3, data.bucket_info_size());
 
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(0).values_size());
+    ASSERT_EQ(1, data.bucket_info(0).values_size());
 
     EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(1).values_size());
+    ASSERT_EQ(1, data.bucket_info(1).values_size());
 
     EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 10 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, data.bucket_info(2).values_size());
+    ASSERT_EQ(1, data.bucket_info(2).values_size());
 }
 
 TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation) {
@@ -291,7 +291,7 @@
     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey,
                                              SharedRefBase::make<FakeSubsystemSleepCallback>(),
                                              util::SUBSYSTEM_SLEEP_STATE);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     processor->mPullerManager->ForceClearPullerCache();
 
@@ -303,7 +303,7 @@
 
     // When creating the config, the value metric producer should register the alarm at the
     // end of the current bucket.
-    EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
+    ASSERT_EQ((size_t)1, processor->mPullerManager->mReceivers.size());
     EXPECT_EQ(bucketSizeNs,
               processor->mPullerManager->mReceivers.begin()->second.front().intervalNs);
     int64_t& expectedPullTimeNs =
@@ -347,30 +347,30 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(1, reports.reports_size());
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(1, reports.reports_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
     StatsLogReport::ValueMetricDataWrapper valueMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).value_metrics(), &valueMetrics);
-    EXPECT_GT((int)valueMetrics.data_size(), 0);
+    ASSERT_GT((int)valueMetrics.data_size(), 0);
 
     auto data = valueMetrics.data(0);
     EXPECT_EQ(util::SUBSYSTEM_SLEEP_STATE, data.dimensions_in_what().field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
     EXPECT_EQ(1 /* subsystem name field */,
               data.dimensions_in_what().value_tuple().dimensions_value(0).field());
     EXPECT_FALSE(data.dimensions_in_what().value_tuple().dimensions_value(0).value_str().empty());
     // We have 2 full buckets, the two surrounding the activation are dropped.
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
 
     auto bucketInfo = data.bucket_info(0);
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, bucketInfo.values_size());
+    ASSERT_EQ(1, bucketInfo.values_size());
 
     bucketInfo = data.bucket_info(1);
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, bucketInfo.start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
-    EXPECT_EQ(1, bucketInfo.values_size());
+    ASSERT_EQ(1, bucketInfo.values_size());
 }
 
 /**
@@ -416,14 +416,14 @@
     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
 
     // Check that ValueMetricProducer was initialized correctly.
-    EXPECT_EQ(1U, processor->mMetricsManagers.size());
+    ASSERT_EQ(1U, processor->mMetricsManagers.size());
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(1, metricsManager->mAllMetricProducers.size());
+    ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_EQ(1, metricProducer->mSlicedStateAtoms.size());
+    ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
-    EXPECT_EQ(0, metricProducer->mStateGroupMap.size());
+    ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
 }
 
 /**
@@ -476,14 +476,14 @@
     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
 
     // Check that ValueMetricProducer was initialized correctly.
-    EXPECT_EQ(1U, processor->mMetricsManagers.size());
+    ASSERT_EQ(1U, processor->mMetricsManagers.size());
     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
     EXPECT_TRUE(metricsManager->isConfigValid());
-    EXPECT_EQ(1, metricsManager->mAllMetricProducers.size());
+    ASSERT_EQ(1, metricsManager->mAllMetricProducers.size());
     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
-    EXPECT_EQ(1, metricProducer->mSlicedStateAtoms.size());
+    ASSERT_EQ(1, metricProducer->mSlicedStateAtoms.size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, metricProducer->mSlicedStateAtoms.at(0));
-    EXPECT_EQ(0, metricProducer->mStateGroupMap.size());
+    ASSERT_EQ(0, metricProducer->mStateGroupMap.size());
 }
 
 /**
@@ -532,7 +532,7 @@
     EXPECT_EQ(0, StateManager::getInstance().getStateTrackersCount());
 
     // Config initialization fails.
-    EXPECT_EQ(0, processor->mMetricsManagers.size());
+    ASSERT_EQ(0, processor->mMetricsManagers.size());
 }
 
 #else
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
index 80f3c28..52bc222 100644
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
@@ -121,7 +121,7 @@
     uint64_t bucketSizeNs =
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     FeedEvents(config, processor);
     vector<uint8_t> buffer;
@@ -134,17 +134,17 @@
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(reports.reports_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
+    ASSERT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
     // Only 1 dimension output. The tag dimension in the predicate has been aggregated.
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
 
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
                                     util::WAKELOCK_STATE_CHANGED, 111);
     // Validate bucket info.
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
     data = reports.reports(0).metrics(0).duration_metrics().data(0);
     // The wakelock holding interval starts from the screen off event and to the end of the 1st
     // bucket.
@@ -158,7 +158,7 @@
     uint64_t bucketSizeNs =
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     FeedEvents(config, processor);
     vector<uint8_t> buffer;
@@ -170,11 +170,11 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(reports.reports_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
+    ASSERT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
     // Dump the report after the end of 2nd bucket.
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
@@ -196,7 +196,7 @@
     uint64_t bucketSizeNs =
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     FeedEvents(config, processor);
     vector<uint8_t> buffer;
@@ -222,10 +222,10 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(reports.reports_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
+    ASSERT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 6);
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     ValidateAttributionUidDimension(data.dimensions_in_what(),
                                     util::WAKELOCK_STATE_CHANGED, 111);
@@ -243,7 +243,7 @@
     uint64_t bucketSizeNs =
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     FeedEvents(config, processor);
     ConfigMetricsReportList reports;
@@ -257,13 +257,13 @@
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
 
-    EXPECT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports_size(), 1);
 
     // When using ProtoOutputStream, if nothing written to a sub msg, it won't be treated as
     // one. It was previsouly 1 because we had a fake onDumpReport which calls add_metric() by
     // itself.
-    EXPECT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(0, reports.reports(0).metrics(0).duration_metrics().data_size());
+    ASSERT_EQ(1, reports.reports(0).metrics_size());
+    ASSERT_EQ(0, reports.reports(0).metrics(0).duration_metrics().data_size());
 }
 
 TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2) {
@@ -273,7 +273,7 @@
     uint64_t bucketSizeNs =
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     FeedEvents(config, processor);
     ConfigMetricsReportList reports;
@@ -285,11 +285,11 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(reports.reports_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
+    ASSERT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
     // Dump the report after the end of 2nd bucket. One dimension with one bucket.
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 1);
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
@@ -305,7 +305,7 @@
     uint64_t bucketSizeNs =
             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
     EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
     FeedEvents(config, processor);
     ConfigMetricsReportList reports;
@@ -331,10 +331,10 @@
     backfillDimensionPath(&reports);
     backfillStringInReport(&reports);
     backfillStartEndTimestamp(&reports);
-    EXPECT_EQ(reports.reports_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
-    EXPECT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
+    ASSERT_EQ(reports.reports_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data_size(), 1);
+    ASSERT_EQ(reports.reports(0).metrics(0).duration_metrics().data(0).bucket_info_size(), 2);
     auto data = reports.reports(0).metrics(0).duration_metrics().data(0);
     ValidateAttributionUidDimension(data.dimensions_in_what(),
                                     util::WAKELOCK_STATE_CHANGED, 111);
diff --git a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
index 4b9bac1..13cdfc2 100644
--- a/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
+++ b/cmds/statsd/tests/external/StatsCallbackPuller_test.cpp
@@ -131,11 +131,11 @@
     EXPECT_TRUE(puller.PullInternal(&dataHolder));
     int64_t endTimeNs = getElapsedRealtimeNs();
 
-    EXPECT_EQ(1, dataHolder.size());
+    ASSERT_EQ(1, dataHolder.size());
     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
     EXPECT_LT(startTimeNs, dataHolder[0]->GetElapsedTimestampNs());
     EXPECT_GT(endTimeNs, dataHolder[0]->GetElapsedTimestampNs());
-    EXPECT_EQ(1, dataHolder[0]->size());
+    ASSERT_EQ(1, dataHolder[0]->size());
     EXPECT_EQ(value, dataHolder[0]->getValues()[0].mValue.int_value);
 }
 
@@ -149,13 +149,13 @@
 
     vector<shared_ptr<LogEvent>> dataHolder;
     EXPECT_FALSE(puller.PullInternal(&dataHolder));
-    EXPECT_EQ(0, dataHolder.size());
+    ASSERT_EQ(0, dataHolder.size());
 }
 
 TEST_F(StatsCallbackPullerTest, PullTimeout) {
     shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
     pullSuccess = true;
-    pullDelayNs = 500000000;  // 500ms.
+    pullDelayNs = MillisToNano(5);  // 5ms.
     pullTimeoutNs = 10000;    // 10 microseconds.
     int64_t value = 4321;
     values.push_back(value);
@@ -173,18 +173,18 @@
     // is bigger.
     EXPECT_LT(pullTimeoutNs, actualPullDurationNs);
     EXPECT_GT(pullDelayNs, actualPullDurationNs);
-    EXPECT_EQ(0, dataHolder.size());
+    ASSERT_EQ(0, dataHolder.size());
 
     // Let the pull return and make sure that the dataHolder is not modified.
     pullThread.join();
-    EXPECT_EQ(0, dataHolder.size());
+    ASSERT_EQ(0, dataHolder.size());
 }
 
 // Register a puller and ensure that the timeout logic works.
 TEST_F(StatsCallbackPullerTest, RegisterAndTimeout) {
     shared_ptr<FakePullAtomCallback> cb = SharedRefBase::make<FakePullAtomCallback>();
     pullSuccess = true;
-    pullDelayNs = 500000000;  // 500 ms.
+    pullDelayNs = MillisToNano(5);  // 5 ms.
     pullTimeoutNs = 10000;    // 10 microsseconds.
     int64_t value = 4321;
     int32_t uid = 123;
@@ -196,7 +196,7 @@
     vector<shared_ptr<LogEvent>> dataHolder;
     int64_t startTimeNs = getElapsedRealtimeNs();
     // Returns false, since StatsPuller code will evaluate the timeout.
-    EXPECT_FALSE(pullerManager->Pull(pullTagId, {uid}, &dataHolder));
+    EXPECT_FALSE(pullerManager->Pull(pullTagId, {uid}, startTimeNs, &dataHolder));
     int64_t endTimeNs = getElapsedRealtimeNs();
     int64_t actualPullDurationNs = endTimeNs - startTimeNs;
 
@@ -204,11 +204,11 @@
     // is bigger.
     EXPECT_LT(pullTimeoutNs, actualPullDurationNs);
     EXPECT_GT(pullDelayNs, actualPullDurationNs);
-    EXPECT_EQ(0, dataHolder.size());
+    ASSERT_EQ(0, dataHolder.size());
 
     // Let the pull return and make sure that the dataHolder is not modified.
     pullThread.join();
-    EXPECT_EQ(0, dataHolder.size());
+    ASSERT_EQ(0, dataHolder.size());
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/tests/external/StatsPullerManager_test.cpp b/cmds/statsd/tests/external/StatsPullerManager_test.cpp
index 6b3f4cc..c76e85e 100644
--- a/cmds/statsd/tests/external/StatsPullerManager_test.cpp
+++ b/cmds/statsd/tests/external/StatsPullerManager_test.cpp
@@ -101,14 +101,14 @@
     sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
 
     vector<shared_ptr<LogEvent>> data;
-    EXPECT_FALSE(pullerManager->Pull(pullTagId1, {unregisteredUid}, &data, true));
+    EXPECT_FALSE(pullerManager->Pull(pullTagId1, {unregisteredUid}, /*timestamp =*/1, &data, true));
 }
 
 TEST(StatsPullerManagerTest, TestPullChoosesCorrectUid) {
     sp<StatsPullerManager> pullerManager = createPullerManagerAndRegister();
 
     vector<shared_ptr<LogEvent>> data;
-    EXPECT_TRUE(pullerManager->Pull(pullTagId1, {uid1}, &data, true));
+    EXPECT_TRUE(pullerManager->Pull(pullTagId1, {uid1}, /*timestamp =*/1, &data, true));
     ASSERT_EQ(data.size(), 1);
     EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
     ASSERT_EQ(data[0]->getValues().size(), 1);
@@ -121,7 +121,7 @@
     pullerManager->RegisterPullUidProvider(configKey, uidProvider);
 
     vector<shared_ptr<LogEvent>> data;
-    EXPECT_FALSE(pullerManager->Pull(pullTagId1, badConfigKey, &data, true));
+    EXPECT_FALSE(pullerManager->Pull(pullTagId1, badConfigKey, /*timestamp =*/1, &data, true));
 }
 
 TEST(StatsPullerManagerTest, TestPullConfigKeyGood) {
@@ -130,7 +130,7 @@
     pullerManager->RegisterPullUidProvider(configKey, uidProvider);
 
     vector<shared_ptr<LogEvent>> data;
-    EXPECT_TRUE(pullerManager->Pull(pullTagId1, configKey, &data, true));
+    EXPECT_TRUE(pullerManager->Pull(pullTagId1, configKey, /*timestamp =*/1, &data, true));
     EXPECT_EQ(data[0]->GetTagId(), pullTagId1);
     ASSERT_EQ(data[0]->getValues().size(), 1);
     EXPECT_EQ(data[0]->getValues()[0].mValue.int_value, uid2);
@@ -142,7 +142,7 @@
     pullerManager->RegisterPullUidProvider(configKey, uidProvider);
 
     vector<shared_ptr<LogEvent>> data;
-    EXPECT_FALSE(pullerManager->Pull(pullTagId2, configKey, &data, true));
+    EXPECT_FALSE(pullerManager->Pull(pullTagId2, configKey, /*timestamp =*/1, &data, true));
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/tests/external/StatsPuller_test.cpp b/cmds/statsd/tests/external/StatsPuller_test.cpp
index 5043358..55a9036 100644
--- a/cmds/statsd/tests/external/StatsPuller_test.cpp
+++ b/cmds/statsd/tests/external/StatsPuller_test.cpp
@@ -39,7 +39,6 @@
 using testing::Contains;
 
 namespace {
-// cooldown time 1sec.
 int pullTagId = 10014;
 
 bool pullSuccess;
@@ -48,7 +47,8 @@
 
 class FakePuller : public StatsPuller {
 public:
-    FakePuller() : StatsPuller(pullTagId, /*coolDown=*/NS_PER_SEC, /*timeout=*/NS_PER_SEC / 2){};
+    FakePuller()
+        : StatsPuller(pullTagId, /*coolDownNs=*/MillisToNano(10), /*timeoutNs=*/MillisToNano(5)){};
 
 private:
     bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override {
@@ -92,25 +92,25 @@
     pullSuccess = true;
 
     vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_TRUE(puller.Pull(&dataHolder));
-    EXPECT_EQ(1, dataHolder.size());
+    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(1, dataHolder.size());
     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    EXPECT_EQ(1, dataHolder[0]->size());
+    ASSERT_EQ(1, dataHolder[0]->size());
     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
 
-    sleep_for(std::chrono::seconds(1));
+    sleep_for(std::chrono::milliseconds(11));
 
     pullData.clear();
     pullData.push_back(createSimpleEvent(2222L, 44));
 
     pullSuccess = true;
 
-    EXPECT_TRUE(puller.Pull(&dataHolder));
-    EXPECT_EQ(1, dataHolder.size());
+    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(1, dataHolder.size());
     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
     EXPECT_EQ(2222L, dataHolder[0]->GetElapsedTimestampNs());
-    EXPECT_EQ(1, dataHolder[0]->size());
+    ASSERT_EQ(1, dataHolder[0]->size());
     EXPECT_EQ(44, dataHolder[0]->getValues()[0].mValue.int_value);
 }
 
@@ -120,47 +120,49 @@
     pullSuccess = true;
 
     vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_TRUE(puller.Pull(&dataHolder));
-    EXPECT_EQ(1, dataHolder.size());
+    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(1, dataHolder.size());
     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    EXPECT_EQ(1, dataHolder[0]->size());
+    ASSERT_EQ(1, dataHolder[0]->size());
     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
 
-    sleep_for(std::chrono::seconds(1));
+    sleep_for(std::chrono::milliseconds(11));
 
     pullData.clear();
     pullData.push_back(createSimpleEvent(2222L, 44));
 
     pullSuccess = false;
     dataHolder.clear();
-    EXPECT_FALSE(puller.Pull(&dataHolder));
-    EXPECT_EQ(0, dataHolder.size());
+    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
 
+    // Fails due to hitting the cool down.
     pullSuccess = true;
     dataHolder.clear();
-    EXPECT_FALSE(puller.Pull(&dataHolder));
-    EXPECT_EQ(0, dataHolder.size());
+    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
 }
 
 // Test pull takes longer than timeout, 2nd pull happens shorter than cooldown
 TEST_F(StatsPullerTest, PullTakeTooLongAndPullFast) {
     pullData.push_back(createSimpleEvent(1111L, 33));
     pullSuccess = true;
-    // timeout is 0.5
-    pullDelayNs = (long)(0.8 * NS_PER_SEC);
+    // timeout is 5ms
+    pullDelayNs = MillisToNano(6);
 
     vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(&dataHolder));
-    EXPECT_EQ(0, dataHolder.size());
+    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
 
     pullData.clear();
     pullData.push_back(createSimpleEvent(2222L, 44));
+    pullDelayNs = 0;
 
     pullSuccess = true;
     dataHolder.clear();
-    EXPECT_FALSE(puller.Pull(&dataHolder));
-    EXPECT_EQ(0, dataHolder.size());
+    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
 }
 
 TEST_F(StatsPullerTest, PullFail) {
@@ -169,19 +171,19 @@
     pullSuccess = false;
 
     vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(&dataHolder));
-    EXPECT_EQ(0, dataHolder.size());
+    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
 }
 
 TEST_F(StatsPullerTest, PullTakeTooLong) {
     pullData.push_back(createSimpleEvent(1111L, 33));
 
     pullSuccess = true;
-    pullDelayNs = NS_PER_SEC;
+    pullDelayNs = MillisToNano(6);
 
     vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(&dataHolder));
-    EXPECT_EQ(0, dataHolder.size());
+    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
 }
 
 TEST_F(StatsPullerTest, PullTooFast) {
@@ -190,11 +192,11 @@
     pullSuccess = true;
 
     vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_TRUE(puller.Pull(&dataHolder));
-    EXPECT_EQ(1, dataHolder.size());
+    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(1, dataHolder.size());
     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    EXPECT_EQ(1, dataHolder[0]->size());
+    ASSERT_EQ(1, dataHolder[0]->size());
     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
 
     pullData.clear();
@@ -203,11 +205,11 @@
     pullSuccess = true;
 
     dataHolder.clear();
-    EXPECT_TRUE(puller.Pull(&dataHolder));
-    EXPECT_EQ(1, dataHolder.size());
+    EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(1, dataHolder.size());
     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
-    EXPECT_EQ(1, dataHolder[0]->size());
+    ASSERT_EQ(1, dataHolder[0]->size());
     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
 }
 
@@ -217,16 +219,93 @@
     pullSuccess = false;
 
     vector<std::shared_ptr<LogEvent>> dataHolder;
-    EXPECT_FALSE(puller.Pull(&dataHolder));
-    EXPECT_EQ(0, dataHolder.size());
+    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
 
     pullData.clear();
     pullData.push_back(createSimpleEvent(2222L, 44));
 
     pullSuccess = true;
 
-    EXPECT_FALSE(puller.Pull(&dataHolder));
-    EXPECT_EQ(0, dataHolder.size());
+    EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
+}
+
+TEST_F(StatsPullerTest, PullSameEventTime) {
+    pullData.push_back(createSimpleEvent(1111L, 33));
+
+    pullSuccess = true;
+    int64_t eventTimeNs = getElapsedRealtimeNs();
+
+    vector<std::shared_ptr<LogEvent>> dataHolder;
+    EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
+    ASSERT_EQ(1, dataHolder.size());
+    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
+    EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
+    ASSERT_EQ(1, dataHolder[0]->size());
+    EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
+
+    pullData.clear();
+    pullData.push_back(createSimpleEvent(2222L, 44));
+
+    // Sleep to ensure the cool down expires.
+    sleep_for(std::chrono::milliseconds(11));
+    pullSuccess = true;
+
+    dataHolder.clear();
+    EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
+    ASSERT_EQ(1, dataHolder.size());
+    EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
+    EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
+    ASSERT_EQ(1, dataHolder[0]->size());
+    EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
+}
+
+// Test pull takes longer than timeout, 2nd pull happens at same event time
+TEST_F(StatsPullerTest, PullTakeTooLongAndPullSameEventTime) {
+    pullData.push_back(createSimpleEvent(1111L, 33));
+    pullSuccess = true;
+    int64_t eventTimeNs = getElapsedRealtimeNs();
+    // timeout is 5ms
+    pullDelayNs = MillisToNano(6);
+
+    vector<std::shared_ptr<LogEvent>> dataHolder;
+    EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
+
+    // Sleep to ensure the cool down expires. 6ms is taken by the delay, so only 5 is needed here.
+    sleep_for(std::chrono::milliseconds(5));
+
+    pullData.clear();
+    pullData.push_back(createSimpleEvent(2222L, 44));
+    pullDelayNs = 0;
+
+    pullSuccess = true;
+    dataHolder.clear();
+    EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
+}
+
+TEST_F(StatsPullerTest, PullFailsAndPullSameEventTime) {
+    pullData.push_back(createSimpleEvent(1111L, 33));
+
+    pullSuccess = false;
+    int64_t eventTimeNs = getElapsedRealtimeNs();
+
+    vector<std::shared_ptr<LogEvent>> dataHolder;
+    EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
+
+    // Sleep to ensure the cool down expires.
+    sleep_for(std::chrono::milliseconds(11));
+
+    pullData.clear();
+    pullData.push_back(createSimpleEvent(2222L, 44));
+
+    pullSuccess = true;
+
+    EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
+    ASSERT_EQ(0, dataHolder.size());
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
index 948d587..5cc10cd 100644
--- a/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
+++ b/cmds/statsd/tests/guardrail/StatsdStats_test.cpp
@@ -42,7 +42,7 @@
     StatsdStatsReport report;
     bool good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
-    EXPECT_EQ(1, report.config_stats_size());
+    ASSERT_EQ(1, report.config_stats_size());
     const auto& configReport = report.config_stats(0);
     EXPECT_EQ(0, configReport.uid());
     EXPECT_EQ(12345, configReport.id());
@@ -69,7 +69,7 @@
     StatsdStatsReport report;
     bool good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
-    EXPECT_EQ(1, report.config_stats_size());
+    ASSERT_EQ(1, report.config_stats_size());
     const auto& configReport = report.config_stats(0);
     // The invalid config should be put into icebox with a deletion time.
     EXPECT_TRUE(configReport.has_deletion_time_sec());
@@ -89,7 +89,7 @@
     StatsdStatsReport report;
     bool good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
-    EXPECT_EQ(1, report.config_stats_size());
+    ASSERT_EQ(1, report.config_stats_size());
     const auto& configReport = report.config_stats(0);
     EXPECT_FALSE(configReport.has_deletion_time_sec());
 
@@ -97,7 +97,7 @@
     stats.dumpStats(&output, false);
     good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
-    EXPECT_EQ(1, report.config_stats_size());
+    ASSERT_EQ(1, report.config_stats_size());
     const auto& configReport2 = report.config_stats(0);
     EXPECT_TRUE(configReport2.has_deletion_time_sec());
 }
@@ -145,21 +145,21 @@
     StatsdStatsReport report;
     bool good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
-    EXPECT_EQ(1, report.config_stats_size());
+    ASSERT_EQ(1, report.config_stats_size());
     const auto& configReport = report.config_stats(0);
-    EXPECT_EQ(2, configReport.broadcast_sent_time_sec_size());
-    EXPECT_EQ(1, configReport.data_drop_time_sec_size());
-    EXPECT_EQ(1, configReport.data_drop_bytes_size());
+    ASSERT_EQ(2, configReport.broadcast_sent_time_sec_size());
+    ASSERT_EQ(1, configReport.data_drop_time_sec_size());
+    ASSERT_EQ(1, configReport.data_drop_bytes_size());
     EXPECT_EQ(123, configReport.data_drop_bytes(0));
-    EXPECT_EQ(3, configReport.dump_report_time_sec_size());
-    EXPECT_EQ(3, configReport.dump_report_data_size_size());
-    EXPECT_EQ(2, configReport.activation_time_sec_size());
-    EXPECT_EQ(1, configReport.deactivation_time_sec_size());
-    EXPECT_EQ(1, configReport.annotation_size());
+    ASSERT_EQ(3, configReport.dump_report_time_sec_size());
+    ASSERT_EQ(3, configReport.dump_report_data_size_size());
+    ASSERT_EQ(2, configReport.activation_time_sec_size());
+    ASSERT_EQ(1, configReport.deactivation_time_sec_size());
+    ASSERT_EQ(1, configReport.annotation_size());
     EXPECT_EQ(123, configReport.annotation(0).field_int64());
     EXPECT_EQ(456, configReport.annotation(0).field_int32());
 
-    EXPECT_EQ(2, configReport.matcher_stats_size());
+    ASSERT_EQ(2, configReport.matcher_stats_size());
     // matcher1 is the first in the list
     if (configReport.matcher_stats(0).id() == StringToId("matcher1")) {
         EXPECT_EQ(2, configReport.matcher_stats(0).matched_times());
@@ -174,18 +174,18 @@
         EXPECT_EQ(StringToId("matcher1"), configReport.matcher_stats(1).id());
     }
 
-    EXPECT_EQ(2, configReport.alert_stats_size());
+    ASSERT_EQ(2, configReport.alert_stats_size());
     bool alert1first = configReport.alert_stats(0).id() == StringToId("alert1");
     EXPECT_EQ(StringToId("alert1"), configReport.alert_stats(alert1first ? 0 : 1).id());
     EXPECT_EQ(2, configReport.alert_stats(alert1first ? 0 : 1).alerted_times());
     EXPECT_EQ(StringToId("alert2"), configReport.alert_stats(alert1first ? 1 : 0).id());
     EXPECT_EQ(1, configReport.alert_stats(alert1first ? 1 : 0).alerted_times());
 
-    EXPECT_EQ(1, configReport.condition_stats_size());
+    ASSERT_EQ(1, configReport.condition_stats_size());
     EXPECT_EQ(StringToId("condition1"), configReport.condition_stats(0).id());
     EXPECT_EQ(250, configReport.condition_stats(0).max_tuple_counts());
 
-    EXPECT_EQ(1, configReport.metric_stats_size());
+    ASSERT_EQ(1, configReport.metric_stats_size());
     EXPECT_EQ(StringToId("metric1"), configReport.metric_stats(0).id());
     EXPECT_EQ(202, configReport.metric_stats(0).max_tuple_counts());
 
@@ -199,21 +199,21 @@
     stats.dumpStats(&output, false);
     good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
-    EXPECT_EQ(1, report.config_stats_size());
+    ASSERT_EQ(1, report.config_stats_size());
     const auto& configReport2 = report.config_stats(0);
-    EXPECT_EQ(1, configReport2.matcher_stats_size());
+    ASSERT_EQ(1, configReport2.matcher_stats_size());
     EXPECT_EQ(StringToId("matcher99"), configReport2.matcher_stats(0).id());
     EXPECT_EQ(1, configReport2.matcher_stats(0).matched_times());
 
-    EXPECT_EQ(1, configReport2.condition_stats_size());
+    ASSERT_EQ(1, configReport2.condition_stats_size());
     EXPECT_EQ(StringToId("condition99"), configReport2.condition_stats(0).id());
     EXPECT_EQ(300, configReport2.condition_stats(0).max_tuple_counts());
 
-    EXPECT_EQ(1, configReport2.metric_stats_size());
+    ASSERT_EQ(1, configReport2.metric_stats_size());
     EXPECT_EQ(StringToId("metric99tion99"), configReport2.metric_stats(0).id());
     EXPECT_EQ(270, configReport2.metric_stats(0).max_tuple_counts());
 
-    EXPECT_EQ(1, configReport2.alert_stats_size());
+    ASSERT_EQ(1, configReport2.alert_stats_size());
     EXPECT_EQ(StringToId("alert99"), configReport2.alert_stats(0).id());
     EXPECT_EQ(1, configReport2.alert_stats(0).alerted_times());
 }
@@ -234,7 +234,7 @@
     bool good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
 
-    EXPECT_EQ(2, report.atom_stats_size());
+    ASSERT_EQ(2, report.atom_stats_size());
     bool sensorAtomGood = false;
     bool dropboxAtomGood = false;
 
@@ -267,7 +267,7 @@
     bool good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
 
-    EXPECT_EQ(2, report.atom_stats_size());
+    ASSERT_EQ(2, report.atom_stats_size());
     bool newAtom1Good = false;
     bool newAtom2Good = false;
 
@@ -313,7 +313,7 @@
     bool good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
 
-    EXPECT_EQ(1, report.pulled_atom_stats_size());
+    ASSERT_EQ(1, report.pulled_atom_stats_size());
 
     EXPECT_EQ(util::DISK_SPACE, report.pulled_atom_stats(0).atom_id());
     EXPECT_EQ(3, report.pulled_atom_stats(0).total_pull());
@@ -348,7 +348,7 @@
     bool good = report.ParseFromArray(&output[0], output.size());
     EXPECT_TRUE(good);
 
-    EXPECT_EQ(2, report.atom_metric_stats().size());
+    ASSERT_EQ(2, report.atom_metric_stats().size());
 
     auto atomStats = report.atom_metric_stats(0);
     EXPECT_EQ(1000L, atomStats.metric_id());
@@ -407,11 +407,11 @@
     const auto& configStats = stats.mConfigStats[key];
 
     size_t maxCount = StatsdStats::kMaxTimestampCount;
-    EXPECT_EQ(maxCount, configStats->broadcast_sent_time_sec.size());
-    EXPECT_EQ(maxCount, configStats->data_drop_time_sec.size());
-    EXPECT_EQ(maxCount, configStats->dump_report_stats.size());
-    EXPECT_EQ(maxCount, configStats->activation_time_sec.size());
-    EXPECT_EQ(maxCount, configStats->deactivation_time_sec.size());
+    ASSERT_EQ(maxCount, configStats->broadcast_sent_time_sec.size());
+    ASSERT_EQ(maxCount, configStats->data_drop_time_sec.size());
+    ASSERT_EQ(maxCount, configStats->dump_report_stats.size());
+    ASSERT_EQ(maxCount, configStats->activation_time_sec.size());
+    ASSERT_EQ(maxCount, configStats->deactivation_time_sec.size());
 
     // the oldest timestamp is the second timestamp in history
     EXPECT_EQ(1, configStats->broadcast_sent_time_sec.front());
@@ -441,13 +441,13 @@
     StatsdStatsReport report;
     EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
     const int maxCount = StatsdStats::kMaxSystemServerRestarts;
-    EXPECT_EQ(maxCount, (int)report.system_restart_sec_size());
+    ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
 
     stats.noteSystemServerRestart(StatsdStats::kMaxSystemServerRestarts + 1);
     output.clear();
     stats.dumpStats(&output, false);
     EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
-    EXPECT_EQ(maxCount, (int)report.system_restart_sec_size());
+    ASSERT_EQ(maxCount, (int)report.system_restart_sec_size());
     EXPECT_EQ(StatsdStats::kMaxSystemServerRestarts + 1, report.system_restart_sec(maxCount - 1));
 }
 
@@ -468,19 +468,19 @@
     StatsdStatsReport report;
     EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
 
-    EXPECT_EQ(2, report.activation_guardrail_stats_size());
+    ASSERT_EQ(2, report.activation_guardrail_stats_size());
     bool uid1Good = false;
     bool uid2Good = false;
     for (const auto& guardrailTimes : report.activation_guardrail_stats()) {
         if (uid1 == guardrailTimes.uid()) {
             uid1Good = true;
-            EXPECT_EQ(2, guardrailTimes.guardrail_met_sec_size());
+            ASSERT_EQ(2, guardrailTimes.guardrail_met_sec_size());
             EXPECT_EQ(10, guardrailTimes.guardrail_met_sec(0));
             EXPECT_EQ(20, guardrailTimes.guardrail_met_sec(1));
         } else if (uid2 == guardrailTimes.uid()) {
             int maxCount = StatsdStats::kMaxTimestampCount;
             uid2Good = true;
-            EXPECT_EQ(maxCount, guardrailTimes.guardrail_met_sec_size());
+            ASSERT_EQ(maxCount, guardrailTimes.guardrail_met_sec_size());
             for (int i = 0; i < maxCount; i++) {
                 EXPECT_EQ(100 - maxCount + i, guardrailTimes.guardrail_met_sec(i));
             }
@@ -515,13 +515,13 @@
     EXPECT_TRUE(report.ParseFromArray(&output[0], output.size()));
 
     // Check error count = numErrors for push atom
-    EXPECT_EQ(1, report.atom_stats_size());
+    ASSERT_EQ(1, report.atom_stats_size());
     const auto& pushedAtomStats = report.atom_stats(0);
     EXPECT_EQ(pushAtomTag, pushedAtomStats.tag());
     EXPECT_EQ(numErrors, pushedAtomStats.error_count());
 
     // Check error count = numErrors for pull atom
-    EXPECT_EQ(1, report.pulled_atom_stats_size());
+    ASSERT_EQ(1, report.pulled_atom_stats_size());
     const auto& pulledAtomStats = report.pulled_atom_stats(0);
     EXPECT_EQ(pullAtomTag, pulledAtomStats.atom_id());
     EXPECT_EQ(numErrors, pulledAtomStats.atom_error_count());
diff --git a/cmds/statsd/tests/indexed_priority_queue_test.cpp b/cmds/statsd/tests/indexed_priority_queue_test.cpp
index d6cd876..3a65456 100644
--- a/cmds/statsd/tests/indexed_priority_queue_test.cpp
+++ b/cmds/statsd/tests/indexed_priority_queue_test.cpp
@@ -44,23 +44,23 @@
     sp<const AATest> aa4 = new AATest{4, emptyMetricId, emptyDimensionId};
     sp<const AATest> aa8 = new AATest{8, emptyMetricId, emptyDimensionId};
 
-    EXPECT_EQ(0u, ipq.size());
+    ASSERT_EQ(0u, ipq.size());
     EXPECT_TRUE(ipq.empty());
 
     ipq.push(aa4);
-    EXPECT_EQ(1u, ipq.size());
+    ASSERT_EQ(1u, ipq.size());
     EXPECT_FALSE(ipq.empty());
 
     ipq.push(aa8);
-    EXPECT_EQ(2u, ipq.size());
+    ASSERT_EQ(2u, ipq.size());
     EXPECT_FALSE(ipq.empty());
 
     ipq.remove(aa4);
-    EXPECT_EQ(1u, ipq.size());
+    ASSERT_EQ(1u, ipq.size());
     EXPECT_FALSE(ipq.empty());
 
     ipq.remove(aa8);
-    EXPECT_EQ(0u, ipq.size());
+    ASSERT_EQ(0u, ipq.size());
     EXPECT_TRUE(ipq.empty());
 }
 
@@ -126,17 +126,17 @@
     sp<const AATest> aa4_b = new AATest{4, emptyMetricId, emptyDimensionId};
 
     ipq.push(aa4_a);
-    EXPECT_EQ(1u, ipq.size());
+    ASSERT_EQ(1u, ipq.size());
     EXPECT_TRUE(ipq.contains(aa4_a));
     EXPECT_FALSE(ipq.contains(aa4_b));
 
     ipq.push(aa4_a);
-    EXPECT_EQ(1u, ipq.size());
+    ASSERT_EQ(1u, ipq.size());
     EXPECT_TRUE(ipq.contains(aa4_a));
     EXPECT_FALSE(ipq.contains(aa4_b));
 
     ipq.push(aa4_b);
-    EXPECT_EQ(2u, ipq.size());
+    ASSERT_EQ(2u, ipq.size());
     EXPECT_TRUE(ipq.contains(aa4_a));
     EXPECT_TRUE(ipq.contains(aa4_b));
 }
@@ -150,7 +150,7 @@
 
     ipq.push(aa4);
     ipq.remove(aa5);
-    EXPECT_EQ(1u, ipq.size());
+    ASSERT_EQ(1u, ipq.size());
     EXPECT_TRUE(ipq.contains(aa4));
     EXPECT_FALSE(ipq.contains(aa5));
 }
@@ -164,17 +164,17 @@
 
     ipq.push(aa4_a);
     ipq.push(aa4_b);
-    EXPECT_EQ(2u, ipq.size());
+    ASSERT_EQ(2u, ipq.size());
     EXPECT_TRUE(ipq.contains(aa4_a));
     EXPECT_TRUE(ipq.contains(aa4_b));
 
     ipq.remove(aa4_b);
-    EXPECT_EQ(1u, ipq.size());
+    ASSERT_EQ(1u, ipq.size());
     EXPECT_TRUE(ipq.contains(aa4_a));
     EXPECT_FALSE(ipq.contains(aa4_b));
 
     ipq.remove(aa4_a);
-    EXPECT_EQ(0u, ipq.size());
+    ASSERT_EQ(0u, ipq.size());
     EXPECT_FALSE(ipq.contains(aa4_a));
     EXPECT_FALSE(ipq.contains(aa4_b));
 }
@@ -205,22 +205,22 @@
     ipq.push(c);
     ipq.push(b);
     ipq.push(a);
-    EXPECT_EQ(3u, ipq.size());
+    ASSERT_EQ(3u, ipq.size());
 
     ipq.pop();
-    EXPECT_EQ(2u, ipq.size());
+    ASSERT_EQ(2u, ipq.size());
     EXPECT_FALSE(ipq.contains(a));
     EXPECT_TRUE(ipq.contains(b));
     EXPECT_TRUE(ipq.contains(c));
 
     ipq.pop();
-    EXPECT_EQ(1u, ipq.size());
+    ASSERT_EQ(1u, ipq.size());
     EXPECT_FALSE(ipq.contains(a));
     EXPECT_FALSE(ipq.contains(b));
     EXPECT_TRUE(ipq.contains(c));
 
     ipq.pop();
-    EXPECT_EQ(0u, ipq.size());
+    ASSERT_EQ(0u, ipq.size());
     EXPECT_FALSE(ipq.contains(a));
     EXPECT_FALSE(ipq.contains(b));
     EXPECT_FALSE(ipq.contains(c));
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 8131725..74ecaac 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -108,15 +108,15 @@
 
     // Flushes at event #2.
     countProducer.flushIfNeededLocked(bucketStartTimeNs + 2);
-    EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
 
     // Flushes.
     countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
     EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
                 countProducer.mPastBuckets.end());
     const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(1UL, buckets.size());
+    ASSERT_EQ(1UL, buckets.size());
     EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
     EXPECT_EQ(2LL, buckets[0].mCount);
@@ -128,10 +128,10 @@
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
 
     countProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
-    EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
     EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
                 countProducer.mPastBuckets.end());
-    EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     const auto& bucketInfo2 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1];
     EXPECT_EQ(bucket2StartTimeNs, bucketInfo2.mBucketStartNs);
     EXPECT_EQ(bucket2StartTimeNs + bucketSizeNs, bucketInfo2.mBucketEndNs);
@@ -139,11 +139,11 @@
 
     // nothing happens in bucket 3. we should not record anything for bucket 3.
     countProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
-    EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
     EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
                 countProducer.mPastBuckets.end());
     const auto& buckets3 = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(2UL, buckets3.size());
+    ASSERT_EQ(2UL, buckets3.size());
 }
 
 TEST(CountMetricProducerTest, TestEventsWithNonSlicedCondition) {
@@ -166,7 +166,7 @@
     makeLogEvent(&event1, bucketStartTimeNs + 1, /*atomId=*/1);
     countProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
 
-    EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
 
     countProducer.onConditionChanged(false /*new condition*/, bucketStartTimeNs + 2);
 
@@ -174,15 +174,15 @@
     LogEvent event2(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event2, bucketStartTimeNs + 10, /*atomId=*/1);
     countProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
-    EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
 
     countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
     EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
                 countProducer.mPastBuckets.end());
 
     const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(1UL, buckets.size());
+    ASSERT_EQ(1UL, buckets.size());
     const auto& bucketInfo = buckets[0];
     EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
@@ -229,15 +229,15 @@
 
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     countProducer.flushIfNeededLocked(bucketStartTimeNs + 1);
-    EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
 
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
     countProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    EXPECT_EQ(1UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, countProducer.mPastBuckets.size());
     EXPECT_TRUE(countProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
                 countProducer.mPastBuckets.end());
     const auto& buckets = countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(1UL, buckets.size());
+    ASSERT_EQ(1UL, buckets.size());
     const auto& bucketInfo = buckets[0];
     EXPECT_EQ(bucketStartTimeNs, bucketInfo.mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.mBucketEndNs);
@@ -271,7 +271,7 @@
     LogEvent event1(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
     EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
 
     // App upgrade or boot complete forces bucket flush.
@@ -284,7 +284,7 @@
             countProducer.onStatsdInitCompleted(eventTimeNs);
             break;
     }
-    EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(bucketStartTimeNs,
               countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
     EXPECT_EQ(eventTimeNs,
@@ -299,7 +299,7 @@
     LogEvent event2(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event2, bucketStartTimeNs + 59 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-    EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(eventTimeNs, countProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(0, countProducer.getCurrentBucketNum());
     EXPECT_EQ(0, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
@@ -308,7 +308,7 @@
     LogEvent event3(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event3, bucketStartTimeNs + 62 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(lastEndTimeNs, countProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(1, countProducer.getCurrentBucketNum());
     EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
@@ -334,7 +334,7 @@
     LogEvent event1(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event1, bucketStartTimeNs + 1, tagId, /*uid=*/"111");
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    EXPECT_EQ(0UL, countProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, countProducer.mPastBuckets.size());
 
     // App upgrade or boot complete forces bucket flush.
     // Check that there's a past bucket and the bucket end is not adjusted since the upgrade
@@ -347,7 +347,7 @@
             countProducer.onStatsdInitCompleted(eventTimeNs);
             break;
     }
-    EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(bucketStartTimeNs,
               countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
@@ -358,13 +358,13 @@
     LogEvent event2(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event2, bucketStartTimeNs + 70 * NS_PER_SEC + 10, tagId, /*uid=*/"222");
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
-    EXPECT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(1UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
 
     // Third event in following bucket.
     LogEvent event3(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event3, bucketStartTimeNs + 121 * NS_PER_SEC + 10, tagId, /*uid=*/"333");
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    EXPECT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(2UL, countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ((int64_t)eventTimeNs,
               countProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
@@ -416,13 +416,13 @@
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
 
-    EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
+    ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
     EXPECT_EQ(2L, countProducer.mCurrentSlicedCounter->begin()->second);
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
 
     // One event in bucket #2. No alarm as bucket #0 is trashed out.
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
+    ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
     EXPECT_EQ(1L, countProducer.mCurrentSlicedCounter->begin()->second);
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), 0U);
 
@@ -430,14 +430,14 @@
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event5);
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event6);
-    EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
+    ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
     EXPECT_EQ(3L, countProducer.mCurrentSlicedCounter->begin()->second);
     // Anomaly at event 6 is within refractory period. The alarm is at event 5 timestamp not event 6
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
               std::ceil(1.0 * event5.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
 
     countProducer.onMatchedLogEvent(1 /*log matcher index*/, event7);
-    EXPECT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
+    ASSERT_EQ(1UL, countProducer.mCurrentSlicedCounter->size());
     EXPECT_EQ(4L, countProducer.mCurrentSlicedCounter->begin()->second);
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY),
               std::ceil(1.0 * event7.GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec));
diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
index 8ef2519..ddda71d 100644
--- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
@@ -104,11 +104,11 @@
     durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
     durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
-    EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
     EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
                 durationProducer.mPastBuckets.end());
     const auto& buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(2UL, buckets.size());
+    ASSERT_EQ(2UL, buckets.size());
     EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[0].mBucketEndNs);
     EXPECT_EQ(bucketSizeNs - 1LL, buckets[0].mDuration);
@@ -150,17 +150,17 @@
     durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
     durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
 
     durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
     durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
     durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
-    EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
     EXPECT_TRUE(durationProducer.mPastBuckets.find(DEFAULT_METRIC_DIMENSION_KEY) !=
                 durationProducer.mPastBuckets.end());
     const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(1UL, buckets2.size());
+    ASSERT_EQ(1UL, buckets2.size());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
     EXPECT_EQ(1LL, buckets2[0].mDuration);
@@ -198,15 +198,15 @@
     durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
     durationProducer.flushIfNeededLocked(bucketStartTimeNs + bucketSizeNs + 1);
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
 
     durationProducer.onMatchedLogEvent(1 /* start index*/, event3);
     durationProducer.onConditionChanged(true /* condition */, bucketStartTimeNs + bucketSizeNs + 2);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event4);
     durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
-    EXPECT_EQ(1UL, durationProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, durationProducer.mPastBuckets.size());
     const auto& buckets2 = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(1UL, buckets2.size());
+    ASSERT_EQ(1UL, buckets2.size());
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets2[0].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets2[0].mBucketEndNs);
     EXPECT_EQ(1LL, buckets2[0].mDuration);
@@ -241,7 +241,7 @@
     LogEvent event1(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event1, startTimeNs, tagId);
     durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
     EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
 
     int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
@@ -253,7 +253,7 @@
             durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
             break;
     }
-    EXPECT_EQ(1UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(1UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     std::vector<DurationBucket> buckets =
             durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
     EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
@@ -268,7 +268,7 @@
     makeLogEvent(&event2, endTimeNs, tagId);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
     buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(3UL, buckets.size());
+    ASSERT_EQ(3UL, buckets.size());
     EXPECT_EQ(partialBucketSplitTimeNs, buckets[1].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[1].mBucketEndNs);
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - partialBucketSplitTimeNs, buckets[1].mDuration);
@@ -303,7 +303,7 @@
     LogEvent event1(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event1, startTimeNs, tagId);
     durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
     EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
 
     int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
@@ -315,7 +315,7 @@
             durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
             break;
     }
-    EXPECT_EQ(2UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(2UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     std::vector<DurationBucket> buckets =
             durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
     EXPECT_EQ(bucketStartTimeNs, buckets[0].mBucketStartNs);
@@ -333,7 +333,7 @@
     makeLogEvent(&event2, endTimeNs, tagId);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
     buckets = durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(3UL, buckets.size());
+    ASSERT_EQ(3UL, buckets.size());
     EXPECT_EQ(partialBucketSplitTimeNs, buckets[2].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[2].mBucketEndNs);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs - partialBucketSplitTimeNs,
@@ -411,7 +411,7 @@
     LogEvent event1(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event1, startTimeNs, tagId);
     durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
     EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
 
     int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
@@ -423,7 +423,7 @@
             durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
             break;
     }
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(0, durationProducer.getCurrentBucketNum());
 
@@ -432,12 +432,12 @@
     LogEvent event2(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event2, endTimeNs, tagId);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
 
     durationProducer.flushIfNeededLocked(bucketStartTimeNs + 3 * bucketSizeNs + 1);
     std::vector<DurationBucket> buckets =
             durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(1UL, buckets.size());
+    ASSERT_EQ(1UL, buckets.size());
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[0].mBucketEndNs);
     EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
@@ -464,7 +464,7 @@
     LogEvent event1(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event1, startTimeNs, tagId);
     durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets.size());
     EXPECT_EQ(bucketStartTimeNs, durationProducer.mCurrentBucketStartTimeNs);
 
     int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 65 * NS_PER_SEC;
@@ -476,7 +476,7 @@
             durationProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
             break;
     }
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(1, durationProducer.getCurrentBucketNum());
 
@@ -485,13 +485,13 @@
     LogEvent event2(/*uid=*/0, /*pid=*/0);
     makeLogEvent(&event2, endTimeNs, tagId);
     durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
-    EXPECT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(0UL, durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(partialBucketSplitTimeNs, durationProducer.mCurrentBucketStartTimeNs);
 
     durationProducer.flushIfNeededLocked(bucketStartTimeNs + 2 * bucketSizeNs + 1);
     std::vector<DurationBucket> buckets =
             durationProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY];
-    EXPECT_EQ(1UL, buckets.size());
+    ASSERT_EQ(1UL, buckets.size());
     EXPECT_EQ(partialBucketSplitTimeNs, buckets[0].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[0].mBucketEndNs);
     EXPECT_EQ(endTimeNs - startTimeNs, buckets[0].mDuration);
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
index 97647a7..5bae364 100644
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -79,7 +79,7 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_event_metrics());
-    EXPECT_EQ(2, report.event_metrics().data_size());
+    ASSERT_EQ(2, report.event_metrics().data_size());
     EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
     EXPECT_EQ(bucketStartTimeNs + 2, report.event_metrics().data(1).elapsed_timestamp_nanos());
 }
@@ -118,7 +118,7 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_event_metrics());
-    EXPECT_EQ(1, report.event_metrics().data_size());
+    ASSERT_EQ(1, report.event_metrics().data_size());
     EXPECT_EQ(bucketStartTimeNs + 1, report.event_metrics().data(0).elapsed_timestamp_nanos());
 }
 
@@ -168,7 +168,7 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_event_metrics());
-    EXPECT_EQ(1, report.event_metrics().data_size());
+    ASSERT_EQ(1, report.event_metrics().data_size());
     EXPECT_EQ(bucketStartTimeNs + 10, report.event_metrics().data(0).elapsed_timestamp_nanos());
 }
 
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 9d2ec88..cc5f459 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -138,11 +138,12 @@
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
                 data->clear();
-                data->push_back(makeLogEvent(tagId, bucketStartTimeNs + 10, 3, "some value", 11));
+                data->push_back(makeLogEvent(tagId, eventTimeNs + 10, 3, "some value", 11));
                 return true;
             }));
 
@@ -156,13 +157,13 @@
     allData.push_back(makeLogEvent(tagId, bucket2StartTimeNs + 1, 10, "some value", 11));
 
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
     EXPECT_EQ(INT, it->mValue.getType());
     EXPECT_EQ(10, it->mValue.int_value);
     it++;
     EXPECT_EQ(11, it->mValue.int_value);
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
     EXPECT_EQ(3, gaugeProducer.mPastBuckets.begin()
                          ->second.back()
                          .mGaugeAtoms.front()
@@ -172,7 +173,7 @@
     allData.clear();
     allData.push_back(makeLogEvent(tagId, bucket3StartTimeNs + 10, 24, "some value", 25));
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
     EXPECT_EQ(INT, it->mValue.getType());
     EXPECT_EQ(24, it->mValue.int_value);
@@ -180,8 +181,8 @@
     EXPECT_EQ(INT, it->mValue.getType());
     EXPECT_EQ(25, it->mValue.int_value);
     // One dimension.
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
     it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
     EXPECT_EQ(INT, it->mValue.getType());
     EXPECT_EQ(10L, it->mValue.int_value);
@@ -190,10 +191,10 @@
     EXPECT_EQ(11L, it->mValue.int_value);
 
     gaugeProducer.flushIfNeededLocked(bucket4StartTimeNs);
-    EXPECT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
     // One dimension.
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    EXPECT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.size());
     it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
     EXPECT_EQ(INT, it->mValue.getType());
     EXPECT_EQ(24L, it->mValue.int_value);
@@ -247,7 +248,7 @@
             break;
     }
     EXPECT_EQ(0UL, (*gaugeProducer.mCurrentSlicedBucket).count(DEFAULT_METRIC_DIMENSION_KEY));
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(bucketStartTimeNs,
               gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
     EXPECT_EQ(partialBucketSplitTimeNs,
@@ -262,7 +263,7 @@
     CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 1, 10);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
     EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(bucketStartTimeNs,
               gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
     EXPECT_EQ(partialBucketSplitTimeNs,
@@ -277,7 +278,7 @@
     CreateTwoValueLogEvent(&event3, tagId, bucketStartTimeNs + 65 * NS_PER_SEC, 1, 10);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
     EXPECT_EQ(1L, gaugeProducer.mCurrentBucketNum);
-    EXPECT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ((int64_t)bucketStartTimeNs + bucketSizeNs, gaugeProducer.mCurrentBucketStartTimeNs);
     EXPECT_EQ(1, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
 
@@ -286,7 +287,7 @@
     CreateTwoValueLogEvent(&event4, tagId, bucketStartTimeNs + 125 * NS_PER_SEC, 1, 10);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
     EXPECT_EQ(2L, gaugeProducer.mCurrentBucketNum);
-    EXPECT_EQ(3UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(3UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(2, anomalyTracker->getSumOverPastBuckets(DEFAULT_METRIC_DIMENSION_KEY));
 }
 
@@ -311,15 +312,15 @@
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             .WillOnce(Return(false))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(
-                                CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 2));
-                        return true;
-                    }));
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 2));
+                return true;
+            }));
 
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
                                       logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
@@ -329,7 +330,7 @@
     vector<shared_ptr<LogEvent>> allData;
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
                          ->second.front()
                          .mFields->begin()
@@ -343,14 +344,14 @@
             gaugeProducer.onStatsdInitCompleted(partialBucketSplitTimeNs);
             break;
     }
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(bucketStartTimeNs,
               gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
     EXPECT_EQ(partialBucketSplitTimeNs,
               gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketEndNs);
     EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
     EXPECT_EQ(partialBucketSplitTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(2, gaugeProducer.mCurrentSlicedBucket->begin()
                          ->second.front()
                          .mFields->begin()
@@ -359,8 +360,8 @@
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + bucketSizeNs + 1, 3));
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
-    EXPECT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(3, gaugeProducer.mCurrentSlicedBucket->begin()
                          ->second.front()
                          .mFields->begin()
@@ -389,7 +390,8 @@
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)).WillOnce(Return(false));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Return(false));
 
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
                                       logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
@@ -399,17 +401,17 @@
     vector<shared_ptr<LogEvent>> allData;
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
                          ->second.front()
                          .mFields->begin()
                          ->mValue.int_value);
 
     gaugeProducer.notifyAppUpgrade(partialBucketSplitTimeNs);
-    EXPECT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
     EXPECT_EQ(bucketStartTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
                          ->second.front()
                          .mFields->begin()
@@ -435,14 +437,16 @@
             new EventMatcherWizard({new SimpleLogMatchingTracker(
                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
 
+    int64_t conditionChangeNs = bucketStartTimeNs + 8;
+
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, conditionChangeNs, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 100));
+                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs + 10, 100));
                 return true;
             }));
 
@@ -451,25 +455,25 @@
                                       bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
 
-    gaugeProducer.onConditionChanged(true, bucketStartTimeNs + 8);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    gaugeProducer.onConditionChanged(true, conditionChangeNs);
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(100, gaugeProducer.mCurrentSlicedBucket->begin()
                            ->second.front()
                            .mFields->begin()
                            ->mValue.int_value);
-    EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
 
     vector<shared_ptr<LogEvent>> allData;
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
 
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(110, gaugeProducer.mCurrentSlicedBucket->begin()
                            ->second.front()
                            .mFields->begin()
                            ->mValue.int_value);
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
     EXPECT_EQ(100, gaugeProducer.mPastBuckets.begin()
                            ->second.back()
                            .mGaugeAtoms.front()
@@ -478,8 +482,8 @@
 
     gaugeProducer.onConditionChanged(false, bucket2StartTimeNs + 10);
     gaugeProducer.flushIfNeededLocked(bucket3StartTimeNs + 10);
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
     EXPECT_EQ(110L, gaugeProducer.mPastBuckets.begin()
                             ->second.back()
                             .mGaugeAtoms.front()
@@ -519,14 +523,16 @@
                         return ConditionState::kTrue;
                     }));
 
+    int64_t sliceConditionChangeNs = bucketStartTimeNs + 8;
+
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, sliceConditionChangeNs, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 10, 1000, 100));
+                data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs + 10, 1000, 100));
                 return true;
             }));
 
@@ -535,22 +541,22 @@
                                       bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
 
-    gaugeProducer.onSlicedConditionMayChange(true, bucketStartTimeNs + 8);
+    gaugeProducer.onSlicedConditionMayChange(true, sliceConditionChangeNs);
 
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     const auto& key = gaugeProducer.mCurrentSlicedBucket->begin()->first;
-    EXPECT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
+    ASSERT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
     EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
 
-    EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(0UL, gaugeProducer.mPastBuckets.size());
 
     vector<shared_ptr<LogEvent>> allData;
     allData.clear();
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1000, 110));
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
 
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
 }
 
 TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
@@ -560,7 +566,8 @@
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)).WillOnce(Return(false));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Return(false));
 
     GaugeMetric metric;
     metric.set_id(metricId);
@@ -596,7 +603,7 @@
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 13));
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(13L, gaugeProducer.mCurrentSlicedBucket->begin()
                            ->second.front()
                            .mFields->begin()
@@ -609,7 +616,7 @@
     allData.clear();
     allData.push_back(event2);
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + bucketSizeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(15L, gaugeProducer.mCurrentSlicedBucket->begin()
                            ->second.front()
                            .mFields->begin()
@@ -621,7 +628,7 @@
     allData.push_back(
             CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 10, 26));
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs + 2 * bucketSizeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_EQ(26L, gaugeProducer.mCurrentSlicedBucket->begin()
                            ->second.front()
                            .mFields->begin()
@@ -633,7 +640,7 @@
     allData.clear();
     allData.push_back(CreateNoValuesLogEvent(tagId, bucketStartTimeNs + 3 * bucketSizeNs + 10));
     gaugeProducer.onDataPulled(allData, /** succeed */ true, bucketStartTimeNs + 3 * bucketSizeNs);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty());
 }
 
@@ -658,17 +665,19 @@
                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
                 data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 4));
+                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 4));
                 return true;
             }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
                 data->clear();
-                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20, 5));
+                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 5));
                 return true;
             }))
             .WillOnce(Return(true));
@@ -679,20 +688,20 @@
                                       tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
     gaugeProducer.prepareFirstBucket();
 
-    EXPECT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
 
     LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
     CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 10);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
     triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+    ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
     triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
 
-    EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
-    EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.size());
+    ASSERT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.size());
     EXPECT_EQ(4, gaugeProducer.mPastBuckets.begin()
                          ->second.back()
                          .mGaugeAtoms[0]
@@ -727,23 +736,26 @@
                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 3, 3, 4));
-                        return true;
-                    }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
                 data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 10, 4, 5));
+                data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 3, 4));
                 return true;
             }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
                 data->clear();
-                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 20, 4, 6));
+                data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 5));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
+                data->clear();
+                data->push_back(CreateTwoValueLogEvent(tagId, eventTimeNs, 4, 6));
                 return true;
             }))
             .WillOnce(Return(true));
@@ -757,24 +769,24 @@
     LogEvent triggerEvent(/*uid=*/0, /*pid=*/0);
     CreateNoValuesLogEvent(&triggerEvent, triggerId, bucketStartTimeNs + 3);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
     triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 10);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->size());
-    EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+    ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->size());
+    ASSERT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
     triggerEvent.setElapsedTimestampNs(bucketStartTimeNs + 20);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
-    EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+    ASSERT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
     triggerEvent.setElapsedTimestampNs(bucket2StartTimeNs + 1);
     gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, triggerEvent);
 
-    EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.size());
+    ASSERT_EQ(2UL, gaugeProducer.mPastBuckets.size());
     auto bucketIt = gaugeProducer.mPastBuckets.begin();
-    EXPECT_EQ(1UL, bucketIt->second.back().mGaugeAtoms.size());
+    ASSERT_EQ(1UL, bucketIt->second.back().mGaugeAtoms.size());
     EXPECT_EQ(3, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
     EXPECT_EQ(4, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
     bucketIt++;
-    EXPECT_EQ(2UL, bucketIt->second.back().mGaugeAtoms.size());
+    ASSERT_EQ(2UL, bucketIt->second.back().mGaugeAtoms.size());
     EXPECT_EQ(4, bucketIt->first.getDimensionKeyInWhat().getValues().begin()->mValue.int_value);
     EXPECT_EQ(5, bucketIt->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
     EXPECT_EQ(6, bucketIt->second.back().mGaugeAtoms[1].mFields->begin()->mValue.int_value);
@@ -801,14 +813,14 @@
                     atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 3, _, _))
             // Bucket start.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 10));
-                        return true;
-                    }));
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, eventTimeNs, 10));
+                return true;
+            }));
 
     int triggerId = 5;
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
@@ -828,14 +840,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_gauge_metrics());
-    EXPECT_EQ(0, report.gauge_metrics().data_size());
-    EXPECT_EQ(1, report.gauge_metrics().skipped_size());
+    ASSERT_EQ(0, report.gauge_metrics().data_size());
+    ASSERT_EQ(1, report.gauge_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.gauge_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 9000000),
               report.gauge_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.gauge_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.gauge_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.gauge_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
diff --git a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
index d2f0f57..fda3daa 100644
--- a/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/MaxDurationTracker_test.cpp
@@ -77,7 +77,7 @@
 
     tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(20LL, buckets[eventKey][0].mDuration);
 }
 
@@ -110,7 +110,7 @@
 
     tracker.flushIfNeeded(bucketStartTimeNs + 3 * bucketSizeNs + 40, &buckets);
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(bucketSizeNs + 40 - 1, buckets[eventKey][0].mDuration);
     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, buckets[eventKey][0].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs, buckets[eventKey][0].mBucketEndNs);
@@ -149,7 +149,7 @@
     EXPECT_TRUE(buckets.find(eventKey) == buckets.end());
 
     tracker.flushIfNeeded(bucketStartTimeNs + 4 * bucketSizeNs, &buckets);
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ((3 * bucketSizeNs) + 20 - 1, buckets[eventKey][0].mDuration);
     EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs, buckets[eventKey][0].mBucketStartNs);
     EXPECT_EQ(bucketStartTimeNs + 4 * bucketSizeNs, buckets[eventKey][0].mBucketEndNs);
@@ -187,7 +187,7 @@
                      bucketStartTimeNs + (2 * bucketSizeNs) + 5, false);
     tracker.flushIfNeeded(bucketStartTimeNs + (3 * bucketSizeNs) + 1, &buckets);
 
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(2 * bucketSizeNs + 5 - 1, buckets[eventKey][0].mDuration);
 }
 
@@ -223,15 +223,15 @@
     tracker.noteConditionChanged(key1, false, conditionStops1);
     unordered_map<MetricDimensionKey, vector<DurationBucket>> buckets;
     tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
-    EXPECT_EQ(0U, buckets.size());
+    ASSERT_EQ(0U, buckets.size());
 
     tracker.noteConditionChanged(key1, true, conditionStarts2);
     tracker.noteConditionChanged(key1, false, conditionStops2);
     tracker.noteStop(key1, eventStopTimeNs, false);
     tracker.flushIfNeeded(bucketStartTimeNs + 2 * bucketSizeNs + 1, &buckets);
-    EXPECT_EQ(1U, buckets.size());
+    ASSERT_EQ(1U, buckets.size());
     vector<DurationBucket> item = buckets.begin()->second;
-    EXPECT_EQ(1UL, item.size());
+    ASSERT_EQ(1UL, item.size());
     EXPECT_EQ((int64_t)(13LL * NS_PER_SEC), item[0].mDuration);
 }
 
@@ -272,11 +272,11 @@
 
     // Remove the anomaly alarm when the duration is no longer fully met.
     tracker.noteConditionChanged(key1, false, eventStartTimeNs + 15 * NS_PER_SEC);
-    EXPECT_EQ(0U, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(0U, anomalyTracker->mAlarms.size());
 
     // Since the condition was off for 10 seconds, the anomaly should trigger 10 sec later.
     tracker.noteConditionChanged(key1, true, eventStartTimeNs + 25 * NS_PER_SEC);
-    EXPECT_EQ(1U, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
     alarm = anomalyTracker->mAlarms.begin()->second;
     EXPECT_EQ((long long)(63ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
 }
@@ -330,7 +330,7 @@
     tracker.noteConditionChanged(key1, false, conditionStops1);
     tracker.noteStart(key2, true, eventStartTimeNs2, conditionKey2);  // Condition is on already.
     tracker.noteConditionChanged(key1, true, conditionStarts2);
-    EXPECT_EQ(1U, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
     auto alarm = anomalyTracker->mAlarms.begin()->second;
     int64_t anomalyFireTimeSec = alarm->timestampSec;
     EXPECT_EQ(conditionStarts2 + 36 * NS_PER_SEC,
@@ -341,7 +341,7 @@
     // gets correctly taken into account in future predictAnomalyTimestampNs calculations.
     std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarms({alarm});
     anomalyTracker->informAlarmsFired(anomalyFireTimeSec * NS_PER_SEC, firedAlarms);
-    EXPECT_EQ(0u, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
     int64_t refractoryPeriodEndsSec = anomalyFireTimeSec + refPeriodSec;
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), refractoryPeriodEndsSec);
 
@@ -352,7 +352,7 @@
     tracker.noteStop(key2, eventStopTimeNs, false);
     tracker.noteStart(key1, true, eventStopTimeNs + 1000000, conditionKey1);
     // Anomaly is ongoing, but we're still in the refractory period.
-    EXPECT_EQ(1U, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
     alarm = anomalyTracker->mAlarms.begin()->second;
     EXPECT_EQ(refractoryPeriodEndsSec, (long long)(alarm->timestampSec));
 
@@ -410,7 +410,7 @@
     tracker.noteStart(key1, true, eventStartTimeNs1, conditionKey1);
     tracker.noteStart(key2, true, eventStartTimeNs2, conditionKey2);
     tracker.noteStop(key1, eventStopTimeNs1, false);
-    EXPECT_EQ(1U, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(1U, anomalyTracker->mAlarms.size());
     auto alarm = anomalyTracker->mAlarms.begin()->second;
     EXPECT_EQ(eventStopTimeNs1 + 35 * NS_PER_SEC,
               (unsigned long long)(alarm->timestampSec * NS_PER_SEC));
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
index 39d3919..1d6f7de 100644
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
@@ -74,7 +74,7 @@
     tracker.flushIfNeeded(eventStartTimeNs + bucketSizeNs + 1, &buckets);
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
 
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(durationTimeNs, buckets[eventKey][0].mDuration);
 }
 
@@ -103,7 +103,7 @@
 
     tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(2003LL, buckets[eventKey][0].mDuration);
 }
 
@@ -133,7 +133,7 @@
 
     tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(2003LL, buckets[eventKey][0].mDuration);
 }
 
@@ -161,7 +161,7 @@
     tracker.noteStart(kEventKey1, true, eventStartTimeNs + 2 * bucketSizeNs, ConditionKey());
     EXPECT_EQ((long long)(bucketStartTimeNs + 2 * bucketSizeNs), tracker.mLastStartTime);
 
-    EXPECT_EQ(2u, buckets[eventKey].size());
+    ASSERT_EQ(2u, buckets[eventKey].size());
     EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
     EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
 
@@ -169,7 +169,7 @@
     tracker.noteStop(kEventKey1, eventStartTimeNs + 2 * bucketSizeNs + 12, false);
     tracker.flushIfNeeded(eventStartTimeNs + 2 * bucketSizeNs + 12, &buckets);
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    EXPECT_EQ(2u, buckets[eventKey].size());
+    ASSERT_EQ(2u, buckets[eventKey].size());
     EXPECT_EQ(bucketSizeNs - 1, buckets[eventKey][0].mDuration);
     EXPECT_EQ(bucketSizeNs, buckets[eventKey][1].mDuration);
 }
@@ -207,7 +207,7 @@
 
     tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(5LL, buckets[eventKey][0].mDuration);
 }
 
@@ -248,7 +248,7 @@
 
     tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(1005LL, buckets[eventKey][0].mDuration);
 }
 
@@ -286,7 +286,7 @@
 
     tracker.flushIfNeeded(bucketStartTimeNs + bucketSizeNs + 1, &buckets);
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(15LL, buckets[eventKey][0].mDuration);
 }
 
@@ -322,7 +322,7 @@
               tracker.predictAnomalyTimestampNs(*anomalyTracker, eventStartTimeNs));
 
     tracker.noteStop(DEFAULT_DIMENSION_KEY, eventStartTimeNs + 3, false);
-    EXPECT_EQ(0u, buckets[eventKey].size());
+    ASSERT_EQ(0u, buckets[eventKey].size());
 
     int64_t event1StartTimeNs = eventStartTimeNs + 10;
     tracker.noteStart(kEventKey1, true, event1StartTimeNs, ConditionKey());
@@ -335,7 +335,7 @@
     tracker.noteStop(kEventKey1, event1StopTimeNs, false);
 
     EXPECT_TRUE(buckets.find(eventKey) != buckets.end());
-    EXPECT_EQ(1u, buckets[eventKey].size());
+    ASSERT_EQ(1u, buckets[eventKey].size());
     EXPECT_EQ(3LL + bucketStartTimeNs + bucketSizeNs - eventStartTimeNs - 10,
               buckets[eventKey][0].mDuration);
 
@@ -486,10 +486,10 @@
     EXPECT_TRUE(tracker.mStarted.empty());
     EXPECT_EQ(10LL, tracker.mStateKeyDurationMap[DEFAULT_DIMENSION_KEY].mDuration);  // 10ns
 
-    EXPECT_EQ(0u, tracker.mStarted.size());
+    ASSERT_EQ(0u, tracker.mStarted.size());
 
     tracker.noteStart(kEventKey1, true, eventStartTimeNs + 20, ConditionKey());
-    EXPECT_EQ(1u, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
     EXPECT_EQ((long long)(52ULL * NS_PER_SEC),  // (10s + 1s + 1ns + 20ns) - 10ns + 40s, rounded up
               (long long)(anomalyTracker->mAlarms.begin()->second->timestampSec * NS_PER_SEC));
     // The alarm is set to fire at 52s, and when it does, an anomaly would be declared. However,
@@ -530,29 +530,29 @@
                                  false, {anomalyTracker});
 
     tracker.noteStart(kEventKey1, true, 15 * NS_PER_SEC, conkey);  // start key1
-    EXPECT_EQ(1u, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
     sp<const InternalAlarm> alarm = anomalyTracker->mAlarms.begin()->second;
     EXPECT_EQ((long long)(55ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
 
     tracker.noteStop(kEventKey1, 17 * NS_PER_SEC, false); // stop key1 (2 seconds later)
-    EXPECT_EQ(0u, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
 
     tracker.noteStart(kEventKey1, true, 22 * NS_PER_SEC, conkey);  // start key1 again
-    EXPECT_EQ(1u, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
     alarm = anomalyTracker->mAlarms.begin()->second;
     EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
 
     tracker.noteStart(kEventKey2, true, 32 * NS_PER_SEC, conkey);  // start key2
-    EXPECT_EQ(1u, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
     alarm = anomalyTracker->mAlarms.begin()->second;
     EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
 
     tracker.noteStop(kEventKey1, 47 * NS_PER_SEC, false); // stop key1
-    EXPECT_EQ(1u, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(1u, anomalyTracker->mAlarms.size());
     alarm = anomalyTracker->mAlarms.begin()->second;
     EXPECT_EQ((long long)(60ULL * NS_PER_SEC), (long long)(alarm->timestampSec * NS_PER_SEC));
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 0U);
@@ -560,11 +560,11 @@
     // Now, at 60s, which is 38s after key1 started again, we have reached 40s of 'on' time.
     std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarms({alarm});
     anomalyTracker->informAlarmsFired(62 * NS_PER_SEC, firedAlarms);
-    EXPECT_EQ(0u, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 62U + refPeriodSec);
 
     tracker.noteStop(kEventKey2, 69 * NS_PER_SEC, false); // stop key2
-    EXPECT_EQ(0u, anomalyTracker->mAlarms.size());
+    ASSERT_EQ(0u, anomalyTracker->mAlarms.size());
     EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(eventKey), 62U + refPeriodSec);
 }
 
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index f493cc4..b6e1075 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -278,13 +278,13 @@
 TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                        return true;
-                    }));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
@@ -295,7 +295,7 @@
 
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -304,7 +304,7 @@
     EXPECT_EQ(11, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(8, curInterval.value.long_value);
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
 
@@ -312,7 +312,7 @@
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
 
@@ -320,8 +320,8 @@
     EXPECT_EQ(23, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(12, curInterval.value.long_value);
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
     EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
@@ -330,7 +330,7 @@
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
 
@@ -338,8 +338,8 @@
     EXPECT_EQ(36, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(13, curInterval.value.long_value);
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(3UL, valueProducer->mPastBuckets.begin()->second.size());
     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
     EXPECT_EQ(12, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
@@ -352,18 +352,20 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Initialize bucket.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 1));
                 return true;
             }))
             // Partial bucket.
-            .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
-                                                        vector<std::shared_ptr<LogEvent>>* data,
-                                                        bool) {
+            .WillOnce(Invoke([partialBucketSplitTimeNs](
+                                     int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                     vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
                 data->clear();
                 data->push_back(
                         CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs + 8, 5));
@@ -416,13 +418,13 @@
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 3, 3));
-                        return true;
-                    }));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                data->clear();
+                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 3, 3));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer = new ValueMetricProducer(
             kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, logEventMatcherIndex,
@@ -435,7 +437,7 @@
 
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -444,7 +446,7 @@
     EXPECT_EQ(11, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(8, curInterval.value.long_value);
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
 
@@ -452,20 +454,20 @@
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket3StartTimeNs + 1, 4, 23));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
     // No new data seen, so data has been cleared.
-    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
 
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(11, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(8, curInterval.value.long_value);
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
 
     allData.clear();
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 3, 36));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
 
@@ -473,8 +475,8 @@
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(36, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.begin()->second.size());
     EXPECT_EQ(8, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
 }
@@ -487,7 +489,8 @@
     metric.set_use_absolute_value_on_reset(true);
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)).WillOnce(Return(true));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Return(true));
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
 
@@ -497,7 +500,7 @@
 
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -505,35 +508,35 @@
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(11, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
 
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(10, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(10, curInterval.value.long_value);
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
     EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second.back().values[0].long_value);
     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second.back().mConditionTrueNs);
 
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(36, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(26, curInterval.value.long_value);
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(2UL, valueProducer->mPastBuckets.begin()->second.size());
     EXPECT_EQ(10, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
     EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[1].values[0].long_value);
@@ -546,7 +549,8 @@
 TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)).WillOnce(Return(false));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Return(false));
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
 
@@ -556,7 +560,7 @@
 
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -564,31 +568,31 @@
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(11, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
 
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 10));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(10, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
 
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1, 36));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(36, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(26, curInterval.value.long_value);
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
     EXPECT_EQ(26, valueProducer->mPastBuckets.begin()->second[0].values[0].long_value);
     EXPECT_EQ(bucketSizeNs, valueProducer->mPastBuckets.begin()->second[0].mConditionTrueNs);
 }
@@ -601,21 +605,24 @@
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);  // First condition change.
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
                 return true;
             }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1);  // Second condition change.
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 130));
                 return true;
             }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 1);  // Third condition change.
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 180));
                 return true;
@@ -627,7 +634,7 @@
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -635,7 +642,7 @@
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(100, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
 
     vector<shared_ptr<LogEvent>> allData;
     allData.clear();
@@ -645,7 +652,7 @@
                                     {bucketStartTimeNs}, {bucket2StartTimeNs});
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
@@ -658,7 +665,7 @@
                                     {bucketStartTimeNs}, {bucket2StartTimeNs});
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curInterval.hasValue);
@@ -690,7 +697,7 @@
     LogEvent event1(/*uid=*/0, /*pid=*/0);
     CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
 
     int64_t partialBucketSplitTimeNs = bucketStartTimeNs + 150;
     switch (GetParam()) {
@@ -745,11 +752,12 @@
     int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 150;
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             .WillOnce(Return(true))
-            .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
-                                                        vector<std::shared_ptr<LogEvent>>* data,
-                                                        bool) {
+            .WillOnce(Invoke([partialBucketSplitTimeNs](
+                                     int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                     vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 120));
                 return true;
@@ -764,7 +772,7 @@
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
 
     valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
 
     switch (GetParam()) {
         case APP_UPGRADE:
@@ -803,7 +811,8 @@
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillOnce(Return());
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)).WillOnce(Return(true));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Return(true));
     ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
                                       eventMatcherWizard, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
@@ -814,10 +823,10 @@
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 100));
 
     valueProducer.onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
 
     valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150);
-    EXPECT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+    ASSERT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
     EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
 }
 
@@ -825,15 +834,18 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1);  // Condition change to true time.
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
                 return true;
             }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs,
+                          bucket2StartTimeNs - 100);  // Condition change to false time.
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs - 100, 120));
                 return true;
@@ -888,7 +900,7 @@
 
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer.mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
@@ -898,7 +910,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(30, curInterval.value.long_value);
 
@@ -929,7 +941,7 @@
     CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10);
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     // has 1 slice
-    EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
 
     valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
 
@@ -938,7 +950,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer.mCurrentSlicedBucket.begin()->second[0];
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
@@ -949,7 +961,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(50, curInterval.value.long_value);
 
@@ -960,7 +972,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(50, curInterval.value.long_value);
 
@@ -1049,7 +1061,8 @@
 TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _)).WillOnce(Return(true));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Return(true));
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
 
@@ -1060,7 +1073,7 @@
 
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -1069,14 +1082,14 @@
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(11, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
 
     // pull 2 at correct time
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 1, 23));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     // tartUpdated:false sum:12
@@ -1093,7 +1106,7 @@
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket6StartTimeNs + 1, 36));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket6StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     // startUpdated:false sum:12
@@ -1119,17 +1132,19 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);  // First condition change.
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
                 return true;
             }))
             // condition becomes false
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1);  // Second condition change.
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
                 return true;
@@ -1140,14 +1155,14 @@
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(100, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
 
     // pull on bucket boundary come late, condition change happens before it
     valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
@@ -1179,24 +1194,27 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
                 return true;
             }))
             // condition becomes false
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 1);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 120));
                 return true;
             }))
             // condition becomes true again
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 25);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 25, 130));
                 return true;
@@ -1208,7 +1226,7 @@
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -1216,13 +1234,13 @@
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(100, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
 
     // pull on bucket boundary come late, condition change happens before it
     valueProducer->onConditionChanged(false, bucket2StartTimeNs + 1);
     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {20}, {bucketSizeNs - 8},
                                     {bucketStartTimeNs}, {bucket2StartTimeNs});
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(false, curBaseInfo.hasBase);
@@ -1287,7 +1305,7 @@
 
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(10, curInterval.value.long_value);
@@ -1296,7 +1314,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(10, curInterval.value.long_value);
 
@@ -1328,7 +1346,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(10, curInterval.value.long_value);
@@ -1339,7 +1357,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(20, curInterval.value.long_value);
 
@@ -1373,7 +1391,7 @@
     CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15);
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval;
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(10, curInterval.value.long_value);
@@ -1383,14 +1401,14 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(25, curInterval.value.long_value);
     EXPECT_EQ(2, curInterval.sampleSize);
 
     valueProducer.flushIfNeededLocked(bucket2StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
-    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+    ASSERT_EQ(1UL, valueProducer.mPastBuckets.size());
+    ASSERT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
 
     EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value -
                          12.5) < epsilon);
@@ -1421,7 +1439,7 @@
     CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15);
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(10, curInterval.value.long_value);
@@ -1430,7 +1448,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(25, curInterval.value.long_value);
 
@@ -1463,7 +1481,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer.mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
@@ -1476,7 +1494,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     EXPECT_EQ(true, curInterval.hasValue);
     EXPECT_EQ(5, curInterval.value.long_value);
@@ -1486,7 +1504,7 @@
     CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 15);
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
 
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
@@ -1497,7 +1515,7 @@
     LogEvent event4(/*uid=*/0, /*pid=*/0);
     CreateRepeatedValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 15);
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
@@ -1538,7 +1556,7 @@
 
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer.mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
@@ -1553,7 +1571,7 @@
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curInterval.hasValue);
@@ -1568,7 +1586,7 @@
     CreateThreeValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 1, 15, 25);
 
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3);
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
 
@@ -1585,7 +1603,7 @@
     CreateThreeValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 1, 15, 29);
 
     valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4);
-    EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
     curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer.mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
@@ -1599,10 +1617,10 @@
 
     valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
 
-    EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
-    EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
-    EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second[0].values.size());
-    EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second[1].values.size());
+    ASSERT_EQ(1UL, valueProducer.mPastBuckets.size());
+    ASSERT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+    ASSERT_EQ(2UL, valueProducer.mPastBuckets.begin()->second[0].values.size());
+    ASSERT_EQ(1UL, valueProducer.mPastBuckets.begin()->second[1].values.size());
 
     EXPECT_EQ(bucketSizeNs, valueProducer.mPastBuckets.begin()->second[0].mConditionTrueNs);
     EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second[0].values[0].long_value);
@@ -1625,18 +1643,18 @@
     metric.set_use_zero_default_base(true);
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
-                        return true;
-                    }));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                data->clear();
+                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
 
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     auto iter = valueProducer->mCurrentSlicedBucket.begin();
     auto& interval1 = iter->second[0];
     auto iterBase = valueProducer->mCurrentBaseInfo.begin();
@@ -1646,7 +1664,7 @@
     EXPECT_EQ(3, baseInfo1.base.long_value);
     EXPECT_EQ(false, interval1.hasValue);
     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
     vector<shared_ptr<LogEvent>> allData;
 
     allData.clear();
@@ -1654,7 +1672,7 @@
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
 
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     EXPECT_EQ(true, baseInfo1.hasBase);
     EXPECT_EQ(11, baseInfo1.base.long_value);
     EXPECT_EQ(false, interval1.hasValue);
@@ -1682,7 +1700,7 @@
     EXPECT_EQ(false, interval2.hasValue);
     EXPECT_EQ(4, interval2.value.long_value);
 
-    EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
     auto iterator = valueProducer->mPastBuckets.begin();
     EXPECT_EQ(bucketSizeNs, iterator->second[0].mConditionTrueNs);
     EXPECT_EQ(8, iterator->second[0].values[0].long_value);
@@ -1701,18 +1719,18 @@
     metric.set_use_zero_default_base(true);
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
-                        return true;
-                    }));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                data->clear();
+                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
 
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     const auto& it = valueProducer->mCurrentSlicedBucket.begin();
     ValueMetricProducer::Interval& interval1 = it->second[0];
     ValueMetricProducer::BaseInfo& baseInfo1 =
@@ -1722,7 +1740,7 @@
     EXPECT_EQ(3, baseInfo1.base.long_value);
     EXPECT_EQ(false, interval1.hasValue);
     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
     vector<shared_ptr<LogEvent>> allData;
 
     allData.clear();
@@ -1730,7 +1748,7 @@
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
 
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     EXPECT_EQ(true, baseInfo1.hasBase);
     EXPECT_EQ(11, baseInfo1.base.long_value);
     EXPECT_EQ(false, interval1.hasValue);
@@ -1751,31 +1769,31 @@
     EXPECT_EQ(4, baseInfo2.base.long_value);
     EXPECT_EQ(false, interval2.hasValue);
     EXPECT_EQ(4, interval2.value.long_value);
-    EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
 
     // next pull somehow did not happen, skip to end of bucket 3
     allData.clear();
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 2, 5));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
 
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     EXPECT_EQ(true, baseInfo2.hasBase);
     EXPECT_EQ(5, baseInfo2.base.long_value);
     EXPECT_EQ(false, interval2.hasValue);
     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
-    EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
 
     allData.clear();
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 2, 13));
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket5StartTimeNs + 1, 1, 5));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket5StartTimeNs);
 
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     // Get new references now that entries have been deleted from the map
     const auto& it3 = valueProducer->mCurrentSlicedBucket.begin();
     const auto& it4 = std::next(valueProducer->mCurrentSlicedBucket.begin());
-    EXPECT_EQ(it3->second.size(), 1);
-    EXPECT_EQ(it4->second.size(), 1);
+    ASSERT_EQ(it3->second.size(), 1);
+    ASSERT_EQ(it4->second.size(), 1);
     ValueMetricProducer::Interval& interval3 = it3->second[0];
     ValueMetricProducer::Interval& interval4 = it4->second[0];
     ValueMetricProducer::BaseInfo& baseInfo3 =
@@ -1794,7 +1812,7 @@
     EXPECT_EQ(false, interval4.hasValue);
     EXPECT_EQ(8, interval4.value.long_value);
 
-    EXPECT_EQ(2UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(2UL, valueProducer->mPastBuckets.size());
 }
 
 /*
@@ -1806,18 +1824,18 @@
     metric.mutable_dimensions_in_what()->add_child()->set_field(1);
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
-                        return true;
-                    }));
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                data->clear();
+                data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1, 3));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
 
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     auto iter = valueProducer->mCurrentSlicedBucket.begin();
     auto& interval1 = iter->second[0];
     auto iterBase = valueProducer->mCurrentBaseInfo.begin();
@@ -1826,7 +1844,7 @@
     EXPECT_EQ(true, baseInfo1.hasBase);
     EXPECT_EQ(3, baseInfo1.base.long_value);
     EXPECT_EQ(false, interval1.hasValue);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
 
     vector<shared_ptr<LogEvent>> allData;
     allData.clear();
@@ -1834,7 +1852,7 @@
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 11));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
 
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     EXPECT_EQ(true, baseInfo1.hasBase);
     EXPECT_EQ(11, baseInfo1.base.long_value);
     EXPECT_EQ(false, interval1.hasValue);
@@ -1870,7 +1888,7 @@
     allData.push_back(CreateTwoValueLogEvent(tagId, bucket4StartTimeNs + 1, 2, 5));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket4StartTimeNs);
     // Only one interval left. One was trimmed.
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     interval2 = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     baseInfo2 = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
@@ -1909,8 +1927,8 @@
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     // Used by onConditionChanged.
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
@@ -1922,7 +1940,7 @@
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -1932,7 +1950,7 @@
 
     vector<shared_ptr<LogEvent>> allData;
     valueProducer->onDataPulled(allData, /** succeed */ false, bucket2StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     EXPECT_EQ(false, curBaseInfo.hasBase);
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(false, valueProducer->mHasGlobalBase);
@@ -1942,9 +1960,10 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);  // Condition change to true.
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
                 return true;
@@ -1957,19 +1976,19 @@
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo& curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curBaseInfo.hasBase);
     EXPECT_EQ(100, curBaseInfo.base.long_value);
     EXPECT_EQ(false, curInterval.hasValue);
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
 
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 20);
 
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(false, curBaseInfo.hasBase);
     EXPECT_EQ(false, valueProducer->mHasGlobalBase);
@@ -1979,15 +1998,17 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 50));
-                        return false;
-                    }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 50));
+                return false;
+            }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 1);  // Condition change to false.
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 100));
                 return true;
@@ -2001,10 +2022,10 @@
     // valueProducer->mCondition = ConditionState::kTrue;
     valueProducer->onConditionChanged(true, bucketStartTimeNs);
 
-    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
 
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 1);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -2019,8 +2040,8 @@
     metric.set_max_pull_delay_sec(0);
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 120));
@@ -2034,7 +2055,7 @@
 
     // Max delay is set to 0 so pull will exceed max delay.
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
-    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
 }
 
 TEST(ValueMetricProducerTest, TestResetBaseOnPullTooLate) {
@@ -2060,15 +2081,15 @@
     // Event should be skipped since it is from previous bucket.
     // Pull should not be called.
     valueProducer.onConditionChanged(true, bucketStartTimeNs);
-    EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
+    ASSERT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
 }
 
 TEST(ValueMetricProducerTest, TestBaseSetOnConditionChange) {
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 1, _, _))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 100));
@@ -2083,7 +2104,7 @@
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 1);
     valueProducer->mHasGlobalBase = true;
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -2100,12 +2121,13 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // First onConditionChanged
             .WillOnce(Return(false))
             // Second onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
                 return true;
@@ -2134,9 +2156,9 @@
 
     valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
 
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
     // Contains base from last pull which was successful.
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -2153,14 +2175,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
@@ -2177,9 +2199,9 @@
     metric.set_condition(StringToId("SCREEN_ON"));
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 2, _, _))
             // First onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 for (int i = 0; i < 2000; i++) {
                     data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
@@ -2193,8 +2215,8 @@
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 2);
     EXPECT_EQ(true, valueProducer->mCurrentBucketIsInvalid);
-    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(0UL, valueProducer->mSkippedBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(0UL, valueProducer->mSkippedBuckets.size());
 
     // Bucket 2 start.
     vector<shared_ptr<LogEvent>> allData;
@@ -2203,7 +2225,7 @@
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
 
     // First bucket added to mSkippedBuckets after flush.
-    EXPECT_EQ(1UL, valueProducer->mSkippedBuckets.size());
+    ASSERT_EQ(1UL, valueProducer->mSkippedBuckets.size());
 
     // Check dump report.
     ProtoOutputStream output;
@@ -2213,14 +2235,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::DIMENSION_GUARDRAIL_REACHED, dropEvent.drop_reason());
@@ -2234,17 +2256,19 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // First onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
                 return true;
             }))
             // Second onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
                 return true;
@@ -2271,9 +2295,9 @@
 
     valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
 
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
     // Contains base from last pull which was successful.
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -2290,14 +2314,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
@@ -2312,17 +2336,19 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // First onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 2);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 120));
                 return true;
             }))
             // Second onConditionChanged
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 3);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 8, 130));
                 return true;
@@ -2349,9 +2375,9 @@
 
     valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1);
 
-    EXPECT_EQ(0UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mPastBuckets.size());
     // Last pull failed so base has been reset.
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -2367,14 +2393,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
@@ -2384,14 +2410,14 @@
 TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onDataPulled) {
     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
             // Start bucket.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                        return true;
-                    }));
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
@@ -2401,41 +2427,43 @@
     allData.clear();
     allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
 
     // Bucket 3 empty.
     allData.clear();
     allData.push_back(CreateNoValuesLogEvent(tagId, bucket3StartTimeNs + 1));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket3StartTimeNs);
     // Data has been trimmed.
-    EXPECT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(0UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
 }
 
 TEST(ValueMetricProducerTest, TestEmptyDataResetsBase_onConditionChanged) {
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // First onConditionChanged
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                        return true;
-                    }))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        return true;
-                    }));
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
+                data->clear();
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -2445,7 +2473,7 @@
 
     // Empty pull.
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(false, curBaseInfo.hasBase);
@@ -2457,26 +2485,29 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // First onConditionChanged
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                        return true;
-                    }))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 2));
-                        return true;
-                    }))
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 5));
-                        return true;
-                    }));
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 11);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 2));
+                return true;
+            }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 12);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 5));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
@@ -2484,7 +2515,7 @@
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 11);
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 12);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval& curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -2496,7 +2527,7 @@
     vector<shared_ptr<LogEvent>> allData;
     allData.clear();
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     // Data is empty, base should be reset.
@@ -2505,7 +2536,7 @@
     EXPECT_EQ(false, curInterval.hasValue);
     EXPECT_EQ(true, valueProducer->mHasGlobalBase);
 
-    EXPECT_EQ(1UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(1UL, valueProducer->mPastBuckets.size());
     assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {1}, {bucketSizeNs - 12 + 1},
                                     {bucketStartTimeNs}, {bucket2StartTimeNs});
 }
@@ -2517,20 +2548,20 @@
     metric.set_condition(StringToId("SCREEN_ON"));
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _, _))
             // First onConditionChanged
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                        return true;
-                    }));
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
 
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 10);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
 
     // End of bucket
     vector<shared_ptr<LogEvent>> allData;
@@ -2539,7 +2570,7 @@
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
 
     // Key 1 should be reset since in not present in the most pull.
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     auto iterator = valueProducer->mCurrentSlicedBucket.begin();
     auto baseInfoIter = valueProducer->mCurrentBaseInfo.begin();
     EXPECT_EQ(true, baseInfoIter->second[0].hasBase);
@@ -2559,18 +2590,20 @@
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     int64_t partialBucketSplitTimeNs = bucketStartTimeNs + bucketSizeNs / 2;
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Initialization.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                        return true;
-                    }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
             // notifyAppUpgrade.
-            .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
-                                                        vector<std::shared_ptr<LogEvent>>* data,
-                                                        bool) {
+            .WillOnce(Invoke([partialBucketSplitTimeNs](
+                                     int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                     vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
                 return true;
@@ -2609,17 +2642,19 @@
 TEST(ValueMetricProducerTest, TestBucketBoundariesOnConditionChange) {
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Second onConditionChanged.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 10, 5));
                 return true;
             }))
             // Third onConditionChanged.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket3StartTimeNs + 10);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket3StartTimeNs + 10, 7));
                 return true;
@@ -2678,14 +2713,14 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetric();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
             // Initialization.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                        return true;
-                    }));
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerNoConditions(pullerManager, metric);
@@ -2708,18 +2743,20 @@
 
     int64_t partialBucketSplitTimeNs = bucket2StartTimeNs + 2;
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Initialization.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                        return true;
-                    }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
             // notifyAppUpgrade.
-            .WillOnce(Invoke([partialBucketSplitTimeNs](int tagId, const ConfigKey&,
-                                                        vector<std::shared_ptr<LogEvent>>* data,
-                                                        bool) {
+            .WillOnce(Invoke([partialBucketSplitTimeNs](
+                                     int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                     vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, partialBucketSplitTimeNs);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, partialBucketSplitTimeNs, 10));
                 return true;
@@ -2746,21 +2783,23 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // First on condition changed.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                        return true;
-                    }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
             // Second on condition changed.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                        return true;
-                    }));
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
@@ -2769,7 +2808,7 @@
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 10);
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 12);
 
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     auto curInterval = valueProducer->mCurrentSlicedBucket.begin()->second[0];
     auto curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
     EXPECT_EQ(true, curInterval.hasValue);
@@ -2788,28 +2827,31 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // First condition change.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
-                        return true;
-                    }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 1));
+                return true;
+            }))
             // 2nd condition change.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
-                        return true;
-                    }))
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 8);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
+                return true;
+            }))
             // 3rd condition change.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
-                        return true;
-                    }));
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 10);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs, 1));
+                return true;
+            }));
 
     sp<ValueMetricProducer> valueProducer =
             ValueMetricProducerTestHelper::createValueProducerWithCondition(pullerManager, metric);
@@ -2848,9 +2890,9 @@
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
 
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
             // Initial pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
@@ -2869,7 +2911,7 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     // Bucket is invalid since we did not pull when dump report was called.
-    EXPECT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
 }
 
 TEST(ValueMetricProducerTest, TestFastDumpWithoutCurrentBucket) {
@@ -2886,9 +2928,9 @@
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
 
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs, _, _))
             // Initial pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
@@ -2912,7 +2954,7 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     // Previous bucket is part of the report.
-    EXPECT_EQ(1, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().data_size());
     EXPECT_EQ(0, report.value_metrics().data(0).bucket_info(0).bucket_num());
 }
 
@@ -2930,16 +2972,18 @@
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, kConfigKey, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, kConfigKey, _)).WillRepeatedly(Return());
 
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Initial pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
                 data->clear();
                 data->push_back(CreateThreeValueLogEvent(tagId, bucketStartTimeNs, tagId, 1, 1));
                 return true;
             }))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
                 data->clear();
                 data->push_back(
                         CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 10, tagId, 3, 3));
@@ -2957,8 +3001,8 @@
                                NO_TIME_CONSTRAINTS, &strSet, &output);
 
     StatsLogReport report = outputStreamToProto(&output);
-    EXPECT_EQ(1, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().data(0).bucket_info_size());
+    ASSERT_EQ(1, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().data(0).bucket_info_size());
     EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
 }
 
@@ -2984,17 +3028,19 @@
     metric.set_use_diff(false);
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
                 return true;
             }))
             // condition becomes false
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 20));
                 return true;
@@ -3006,7 +3052,7 @@
     valueProducer->onConditionChanged(true, bucketStartTimeNs + 8);
     valueProducer->onConditionChanged(false, bucketStartTimeNs + 50);
     // has one slice
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     ValueMetricProducer::Interval curInterval =
             valueProducer->mCurrentSlicedBucket.begin()->second[0];
     ValueMetricProducer::BaseInfo curBaseInfo = valueProducer->mCurrentBaseInfo.begin()->second[0];
@@ -3032,9 +3078,9 @@
     metric.set_use_diff(false);
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 8, _, _))
             // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
@@ -3083,10 +3129,11 @@
     metric.set_use_diff(false);
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // condition becomes true
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 8);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 30, 10));
                 return true;
@@ -3122,9 +3169,9 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 20, _, _))
             // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 20, 10));
@@ -3145,14 +3192,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs + 40),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::DUMP_REPORT_REQUESTED, dropEvent.drop_reason());
@@ -3167,9 +3214,9 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 50, _, _))
             // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
@@ -3198,14 +3245,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(1, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(1, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
@@ -3220,17 +3267,19 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
                 return true;
             }))
             // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 100);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 100, 15));
                 return true;
@@ -3261,14 +3310,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(1, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(1, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(bucket2StartTimeNs + 100),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::EVENT_IN_WRONG_BUCKET, dropEvent.drop_reason());
@@ -3283,17 +3332,19 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
                 return true;
             }))
             // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10000);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 100, 15));
                 return true;
@@ -3315,14 +3366,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
@@ -3337,10 +3388,11 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 10));
                 return true;
@@ -3363,14 +3415,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::PULL_FAILED, dropEvent.drop_reason());
@@ -3385,17 +3437,19 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
                 return true;
             }))
             // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket4StartTimeNs + 10);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucket4StartTimeNs + 1000, 15));
                 return true;
@@ -3418,14 +3472,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(bucket2StartTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::MULTIPLE_BUCKETS_SKIPPED, dropEvent.drop_reason());
@@ -3441,17 +3495,19 @@
     metric.set_min_bucket_size_nanos(10000000000);  // 10 seconds
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
                 return true;
             }))
             // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 9000000);
                 data->clear();
                 data->push_back(
                         CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 9000000, 15));
@@ -3473,14 +3529,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(1, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::BUCKET_TOO_SMALL, dropEvent.drop_reason());
@@ -3494,9 +3550,9 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, bucketStartTimeNs + 10, _, _))
             // Condition change to true.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 10));
@@ -3519,14 +3575,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(2, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(2, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
@@ -3545,10 +3601,11 @@
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithCondition();
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // First condition change event.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
                 for (int i = 0; i < 2000; i++) {
                     data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, i));
                 }
@@ -3563,8 +3620,9 @@
             .WillOnce(Return(false))
             .WillOnce(Return(false))
             .WillOnce(Return(false))
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 220);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 220, 10));
                 return true;
@@ -3602,14 +3660,14 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(0, report.value_metrics().data_size());
-    EXPECT_EQ(1, report.value_metrics().skipped_size());
+    ASSERT_EQ(0, report.value_metrics().data_size());
+    ASSERT_EQ(1, report.value_metrics().skipped_size());
 
     EXPECT_EQ(NanoToMillis(bucketStartTimeNs),
               report.value_metrics().skipped(0).start_bucket_elapsed_millis());
     EXPECT_EQ(NanoToMillis(dumpReportTimeNs),
               report.value_metrics().skipped(0).end_bucket_elapsed_millis());
-    EXPECT_EQ(10, report.value_metrics().skipped(0).drop_event_size());
+    ASSERT_EQ(10, report.value_metrics().skipped(0).drop_event_size());
 
     auto dropEvent = report.value_metrics().skipped(0).drop_event(0);
     EXPECT_EQ(BucketDropReason::CONDITION_UNKNOWN, dropEvent.drop_reason());
@@ -3662,38 +3720,43 @@
     // Set up ValueMetricProducer.
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE");
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // ValueMetricProducer initialized.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                        return true;
-                    }))
-            // Screen state change to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+                return true;
+            }))
+            // Screen state change to ON.
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5, 5));
                 return true;
             }))
             // Screen state change to OFF.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 9));
                 return true;
             }))
             // Screen state change to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 15, 21));
                 return true;
             }))
             // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 30));
                 return true;
@@ -3710,7 +3773,7 @@
     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
 
     // Bucket status after metric initialized.
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {}
     auto it = valueProducer->mCurrentSlicedBucket.begin();
     auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
@@ -3723,7 +3786,7 @@
     auto screenEvent = CreateScreenStateChangedEvent(
             bucketStartTimeNs + 5, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
     StateManager::getInstance().onLogEvent(*screenEvent);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {}
     it = valueProducer->mCurrentSlicedBucket.begin();
     itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
@@ -3737,7 +3800,7 @@
     screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 10,
                                                 android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
     StateManager::getInstance().onLogEvent(*screenEvent);
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {}
     it = valueProducer->mCurrentSlicedBucket.begin();
     itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
@@ -3757,7 +3820,7 @@
     screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 15,
                                                 android::view::DisplayStateEnum::DISPLAY_STATE_ON);
     StateManager::getInstance().onLogEvent(*screenEvent);
-    EXPECT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(3UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {}
     it = valueProducer->mCurrentSlicedBucket.begin();
     itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
@@ -3787,21 +3850,21 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(3, report.value_metrics().data_size());
+    ASSERT_EQ(3, report.value_metrics().data_size());
 
     auto data = report.value_metrics().data(0);
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
 
     data = report.value_metrics().data(1);
-    EXPECT_EQ(1, report.value_metrics().data(1).bucket_info_size());
+    ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
     EXPECT_EQ(13, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
 
     data = report.value_metrics().data(2);
-    EXPECT_EQ(1, report.value_metrics().data(2).bucket_info_size());
+    ASSERT_EQ(1, report.value_metrics().data(2).bucket_info_size());
     EXPECT_EQ(12, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -3818,38 +3881,43 @@
     // Set up ValueMetricProducer.
     ValueMetric metric = ValueMetricProducerTestHelper::createMetricWithState("SCREEN_STATE_ONOFF");
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // ValueMetricProducer initialized.
-            .WillOnce(Invoke(
-                    [](int tagId, const ConfigKey&, vector<std::shared_ptr<LogEvent>>* data, bool) {
-                        data->clear();
-                        data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
-                        return true;
-                    }))
-            // Screen state change to ON.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
+                data->clear();
+                data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs, 3));
+                return true;
+            }))
+            // Screen state change to ON.
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
+                                vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 5);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 5, 5));
                 return true;
             }))
             // Screen state change to VR.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 10);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 10, 9));
                 return true;
             }))
             // Screen state change to OFF.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 15);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 15, 21));
                 return true;
             }))
             // Dump report requested.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 50);
                 data->clear();
                 data->push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 50, 30));
                 return true;
@@ -3878,7 +3946,7 @@
     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
 
     // Bucket status after metric initialized.
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {}
     auto it = valueProducer->mCurrentSlicedBucket.begin();
     auto itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
@@ -3891,7 +3959,7 @@
     auto screenEvent = CreateScreenStateChangedEvent(
             bucketStartTimeNs + 5, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
     StateManager::getInstance().onLogEvent(*screenEvent);
-    EXPECT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(1UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {}
     it = valueProducer->mCurrentSlicedBucket.begin();
     itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
@@ -3905,7 +3973,7 @@
     screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 10,
                                                 android::view::DisplayStateEnum::DISPLAY_STATE_VR);
     StateManager::getInstance().onLogEvent(*screenEvent);
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {}
     it = valueProducer->mCurrentSlicedBucket.begin();
     itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
@@ -3925,7 +3993,7 @@
     screenEvent = CreateScreenStateChangedEvent(bucketStartTimeNs + 15,
                                                 android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
     StateManager::getInstance().onLogEvent(*screenEvent);
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {}
     it = valueProducer->mCurrentSlicedBucket.begin();
     itBase = valueProducer->mCurrentBaseInfo.find(it->first.getDimensionKeyInWhat());
@@ -3949,21 +4017,21 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(3, report.value_metrics().data_size());
+    ASSERT_EQ(3, report.value_metrics().data_size());
 
     auto data = report.value_metrics().data(0);
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(2, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
 
     data = report.value_metrics().data(1);
-    EXPECT_EQ(1, report.value_metrics().data(1).bucket_info_size());
+    ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
     EXPECT_EQ(16, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
     EXPECT_EQ(screenOnGroup.group_id(), data.slice_by_state(0).group_id());
 
     data = report.value_metrics().data(2);
-    EXPECT_EQ(1, report.value_metrics().data(2).bucket_info_size());
+    ASSERT_EQ(1, report.value_metrics().data(2).bucket_info_size());
     EXPECT_EQ(9, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
@@ -3990,18 +4058,20 @@
     *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
-    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
+    EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _, _))
             // ValueMetricProducer initialized.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs);
                 data->clear();
                 data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 2 /*uid*/, 7));
                 data->push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs, 1 /*uid*/, 3));
                 return true;
             }))
             // Uid 1 process state change from kStateUnknown -> Foreground
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 20);
                 data->clear();
                 data->push_back(
                         CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 20, 1 /*uid*/, 6));
@@ -4012,8 +4082,9 @@
                 return true;
             }))
             // Uid 2 process state change from kStateUnknown -> Background
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucketStartTimeNs + 40);
                 data->clear();
                 data->push_back(
                         CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 40, 2 /*uid*/, 9));
@@ -4024,8 +4095,9 @@
                 return true;
             }))
             // Uid 1 process state change from Foreground -> Background
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 20);
                 data->clear();
                 data->push_back(
                         CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 20, 1 /*uid*/, 13));
@@ -4036,8 +4108,9 @@
                 return true;
             }))
             // Uid 1 process state change from Background -> Foreground
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 40);
                 data->clear();
                 data->push_back(
                         CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 40, 1 /*uid*/, 17));
@@ -4048,8 +4121,9 @@
                 return true;
             }))
             // Dump report pull.
-            .WillOnce(Invoke([](int tagId, const ConfigKey&,
+            .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data, bool) {
+                EXPECT_EQ(eventTimeNs, bucket2StartTimeNs + 50);
                 data->clear();
                 data->push_back(
                         CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 50, 2 /*uid*/, 20));
@@ -4069,7 +4143,7 @@
     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
 
     // Bucket status after metric initialized.
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {uid 1}.
     auto it = valueProducer->mCurrentSlicedBucket.begin();
     EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
@@ -4094,7 +4168,7 @@
     auto uidProcessEvent = CreateUidProcessStateChangedEvent(
             bucketStartTimeNs + 20, 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
     StateManager::getInstance().onLogEvent(*uidProcessEvent);
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {uid 1}.
     it = valueProducer->mCurrentSlicedBucket.begin();
     EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
@@ -4121,7 +4195,7 @@
     uidProcessEvent = CreateUidProcessStateChangedEvent(
             bucketStartTimeNs + 40, 2 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
     StateManager::getInstance().onLogEvent(*uidProcessEvent);
-    EXPECT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentSlicedBucket.size());
     // Base for dimension key {uid 1}.
     it = valueProducer->mCurrentSlicedBucket.begin();
     EXPECT_EQ(1, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
@@ -4151,9 +4225,9 @@
 
     // Buckets flushed after end of first bucket.
     // None of the buckets should have a value.
-    EXPECT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(4UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
+    ASSERT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(4UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
     // Base for dimension key {uid 2}.
     it = valueProducer->mCurrentSlicedBucket.begin();
     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
@@ -4161,7 +4235,7 @@
     EXPECT_EQ(true, itBase->second[0].hasBase);
     EXPECT_EQ(15, itBase->second[0].base.long_value);
     // Value for key {uid 2, BACKGROUND}.
-    EXPECT_EQ(1, it->first.getStateValuesKey().getValues().size());
+    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
     EXPECT_EQ(1006, it->first.getStateValuesKey().getValues()[0].mValue.int_value);
     EXPECT_EQ(false, it->second[0].hasValue);
 
@@ -4172,13 +4246,13 @@
     EXPECT_EQ(true, itBase->second[0].hasBase);
     EXPECT_EQ(10, itBase->second[0].base.long_value);
     // Value for key {uid 1, kStateUnknown}
-    EXPECT_EQ(0, it->first.getStateValuesKey().getValues().size());
+    ASSERT_EQ(0, it->first.getStateValuesKey().getValues().size());
     // EXPECT_EQ(-1, it->first.getStateValuesKey().getValues()[0].mValue.int_value);
     EXPECT_EQ(false, it->second[0].hasValue);
 
     // Value for key {uid 1, FOREGROUND}
     it++;
-    EXPECT_EQ(1, it->first.getStateValuesKey().getValues().size());
+    ASSERT_EQ(1, it->first.getStateValuesKey().getValues().size());
     EXPECT_EQ(1005, it->first.getStateValuesKey().getValues()[0].mValue.int_value);
     EXPECT_EQ(false, it->second[0].hasValue);
 
@@ -4191,9 +4265,9 @@
             bucket2StartTimeNs + 20, 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_BACKGROUND);
     StateManager::getInstance().onLogEvent(*uidProcessEvent);
 
-    EXPECT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(4UL, valueProducer->mPastBuckets.size());
-    EXPECT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
+    ASSERT_EQ(4UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(4UL, valueProducer->mPastBuckets.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
     // Base for dimension key {uid 2}.
     it = valueProducer->mCurrentSlicedBucket.begin();
     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
@@ -4225,8 +4299,8 @@
             bucket2StartTimeNs + 40, 1 /* uid */, android::app::PROCESS_STATE_IMPORTANT_FOREGROUND);
     StateManager::getInstance().onLogEvent(*uidProcessEvent);
 
-    EXPECT_EQ(5UL, valueProducer->mCurrentSlicedBucket.size());
-    EXPECT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
+    ASSERT_EQ(5UL, valueProducer->mCurrentSlicedBucket.size());
+    ASSERT_EQ(2UL, valueProducer->mCurrentBaseInfo.size());
     // Base for dimension key {uid 2}
     it = valueProducer->mCurrentSlicedBucket.begin();
     EXPECT_EQ(2, it->first.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
@@ -4261,10 +4335,10 @@
 
     StatsLogReport report = outputStreamToProto(&output);
     EXPECT_TRUE(report.has_value_metrics());
-    EXPECT_EQ(5, report.value_metrics().data_size());
+    ASSERT_EQ(5, report.value_metrics().data_size());
 
     auto data = report.value_metrics().data(0);
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(4, report.value_metrics().data(0).bucket_info(0).values(0).value_long());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -4272,7 +4346,7 @@
               data.slice_by_state(0).value());
 
     data = report.value_metrics().data(1);
-    EXPECT_EQ(1, report.value_metrics().data(1).bucket_info_size());
+    ASSERT_EQ(1, report.value_metrics().data(1).bucket_info_size());
     EXPECT_EQ(2, report.value_metrics().data(1).bucket_info(0).values(0).value_long());
 
     data = report.value_metrics().data(2);
@@ -4280,12 +4354,12 @@
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
               data.slice_by_state(0).value());
-    EXPECT_EQ(2, report.value_metrics().data(2).bucket_info_size());
+    ASSERT_EQ(2, report.value_metrics().data(2).bucket_info_size());
     EXPECT_EQ(4, report.value_metrics().data(2).bucket_info(0).values(0).value_long());
     EXPECT_EQ(7, report.value_metrics().data(2).bucket_info(1).values(0).value_long());
 
     data = report.value_metrics().data(3);
-    EXPECT_EQ(1, report.value_metrics().data(3).bucket_info_size());
+    ASSERT_EQ(1, report.value_metrics().data(3).bucket_info_size());
     EXPECT_EQ(3, report.value_metrics().data(3).bucket_info(0).values(0).value_long());
 
     data = report.value_metrics().data(4);
@@ -4293,7 +4367,7 @@
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
               data.slice_by_state(0).value());
-    EXPECT_EQ(2, report.value_metrics().data(4).bucket_info_size());
+    ASSERT_EQ(2, report.value_metrics().data(4).bucket_info_size());
     EXPECT_EQ(6, report.value_metrics().data(4).bucket_info(0).values(0).value_long());
     EXPECT_EQ(5, report.value_metrics().data(4).bucket_info(1).values(0).value_long());
 }
diff --git a/cmds/statsd/tests/metrics/metrics_test_helper.h b/cmds/statsd/tests/metrics/metrics_test_helper.h
index 46ef0f6..eeb38a4 100644
--- a/cmds/statsd/tests/metrics/metrics_test_helper.h
+++ b/cmds/statsd/tests/metrics/metrics_test_helper.h
@@ -38,10 +38,11 @@
                       int64_t nextPulltimeNs, int64_t intervalNs));
     MOCK_METHOD3(UnRegisterReceiver,
                  void(int tagId, const ConfigKey& key, wp<PullDataReceiver> receiver));
-    MOCK_METHOD4(Pull, bool(const int pullCode, const ConfigKey& key,
+    MOCK_METHOD5(Pull, bool(const int pullCode, const ConfigKey& key, const int64_t eventTimeNs,
                             vector<std::shared_ptr<LogEvent>>* data, bool useUids));
-    MOCK_METHOD4(Pull, bool(const int pullCode, const vector<int32_t>& uids,
-                            vector<std::shared_ptr<LogEvent>>* data, bool useUids));
+    MOCK_METHOD5(Pull,
+                 bool(const int pullCode, const vector<int32_t>& uids, const int64_t eventTimeNs,
+                      vector<std::shared_ptr<LogEvent>>* data, bool useUids));
     MOCK_METHOD2(RegisterPullUidProvider,
                  void(const ConfigKey& configKey, wp<PullUidProvider> provider));
     MOCK_METHOD2(UnregisterPullUidProvider,
diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
index 363fcb4..e384b6a 100644
--- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
+++ b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
@@ -190,8 +190,8 @@
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     const vector<int32_t> uids = {AID_SYSTEM};
-    EXPECT_CALL(*pullerManager, Pull(10016, uids, _, _))
-            .WillRepeatedly(Invoke([](int tagId, const vector<int32_t>&,
+    EXPECT_CALL(*pullerManager, Pull(10016, uids, _, _, _))
+            .WillRepeatedly(Invoke([](int tagId, const vector<int32_t>&, const int64_t,
                                       vector<std::shared_ptr<LogEvent>>* data, bool) {
                 data->clear();
                 data->push_back(makeCpuActiveTimeAtom(/*uid=*/kUid1, /*timeMillis=*/kCpuTime1));
diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp
index ba2a4cf..13e8f5c 100644
--- a/cmds/statsd/tests/state/StateTracker_test.cpp
+++ b/cmds/statsd/tests/state/StateTracker_test.cpp
@@ -205,7 +205,7 @@
     std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(timestampNs, attributionUids1,
                                                                   attributionTags1, "wakelockName");
     mgr.onLogEvent(*event1);
-    EXPECT_EQ(1, listener->updates.size());
+    ASSERT_EQ(1, listener->updates.size());
     EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
     EXPECT_EQ(1, listener->updates[0].mState);
     listener->updates.clear();
@@ -213,17 +213,17 @@
     std::unique_ptr<LogEvent> event2 = CreateAcquireWakelockEvent(
             timestampNs + 1000, attributionUids1, attributionTags1, "wakelockName");
     mgr.onLogEvent(*event2);
-    EXPECT_EQ(0, listener->updates.size());
+    ASSERT_EQ(0, listener->updates.size());
 
     std::unique_ptr<LogEvent> event3 = CreateReleaseWakelockEvent(
             timestampNs + 2000, attributionUids1, attributionTags1, "wakelockName");
     mgr.onLogEvent(*event3);
-    EXPECT_EQ(0, listener->updates.size());
+    ASSERT_EQ(0, listener->updates.size());
 
     std::unique_ptr<LogEvent> event4 = CreateReleaseWakelockEvent(
             timestampNs + 3000, attributionUids1, attributionTags1, "wakelockName");
     mgr.onLogEvent(*event4);
-    EXPECT_EQ(1, listener->updates.size());
+    ASSERT_EQ(1, listener->updates.size());
     EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
     EXPECT_EQ(0, listener->updates[0].mState);
 }
@@ -247,7 +247,7 @@
             CreateBleScanStateChangedEvent(timestampNs, attributionUids1, attributionTags1,
                                            BleScanStateChanged::ON, false, false, false);
     mgr.onLogEvent(*event1);
-    EXPECT_EQ(1, listener->updates.size());
+    ASSERT_EQ(1, listener->updates.size());
     EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
     EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
     FieldValue stateFieldValue;
@@ -259,7 +259,7 @@
             CreateBleScanStateChangedEvent(timestampNs + 1000, attributionUids2, attributionTags1,
                                            BleScanStateChanged::ON, false, false, false);
     mgr.onLogEvent(*event2);
-    EXPECT_EQ(1, listener->updates.size());
+    ASSERT_EQ(1, listener->updates.size());
     EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value);
     EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState);
     mgr.getStateValue(util::BLE_SCAN_STATE_CHANGED, listener->updates[0].mKey, &stateFieldValue);
@@ -270,7 +270,7 @@
             CreateBleScanStateChangedEvent(timestampNs + 2000, attributionUids2, attributionTags1,
                                            BleScanStateChanged::RESET, false, false, false);
     mgr.onLogEvent(*event3);
-    EXPECT_EQ(2, listener->updates.size());
+    ASSERT_EQ(2, listener->updates.size());
     for (const TestStateListener::Update& update : listener->updates) {
         EXPECT_EQ(BleScanStateChanged::OFF, update.mState);
 
@@ -294,7 +294,7 @@
     mgr.onLogEvent(*event);
 
     // check listener was updated
-    EXPECT_EQ(1, listener1->updates.size());
+    ASSERT_EQ(1, listener1->updates.size());
     EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey);
     EXPECT_EQ(2, listener1->updates[0].mState);
 
@@ -319,7 +319,7 @@
     mgr.onLogEvent(*event);
 
     // check listener was updated
-    EXPECT_EQ(1, listener1->updates.size());
+    ASSERT_EQ(1, listener1->updates.size());
     EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
     EXPECT_EQ(1002, listener1->updates[0].mState);
 
@@ -346,8 +346,8 @@
     EXPECT_EQ(1, mgr.getListenersCount(util::WAKELOCK_STATE_CHANGED));
 
     // Check listener was updated.
-    EXPECT_EQ(1, listener1->updates.size());
-    EXPECT_EQ(3, listener1->updates[0].mKey.getValues().size());
+    ASSERT_EQ(1, listener1->updates.size());
+    ASSERT_EQ(3, listener1->updates[0].mKey.getValues().size());
     EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
     EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value);
     EXPECT_EQ("wakelockName", listener1->updates[0].mKey.getValues()[2].mValue.str_value);
@@ -388,7 +388,7 @@
     mgr.onLogEvent(*event);
 
     // check listener was updated
-    EXPECT_EQ(1, listener1->updates.size());
+    ASSERT_EQ(1, listener1->updates.size());
     EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value);
     EXPECT_EQ(1, listener1->updates[0].mState);
 
@@ -416,9 +416,9 @@
 
     // check listener was updated
     mgr.onLogEvent(*event1);
-    EXPECT_EQ(0, listener1->updates.size());
+    ASSERT_EQ(0, listener1->updates.size());
     mgr.onLogEvent(*event2);
-    EXPECT_EQ(0, listener1->updates.size());
+    ASSERT_EQ(0, listener1->updates.size());
 }
 
 TEST(StateTrackerTest, TestStateQuery) {
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index 2315fd7..6a7ad1f 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -956,11 +956,11 @@
 void ValidateWakelockAttributionUidAndTagDimension(const DimensionsValue& value, const int atomId,
                                                    const int uid, const string& tag) {
     EXPECT_EQ(value.field(), atomId);
-    EXPECT_EQ(value.value_tuple().dimensions_value_size(), 2);
+    ASSERT_EQ(value.value_tuple().dimensions_value_size(), 2);
     // Attribution field.
     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
     // Uid field.
-    EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 1);
+    ASSERT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value_size(), 1);
     EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).field(), 1);
     EXPECT_EQ(value.value_tuple().dimensions_value(0).value_tuple().dimensions_value(0).value_int(),
               uid);
@@ -971,7 +971,7 @@
 
 void ValidateAttributionUidDimension(const DimensionsValue& value, int atomId, int uid) {
     EXPECT_EQ(value.field(), atomId);
-    EXPECT_EQ(value.value_tuple().dimensions_value_size(), 1);
+    ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
     // Attribution field.
     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1);
     // Uid only.
@@ -985,7 +985,7 @@
 
 void ValidateUidDimension(const DimensionsValue& value, int node_idx, int atomId, int uid) {
     EXPECT_EQ(value.field(), atomId);
-    EXPECT_GT(value.value_tuple().dimensions_value_size(), node_idx);
+    ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
     // Attribution field.
     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx).field(), 1);
     EXPECT_EQ(value.value_tuple().dimensions_value(node_idx)
@@ -997,7 +997,7 @@
 void ValidateAttributionUidAndTagDimension(
     const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag) {
     EXPECT_EQ(value.field(), atomId);
-    EXPECT_GT(value.value_tuple().dimensions_value_size(), node_idx);
+    ASSERT_GT(value.value_tuple().dimensions_value_size(), node_idx);
     // Attribution field.
     EXPECT_EQ(1, value.value_tuple().dimensions_value(node_idx).field());
     // Uid only.
@@ -1016,7 +1016,7 @@
 void ValidateAttributionUidAndTagDimension(
     const DimensionsValue& value, int atomId, int uid, const std::string& tag) {
     EXPECT_EQ(value.field(), atomId);
-    EXPECT_EQ(1, value.value_tuple().dimensions_value_size());
+    ASSERT_EQ(1, value.value_tuple().dimensions_value_size());
     // Attribution field.
     EXPECT_EQ(1, value.value_tuple().dimensions_value(0).field());
     // Uid only.
@@ -1339,7 +1339,7 @@
         // stats_event.h/c uses a vector as opposed to a buffer.
         p.buffer.assign(buffer, buffer + size);
         parcels.push_back(std::move(p));
-        AStatsEvent_write(event);
+        AStatsEvent_release(event);
     }
     resultReceiver->pullFinished(atomTag, /*success=*/true, parcels);
     return Status::ok();
diff --git a/cmds/statsd/tests/storage/StorageManager_test.cpp b/cmds/statsd/tests/storage/StorageManager_test.cpp
index 27a86e42..74eafbf 100644
--- a/cmds/statsd/tests/storage/StorageManager_test.cpp
+++ b/cmds/statsd/tests/storage/StorageManager_test.cpp
@@ -49,10 +49,10 @@
     EXPECT_TRUE(result);
 
     EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
-    EXPECT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
+    ASSERT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
     EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
     EXPECT_EQ(trainInfo.status, trainInfoResult.status);
-    EXPECT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
+    ASSERT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
     EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
 }
 
@@ -75,10 +75,10 @@
     EXPECT_TRUE(result);
 
     EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
-    EXPECT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
+    ASSERT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
     EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
     EXPECT_EQ(trainInfo.status, trainInfoResult.status);
-    EXPECT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
+    ASSERT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
     EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
 }
 
diff --git a/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java
index c35f7fc..3b14be7 100644
--- a/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java
+++ b/cmds/uiautomator/cmds/uiautomator/src/com/android/commands/uiautomator/DumpCommand.java
@@ -16,6 +16,7 @@
 
 package com.android.commands.uiautomator;
 
+import android.accessibilityservice.AccessibilityServiceInfo;
 import android.app.UiAutomation;
 import android.graphics.Point;
 import android.hardware.display.DisplayManagerGlobal;
@@ -61,11 +62,14 @@
     public void run(String[] args) {
         File dumpFile = DEFAULT_DUMP_FILE;
         boolean verboseMode = true;
+        boolean allWindows = false;
 
         for (String arg : args) {
             if (arg.equals("--compressed"))
                 verboseMode = false;
-            else if (!arg.startsWith("-")) {
+            else if (arg.equals("--windows")) {
+                allWindows = true;
+            } else if (!arg.startsWith("-")) {
                 dumpFile = new File(arg);
             }
         }
@@ -85,18 +89,28 @@
         try {
             UiAutomation uiAutomation = automationWrapper.getUiAutomation();
             uiAutomation.waitForIdle(1000, 1000 * 10);
-            AccessibilityNodeInfo info = uiAutomation.getRootInActiveWindow();
-            if (info == null) {
-                System.err.println("ERROR: null root node returned by UiTestAutomationBridge.");
-                return;
-            }
+            if (allWindows) {
+                AccessibilityServiceInfo info = uiAutomation.getServiceInfo();
+                info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
+                uiAutomation.setServiceInfo(info);
+                AccessibilityNodeInfoDumper.dumpWindowsToFile(
+                        uiAutomation.getWindowsOnAllDisplays(), dumpFile,
+                        DisplayManagerGlobal.getInstance());
+            } else {
+                AccessibilityNodeInfo info = uiAutomation.getRootInActiveWindow();
+                if (info == null) {
+                    System.err.println("ERROR: null root node returned by UiTestAutomationBridge.");
+                    return;
+                }
 
-            Display display =
-                    DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
-            int rotation = display.getRotation();
-            Point size = new Point();
-            display.getSize(size);
-            AccessibilityNodeInfoDumper.dumpWindowToFile(info, dumpFile, rotation, size.x, size.y);
+                Display display =
+                        DisplayManagerGlobal.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
+                int rotation = display.getRotation();
+                Point size = new Point();
+                display.getSize(size);
+                AccessibilityNodeInfoDumper.dumpWindowToFile(info, dumpFile, rotation, size.x,
+                        size.y);
+            }
         } catch (TimeoutException re) {
             System.err.println("ERROR: could not get idle state.");
             return;
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
index 63c51e8..ab198b3 100644
--- a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
@@ -16,11 +16,17 @@
 
 package com.android.uiautomator.core;
 
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManagerGlobal;
 import android.os.Environment;
 import android.os.SystemClock;
 import android.util.Log;
+import android.util.SparseArray;
 import android.util.Xml;
+import android.view.Display;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
 
 import org.xmlpull.v1.XmlSerializer;
 
@@ -28,6 +34,7 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.StringWriter;
+import java.util.List;
 
 /**
  *
@@ -98,6 +105,95 @@
         Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms");
     }
 
+    /**
+     * Using {@link AccessibilityWindowInfo} this method will dump some window information and
+     * then walk the layout hierarchy of it's
+     * and generates an xml dump to the location specified by <code>dumpFile</code>
+     * @param allWindows All windows indexed by display-id.
+     * @param dumpFile The file to dump to.
+     */
+    public static void dumpWindowsToFile(SparseArray<List<AccessibilityWindowInfo>> allWindows,
+            File dumpFile, DisplayManagerGlobal displayManager) {
+        if (allWindows.size() == 0) {
+            return;
+        }
+        final long startTime = SystemClock.uptimeMillis();
+        try {
+            FileWriter writer = new FileWriter(dumpFile);
+            XmlSerializer serializer = Xml.newSerializer();
+            StringWriter stringWriter = new StringWriter();
+            serializer.setOutput(stringWriter);
+            serializer.startDocument("UTF-8", true);
+            serializer.startTag("", "displays");
+            for (int d = 0, nd = allWindows.size(); d < nd; ++d) {
+                int displayId = allWindows.keyAt(d);
+                Display display = displayManager.getRealDisplay(displayId);
+                if (display == null) {
+                    continue;
+                }
+                final List<AccessibilityWindowInfo> windows = allWindows.valueAt(d);
+                if (windows.isEmpty()) {
+                    continue;
+                }
+                serializer.startTag("", "display");
+                serializer.attribute("", "id", Integer.toString(displayId));
+                int rotation = display.getRotation();
+                Point size = new Point();
+                display.getSize(size);
+                for (int i = 0, n = windows.size(); i < n; ++i) {
+                    dumpWindowRec(windows.get(i), serializer, i, size.x, size.y, rotation);
+                }
+                serializer.endTag("", "display");
+            }
+            serializer.endTag("", "displays");
+            serializer.endDocument();
+            writer.write(stringWriter.toString());
+            writer.close();
+        } catch (IOException e) {
+            Log.e(LOGTAG, "failed to dump window to file", e);
+        }
+        final long endTime = SystemClock.uptimeMillis();
+        Log.w(LOGTAG, "Fetch time: " + (endTime - startTime) + "ms");
+    }
+
+    private static void dumpWindowRec(AccessibilityWindowInfo winfo, XmlSerializer serializer,
+            int index, int width, int height, int rotation) throws IOException {
+        serializer.startTag("", "window");
+        serializer.attribute("", "index", Integer.toString(index));
+        final CharSequence title = winfo.getTitle();
+        serializer.attribute("", "title", title != null ? title.toString() : "");
+        final Rect tmpBounds = new Rect();
+        winfo.getBoundsInScreen(tmpBounds);
+        serializer.attribute("", "bounds", tmpBounds.toShortString());
+        serializer.attribute("", "active", Boolean.toString(winfo.isActive()));
+        serializer.attribute("", "focused", Boolean.toString(winfo.isFocused()));
+        serializer.attribute("", "accessibility-focused",
+                Boolean.toString(winfo.isAccessibilityFocused()));
+        serializer.attribute("", "id", Integer.toString(winfo.getId()));
+        serializer.attribute("", "layer", Integer.toString(winfo.getLayer()));
+        serializer.attribute("", "type", AccessibilityWindowInfo.typeToString(winfo.getType()));
+        int count = winfo.getChildCount();
+        for (int i = 0; i < count; ++i) {
+            AccessibilityWindowInfo child = winfo.getChild(i);
+            if (child == null) {
+                Log.i(LOGTAG, String.format("Null window child %d/%d, parent: %s", i, count,
+                        winfo.getTitle()));
+                continue;
+            }
+            dumpWindowRec(child, serializer, i, width, height, rotation);
+            child.recycle();
+        }
+        AccessibilityNodeInfo root = winfo.getRoot();
+        if (root != null) {
+            serializer.startTag("", "hierarchy");
+            serializer.attribute("", "rotation", Integer.toString(rotation));
+            dumpNodeRec(root, serializer, 0, width, height);
+            root.recycle();
+            serializer.endTag("", "hierarchy");
+        }
+        serializer.endTag("", "window");
+    }
+
     private static void dumpNodeRec(AccessibilityNodeInfo node, XmlSerializer serializer,int index,
             int width, int height) throws IOException {
         serializer.startTag("", "node");
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9067069..97b704c 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -601,6 +601,20 @@
     @TestApi
     public static final int PROCESS_CAPABILITY_FOREGROUND_MICROPHONE = 1 << 2;
 
+    // TODO: remove this when development is done.
+    // These are debug flags used between OomAdjuster and AppOpsService to detect and report absence
+    // of the real flags.
+    /** @hide */
+    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q = 1 << 27;
+    /** @hide */
+    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q = 1 << 28;
+    /** @hide */
+    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE = 1 << 29;
+    /** @hide */
+    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA = 1 << 30;
+    /** @hide */
+    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1 << 31;
+
     /** @hide all capabilities, the ORing of all flags in {@link ProcessCapability}*/
     @TestApi
     public static final int PROCESS_CAPABILITY_ALL = PROCESS_CAPABILITY_FOREGROUND_LOCATION
@@ -623,6 +637,51 @@
     public static final int PROCESS_CAPABILITY_ALL_IMPLICIT = PROCESS_CAPABILITY_FOREGROUND_CAMERA
             | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
 
+    /**
+     * Print capability bits in human-readable form.
+     * @hide
+     */
+    public static void printCapabilitiesSummary(PrintWriter pw, @ProcessCapability int caps) {
+        pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_LOCATION) != 0 ? 'L' : '-');
+        pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0 ? 'C' : '-');
+        pw.print((caps & PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0 ? 'M' : '-');
+    }
+
+    /**
+     * Print capability bits in human-readable form.
+     * @hide
+     */
+    public static void printCapabilitiesFull(PrintWriter pw, @ProcessCapability int caps) {
+        printCapabilitiesSummary(pw, caps);
+        if ((caps & DEBUG_PROCESS_CAPABILITY_FOREGROUND_LOCATION) != 0) {
+            pw.print(" !L");
+        }
+        if ((caps & DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA) != 0) {
+            pw.print(" !C");
+        }
+        if ((caps & DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q) != 0) {
+            pw.print(" !Cq");
+        }
+        if ((caps & DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE) != 0) {
+            pw.print(" !M");
+        }
+        if ((caps & DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q) != 0) {
+            pw.print(" !Mq");
+        }
+        final int remain = caps & ~(PROCESS_CAPABILITY_FOREGROUND_LOCATION
+                | PROCESS_CAPABILITY_FOREGROUND_CAMERA
+                | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
+                | DEBUG_PROCESS_CAPABILITY_FOREGROUND_LOCATION
+                | DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA
+                | DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q
+                | DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
+                | DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q);
+        if (remain != 0) {
+            pw.print('+');
+            pw.print(remain);
+        }
+    }
+
     // NOTE: If PROCESS_STATEs are added, then new fields must be added
     // to frameworks/base/core/proto/android/app/enums.proto and the following method must
     // be updated to correctly map between them.
@@ -2231,7 +2290,8 @@
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeLong(mId);
             ComponentName.writeToParcel(mTopActivityComponent, dest);
-            dest.writeParcelable(mSnapshot, 0);
+            dest.writeParcelable(mSnapshot != null && !mSnapshot.isDestroyed() ? mSnapshot : null,
+                    0);
             dest.writeInt(mColorSpace.getId());
             dest.writeInt(mOrientation);
             dest.writeInt(mRotation);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index d321288..b058dcd 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -3688,7 +3688,7 @@
         /**
          * @hide
          */
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
+        @UnsupportedAppUsage(/*maxTargetSdk = Build.VERSION_CODES.R,*/ publicAlternatives = "{@code "
                 + "#getOpStr()}")
         public int getOp() {
             return mOp;
@@ -3707,7 +3707,7 @@
          * @deprecated Use {@link #getLastAccessTime(int)} instead
          */
         @Deprecated
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
+        @UnsupportedAppUsage(/*maxTargetSdk = Build.VERSION_CODES.R,*/ publicAlternatives = "{@code "
                 + "#getLastAccessTime(int)}")
         public long getTime() {
             return getLastAccessTime(OP_FLAGS_ALL);
@@ -3822,7 +3822,7 @@
          * @deprecated Use {@link #getLastRejectTime(int)} instead
          */
         @Deprecated
-        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
+        @UnsupportedAppUsage(/*maxTargetSdk = Build.VERSION_CODES.R,*/ publicAlternatives = "{@code "
                 + "#getLastRejectTime(int)}")
         public long getRejectTime() {
             return getLastRejectTime(OP_FLAGS_ALL);
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 8dfce14..4c3e888 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -58,7 +58,9 @@
 
     void setShowBadge(String pkg, int uid, boolean showBadge);
     boolean canShowBadge(String pkg, int uid);
-    boolean hasSentMessage(String pkg, int uid);
+    boolean isInInvalidMsgState(String pkg, int uid);
+    boolean hasUserDemotedInvalidMsgApp(String pkg, int uid);
+    void setInvalidMsgAppDemoted(String pkg, int uid, boolean isDemoted);
     void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled);
     /**
      * Updates the notification's enabled state. Additionally locks importance for all of the
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 745add1..79da1f6 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -1183,7 +1183,8 @@
                     return NO_MATCH_DATA;
                 }
             }
-            if (mPort >= 0) {
+            // if we're dealing with wildcard support, we ignore ports
+            if (!wildcardSupported && mPort >= 0) {
                 if (mPort != data.getPort()) {
                     return NO_MATCH_DATA;
                 }
@@ -1580,12 +1581,13 @@
      * @param wildcardSupported if true, will allow parameters to use wildcards
      */
     private int matchData(String type, String scheme, Uri data, boolean wildcardSupported) {
-        final ArrayList<String> types = mDataTypes;
+        final boolean wildcardWithMimegroups = wildcardSupported && countMimeGroups() != 0;
+        final List<String> types = mDataTypes;
         final ArrayList<String> schemes = mDataSchemes;
 
         int match = MATCH_CATEGORY_EMPTY;
 
-        if (types == null && schemes == null) {
+        if (!wildcardWithMimegroups && types == null && schemes == null) {
             return ((type == null && data == null)
                 ? (MATCH_CATEGORY_EMPTY+MATCH_ADJUSTMENT_NORMAL) : NO_MATCH_DATA);
         }
@@ -1640,7 +1642,9 @@
             }
         }
 
-        if (types != null) {
+        if (wildcardWithMimegroups) {
+            return MATCH_CATEGORY_TYPE;
+        } else if (types != null) {
             if (findMimeType(type)) {
                 match = MATCH_CATEGORY_TYPE;
             } else {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 4d718ef..9832bc1 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -51,7 +51,9 @@
 import android.content.pm.parsing.PackageInfoWithoutStateUtils;
 import android.content.pm.parsing.ParsingPackage;
 import android.content.pm.parsing.ParsingPackageUtils;
+import android.content.pm.parsing.result.ParseInput;
 import android.content.pm.parsing.result.ParseResult;
+import android.content.pm.parsing.result.ParseTypeImpl;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.Rect;
@@ -3049,6 +3051,16 @@
     public static final String FEATURE_IPSEC_TUNNELS = "android.software.ipsec_tunnels";
 
     /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports a system interface for the user to select
+     * and bind device control services provided by applications.
+     *
+     * @see android.service.controls.ControlsProviderService
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_CONTROLS = "android.software.controls";
+
+    /**
      * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device has
      * the requisite hardware support to support reboot escrow of synthetic password for updates.
      *
@@ -6051,7 +6063,8 @@
         boolean collectCertificates = (flags & PackageManager.GET_SIGNATURES) != 0
                 || (flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0;
 
-        ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefaultOneTime(
+        ParseInput input = ParseTypeImpl.forParsingWithoutPlatformCompat().reset();
+        ParseResult<ParsingPackage> result = ParsingPackageUtils.parseDefault(input,
                 new File(archiveFilePath), 0, collectCertificates);
         if (result.isError()) {
             return null;
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index cb29431..5a79475 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -131,14 +131,23 @@
     public static final String TAG = ParsingUtils.TAG;
 
     /**
-     * For cases outside of PackageManagerService when an APK needs to be parsed as a one-off
-     * request, without caching the input object and without querying the internal system state
-     * for feature support.
+     * @see #parseDefault(ParseInput, File, int, boolean)
      */
     @NonNull
     public static ParseResult<ParsingPackage> parseDefaultOneTime(File file,
             @PackageParser.ParseFlags int parseFlags, boolean collectCertificates) {
         ParseInput input = ParseTypeImpl.forDefaultParsing().reset();
+        return parseDefault(input, file, parseFlags, collectCertificates);
+    }
+
+    /**
+     * For cases outside of PackageManagerService when an APK needs to be parsed as a one-off
+     * request, without caching the input object and without querying the internal system state
+     * for feature support.
+     */
+    @NonNull
+    public static ParseResult<ParsingPackage> parseDefault(ParseInput input, File file,
+            @PackageParser.ParseFlags int parseFlags, boolean collectCertificates) {
         ParseResult<ParsingPackage> result;
 
         ParsingPackageUtils parser = new ParsingPackageUtils(false, null, null, new Callback() {
diff --git a/core/java/android/content/pm/parsing/result/ParseInput.java b/core/java/android/content/pm/parsing/result/ParseInput.java
index d5898b7..0fb18ae 100644
--- a/core/java/android/content/pm/parsing/result/ParseInput.java
+++ b/core/java/android/content/pm/parsing/result/ParseInput.java
@@ -16,6 +16,7 @@
 
 package android.content.pm.parsing.result;
 
+import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.ChangeId;
@@ -69,6 +70,25 @@
         @ChangeId
         @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
         public static final long RESOURCES_ARSC_COMPRESSED = 132742131;
+
+        /**
+         * TODO(chiuwinson): This is required because PackageManager#getPackageArchiveInfo
+         *   cannot read the targetSdk info from the changeId because it requires the
+         *   READ_COMPAT_CHANGE_CONFIG which cannot be obtained automatically without entering the
+         *   server process. This should be removed once an alternative is found, or if the API
+         *   is removed.
+         * @return the targetSdk that this change is gated on (> check), or -1 if disabled
+         */
+        @IntRange(from = -1, to = Integer.MAX_VALUE)
+        public static int getTargetSdkForChange(long changeId) {
+            if (changeId == MISSING_APP_TAG
+                    || changeId == EMPTY_INTENT_ACTION_CATEGORY
+                    || changeId == RESOURCES_ARSC_COMPRESSED) {
+                return Build.VERSION_CODES.Q;
+            }
+
+            return -1;
+        }
     }
 
     <ResultType> ParseResult<ResultType> success(ResultType result);
diff --git a/core/java/android/content/pm/parsing/result/ParseTypeImpl.java b/core/java/android/content/pm/parsing/result/ParseTypeImpl.java
index 91e571b..14992fb 100644
--- a/core/java/android/content/pm/parsing/result/ParseTypeImpl.java
+++ b/core/java/android/content/pm/parsing/result/ParseTypeImpl.java
@@ -65,6 +65,21 @@
     private Integer mTargetSdkVersion;
 
     /**
+     * Specifically for {@link PackageManager#getPackageArchiveInfo(String, int)} where
+     * {@link IPlatformCompat} cannot be used because the cross-package READ_COMPAT_CHANGE_CONFIG
+     * permission cannot be obtained.
+     */
+    public static ParseTypeImpl forParsingWithoutPlatformCompat() {
+        return new ParseTypeImpl((changeId, packageName, targetSdkVersion) -> {
+            int gateSdkVersion = DeferredError.getTargetSdkForChange(changeId);
+            if (gateSdkVersion == -1) {
+                return false;
+            }
+            return targetSdkVersion > gateSdkVersion;
+        });
+    }
+
+    /**
      * Assumes {@link Context#PLATFORM_COMPAT_SERVICE} is available to the caller. For use
      * with {@link android.content.pm.parsing.ApkLiteParseUtils} or similar where parsing is
      * done outside of {@link com.android.server.pm.PackageManagerService}.
diff --git a/core/java/android/debug/AdbNotifications.java b/core/java/android/debug/AdbNotifications.java
index fed5f5f..9f1a5f8 100644
--- a/core/java/android/debug/AdbNotifications.java
+++ b/core/java/android/debug/AdbNotifications.java
@@ -17,11 +17,13 @@
 package android.debug;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -42,8 +44,9 @@
      * Builds a notification to show connected state for adb over a transport type.
      * @param context the context
      * @param transportType the adb transport type.
-     * @return a newly created Notification for the transport type.
+     * @return a newly created Notification for the transport type, or null on error.
      */
+    @Nullable
     public static Notification createNotification(@NonNull Context context,
             byte transportType) {
         Resources resources = context.getResources();
@@ -66,10 +69,16 @@
 
         Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        intent.setPackage(context.getPackageManager().resolveActivity(intent,
-                PackageManager.MATCH_SYSTEM_ONLY).activityInfo.packageName);
-        PendingIntent pIntent = PendingIntent.getActivityAsUser(context, 0, intent,
-                PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT);
+        ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent,
+                PackageManager.MATCH_SYSTEM_ONLY);
+        // Settings app may not be available (e.g. device policy manager removes it)
+        PendingIntent pIntent = null;
+        if (resolveInfo != null) {
+            intent.setPackage(resolveInfo.activityInfo.packageName);
+            pIntent = PendingIntent.getActivityAsUser(context, 0, intent,
+                    PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT);
+        }
+
 
         return new Notification.Builder(context, SystemNotificationChannels.DEVELOPER_IMPORTANT)
                 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 2012039..b149d77 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -43,6 +43,10 @@
  * through the {@link CameraManager CameraManager}
  * interface with {@link CameraManager#getCameraCharacteristics}.</p>
  *
+ * <p>When obtained by a client that does not hold the CAMERA permission, some metadata values are
+ * not included. The list of keys that require the permission is given by
+ * {@link #getKeysNeedingPermission}.</p>
+ *
  * <p>{@link CameraCharacteristics} objects are immutable.</p>
  *
  * @see CameraDevice
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index e81c649..230aa04 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -362,6 +362,11 @@
      * cameras that can only be used as part of logical multi-camera. These cameras cannot be
      * opened directly via {@link #openCamera}</p>
      *
+     * <p>Also starting with API level 29, while most basic camera information is still available
+     * even without the CAMERA permission, some values are not available to apps that do not hold
+     * that permission. The keys not available are listed by
+     * {@link CameraCharacteristics#getKeysNeedingPermission}.</p>
+     *
      * @param cameraId The id of the camera device to query. This could be either a standalone
      * camera ID which can be directly opened by {@link #openCamera}, or a physical camera ID that
      * can only used as part of a logical multi-camera.
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index ae04693..b546967 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -3949,14 +3949,24 @@
             new Key<Integer>("android.sensor.testPatternMode", int.class);
 
     /**
-     * <p>Duration between the start of first row exposure
-     * and the start of last row exposure.</p>
-     * <p>This is the exposure time skew between the first and last
-     * row exposure start times. The first row and the last row are
-     * the first and last rows inside of the
+     * <p>Duration between the start of exposure for the first row of the image sensor,
+     * and the start of exposure for one past the last row of the image sensor.</p>
+     * <p>This is the exposure time skew between the first and <code>(last+1)</code> row exposure start times. The
+     * first row and the last row are the first and last rows inside of the
      * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
-     * <p>For typical camera sensors that use rolling shutters, this is also equivalent
-     * to the frame readout time.</p>
+     * <p>For typical camera sensors that use rolling shutters, this is also equivalent to the frame
+     * readout time.</p>
+     * <p>If the image sensor is operating in a binned or cropped mode due to the current output
+     * target resolutions, it's possible this skew is reported to be larger than the exposure
+     * time, for example, since it is based on the full array even if a partial array is read
+     * out. Be sure to scale the number to cover the section of the sensor actually being used
+     * for the outputs you care about. So if your output covers N rows of the active array of
+     * height H, scale this value by N/H to get the total skew for that viewport.</p>
+     * <p><em>Note:</em> Prior to Android 11, this field was described as measuring duration from
+     * first to last row of the image sensor, which is not equal to the frame readout time for a
+     * rolling shutter sensor. Implementations generally reported the latter value, so to resolve
+     * the inconsistency, the description has been updated to range from (first, last+1) row
+     * exposure start, instead.</p>
      * <p><b>Units</b>: Nanoseconds</p>
      * <p><b>Range of valid values:</b><br>
      * &gt;= 0 and &lt;
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 7332ede..36ffe50 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -48,6 +48,7 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
@@ -4693,4 +4694,28 @@
             Log.d(TAG, "StackLog:" + sb.toString());
         }
     }
+
+    /**
+     * Simulates a Data Stall for the specified Network.
+     *
+     * <p>The caller must be the owner of the specified Network.
+     *
+     * @param detectionMethod The detection method used to identify the Data Stall.
+     * @param timestampMillis The timestamp at which the stall 'occurred', in milliseconds.
+     * @param network The Network for which a Data Stall is being simluated.
+     * @param extras The PersistableBundle of extras included in the Data Stall notification.
+     * @throws SecurityException if the caller is not the owner of the given network.
+     * @hide
+     */
+    @TestApi
+    @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_TEST_NETWORKS,
+            android.Manifest.permission.NETWORK_STACK})
+    public void simulateDataStall(int detectionMethod, long timestampMillis,
+            @NonNull Network network, @NonNull PersistableBundle extras) {
+        try {
+            mService.simulateDataStall(detectionMethod, timestampMillis, network, extras);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 1434560..69a47f2 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -18,6 +18,7 @@
 
 import android.app.PendingIntent;
 import android.net.ConnectionInfo;
+import android.net.ConnectivityDiagnosticsManager;
 import android.net.IConnectivityDiagnosticsCallback;
 import android.net.LinkProperties;
 import android.net.Network;
@@ -33,6 +34,7 @@
 import android.os.IBinder;
 import android.os.Messenger;
 import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
 import android.os.ResultReceiver;
 
 import com.android.internal.net.LegacyVpnInfo;
@@ -227,4 +229,7 @@
     void unregisterConnectivityDiagnosticsCallback(in IConnectivityDiagnosticsCallback callback);
 
     IBinder startOrGetTestNetworkService();
+
+    void simulateDataStall(int detectionMethod, long timestampMillis, in Network network,
+                in PersistableBundle extras);
 }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 52d6fdf..9ded22f 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -677,16 +677,27 @@
      * restrictions.
      * @hide
      */
-    public void restrictCapabilitesForTestNetwork() {
+    public void restrictCapabilitesForTestNetwork(int creatorUid) {
         final long originalCapabilities = mNetworkCapabilities;
         final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
         final int originalSignalStrength = mSignalStrength;
+        final int originalOwnerUid = getOwnerUid();
+        final int[] originalAdministratorUids = getAdministratorUids();
         clearAll();
         // Reset the transports to only contain TRANSPORT_TEST.
         mTransportTypes = (1 << TRANSPORT_TEST);
         mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
         mNetworkSpecifier = originalSpecifier;
         mSignalStrength = originalSignalStrength;
+
+        // Only retain the owner and administrator UIDs if they match the app registering the remote
+        // caller that registered the network.
+        if (originalOwnerUid == creatorUid) {
+            setOwnerUid(creatorUid);
+        }
+        if (ArrayUtils.contains(originalAdministratorUids, creatorUid)) {
+            setAdministratorUids(new int[] {creatorUid});
+        }
     }
 
     /**
diff --git a/core/java/android/os/IIncidentDumpCallback.aidl b/core/java/android/os/IIncidentDumpCallback.aidl
index 09b5b01..d94df34 100644
--- a/core/java/android/os/IIncidentDumpCallback.aidl
+++ b/core/java/android/os/IIncidentDumpCallback.aidl
@@ -25,7 +25,8 @@
  */
 oneway interface IIncidentDumpCallback {
     /**
-     * Dumps section data to the given ParcelFileDescriptor.
+     * Dumps section data to the given ParcelFileDescriptor, which needs to be
+     * closed properly after writing the data.
      */
     void onDumpSection(in ParcelFileDescriptor fd);
 }
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index 321dc9e..958c7fb 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -92,10 +92,7 @@
             }
         }
 
-        if (!result.mDefaultStorage.startLoading()) {
-            // TODO(b/146080380): add incremental-specific error code
-            throw new IOException("Failed to start loading data for Incremental installation.");
-        }
+        result.startLoading();
 
         return result;
     }
@@ -144,6 +141,15 @@
     }
 
     /**
+     * Starts or re-starts loading of data.
+     */
+    public void startLoading() throws IOException {
+        if (!mDefaultStorage.startLoading()) {
+            throw new IOException("Failed to start loading data for Incremental installation.");
+        }
+    }
+
+    /**
      * Resets the states and unbinds storage instances for an installation session.
      * TODO(b/136132412): make sure unnecessary binds are removed but useful storages are kept
      */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ae88ba5..e0bc764 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9936,6 +9936,11 @@
         * @hide */
        public static final String PACKAGE_VERIFIER_TIMEOUT = "verifier_timeout";
 
+        /** Timeout for app integrity verification.
+         * @hide */
+        public static final String APP_INTEGRITY_VERIFICATION_TIMEOUT =
+                "app_integrity_verification_timeout";
+
        /** Default response code for package verification.
         * @hide */
        public static final String PACKAGE_VERIFIER_DEFAULT_RESPONSE = "verifier_default_response";
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 926d8fc..0410c90 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -336,7 +336,7 @@
     * an input channel where the client can receive input.
     */
     void grantInputChannel(int displayId, in SurfaceControl surface, in IWindow window,
-            in IBinder hostInputToken, int flags, out InputChannel outInputChannel);
+            in IBinder hostInputToken, int flags, int type, out InputChannel outInputChannel);
 
     /**
      * Update the flags on an input channel associated with a particular surface.
diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java
index dbbe4b6..a480072 100644
--- a/core/java/android/view/ImeFocusController.java
+++ b/core/java/android/view/ImeFocusController.java
@@ -208,26 +208,6 @@
     }
 
     /**
-     * Called by {@link ViewRootImpl} to feedback the state of the screen for this view.
-     * @param newScreenState The new state of the screen. Can be either
-     *                       {@link View#SCREEN_STATE_ON} or {@link View#SCREEN_STATE_OFF}
-     */
-    @UiThread
-    void onScreenStateChanged(int newScreenState) {
-        if (!getImmDelegate().isCurrentRootView(mViewRootImpl)) {
-            return;
-        }
-        // Close input connection and IME when the screen is turn off for security concern.
-        if (newScreenState == View.SCREEN_STATE_OFF && mServedView != null) {
-            if (DEBUG) {
-                Log.d(TAG, "onScreenStateChanged, disconnect input when screen turned off");
-            }
-            mNextServedView = null;
-            mViewRootImpl.dispatchCheckFocus();
-        }
-    }
-
-    /**
      * @param windowAttribute {@link WindowManager.LayoutParams} to be checked.
      * @return Whether the window is in local focus mode or not.
      */
diff --git a/core/java/android/view/InsetsAnimationThreadControlRunner.java b/core/java/android/view/InsetsAnimationThreadControlRunner.java
index 9dfdd06..3215b7c 100644
--- a/core/java/android/view/InsetsAnimationThreadControlRunner.java
+++ b/core/java/android/view/InsetsAnimationThreadControlRunner.java
@@ -21,6 +21,7 @@
 import android.annotation.UiThread;
 import android.graphics.Rect;
 import android.os.Handler;
+import android.os.Trace;
 import android.util.SparseArray;
 import android.view.InsetsController.AnimationType;
 import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams;
@@ -60,6 +61,9 @@
 
         @Override
         public void notifyFinished(InsetsAnimationControlRunner runner, boolean shown) {
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW,
+                    "InsetsAsyncAnimation: " + WindowInsets.Type.toString(runner.getTypes()),
+                    runner.getTypes());
             releaseControls(mControl.getControls());
             mMainThreadHandler.post(() ->
                     mOuterCallbacks.notifyFinished(InsetsAnimationThreadControlRunner.this, shown));
@@ -93,7 +97,11 @@
         mOuterCallbacks = controller;
         mControl = new InsetsAnimationControlImpl(controls, frame, state, listener,
                 types, mCallbacks, durationMs, interpolator, animationType);
-        InsetsAnimationThread.getHandler().post(() -> listener.onReady(mControl, types));
+        InsetsAnimationThread.getHandler().post(() -> {
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW,
+                    "InsetsAsyncAnimation: " + WindowInsets.Type.toString(types), types);
+            listener.onReady(mControl, types);
+        });
     }
 
     private void releaseControls(SparseArray<InsetsSourceControl> controls) {
@@ -102,15 +110,6 @@
         }
     }
 
-    private SparseArray<InsetsSourceControl> copyControls(
-            SparseArray<InsetsSourceControl> controls) {
-        SparseArray<InsetsSourceControl> copy = new SparseArray<>(controls.size());
-        for (int i = 0; i < controls.size(); i++) {
-            copy.append(controls.keyAt(i), new InsetsSourceControl(controls.valueAt(i)));
-        }
-        return copy;
-    }
-
     @Override
     @UiThread
     public int getTypes() {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 2d17b6d..d12a122 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -35,6 +35,7 @@
 import android.graphics.Rect;
 import android.os.CancellationSignal;
 import android.os.Handler;
+import android.os.Trace;
 import android.util.ArraySet;
 import android.util.Pair;
 import android.util.SparseArray;
@@ -567,11 +568,15 @@
     private void updateState(InsetsState newState) {
         mState.setDisplayFrame(newState.getDisplayFrame());
         for (int i = newState.getSourcesCount() - 1; i >= 0; i--) {
-            InsetsSource source = newState.sourceAt(i);
-            getSourceConsumer(source.getType()).updateSource(source);
+            final InsetsSource source = newState.sourceAt(i);
+            final int type = source.getType();
+            final InsetsSourceConsumer consumer = getSourceConsumer(type);
+            consumer.updateSource(source);
+            mHost.updateCompatSysUiVisibility(type, source.isVisible(),
+                    consumer.getControl() != null);
         }
         for (int i = mState.getSourcesCount() - 1; i >= 0; i--) {
-            InsetsSource source = mState.sourceAt(i);
+            final InsetsSource source = mState.sourceAt(i);
             if (newState.peekSource(source.getType()) == null) {
                 mState.removeSource(source.getType());
             }
@@ -1006,14 +1011,6 @@
     }
 
     /**
-     * @see ViewRootImpl#updateCompatSysUiVisibility(int, boolean, boolean)
-     */
-    public void updateCompatSysUiVisibility(@InternalInsetsType int type, boolean visible,
-            boolean hasControl) {
-        mHost.updateCompatSysUiVisibility(type, visible, hasControl);
-    }
-
-    /**
      * Called when current window gains focus.
      */
     public void onWindowFocusGained() {
@@ -1143,6 +1140,8 @@
             if (controller.isCancelled()) {
                 return;
             }
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW,
+                    "InsetsAnimation: " + WindowInsets.Type.toString(types), types);
             for (int i = mRunningAnimations.size() - 1; i >= 0; i--) {
                 RunningAnimation runningAnimation = mRunningAnimations.get(i);
                 if (runningAnimation.runner == controller) {
@@ -1159,6 +1158,9 @@
 
     @VisibleForTesting
     public void dispatchAnimationEnd(WindowInsetsAnimation animation) {
+        Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW,
+                "InsetsAnimation: " + WindowInsets.Type.toString(animation.getTypeMask()),
+                animation.getTypeMask());
         mHost.dispatchWindowInsetsAnimationEnd(animation);
     }
 
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 2dcfd89..a0cdcfe 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -200,20 +200,12 @@
     }
 
     boolean applyLocalVisibilityOverride() {
-        InsetsSource source = mState.peekSource(mType);
-        final boolean isVisible = source != null && source.isVisible();
-        final boolean hasControl = mSourceControl != null;
-
-        // We still need to let the legacy app know the visibility change even if we don't have the
-        // control.
-        mController.updateCompatSysUiVisibility(
-                mType, hasControl ? mRequestedVisible : isVisible, hasControl);
 
         // If we don't have control, we are not able to change the visibility.
-        if (!hasControl) {
+        if (mSourceControl == null) {
             return false;
         }
-        if (isVisible == mRequestedVisible) {
+        if (mState.getSource(mType).isVisible() == mRequestedVisible) {
             return false;
         }
         mState.getSource(mType).setVisible(mRequestedVisible);
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 7086dc0..3850781 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -275,12 +275,4 @@
         // ViewRoot will release mSurfaceControl for us.
         mViewRoot.die(false /* immediate */);
     }
-
-    /**
-     * Tell this viewroot to clean itself up.
-     * @hide
-     */
-    public void die() {
-        mViewRoot.die(false /* immediate */);
-    }
 }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index db6fe0f..bd811fc 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -134,6 +134,23 @@
     // we need to preserve the old one until the new one has drawn.
     SurfaceControl mDeferredDestroySurfaceControl;
     SurfaceControl mBackgroundControl;
+
+    /**
+     * We use this lock in SOME cases when reading or writing SurfaceControl,
+     * but use the following model so that the RenderThread can run locklessly
+     * in the position up-date case.
+     *
+     * 1. UI Thread can read from mSurfaceControl (use in Transactions) without
+     * holding the lock.
+     * 2. UI Thread will hold the lock when writing to mSurfaceControl (calling release
+     * or remove).
+     * 3. Render thread will also hold the lock when writing to mSurfaceControl (e.g.
+     * calling release from positionLost).
+     * 3. RenderNode.PositionUpdateListener::positionChanged will only be called
+     * when the UI thread is paused (blocked on the Render thread).
+     * 4. positionChanged thus will not be required to hold the lock as the
+     * UI thread is blocked, and the other writer is the RT itself.
+     */
     final Object mSurfaceControlLock = new Object();
     final Rect mTmpRect = new Rect();
 
@@ -1297,15 +1314,19 @@
                 (viewRoot != null ? viewRoot.getBLASTSyncTransaction() : mRtTransaction) :
                 mRtTransaction;
 
-            if (frameNumber > 0 && viewRoot !=  null && !useBLAST) {
-                if (viewRoot.mSurface.isValid()) {
-                    mRtTransaction.deferTransactionUntil(mSurfaceControl,
-                            viewRoot.getRenderSurfaceControl(), frameNumber);
-                }
-            }
-            t.hide(mSurfaceControl);
-
+            /**
+             * positionLost can be called while UI thread is un-paused so we
+             * need to hold the lock here.
+             */
             synchronized (mSurfaceControlLock) {
+                if (frameNumber > 0 && viewRoot !=  null && !useBLAST) {
+                    if (viewRoot.mSurface.isValid()) {
+                        mRtTransaction.deferTransactionUntil(mSurfaceControl,
+                                viewRoot.getRenderSurfaceControl(), frameNumber);
+                    }
+                }
+                t.hide(mSurfaceControl);
+
                 if (mRtReleaseSurfaces) {
                     mRtReleaseSurfaces = false;
                     mRtTransaction.remove(mSurfaceControl);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5b9cd77..d928356 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1496,7 +1496,6 @@
                         final int newScreenState = toViewScreenState(newDisplayState);
                         if (oldScreenState != newScreenState) {
                             mView.dispatchScreenStateChanged(newScreenState);
-                            mImeFocusController.onScreenStateChanged(newScreenState);
                         }
                         if (oldDisplayState == Display.STATE_OFF) {
                             // Draw was suppressed so we need to for it to happen here.
@@ -1977,6 +1976,10 @@
             mCompatibleVisibilityInfo.globalVisibility =
                     (mCompatibleVisibilityInfo.globalVisibility & ~View.SYSTEM_UI_FLAG_LOW_PROFILE)
                             | (mAttachInfo.mSystemUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE);
+            if (mDispatchedSystemUiVisibility != mCompatibleVisibilityInfo.globalVisibility) {
+                mHandler.sendMessage(mHandler.obtainMessage(
+                        MSG_DISPATCH_SYSTEM_UI_VISIBILITY, mCompatibleVisibilityInfo));
+            }
             if (mAttachInfo.mKeepScreenOn != oldScreenOn
                     || mAttachInfo.mSystemUiVisibility != params.subtreeSystemUiVisibility
                     || mAttachInfo.mHasSystemUiListeners != params.hasSystemUiListeners) {
@@ -2030,7 +2033,7 @@
             info.globalVisibility |= systemUiFlag;
         }
         if (mDispatchedSystemUiVisibility != info.globalVisibility) {
-            scheduleTraversals();
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_SYSTEM_UI_VISIBILITY, info));
         }
     }
 
@@ -2478,9 +2481,6 @@
             mAttachInfo.mForceReportNewAttributes = false;
             params = lp;
         }
-        if (sNewInsetsMode == NEW_INSETS_MODE_FULL) {
-            handleDispatchSystemUiVisibilityChanged(mCompatibleVisibilityInfo);
-        }
 
         if (mFirst || mAttachInfo.mViewVisibilityChanged) {
             mAttachInfo.mViewVisibilityChanged = false;
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index aad1c60..4d6b72f 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -1328,30 +1328,36 @@
             }
         }
 
-        static String toString(@InsetsType int type) {
-            switch (type) {
-                case STATUS_BARS:
-                    return "statusBars";
-                case NAVIGATION_BARS:
-                    return "navigationBars";
-                case CAPTION_BAR:
-                    return "captionBar";
-                case IME:
-                    return "ime";
-                case SYSTEM_GESTURES:
-                    return "systemGestures";
-                case MANDATORY_SYSTEM_GESTURES:
-                    return "mandatorySystemGestures";
-                case TAPPABLE_ELEMENT:
-                    return "tappableElement";
-                case DISPLAY_CUTOUT:
-                    return "displayCutout";
-                case WINDOW_DECOR:
-                    return "windowDecor";
-                default:
-                    throw new IllegalArgumentException("type needs to be >= FIRST and <= LAST,"
-                            + " type=" + type);
+        static String toString(@InsetsType int types) {
+            StringBuilder result = new StringBuilder();
+            if ((types & STATUS_BARS) != 0) {
+                result.append("statusBars |");
             }
+            if ((types & NAVIGATION_BARS) != 0) {
+                result.append("navigationBars |");
+            }
+            if ((types & IME) != 0) {
+                result.append("ime |");
+            }
+            if ((types & SYSTEM_GESTURES) != 0) {
+                result.append("systemGestures |");
+            }
+            if ((types & MANDATORY_SYSTEM_GESTURES) != 0) {
+                result.append("mandatorySystemGestures |");
+            }
+            if ((types & TAPPABLE_ELEMENT) != 0) {
+                result.append("tappableElement |");
+            }
+            if ((types & DISPLAY_CUTOUT) != 0) {
+                result.append("displayCutout |");
+            }
+            if ((types & WINDOW_DECOR) != 0) {
+                result.append("windowDecor |");
+            }
+            if (result.length() > 0) {
+                result.delete(result.length() - 2, result.length());
+            }
+            return result.toString();
         }
 
         private Type() {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 8cb05da..7607127 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1162,7 +1162,7 @@
 
         /**
          * Window type: shows directly above the keyguard. The layer is
-         * reserved for screenshot region selection. These windows must not take input focus.
+         * reserved for screenshot animation, region selection and UI.
          * In multiuser systems shows only on the owning user's window.
          * @hide
          */
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index cd954c4..d20ffb3 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -143,7 +143,7 @@
                 WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0)) {
             try {
                 mRealWm.grantInputChannel(displayId, sc, window, mHostInputToken, attrs.flags,
-                        outInputChannel);
+                        attrs.type, outInputChannel);
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to grant input to surface: ", e);
             }
@@ -432,7 +432,7 @@
 
     @Override
     public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window,
-            IBinder hostInputToken, int flags, InputChannel outInputChannel) {
+            IBinder hostInputToken, int flags, int type, InputChannel outInputChannel) {
     }
 
     @Override
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index ca5c417..813234f 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -752,7 +752,10 @@
         }
     }
 
-    private static String typeToString(int type) {
+    /**
+     * @hide
+     */
+    public static String typeToString(int type) {
         switch (type) {
             case TYPE_APPLICATION: {
                 return "TYPE_APPLICATION";
@@ -770,7 +773,7 @@
                 return "TYPE_SPLIT_SCREEN_DIVIDER";
             }
             default:
-                return "<UNKNOWN>";
+                return "<UNKNOWN:" + type + ">";
         }
     }
 
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 4519aef..d021fc9 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -346,7 +346,7 @@
 
 
     /** @hide */
-    public static final int DEFAULT_MAX_BUFFER_SIZE = 100;
+    public static final int DEFAULT_MAX_BUFFER_SIZE = 500; // Enough for typical busy screen.
     /** @hide */
     public static final int DEFAULT_IDLE_FLUSHING_FREQUENCY_MS = 5_000;
     /** @hide */
diff --git a/core/java/android/view/inputmethod/InlineSuggestion.java b/core/java/android/view/inputmethod/InlineSuggestion.java
index 4c72474..e4ac588 100644
--- a/core/java/android/view/inputmethod/InlineSuggestion.java
+++ b/core/java/android/view/inputmethod/InlineSuggestion.java
@@ -326,11 +326,13 @@
 
         @MainThread
         private void handleOnSurfacePackageReleased() {
-            mSurfacePackage = null;
-            try {
-                mInlineContentProvider.onSurfacePackageReleased();
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Error calling onSurfacePackageReleased(): " + e);
+            if (mSurfacePackage != null) {
+                try {
+                    mInlineContentProvider.onSurfacePackageReleased();
+                } catch (RemoteException e) {
+                    Slog.w(TAG, "Error calling onSurfacePackageReleased(): " + e);
+                }
+                mSurfacePackage = null;
             }
         }
 
@@ -573,7 +575,7 @@
     };
 
     @DataClass.Generated(
-            time = 1588308946517L,
+            time = 1589396017700L,
             codegenVersion = "1.0.15",
             sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestion.java",
             inputSignatures = "private static final  java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\nprivate @com.android.internal.util.DataClass.ParcelWith(android.view.inputmethod.InlineSuggestion.InlineContentCallbackImplParceling.class) @android.annotation.Nullable android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl mInlineContentCallback\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic  void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.widget.inline.InlineContentView>)\nprivate static  boolean isValid(int,int,int)\nprivate synchronized  android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl getInlineContentCallback(android.content.Context,java.util.concurrent.Executor,java.util.function.Consumer<android.widget.inline.InlineContentView>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)")
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index f8522ed..f78ec7c 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -189,14 +189,29 @@
     public void onCloseWindow(WebView window) {}
 
     /**
-     * Tell the client to display a javascript alert dialog.  If the client
-     * returns {@code true}, WebView will assume that the client will handle the
-     * dialog.  If the client returns {@code false}, it will continue execution.
+     * Notify the host application that the web page wants to display a
+     * JavaScript {@code alert()} dialog.
+     * <p>The default behavior if this method returns {@code false} or is not
+     * overridden is to show a dialog containing the alert message and suspend
+     * JavaScript execution until the dialog is dismissed.
+     * <p>To show a custom dialog, the app should return {@code true} from this
+     * method, in which case the default dialog will not be shown and JavaScript
+     * execution will be suspended. The app should call
+     * {@code JsResult.confirm()} when the custom dialog is dismissed such that
+     * JavaScript execution can be resumed.
+     * <p>To suppress the dialog and allow JavaScript execution to
+     * continue, call {@code JsResult.confirm()} immediately and then return
+     * {@code true}.
+     * <p>Note that if the {@link WebChromeClient} is {@code null}, the default
+     * dialog will be suppressed and Javascript execution will continue
+     * immediately.
+     *
      * @param view The WebView that initiated the callback.
      * @param url The url of the page requesting the dialog.
      * @param message Message to be displayed in the window.
-     * @param result A JsResult to confirm that the user hit enter.
-     * @return boolean Whether the client will handle the alert dialog.
+     * @param result A JsResult to confirm that the user closed the window.
+     * @return boolean {@code true} if the request is handled or ignored.
+     * {@code false} if WebView needs to show the default dialog.
      */
     public boolean onJsAlert(WebView view, String url, String message,
             JsResult result) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 29914aa..226f5797 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -8315,23 +8315,6 @@
         return false;
     }
 
-    /**
-     * Returns true if pressing TAB in this field advances focus instead
-     * of inserting the character.  Insert tabs only in multi-line editors.
-     */
-    private boolean shouldAdvanceFocusOnTab() {
-        if (getKeyListener() != null && !mSingleLine && mEditor != null
-                && (mEditor.mInputType & EditorInfo.TYPE_MASK_CLASS)
-                        == EditorInfo.TYPE_CLASS_TEXT) {
-            int multilineFlags = EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE
-                    | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
-            if ((mEditor.mInputType & multilineFlags) != 0) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     private boolean isDirectionalNavigationKey(int keyCode) {
         switch(keyCode) {
             case KeyEvent.KEYCODE_DPAD_UP:
@@ -8400,9 +8383,8 @@
 
             case KeyEvent.KEYCODE_TAB:
                 if (event.hasNoModifiers() || event.hasModifiers(KeyEvent.META_SHIFT_ON)) {
-                    if (shouldAdvanceFocusOnTab()) {
-                        return KEY_EVENT_NOT_HANDLED;
-                    }
+                    // Tab is used to move focus.
+                    return KEY_EVENT_NOT_HANDLED;
                 }
                 break;
 
diff --git a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
index 37a5a63..0d16cc4 100644
--- a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
@@ -128,9 +128,8 @@
                         mResolverRankerService.compute(targets);
                     } else {
                         Log.i(TAG, "AppPredictionService response received");
-                        Message msg =
-                            Message.obtain(mHandler, RANKER_SERVICE_RESULT, sortedAppTargets);
-                        msg.sendToTarget();
+                        // Skip sending to Handler which takes extra time to dispatch messages.
+                        handleResult(sortedAppTargets);
                     }
                 }
         );
@@ -141,23 +140,35 @@
         // Null value is okay if we have defaulted to the ResolverRankerService.
         if (msg.what == RANKER_SERVICE_RESULT && msg.obj != null) {
             final List<AppTarget> sortedAppTargets = (List<AppTarget>) msg.obj;
-            if (checkAppTargetRankValid(sortedAppTargets)) {
-                sortedAppTargets.forEach(target -> mTargetScores.put(
-                        new ComponentName(target.getPackageName(), target.getClassName()),
-                        target.getRank()));
-            }
-            for (int i = 0; i < sortedAppTargets.size(); i++) {
-                ComponentName componentName = new ComponentName(
-                        sortedAppTargets.get(i).getPackageName(),
-                        sortedAppTargets.get(i).getClassName());
-                mTargetRanks.put(componentName, i);
-                Log.i(TAG, "handleResultMessage, sortedAppTargets #" + i + ": " + componentName);
-            }
+            handleSortedAppTargets(sortedAppTargets);
         } else if (msg.obj == null && mResolverRankerService == null) {
             Log.e(TAG, "Unexpected null result");
         }
     }
 
+    private void handleResult(List<AppTarget> sortedAppTargets) {
+        if (mHandler.hasMessages(RANKER_RESULT_TIMEOUT)) {
+            handleSortedAppTargets(sortedAppTargets);
+            mHandler.removeMessages(RANKER_RESULT_TIMEOUT);
+            afterCompute();
+        }
+    }
+
+    private void handleSortedAppTargets(List<AppTarget> sortedAppTargets) {
+        if (checkAppTargetRankValid(sortedAppTargets)) {
+            sortedAppTargets.forEach(target -> mTargetScores.put(
+                    new ComponentName(target.getPackageName(), target.getClassName()),
+                    target.getRank()));
+        }
+        for (int i = 0; i < sortedAppTargets.size(); i++) {
+            ComponentName componentName = new ComponentName(
+                    sortedAppTargets.get(i).getPackageName(),
+                    sortedAppTargets.get(i).getClassName());
+            mTargetRanks.put(componentName, i);
+            Log.i(TAG, "handleSortedAppTargets, sortedAppTargets #" + i + ": " + componentName);
+        }
+    }
+
     private boolean checkAppTargetRankValid(List<AppTarget> sortedAppTargets) {
         for (AppTarget target : sortedAppTargets) {
             if (target.getRank() != 0) {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 3fc3f3e..cff669e 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -778,6 +778,11 @@
         mDirectShareShortcutInfoCache = new HashMap<>();
     }
 
+    @Override
+    protected int appliedThemeResId() {
+        return R.style.Theme_DeviceDefault_Chooser;
+    }
+
     private AppPredictor setupAppPredictorForUser(UserHandle userHandle,
             AppPredictor.Callback appPredictorCallback) {
         AppPredictor appPredictor = getAppPredictorForDirectShareIfEnabled(userHandle);
diff --git a/core/java/com/android/internal/app/ChooserListAdapter.java b/core/java/com/android/internal/app/ChooserListAdapter.java
index f426bc0..492f98c 100644
--- a/core/java/com/android/internal/app/ChooserListAdapter.java
+++ b/core/java/com/android/internal/app/ChooserListAdapter.java
@@ -30,6 +30,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
+import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -103,7 +104,7 @@
     private Set<ComponentName> mPendingChooserTargetService = new HashSet<>();
     private Set<ComponentName> mShortcutComponents = new HashSet<>();
     private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
-    private final List<TargetInfo> mCallerTargets = new ArrayList<>();
+    private final List<DisplayResolveInfo> mCallerTargets = new ArrayList<>();
 
     private final ChooserActivity.BaseChooserTargetComparator mBaseTargetComparator =
             new ChooserActivity.BaseChooserTargetComparator();
@@ -253,28 +254,44 @@
             holder.text.setBackground(null);
             holder.itemView.setBackground(holder.defaultItemViewBackground);
         }
+
+        // If the target is grouped show an indicator
+        if (info instanceof MultiDisplayResolveInfo) {
+            Drawable bkg = mContext.getDrawable(R.drawable.chooser_group_background);
+            holder.text.setPaddingRelative(0, 0, bkg.getIntrinsicWidth() /* end */, 0);
+            holder.text.setBackground(bkg);
+        } else {
+            holder.text.setBackground(null);
+            holder.text.setPaddingRelative(0, 0, 0, 0);
+        }
     }
 
     void updateAlphabeticalList() {
         mSortedList.clear();
+        List<DisplayResolveInfo> tempList = new ArrayList<>();
+        tempList.addAll(mDisplayList);
+        tempList.addAll(mCallerTargets);
         if (mEnableStackedApps) {
             // Consolidate multiple targets from same app.
             Map<String, DisplayResolveInfo> consolidated = new HashMap<>();
-            for (DisplayResolveInfo info : mDisplayList) {
+            for (DisplayResolveInfo info : tempList) {
                 String packageName = info.getResolvedComponentName().getPackageName();
-                if (consolidated.get(packageName) != null) {
-                    // create consolidated target
-                    MultiDisplayResolveInfo multiDisplayResolveInfo =
-                            new MultiDisplayResolveInfo(packageName, info);
-                    multiDisplayResolveInfo.addTarget(consolidated.get(packageName));
-                    consolidated.put(packageName, multiDisplayResolveInfo);
-                } else {
+                DisplayResolveInfo multiDri = consolidated.get(packageName);
+                if (multiDri == null) {
                     consolidated.put(packageName, info);
+                } else if (multiDri instanceof MultiDisplayResolveInfo) {
+                    ((MultiDisplayResolveInfo) multiDri).addTarget(info);
+                } else {
+                    // create consolidated target from the single DisplayResolveInfo
+                    MultiDisplayResolveInfo multiDisplayResolveInfo =
+                            new MultiDisplayResolveInfo(packageName, multiDri);
+                    multiDisplayResolveInfo.addTarget(info);
+                    consolidated.put(packageName, multiDisplayResolveInfo);
                 }
             }
             mSortedList.addAll(consolidated.values());
         } else {
-            mSortedList.addAll(mDisplayList);
+            mSortedList.addAll(tempList);
         }
         Collections.sort(mSortedList, new ChooserActivity.AzInfoComparator(mContext));
     }
@@ -326,7 +343,10 @@
         return standardCount > mChooserListCommunicator.getMaxRankedTargets() ? standardCount : 0;
     }
 
-    int getRankedTargetCount() {
+    /**
+     * Fetch ranked app target count
+     */
+    public int getRankedTargetCount() {
         int spacesAvailable =
                 mChooserListCommunicator.getMaxRankedTargets() - getCallerTargetCount();
         return Math.min(spacesAvailable, super.getCount());
@@ -411,6 +431,19 @@
         return null;
     }
 
+    // Check whether {@code dri} should be added into mDisplayList.
+    @Override
+    protected boolean shouldAddResolveInfo(DisplayResolveInfo dri) {
+        // Checks if this info is already listed in callerTargets.
+        for (TargetInfo existingInfo : mCallerTargets) {
+            if (mResolverListCommunicator
+                    .resolveInfoMatch(dri.getResolveInfo(), existingInfo.getResolveInfo())) {
+                return false;
+            }
+        }
+        return super.shouldAddResolveInfo(dri);
+    }
+
     /**
      * Fetch surfaced direct share target info
      */
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 9c2df13..4b5735c 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -324,7 +324,7 @@
     protected void onCreate(Bundle savedInstanceState, Intent intent,
             CharSequence title, int defaultTitleRes, Intent[] initialIntents,
             List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
-        setTheme(R.style.Theme_DeviceDefault_Resolver);
+        setTheme(appliedThemeResId());
         super.onCreate(savedInstanceState);
 
         // Determine whether we should show that intent is forwarded
@@ -358,6 +358,7 @@
                 : isHttpSchemeAndViewAction(getTargetIntent());
 
         mSupportsAlwaysUseOption = supportsAlwaysUseOption;
+        mWorkProfileUserHandle = fetchWorkProfileUserProfile();
 
         // The last argument of createResolverListAdapter is whether to do special handling
         // of the last used choice to highlight it in the list.  We need to always
@@ -366,7 +367,6 @@
         // to handle. We also turn it off when the work tab is shown to simplify the UX.
         boolean filterLastUsed = mSupportsAlwaysUseOption && !isVoiceInteraction()
                 && !shouldShowTabs();
-        mWorkProfileUserHandle = fetchWorkProfileUserProfile();
         mMultiProfilePagerAdapter = createMultiProfilePagerAdapter(initialIntents, rList, filterLastUsed);
         if (configureContentView()) {
             return;
@@ -507,6 +507,10 @@
                 /* shouldShowNoCrossProfileIntentsEmptyState= */ getUser().equals(intentUser));
     }
 
+    protected int appliedThemeResId() {
+        return R.style.Theme_DeviceDefault_Resolver;
+    }
+
     /**
      * Returns the user id of the user that the starting intent originated from.
      * <p>This is not necessarily equal to {@link #getUserId()} or {@link UserHandle#myUserId()},
@@ -1612,6 +1616,7 @@
     }
 
     private void setupProfileTabs() {
+        maybeHideDivider();
         TabHost tabHost = findViewById(R.id.profile_tabhost);
         tabHost.setup();
         ViewPager viewPager = findViewById(R.id.profile_pager);
@@ -1660,6 +1665,17 @@
         findViewById(R.id.resolver_tab_divider).setVisibility(View.VISIBLE);
     }
 
+    private void maybeHideDivider() {
+        if (!isIntentPicker()) {
+            return;
+        }
+        final View divider = findViewById(R.id.divider);
+        if (divider == null) {
+            return;
+        }
+        divider.setVisibility(View.GONE);
+    }
+
     /**
      * Callback called when user changes the profile tab.
      * <p>This method is intended to be overridden by subclasses.
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index 24bf98b..af9c040 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -85,7 +85,7 @@
 
     private int mLastChosenPosition = -1;
     private boolean mFilterLastUsed;
-    private final ResolverListCommunicator mResolverListCommunicator;
+    final ResolverListCommunicator mResolverListCommunicator;
     private Runnable mPostListReadyRunnable;
     private final boolean mIsAudioCaptureDevice;
     private boolean mIsTabLoaded;
@@ -443,17 +443,24 @@
         // TODO(arangelov): Is that UserHandle.USER_CURRENT check okay?
         if (dri != null && dri.getResolveInfo() != null
                 && dri.getResolveInfo().targetUserId == UserHandle.USER_CURRENT) {
-            // Checks if this info is already listed in display.
-            for (DisplayResolveInfo existingInfo : mDisplayList) {
-                if (mResolverListCommunicator
-                        .resolveInfoMatch(dri.getResolveInfo(), existingInfo.getResolveInfo())) {
-                    return;
-                }
+            if (shouldAddResolveInfo(dri)) {
+                mDisplayList.add(dri);
             }
-            mDisplayList.add(dri);
         }
     }
 
+    // Check whether {@code dri} should be added into mDisplayList.
+    protected boolean shouldAddResolveInfo(DisplayResolveInfo dri) {
+        // Checks if this info is already listed in display.
+        for (DisplayResolveInfo existingInfo : mDisplayList) {
+            if (mResolverListCommunicator
+                    .resolveInfoMatch(dri.getResolveInfo(), existingInfo.getResolveInfo())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     @Nullable
     public ResolveInfo resolveInfoForPosition(int position, boolean filtered) {
         TargetInfo target = targetInfoForPosition(position, filtered);
diff --git a/core/java/com/android/internal/app/SimpleIconFactory.java b/core/java/com/android/internal/app/SimpleIconFactory.java
index d618cdf..ffe2dbe 100644
--- a/core/java/com/android/internal/app/SimpleIconFactory.java
+++ b/core/java/com/android/internal/app/SimpleIconFactory.java
@@ -20,6 +20,7 @@
 import static android.graphics.Paint.DITHER_FLAG;
 import static android.graphics.Paint.FILTER_BITMAP_FLAG;
 
+import android.annotation.AttrRes;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
@@ -46,6 +47,7 @@
 import android.os.UserHandle;
 import android.util.AttributeSet;
 import android.util.Pools.SynchronizedPool;
+import android.util.TypedValue;
 
 import com.android.internal.R;
 
@@ -92,10 +94,8 @@
             final ActivityManager am = (ActivityManager) ctx.getSystemService(ACTIVITY_SERVICE);
             final int iconDpi = (am == null) ? 0 : am.getLauncherLargeIconDensity();
 
-            final Resources r = ctx.getResources();
-            final int iconSize = r.getDimensionPixelSize(R.dimen.resolver_icon_size);
-            final int badgeSize = r.getDimensionPixelSize(R.dimen.resolver_badge_size);
-
+            final int iconSize = getIconSizeFromContext(ctx);
+            final int badgeSize = getBadgeSizeFromContext(ctx);
             instance = new SimpleIconFactory(ctx, iconDpi, iconSize, badgeSize);
             instance.setWrapperBackgroundColor(Color.WHITE);
         }
@@ -103,6 +103,27 @@
         return instance;
     }
 
+    private static int getAttrDimFromContext(Context ctx, @AttrRes int attrId, String errorMsg) {
+        final Resources res = ctx.getResources();
+        TypedValue outVal = new TypedValue();
+        if (!ctx.getTheme().resolveAttribute(attrId, outVal, true)) {
+            throw new IllegalStateException(errorMsg);
+        }
+        return res.getDimensionPixelSize(outVal.resourceId);
+    }
+
+    private static int getIconSizeFromContext(Context ctx) {
+        return getAttrDimFromContext(ctx,
+                com.android.internal.R.attr.iconfactoryIconSize,
+                "Expected theme to define iconfactoryIconSize.");
+    }
+
+    private static int getBadgeSizeFromContext(Context ctx) {
+        return getAttrDimFromContext(ctx,
+                com.android.internal.R.attr.iconfactoryBadgeSize,
+                "Expected theme to define iconfactoryBadgeSize.");
+    }
+
     /**
      * Recycles the SimpleIconFactory so others may use it.
      *
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 6f33096..d238d0e 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -61,22 +61,6 @@
     public static final String SCREENSHOT_NOTIFICATION_SMART_ACTIONS_TIMEOUT_MS =
             "screenshot_notification_smart_actions_timeout_ms";
 
-    // Flags related to controls
-
-    /**
-     * (boolean) Whether to have split behavior when opening QS
-     */
-    public static final String QS_SPLIT_ENABLED = "qs_split_enabled";
-
-    /**
-     * (int) Open settings panels for WiFi and BT tiles
-     * 0 - default behavior, link to settings
-     * 1 - open panel on long press, click remains the same
-     * 2 - open panel on click, long press remains the same
-     * 3 - use details on long press
-     */
-    public static final String QS_USE_SETTINGS_PANELS = "qs_use_settings_panels";
-
     // Flags related to Smart Suggestions - these are read in SmartReplyConstants.
 
     /** (boolean) Whether to enable smart suggestions in notifications. */
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index 49c9302..ad6c7e8 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -132,6 +132,7 @@
                     }
                 };
     }
+
     private static final String TAG = "ScreenshotHelper";
 
     // Time until we give up on the screenshot & show an error instead.
@@ -146,8 +147,6 @@
         mContext = context;
     }
 
-
-
     /**
      * Request a screenshot be taken.
      *
@@ -284,8 +283,8 @@
                             break;
                         case SCREENSHOT_MSG_PROCESS_COMPLETE:
                             synchronized (mScreenshotLock) {
-                                if (mScreenshotConnection == myConn) {
-                                    mContext.unbindService(mScreenshotConnection);
+                                if (myConn != null && mScreenshotConnection == myConn) {
+                                    mContext.unbindService(myConn);
                                     mScreenshotConnection = null;
                                     mScreenshotService = null;
                                 }
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index d9b2902..03a7b3d 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1369,7 +1369,7 @@
 
     public void registerStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
         try {
-            getLockSettings().registerStrongAuthTracker(strongAuthTracker.mStub);
+            getLockSettings().registerStrongAuthTracker(strongAuthTracker.getStub());
         } catch (RemoteException e) {
             throw new RuntimeException("Could not register StrongAuthTracker");
         }
@@ -1377,7 +1377,7 @@
 
     public void unregisterStrongAuthTracker(final StrongAuthTracker strongAuthTracker) {
         try {
-            getLockSettings().unregisterStrongAuthTracker(strongAuthTracker.mStub);
+            getLockSettings().unregisterStrongAuthTracker(strongAuthTracker.getStub());
         } catch (RemoteException e) {
             Log.e(TAG, "Could not unregister StrongAuthTracker", e);
         }
@@ -1740,7 +1740,7 @@
             }
         }
 
-        protected final IStrongAuthTracker.Stub mStub = new IStrongAuthTracker.Stub() {
+        private final IStrongAuthTracker.Stub mStub = new IStrongAuthTracker.Stub() {
             @Override
             public void onStrongAuthRequiredChanged(@StrongAuthFlags int strongAuthFlags,
                     int userId) {
@@ -1755,6 +1755,10 @@
             }
         };
 
+        public IStrongAuthTracker.Stub getStub() {
+            return mStub;
+        }
+
         private class H extends Handler {
             static final int MSG_ON_STRONG_AUTH_REQUIRED_CHANGED = 1;
             static final int MSG_ON_IS_NON_STRONG_BIOMETRIC_ALLOWED_CHANGED = 2;
diff --git a/core/proto/android/app/tvsettings_enums.proto b/core/proto/android/app/tvsettings_enums.proto
index 30d365c..31c5dd6 100644
--- a/core/proto/android/app/tvsettings_enums.proto
+++ b/core/proto/android/app/tvsettings_enums.proto
@@ -44,6 +44,24 @@
     /** Denotes that a toggle is clicked by a user. */
     TOGGLE_INTERACTED = 3;
 
+    /**
+     * Denotes that a TvSettings page is being focused in the forward direction
+     * into the settings tree.
+     */
+    PAGE_FOCUSED_FORWARD = 4;
+
+    /**
+     * Denotes that a TvSettings page is being focused in the backward direction
+     * up the settings tree.
+     */
+    PAGE_FOCUSED_BACKWARD = 5;
+
+    /** Denotes that a toggle is turned on by a user. */
+    TOGGLED_ON = 6;
+
+    /** Denotes that a toggle is turned off by a user. */
+    TOGGLED_OFF = 7;
+
 }
 
 /**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0bf5045..3cd0f03 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5053,7 +5053,7 @@
                  android:forceQueryable="true"
                  android:directBootAware="true">
         <activity android:name="com.android.internal.app.ChooserActivity"
-                android:theme="@style/Theme.DeviceDefault.Resolver"
+                android:theme="@style/Theme.DeviceDefault.Chooser"
                 android:finishOnCloseSystemDialogs="true"
                 android:excludeFromRecents="true"
                 android:documentLaunchMode="never"
diff --git a/core/res/res/drawable/chooser_group_background.xml b/core/res/res/drawable/chooser_group_background.xml
new file mode 100644
index 0000000..2bf9337
--- /dev/null
+++ b/core/res/res/drawable/chooser_group_background.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/ic_chooser_group_arrow"
+          android:gravity="end|center_vertical"
+          android:width="12dp"
+          android:height="12dp"
+          android:start="4dp"
+          android:end="4dp" />
+</layer-list>
diff --git a/core/res/res/drawable/ic_chooser_group_arrow.xml b/core/res/res/drawable/ic_chooser_group_arrow.xml
new file mode 100644
index 0000000..d42bb97
--- /dev/null
+++ b/core/res/res/drawable/ic_chooser_group_arrow.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ 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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="12dp"
+        android:height="12dp"
+        android:viewportWidth="12"
+        android:viewportHeight="12"
+        android:tint="?attr/textColorSecondary">
+    <path
+        android:pathData="M2,4L6,8L10,4L2,4Z"
+        android:fillColor="#FF000000"/>
+</vector>
diff --git a/core/res/res/layout/car_user_switching_dialog.xml b/core/res/res/layout/car_user_switching_dialog.xml
deleted file mode 100644
index d727434..0000000
--- a/core/res/res/layout/car_user_switching_dialog.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:fitsSystemWindows="true"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
-
-  <ImageView
-      android:id="@+id/user_loading_avatar"
-      android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
-      android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height"
-      android:layout_centerHorizontal="true"/>
-
-  <TextView android:id="@+id/user_loading"
-      android:layout_width="match_parent"
-      android:layout_height="wrap_content"
-      android:layout_marginTop="@dimen/car_padding_4"
-      android:textSize="@dimen/car_body1_size"
-      android:textColor="@color/car_body1"
-      android:layout_below="@id/user_loading_avatar"
-      android:gravity="center"/>
-
-</RelativeLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/resolver_empty_states.xml b/core/res/res/layout/resolver_empty_states.xml
index fe11769..196a0e8 100644
--- a/core/res/res/layout/resolver_empty_states.xml
+++ b/core/res/res/layout/resolver_empty_states.xml
@@ -59,7 +59,7 @@
         <Button
             android:id="@+id/resolver_empty_state_button"
             android:layout_below="@+id/resolver_empty_state_subtitle"
-            android:layout_marginTop="16dp"
+            android:layout_marginTop="8dp"
             android:text="@string/resolver_switch_on_work"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 425a47f..ae9a4e9 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1406,7 +1406,7 @@
     <string name="grant_credentials_permission_message_header" msgid="5365733888842570481">"የሚከተለው ወይም ተጨማሪ መተግበሪያዎች ወደ መለያህ ለመድረስ አሁን እና ወደፊት ፈቃድ ትጠይቃለህ።"</string>
     <string name="grant_credentials_permission_message_footer" msgid="1886710210516246461">"ይህን ጥየቃ መፍቀድ ይፈልጋሉ?"</string>
     <string name="grant_permissions_header_text" msgid="3420736827804657201">"የመድረሻ ጥያቄ"</string>
-    <string name="allow" msgid="6195617008611933762">"ይፍቀዱ"</string>
+    <string name="allow" msgid="6195617008611933762">"ፍቀድ"</string>
     <string name="deny" msgid="6632259981847676572">"ያስተባብሉ"</string>
     <string name="permission_request_notification_title" msgid="1810025922441048273">"ፈቃድ ተጠይቋል"</string>
     <string name="permission_request_notification_with_subtitle" msgid="3743417870360129298">\n" ለ<xliff:g id="ACCOUNT">%s</xliff:g> መለያ ፈቃድ ተጠይቋል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 06af5325..f64e0c9 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -239,7 +239,7 @@
     <string name="reboot_safemode_title" msgid="5853949122655346734">"إعادة تشغيل في الوضع الآمن"</string>
     <string name="reboot_safemode_confirm" msgid="1658357874737219624">"هل تريد إعادة تشغيل الكمبيوتر في الوضع الآمن؟ سيؤدي ذلك إلى إيقاف جميع تطبيقات الجهات الخارجية التي تم تثبيتها. ستتم استعادتها عند إعادة التشغيل مرة أخرى."</string>
     <string name="recent_tasks_title" msgid="8183172372995396653">"حديثة"</string>
-    <string name="no_recent_tasks" msgid="9063946524312275906">"ليست هناك تطبيقات حديثة."</string>
+    <string name="no_recent_tasks" msgid="9063946524312275906">"لم يتمّ استخدام تطبيقات مؤخرًا."</string>
     <string name="global_actions" product="tablet" msgid="4412132498517933867">"خيارات الجهاز اللوحي"</string>
     <string name="global_actions" product="tv" msgid="3871763739487450369">"‏خيارات Android TV"</string>
     <string name="global_actions" product="default" msgid="6410072189971495460">"خيارات الهاتف"</string>
@@ -1222,7 +1222,7 @@
     <string name="whichSendToApplication" msgid="77101541959464018">"إرسال باستخدام"</string>
     <string name="whichSendToApplicationNamed" msgid="3385686512014670003">"‏إرسال باستخدام %1$s"</string>
     <string name="whichSendToApplicationLabel" msgid="3543240188816513303">"إرسال"</string>
-    <string name="whichHomeApplication" msgid="8276350727038396616">"تحديد تطبيق شاشة رئيسية"</string>
+    <string name="whichHomeApplication" msgid="8276350727038396616">"اختيار تطبيق شاشة رئيسية"</string>
     <string name="whichHomeApplicationNamed" msgid="5855990024847433794">"‏استخدام %1$s كصفحة رئيسية"</string>
     <string name="whichHomeApplicationLabel" msgid="8907334282202933959">"التقاط صورة"</string>
     <string name="whichImageCaptureApplication" msgid="2737413019463215284">"التقاط صورة باستخدام"</string>
@@ -1886,8 +1886,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"تم التحديث بواسطة المشرف"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"تم الحذف بواسطة المشرف"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"حسنًا"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"‏لإطالة عمر البطارية، تعمل \"توفير شحن البطارية\" على:\n\n• تفعيل \"المظهر الداكن\"\n• إيقاف أو تقييد النشاط في الخلفية وبعض التأثيرات المرئية والميزات الأخرى، مثل \"Ok Google\".\n\n"<annotation id="url">"مزيد من المعلومات"</annotation></string>
-    <string name="battery_saver_description" msgid="8587408568232177204">"‏لإطالة عمر البطارية، تعمل ميزة \"توفير شحن البطارية\" على:\n\n• تفعيل \"المظهر الداكن\"\n• إيقاف أو تقييد النشاط في الخلفية وبعض التأثيرات المرئية والميزات الأخرى، مثل \"Ok Google\"."</string>
+    <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"‏لإطالة عمر البطارية، تعمل ميزة \"توفير شحن البطارية\" على:\n\n• تفعيل \"المظهر الداكن\"\n• إيقاف أو حظر النشاط في الخلفية وبعض التأثيرات المرئية والميزات الأخرى، مثل \"Ok Google\".\n\n"<annotation id="url">"مزيد من المعلومات"</annotation></string>
+    <string name="battery_saver_description" msgid="8587408568232177204">"‏لإطالة عمر البطارية، تعمل ميزة \"توفير شحن البطارية\" على:\n\n• تفعيل \"المظهر الداكن\"\n• إيقاف أو حظر النشاط في الخلفية وبعض التأثيرات المرئية والميزات الأخرى، مثل \"Ok Google\"."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"للمساعدة في خفض استخدام البيانات، تمنع ميزة \"توفير البيانات\" بعض التطبيقات من إرسال البيانات وتلقّيها في الخلفية. يمكن للتطبيقات المتاحة لديك الآن استخدام البيانات، ولكن لا يمكنها الإكثار من ذلك. وهذا يعني أن الصور مثلاً لا تظهر حتى تنقر عليها."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"هل تريد تفعيل توفير البيانات؟"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"تفعيل"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 0f28222..9c45ff3 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -2087,7 +2087,7 @@
     <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Grupna konverzacija"</string>
     <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Lično"</string>
-    <string name="resolver_work_tab" msgid="2690019516263167035">"Poslovni"</string>
+    <string name="resolver_work_tab" msgid="2690019516263167035">"Poslovno"</string>
     <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Lični prikaz"</string>
     <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Prikaz za posao"</string>
     <string name="resolver_cant_share_with_work_apps" msgid="637686613606502219">"Ne možete da delite ovaj sadržaj pomoću aplikacija za posao"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 64d8d31..c9605e0 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -567,10 +567,10 @@
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_icon_content_description" msgid="4741068463175388817">"Ícono de huella digital"</string>
-    <string name="permlab_manageFace" msgid="4569549381889283282">"administrar el hardware de Desbloqueo facial"</string>
+    <string name="permlab_manageFace" msgid="4569549381889283282">"administrar el hardware de desbloqueo facial"</string>
     <string name="permdesc_manageFace" msgid="6204569688492710471">"Permite que la app emplee métodos para agregar y borrar plantillas de rostros para su uso."</string>
-    <string name="permlab_useFaceAuthentication" msgid="1011430526454859030">"usar el hardware de Desbloqueo facial"</string>
-    <string name="permdesc_useFaceAuthentication" msgid="3115697017684668012">"Permite que la app use el hardware de Desbloqueo facial con fines de autenticación"</string>
+    <string name="permlab_useFaceAuthentication" msgid="1011430526454859030">"usar el hardware de desbloqueo facial"</string>
+    <string name="permdesc_useFaceAuthentication" msgid="3115697017684668012">"Permite que la app use el hardware de desbloqueo facial con fines de autenticación"</string>
     <string name="face_recalibrate_notification_name" msgid="6006095897989257026">"Desbloqueo facial"</string>
     <string name="face_recalibrate_notification_title" msgid="5944930528030496897">"Vuelve a registrar tu rostro"</string>
     <string name="face_recalibrate_notification_content" msgid="892757485125249962">"Para mejorar el reconocimiento, vuelve a registrar tu rostro"</string>
@@ -586,8 +586,8 @@
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Mira directamente al dispositivo."</string>
     <string name="face_acquired_not_detected" msgid="2945945257956443257">"Ubica el rostro directamente frente al teléfono."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Te estás moviendo demasiado. No muevas el teléfono"</string>
-    <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Vuelve a registrar tu cara."</string>
-    <string name="face_acquired_too_different" msgid="4699657338753282542">"Ya no se reconoce la cara. Vuelve a intentarlo."</string>
+    <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Vuelve a registrar tu rostro."</string>
+    <string name="face_acquired_too_different" msgid="4699657338753282542">"Ya no se reconoce el rostro. Vuelve a intentarlo."</string>
     <string name="face_acquired_too_similar" msgid="7684650785108399370">"Es muy similar a la anterior. Haz otra pose."</string>
     <string name="face_acquired_pan_too_extreme" msgid="7822191262299152527">"Gira la cabeza un poco menos."</string>
     <string name="face_acquired_tilt_too_extreme" msgid="8119978324129248059">"Gira la cabeza un poco menos."</string>
@@ -597,15 +597,15 @@
   <string-array name="face_acquired_vendor">
   </string-array>
     <string name="face_error_hw_not_available" msgid="5085202213036026288">"No se verificó el rostro. Hardware no disponible."</string>
-    <string name="face_error_timeout" msgid="522924647742024699">"Vuelve a probar el Desbloqueo facial."</string>
+    <string name="face_error_timeout" msgid="522924647742024699">"Vuelve a probar el desbloqueo facial."</string>
     <string name="face_error_no_space" msgid="5649264057026021723">"No hay espacio para datos faciales nuevos. Borra uno viejo."</string>
     <string name="face_error_canceled" msgid="2164434737103802131">"Se canceló el reconocimiento facial."</string>
-    <string name="face_error_user_canceled" msgid="8553045452825849843">"El usuario canceló el Desbloqueo facial."</string>
+    <string name="face_error_user_canceled" msgid="8553045452825849843">"El usuario canceló el desbloqueo facial."</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Demasiados intentos. Inténtalo de nuevo más tarde."</string>
-    <string name="face_error_lockout_permanent" msgid="8277853602168960343">"Demasiados intentos. Se inhabilitó el Desbloqueo facial."</string>
-    <string name="face_error_unable_to_process" msgid="5723292697366130070">"No se pudo verificar la cara. Vuelve a intentarlo."</string>
-    <string name="face_error_not_enrolled" msgid="7369928733504691611">"No configuraste el Desbloqueo facial."</string>
-    <string name="face_error_hw_not_present" msgid="1070600921591729944">"No se admite el Desbloqueo facial en este dispositivo."</string>
+    <string name="face_error_lockout_permanent" msgid="8277853602168960343">"Demasiados intentos. Se inhabilitó el desbloqueo facial."</string>
+    <string name="face_error_unable_to_process" msgid="5723292697366130070">"No se pudo verificar el rostro. Vuelve a intentarlo."</string>
+    <string name="face_error_not_enrolled" msgid="7369928733504691611">"No configuraste el desbloqueo facial."</string>
+    <string name="face_error_hw_not_present" msgid="1070600921591729944">"No se admite el desbloqueo facial en este dispositivo."</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"Se inhabilitó temporalmente el sensor."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Rostro <xliff:g id="FACEID">%d</xliff:g>"</string>
   <string-array name="face_error_vendor">
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index f19b65d..04d6ee3 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1661,7 +1661,7 @@
     <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Para cambiar de una función a otra, mantén pulsado el botón Accesibilidad."</string>
     <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Para cambiar de una función a otra, desliza hacia arriba con dos dedos y mantén pulsada la pantalla."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Para cambiar de una función a otra, desliza tres dedos hacia arriba y mantén pulsada la pantalla."</string>
-    <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliar"</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ampliación"</string>
     <string name="user_switched" msgid="7249833311585228097">"Usuario actual: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Cambiando a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Cerrando la sesión de <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1794,8 +1794,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"Actualizado por el administrador"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado por el administrador"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Para que la batería dure más, Ahorro de batería:\n\n• Activa el tema oscuro\n•Desactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\"\n\n"<annotation id="url">"Más información"</annotation></string>
-    <string name="battery_saver_description" msgid="8587408568232177204">"Para que la batería dure más, Ahorro de batería:\n\n• Activa el tema oscuro\n•Desactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\""</string>
+    <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"Para que la batería dure más, el modo Ahorro de batería hace lo siguiente:\n\n• Activa el tema oscuro\n•Desactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\"\n\n"<annotation id="url">"Más información"</annotation></string>
+    <string name="battery_saver_description" msgid="8587408568232177204">"Para que la batería dure más, el modo Ahorro de batería hace lo siguiente:\n\n• Activa el tema oscuro\n• Desactiva o restringe actividad en segundo plano, algunos efectos visuales y otras funciones como \"Ok Google\""</string>
     <string name="data_saver_description" msgid="4995164271550590517">"El modo Ahorro de datos evita que algunas aplicaciones envíen o reciban datos en segundo plano, lo que puede reducir el uso de datos. Una aplicación activa puede acceder a los datos, aunque con menos frecuencia. Esto significa que es posible que, por ejemplo, algunas imágenes no se muestren hasta que las toques."</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"¿Activar Ahorro de datos?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Activar"</string>
@@ -2000,7 +2000,7 @@
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"Micrófono"</string>
     <string name="notification_appops_overlay_active" msgid="5571732753262836481">"se muestra sobre otras aplicaciones que haya en la pantalla"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación sobre el modo rutina"</string>
-    <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Puede que se agote la batería antes de lo habitual"</string>
+    <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"Quizás se agote la batería antes de lo habitual"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"Se ha activado el modo Ahorro de batería para aumentar la duración de la batería"</string>
     <string name="battery_saver_notification_channel_name" msgid="3918243458067916913">"Ahorro de batería"</string>
     <string name="battery_saver_off_notification_title" msgid="7637255960468032515">"Ahorro de batería desactivado"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index c77fd56..9fb8eff 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -173,10 +173,10 @@
     <string name="contentServiceSync" msgid="2341041749565687871">"همگام‌سازی"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="5766411446676388623">"همگام‌سازی نشد"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="4562226280528716090">"تعداد <xliff:g id="CONTENT_TYPE">%s</xliff:g> برای حذف بیش از حد مجاز شد."</string>
-    <string name="low_memory" product="tablet" msgid="5557552311566179924">"‏حافظه رایانهٔ لوحی پر است! برخی از فایل‎ها را حذف کنید تا فضا آزاد شود."</string>
+    <string name="low_memory" product="tablet" msgid="5557552311566179924">"‏فضای ذخیره‌سازی رایانهٔ لوحی پر است! برخی از فایل‎ها را حذف کنید تا فضا آزاد شود."</string>
     <string name="low_memory" product="watch" msgid="3479447988234030194">"حافظه ساعت پر است. برای آزادسازی فضا، چند فایل را حذف کنید."</string>
     <string name="low_memory" product="tv" msgid="6663680413790323318">"‏فضای ذخیره‌سازی دستگاه Android TV پر است. برخی از فایل‌ها را حذف کنید تا فضا آزاد شود."</string>
-    <string name="low_memory" product="default" msgid="2539532364144025569">"حافظه تلفن پر است. بعضی از فایل‌ها را حذف کنید تا فضا آزاد شود."</string>
+    <string name="low_memory" product="default" msgid="2539532364144025569">"فضای ذخیره‌سازی تلفن پر است. بعضی از فایل‌ها را حذف کنید تا فضا آزاد شود."</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
       <item quantity="one">مرجع صدور گواهی نصب شد</item>
       <item quantity="other">مراجع صدور گواهی نصب شدند</item>
@@ -383,7 +383,7 @@
     <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"به برنامه امکان می‌دهد قسمت‌هایی از خود را در حافظه دائمی کند. این کار حافظه موجود را برای سایر برنامه‌ها محدود کرده و باعث کندی تلفن می‌شود."</string>
     <string name="permlab_foregroundService" msgid="1768855976818467491">"اجرای سرویس پیش‌زمینه"</string>
     <string name="permdesc_foregroundService" msgid="8720071450020922795">"به برنامه اجازه می‌دهد از سرویس‌های پیش‌زمینه استفاده کند."</string>
-    <string name="permlab_getPackageSize" msgid="375391550792886641">"اندازه گیری فضای حافظه برنامه"</string>
+    <string name="permlab_getPackageSize" msgid="375391550792886641">"اندازه‌گیری اندازه فضای ذخیره‌سازی برنامه"</string>
     <string name="permdesc_getPackageSize" msgid="742743530909966782">"‏به برنامه اجازه می‎دهد تا کدها، داده‎ها و اندازه‎های حافظهٔ پنهان خود را بازیابی کند"</string>
     <string name="permlab_writeSettings" msgid="8057285063719277394">"تغییر تنظیمات سیستم"</string>
     <string name="permdesc_writeSettings" msgid="8293047411196067188">"‏به برنامه اجازه می‎دهد تا داده‎های تنظیم سیستم را تغییر دهد. برنامه‎های مخرب می‎توانند پیکربندی سیستم شما را خراب کنند."</string>
@@ -617,10 +617,10 @@
     <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"به برنامه اجازه می‌دهد تنظیمات همگام‌سازی را برای حساب تغییر دهد. به‌عنوان مثال، از این ویژگی می‌توان برای فعال کردن همگام‌سازی برنامه «افراد» با یک حساب استفاده کرد."</string>
     <string name="permlab_readSyncStats" msgid="3747407238320105332">"خواندن اطلاعات آماری همگام‌سازی"</string>
     <string name="permdesc_readSyncStats" msgid="3867809926567379434">"به یک برنامه اجازه می‌دهد وضعیت همگام‌سازی یک حساب را بخواند، از جمله سابقه رویدادهای همگام‌سازی و میزان داده‌های همگام‌سازی شده."</string>
-    <string name="permlab_sdcardRead" msgid="5791467020950064920">"خواندن محتوای فضای ذخیره هم‌رسانی‌شده"</string>
+    <string name="permlab_sdcardRead" msgid="5791467020950064920">"خواندن محتوای فضای ذخیره‌سازی مشترک"</string>
     <string name="permdesc_sdcardRead" msgid="6872973242228240382">"به برنامه اجازه می‌دهد محتوای فضای ذخیره هم‌رسانی‌شده‌تان را بخواند."</string>
-    <string name="permlab_sdcardWrite" msgid="4863021819671416668">"تغییر یا حذف محتوای فضای ذخیره هم‌رسانی‌شده"</string>
-    <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"به برنامه اجازه می‌دهد محتوای فضای ذخیره هم‌رسانی‌شده‌تان را بنویسد."</string>
+    <string name="permlab_sdcardWrite" msgid="4863021819671416668">"تغییر یا حذف محتوای فضای ذخیره‌سازی مشترک"</string>
+    <string name="permdesc_sdcardWrite" msgid="8376047679331387102">"به برنامه اجازه می‌دهد محتوای فضای ذخیره‌سازی مشترکتان را بنویسد."</string>
     <string name="permlab_use_sip" msgid="8250774565189337477">"‏تماس گرفتن/دریافت تماس از طریق SIP"</string>
     <string name="permdesc_use_sip" msgid="3590270893253204451">"‏به برنامه اجازه می‌دهد تماس‌های SIP بگیرد یا دریافت کند."</string>
     <string name="permlab_register_sim_subscription" msgid="1653054249287576161">"ثبت ارتباطات سیم کارت مخابراتی جدید"</string>
@@ -694,7 +694,7 @@
     <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"پروکسی کلی دستگاه را برای استفاده هنگام فعال بودن این خط‌مشی تنظیم می‌کند. تنها مالک دستگاه می‌تواند پروکسی کلی را تنظیم کند."</string>
     <string name="policylab_expirePassword" msgid="6015404400532459169">"تنظیم تاریخ انقضای گذرواژه قفل صفحه"</string>
     <string name="policydesc_expirePassword" msgid="9136524319325960675">"تغییر تعداد دفعاتی که گذرواژه، پین یا الگوی قفل صفحه باید تغییر کند."</string>
-    <string name="policylab_encryptedStorage" msgid="9012936958126670110">"تنظیم رمزگذاری حافظه"</string>
+    <string name="policylab_encryptedStorage" msgid="9012936958126670110">"تنظیم رمزگذاری فضای ذخیره‌سازی"</string>
     <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"اطلاعات ذخیره شده برنامه باید رمزگذاری شود."</string>
     <string name="policylab_disableCamera" msgid="5749486347810162018">"غیرفعال کردن دوربین‌ها"</string>
     <string name="policydesc_disableCamera" msgid="3204405908799676104">"جلوگیری از استفاده از همه دوربین‌های دستگاه."</string>
@@ -1107,7 +1107,7 @@
     <string name="deleteText" msgid="4200807474529938112">"حذف"</string>
     <string name="inputMethod" msgid="1784759500516314751">"روش ورودی"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"کنش‌های متنی"</string>
-    <string name="low_internal_storage_view_title" msgid="9024241779284783414">"حافظه درحال پر شدن است"</string>
+    <string name="low_internal_storage_view_title" msgid="9024241779284783414">"فضای ذخیره‌سازی درحال پر شدن است"</string>
     <string name="low_internal_storage_view_text" msgid="8172166728369697835">"برخی از عملکردهای سیستم ممکن است کار نکنند"</string>
     <string name="low_internal_storage_view_text_no_boot" msgid="7368968163411251788">"فضای ذخیره‌سازی سیستم کافی نیست. اطمینان حاصل کنید که دارای ۲۵۰ مگابایت فضای خالی هستید و سیستم را راه‌اندازی مجدد کنید."</string>
     <string name="app_running_notification_title" msgid="8985999749231486569">"<xliff:g id="APP_NAME">%1$s</xliff:g> در حال اجرا است"</string>
@@ -1504,7 +1504,7 @@
     <string name="action_menu_overflow_description" msgid="4579536843510088170">"سایر گزینه‌ها"</string>
     <string name="action_bar_home_description_format" msgid="5087107531331621803">"‎%1$s, %2$s"</string>
     <string name="action_bar_home_subtitle_description_format" msgid="4346835454749569826">"‎%1$s, %2$s, %3$s"</string>
-    <string name="storage_internal" msgid="8490227947584914460">"حافظه داخلی مشترک"</string>
+    <string name="storage_internal" msgid="8490227947584914460">"فضای ذخیره‌سازی داخلی مشترک"</string>
     <string name="storage_sd_card" msgid="3404740277075331881">"‏کارت SD"</string>
     <string name="storage_sd_card_label" msgid="7526153141147470509">"‏کارت SD ‏<xliff:g id="MANUFACTURER">%s</xliff:g>"</string>
     <string name="storage_usb_drive" msgid="448030813201444573">"‏درایو USB"</string>
@@ -1921,7 +1921,7 @@
     <string name="app_category_news" msgid="1172762719574964544">"اخبار و مجله"</string>
     <string name="app_category_maps" msgid="6395725487922533156">"نقشه و پیمایش"</string>
     <string name="app_category_productivity" msgid="1844422703029557883">"بهره‌وری"</string>
-    <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"حافظه دستگاه"</string>
+    <string name="device_storage_monitor_notification_channel" msgid="5164244565844470758">"فضای ذخیره‌سازی دستگاه"</string>
     <string name="adb_debugging_notification_channel_tv" msgid="4764046459631031496">"‏اشکال‌زدایی USB"</string>
     <string name="time_picker_hour_label" msgid="4208590187662336864">"ساعت"</string>
     <string name="time_picker_minute_label" msgid="8307452311269824553">"دقیقه"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index f7f2e94..d23a5bd 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -142,7 +142,7 @@
     <string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
     <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi-puhelut"</string>
     <string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
-    <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Ei käytössä"</string>
+    <string name="wifi_calling_off_summary" msgid="5626710010766902560">"Ei päällä"</string>
     <string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Soita Wi-Fin kautta"</string>
     <string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Soita mobiiliverkon kautta"</string>
     <string name="wfc_mode_wifi_only_summary" msgid="104951993894678665">"Vain Wi-Fi"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 3de09a0..000d03c 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1631,8 +1631,8 @@
     <string name="accessibility_shortcut_single_service_warning" msgid="6363127705112844257">"音量大と音量小の両方のボタンを数秒ほど長押しすると、ユーザー補助機能の <xliff:g id="SERVICE">%1$s</xliff:g> が ON になります。この機能が ON になると、デバイスの動作が変わることがあります。\n\nこのショートカットは [設定] &gt; [ユーザー補助] で別の機能に変更できます。"</string>
     <string name="accessibility_shortcut_on" msgid="5463618449556111344">"ON にする"</string>
     <string name="accessibility_shortcut_off" msgid="3651336255403648739">"ON にしない"</string>
-    <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"オン"</string>
-    <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"オフ"</string>
+    <string name="accessibility_shortcut_menu_item_status_on" msgid="6608392117189732543">"ON"</string>
+    <string name="accessibility_shortcut_menu_item_status_off" msgid="5531598275559472393">"OFF"</string>
     <string name="accessibility_enable_service_title" msgid="3931558336268541484">"<xliff:g id="SERVICE">%1$s</xliff:g> にデバイスのフル コントロールを許可しますか?"</string>
     <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"<xliff:g id="SERVICE">%1$s</xliff:g> をオンにすると、デバイスデータの暗号化の強化に画面ロックは使用されなくなります。"</string>
     <string name="accessibility_service_warning_description" msgid="291674995220940133">"フル コントロールは、ユーザー補助機能を必要とするユーザーをサポートするアプリには適していますが、ほとんどのアプリには適していません。"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index d41aba6..6259e4f 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1230,7 +1230,7 @@
     <string name="volume_icon_description_media" msgid="4997633254078171233">"ລະດັບສຽງຂອງສື່"</string>
     <string name="volume_icon_description_notification" msgid="579091344110747279">"ລະດັບສຽງການແຈ້ງເຕືອນ"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"ຣິງໂທນເລີ່ມຕົ້ນ"</string>
-    <string name="ringtone_default_with_actual" msgid="2709686194556159773">"Default (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_default_with_actual" msgid="2709686194556159773">"ຄ່າເລີ່ມຕົ້ນ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="397111123930141876">"ບໍ່ມີ"</string>
     <string name="ringtone_picker_title" msgid="667342618626068253">"ຣິງໂທນ"</string>
     <string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"Alarm sounds"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 3b57500c..fa0bb8b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1231,8 +1231,8 @@
     <string name="dump_heap_ready_notification" msgid="2302452262927390268">"<xliff:g id="PROC">%1$s</xliff:g> kaudzes izraksts ir gatavs"</string>
     <string name="dump_heap_notification_detail" msgid="8431586843001054050">"Apkopots kaudzes izraksts. Pieskarieties, lai kopīgotu."</string>
     <string name="dump_heap_title" msgid="4367128917229233901">"Vai kopīgot kaudzes izrakstu?"</string>
-    <string name="dump_heap_text" msgid="1692649033835719336">"Process <xliff:g id="PROC">%1$s</xliff:g> pārsniedza atmiņas ierobežojumu (<xliff:g id="SIZE">%2$s</xliff:g>). Tika apkopots kaudzes izraksts, ko varat kopīgot ar procesa izstrādātāju. Ņemiet vērā: kaudzes izrakstā var būt ietverta jūsu personas informācija, kurai var piekļūt lietojumprogramma."</string>
-    <string name="dump_heap_system_text" msgid="6805155514925350849">"Process <xliff:g id="PROC">%1$s</xliff:g> pārsniedza atmiņas ierobežojumu (<xliff:g id="SIZE">%2$s</xliff:g>). Tika apkopots kaudzes izraksts, ko varat kopīgot. Ievērojiet piesardzību, jo kaudzes izrakstā var būt ietverta visa sensitīvā personas informācija, kurai var piekļūt process, tostarp jūsu rakstīts teksts."</string>
+    <string name="dump_heap_text" msgid="1692649033835719336">"Process <xliff:g id="PROC">%1$s</xliff:g> pārsniedza atmiņas ierobežojumu (<xliff:g id="SIZE">%2$s</xliff:g>). Tika vākts kaudzes izraksts, ko varat kopīgot ar procesa izstrādātāju. Ņemiet vērā: kaudzes izrakstā var būt ietverta jūsu personas informācija, kurai var piekļūt lietojumprogramma."</string>
+    <string name="dump_heap_system_text" msgid="6805155514925350849">"Process <xliff:g id="PROC">%1$s</xliff:g> pārsniedza atmiņas ierobežojumu (<xliff:g id="SIZE">%2$s</xliff:g>). Tika vākts kaudzes izraksts, ko varat kopīgot. Ievērojiet piesardzību, jo kaudzes izrakstā var būt ietverta visa sensitīvā personas informācija, kurai var piekļūt process, tostarp jūsu rakstīts teksts."</string>
     <string name="dump_heap_ready_text" msgid="5849618132123045516">"Ir pieejams procesa <xliff:g id="PROC">%1$s</xliff:g> kaudzes izraksts, ko varat kopīgot. Ievērojiet piesardzību, jo kaudzes izrakstā var būt ietverta visa sensitīvā personas informācija, kurai var piekļūt process, tostarp jūsu rakstīts teksts."</string>
     <string name="sendText" msgid="493003724401350724">"Izvēlieties darbību tekstam"</string>
     <string name="volume_ringtone" msgid="134784084629229029">"Zvanītāja skaļums"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 902aa16..238a4e6 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -268,7 +268,7 @@
     <string name="status_bar_notification_info_overflow" msgid="3330152558746563475">"999+"</string>
     <string name="notification_hidden_text" msgid="2835519769868187223">"Шинэ мэдэгдэл"</string>
     <string name="notification_channel_virtual_keyboard" msgid="6465975799223304567">"Виртуал гар"</string>
-    <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Бодит гар"</string>
+    <string name="notification_channel_physical_keyboard" msgid="5417306456125988096">"Биет гар"</string>
     <string name="notification_channel_security" msgid="8516754650348238057">"Аюулгүй байдал"</string>
     <string name="notification_channel_car_mode" msgid="2123919247040988436">"Машины горим"</string>
     <string name="notification_channel_account" msgid="6436294521740148173">"Бүртгэлийн төлөв"</string>
@@ -1327,7 +1327,7 @@
     <string name="share_remote_bugreport_action" msgid="7630880678785123682">"ХУВААЛЦАХ"</string>
     <string name="decline_remote_bugreport_action" msgid="4040894777519784346">"ТАТГАЛЗАХ"</string>
     <string name="select_input_method" msgid="3971267998568587025">"Оруулах аргыг сонгоно уу"</string>
-    <string name="show_ime" msgid="6406112007347443383">"Бодит гар идэвхтэй үед үүнийг дэлгэцэнд харуулна уу"</string>
+    <string name="show_ime" msgid="6406112007347443383">"Биет гар идэвхтэй үед үүнийг дэлгэцэд харуулна уу"</string>
     <string name="hardware" msgid="1800597768237606953">"Хийсвэр гарыг харуулах"</string>
     <string name="select_keyboard_layout_notification_title" msgid="4427643867639774118">"Биет гарыг хэлбэрт оруулах"</string>
     <string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Хэл болон бүдүүвчийг сонгохын тулд дарна уу"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index fbeb310..1840479 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -108,7 +108,7 @@
     <string name="serviceClassDataSync" msgid="7895071363569133704">"सिंक करा"</string>
     <string name="serviceClassPacket" msgid="1430642951399303804">"पॅकेट"</string>
     <string name="serviceClassPAD" msgid="6850244583416306321">"PAD"</string>
-    <string name="roamingText0" msgid="7793257871609854208">"रोमिंग दर्शक चालू"</string>
+    <string name="roamingText0" msgid="7793257871609854208">"रोमिंग दर्शक सुरू"</string>
     <string name="roamingText1" msgid="5073028598334616445">"रोमिंग दर्शक बंद"</string>
     <string name="roamingText2" msgid="2834048284153110598">"रोमिंग दर्शक फ्लॅशिंग"</string>
     <string name="roamingText3" msgid="831690234035748988">"अतिपरिचित क्षेत्राबाहेर"</string>
@@ -119,12 +119,12 @@
     <string name="roamingText8" msgid="7774800704373721973">"रोमिंग - प्रीमियम भागीदार"</string>
     <string name="roamingText9" msgid="1933460020190244004">"रोमिंग - पूर्ण सेवा कार्यक्षमता"</string>
     <string name="roamingText10" msgid="7434767033595769499">"रोमिंग - आंशिक सेवा कार्यक्षमता"</string>
-    <string name="roamingText11" msgid="5245687407203281407">"रोमिंग बॅनर चालू"</string>
+    <string name="roamingText11" msgid="5245687407203281407">"रोमिंग बॅनर सुरू"</string>
     <string name="roamingText12" msgid="673537506362152640">"रोमिंग बॅनर बंद"</string>
     <string name="roamingTextSearching" msgid="5323235489657753486">"सेवा शोधत आहे"</string>
     <string name="wfcRegErrorTitle" msgid="3193072971584858020">"वाय-फाय कॉलिंग सेट करता आले नाही"</string>
   <string-array name="wfcOperatorErrorAlertMessages">
-    <item msgid="468830943567116703">"वाय-फायवरून कॉल करण्यासाठी आणि मेसेज पाठवण्यासाठी आधी तुमच्या कॅरियरला ही सेवा सेट अप करण्यास सांगा. नंतर सेटिंग्जमधून वाय-फाय वापरून कॉल करणे पुन्हा चालू करा. (एरर कोड <xliff:g id="CODE">%1$s</xliff:g>)"</item>
+    <item msgid="468830943567116703">"वाय-फायवरून कॉल करण्यासाठी आणि मेसेज पाठवण्यासाठी आधी तुमच्या कॅरियरला ही सेवा सेट अप करण्यास सांगा. नंतर सेटिंग्जमधून वाय-फाय वापरून कॉल करणे पुन्हा सुरू करा. (एरर कोड <xliff:g id="CODE">%1$s</xliff:g>)"</item>
   </string-array>
   <string-array name="wfcOperatorErrorNotificationMessages">
     <item msgid="4795145070505729156">"तुमच्या या वाहकासह वाय-फाय कॉलिंग नोंदणी करताना समस्या आली आहे:<xliff:g id="CODE">%1$s</xliff:g>"</item>
@@ -209,13 +209,13 @@
     <string name="power_dialog" product="tv" msgid="7792839006640933763">"Android TV पर्याय"</string>
     <string name="power_dialog" product="default" msgid="1107775420270203046">"फोन पर्याय"</string>
     <string name="silent_mode" msgid="8796112363642579333">"मूक मोड"</string>
-    <string name="turn_on_radio" msgid="2961717788170634233">"वायरलेस चालू करा"</string>
+    <string name="turn_on_radio" msgid="2961717788170634233">"वायरलेस सुरू करा"</string>
     <string name="turn_off_radio" msgid="7222573978109933360">"वायरलेस बंद करा"</string>
     <string name="screen_lock" msgid="2072642720826409809">"स्क्रीन लॉक"</string>
     <string name="power_off" msgid="4111692782492232778">"बंद करा"</string>
     <string name="silent_mode_silent" msgid="5079789070221150912">"रिंगर बंद"</string>
     <string name="silent_mode_vibrate" msgid="8821830448369552678">"रिंगर व्हायब्रेट"</string>
-    <string name="silent_mode_ring" msgid="6039011004781526678">"रिंगर चालू"</string>
+    <string name="silent_mode_ring" msgid="6039011004781526678">"रिंगर सुरू"</string>
     <string name="reboot_to_update_title" msgid="2125818841916373708">"Android सिस्टम अपडेट"</string>
     <string name="reboot_to_update_prepare" msgid="6978842143587422365">"अपडेट करण्याची तयारी करत आहे…"</string>
     <string name="reboot_to_update_package" msgid="4644104795527534811">"अपडेट पॅकेज प्रक्रिया करत आहे…"</string>
@@ -317,7 +317,7 @@
     <string name="permgroupdesc_sensors" msgid="2610631290633747752">"आपल्‍या महत्त्वाच्या मापनांविषयी सेंसर डेटा अ‍ॅक्सेस करा"</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="7554282892101587296">"विंडोमधील आशय पुन्हा मिळवा"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="6195610527625237661">"तुम्ही वापरत असलेल्‍या विंडोमधील आशय तपासा."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"स्पर्श करून अन्वेषण चालू करा"</string>
+    <string name="capability_title_canRequestTouchExploration" msgid="327598364696316213">"स्पर्श करून अन्वेषण सुरू करा"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="4394677060796752976">"टॅप केलेले आयटम मोठ्‍याने बोलले जातील आणि जेश्चरचा वापर करून स्क्रीन एक्सप्लोर केली जाऊ शकते."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2772371671541753254">"तुम्ही टाइप करता त्या मजकुराचे निरीक्षण करा"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="2381315802405773092">"यामध्ये क्रेडिट कार्ड नंबर आणि पासवर्ड यासारखा वैयक्तिक डेटा समाविष्‍ट आहे."</string>
@@ -374,7 +374,7 @@
     <string name="permlab_systemAlertWindow" msgid="5757218350944719065">"हा अ‍ॅप इतर अ‍ॅप्सच्या शीर्षस्थानी दिसू शकतो."</string>
     <string name="permdesc_systemAlertWindow" msgid="1145660714855738308">"हे अ‍ॅप इतर अ‍ॅप्सच्या शीर्षस्थानी किंवा स्क्रीनच्या इतर भागांवर दिसू शकतो. हे सामान्य अ‍ॅप वापरात व्यत्यय आणू शकते किंवा इतर अ‍ॅप्सची डिस्प्ले पद्धत बदलू शकते."</string>
     <string name="permlab_runInBackground" msgid="541863968571682785">"पार्श्वभूमीत चालवा"</string>
-    <string name="permdesc_runInBackground" msgid="4344539472115495141">"हे अ‍ॅप पार्श्वभूमीत चालू शकते. हे बॅटरी अधिक जलद संपवू शकते."</string>
+    <string name="permdesc_runInBackground" msgid="4344539472115495141">"हे अ‍ॅप पार्श्वभूमीत सुरू शकते. हे बॅटरी अधिक जलद संपवू शकते."</string>
     <string name="permlab_useDataInBackground" msgid="783415807623038947">"पार्श्वभूमीत डेटा वापरा"</string>
     <string name="permdesc_useDataInBackground" msgid="1230753883865891987">"हे अ‍ॅप पार्श्वभूमीत डेटा वापरू शकते. हे डेटाचा वापर वाढवू शकते."</string>
     <string name="permlab_persistentActivity" msgid="464970041740567970">"अ‍ॅप नेहमी चालवा"</string>
@@ -388,9 +388,9 @@
     <string name="permlab_writeSettings" msgid="8057285063719277394">"सिस्टम सेटिंग्ज सुधारित करा"</string>
     <string name="permdesc_writeSettings" msgid="8293047411196067188">"सिस्टीमचा सेटिंग्ज डेटा सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. दुर्भावनापूर्ण अ‍ॅप्स आपल्या सिस्टीमचे कॉन्फिगरेशन दूषित करू शकतात."</string>
     <string name="permlab_receiveBootCompleted" msgid="6643339400247325379">"सुरूवातीस चालवा"</string>
-    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"जसे सिस्टम बूट करणे समाप्त करते तसे अ‍ॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे टॅबलेट प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर टॅबलेटला धीमे करण्यास अ‍ॅप ला अनुमती देते."</string>
-    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"सिस्टम बूट होणे संपल्यावर ॲपला स्वतः सुरू होण्याची अनुमती देते. यामुळे तुमच्या Android TV डिव्हाइसला सुरू होण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर डिव्हाइसलाच धीमे करण्याची अनुमती ॲपला देते."</string>
-    <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"जसे सिस्टम बूट करणे समाप्त करते तसे अ‍ॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे फोन प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी चालू राहून एकंदर फोनला धीमे करण्यास अ‍ॅप ला अनुमती देते."</string>
+    <string name="permdesc_receiveBootCompleted" product="tablet" msgid="5565659082718177484">"जसे सिस्टम बूट करणे समाप्त करते तसे अ‍ॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे टॅबलेट प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर टॅबलेटला धीमे करण्यास अ‍ॅप ला अनुमती देते."</string>
+    <string name="permdesc_receiveBootCompleted" product="tv" msgid="4900842256047614307">"सिस्टम बूट होणे संपल्यावर ॲपला स्वतः सुरू होण्याची अनुमती देते. यामुळे तुमच्या Android TV डिव्हाइसला सुरू होण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर डिव्हाइसलाच धीमे करण्याची अनुमती ॲपला देते."</string>
+    <string name="permdesc_receiveBootCompleted" product="default" msgid="7912677044558690092">"जसे सिस्टम बूट करणे समाप्त करते तसे अ‍ॅप ला स्वतः प्रारंभ करण्यास अनुमती देते. यामुळे फोन प्रारंभ करण्यास वेळ लागू शकतो आणि नेहमी सुरू राहून एकंदर फोनला धीमे करण्यास अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_broadcastSticky" msgid="4552241916400572230">"रोचक प्रसारण पाठवा"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="5058486069846384013">"रोचक प्रसारणे पाठविण्यासाठी अ‍ॅप ला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो टॅब्लेटला धीमा किंवा अस्थिर करू शकतो."</string>
     <string name="permdesc_broadcastSticky" product="tv" msgid="2338185920171000650">"चिकट प्रसारणे पाठविण्यासाठी ॲपला अनुमती देते, जे प्रसारण समाप्त झाल्यानंतर देखील तसेच राहते. अत्याधिक वापरामुळे बरीच मेमरी वापरली जाऊन तो तुमच्या Android TV डिव्हाइसला धीमा किंवा अस्थिर करू शकतो."</string>
@@ -613,7 +613,7 @@
     <string name="face_icon_content_description" msgid="465030547475916280">"चेहरा आयकन"</string>
     <string name="permlab_readSyncSettings" msgid="6250532864893156277">"सिंक सेटिंग्‍ज वाचा"</string>
     <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"खात्याच्या सिंक सेटिंग्ज वाचण्यासाठी अ‍ॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांचा अ‍ॅप संकालित केला आहे किंवा नाही हे निर्धारित करू शकते."</string>
-    <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"सिंक चालू आणि बंद करा टॉगल करा"</string>
+    <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"सिंक सुरू आणि बंद करा टॉगल करा"</string>
     <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"खात्यासाठी सिंक सेटिंग्ज सुधारित करण्यासाठी अ‍ॅप ला अनुमती देते. उदाहरणार्थ, हे खात्यासह लोकांच्या अ‍ॅप चे सिंक सक्षम करण्यासाठी वापरले जाऊ शकते."</string>
     <string name="permlab_readSyncStats" msgid="3747407238320105332">"सिंक आकडेवारी वाचा"</string>
     <string name="permdesc_readSyncStats" msgid="3867809926567379434">"सिंक इव्हेंटचा इतिहास आणि किती डेटाचे सिंक केले आहे यासह, खात्याची सिंक स्थिती वाचण्यासाठी अ‍ॅप ला अनुमती देते."</string>
@@ -881,7 +881,7 @@
     <string name="lockscreen_glogin_account_recovery_hint" msgid="1683405808525090649">"तुमचे वापरकर्तानाव किंवा पासवर्ड विसरलात?\n "<b>"google.com/accounts/recovery"</b>" ला भेट द्या."</string>
     <string name="lockscreen_glogin_checking_password" msgid="2607271802803381645">"तपासत आहे..."</string>
     <string name="lockscreen_unlock_label" msgid="4648257878373307582">"अनलॉक करा"</string>
-    <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"ध्वनी सुरु"</string>
+    <string name="lockscreen_sound_on_label" msgid="1660281470535492430">"ध्वनी सुरू"</string>
     <string name="lockscreen_sound_off_label" msgid="2331496559245450053">"ध्वनी बंद"</string>
     <string name="lockscreen_access_pattern_start" msgid="3778502525702613399">"पॅटर्न सुरू केला"</string>
     <string name="lockscreen_access_pattern_cleared" msgid="7493849102641167049">"पॅटर्न साफ केला"</string>
@@ -988,8 +988,8 @@
     <string name="searchview_description_submit" msgid="6771060386117334686">"क्वेरी सबमिट करा"</string>
     <string name="searchview_description_voice" msgid="42360159504884679">"व्हॉइस शोध"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="5095399706284943314">"स्पर्श करून एक्सप्लोर करा सक्षम करायचे?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श करून एक्सप्लोर करा सक्षम करू इच्छिते. स्पर्श करून एक्सप्लोर करा चालू असते, तेव्हा तुम्ही तुमच्या बोटाखाली काय आहे त्याचे वर्णन ऐकू किंवा पाहू शकता किंवा टॅब्लेटसह संवाद साधण्यासाठी जेश्चर करू शकता."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श करून एक्सप्लोर करा सक्षम करू इच्छिते. स्पर्श करून एक्सप्लोर करा चालू असते, तेव्हा तुम्ही तुमच्या बोटाखाली काय आहे त्याचे वर्णन ऐकू किंवा पाहू शकता किंवा फोनसह संवाद साधण्यासाठी जेश्चर करू शकता."</string>
+    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="1037295476738940824">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श करून एक्सप्लोर करा सक्षम करू इच्छिते. स्पर्श करून एक्सप्लोर करा सुरू असते, तेव्हा तुम्ही तुमच्या बोटाखाली काय आहे त्याचे वर्णन ऐकू किंवा पाहू शकता किंवा टॅब्लेटसह संवाद साधण्यासाठी जेश्चर करू शकता."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="4312979647356179250">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> स्पर्श करून एक्सप्लोर करा सक्षम करू इच्छिते. स्पर्श करून एक्सप्लोर करा सुरू असते, तेव्हा तुम्ही तुमच्या बोटाखाली काय आहे त्याचे वर्णन ऐकू किंवा पाहू शकता किंवा फोनसह संवाद साधण्यासाठी जेश्चर करू शकता."</string>
     <string name="oneMonthDurationPast" msgid="4538030857114635777">"1 महिन्यापूर्वी"</string>
     <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"1 महिन्यापूर्वी"</string>
     <plurals name="last_num_days" formatted="false" msgid="687443109145393632">
@@ -1203,7 +1203,7 @@
     <string name="heavy_weight_notification" msgid="8382784283600329576">"रन होणारे <xliff:g id="APP">%1$s</xliff:g>"</string>
     <string name="heavy_weight_notification_detail" msgid="6802247239468404078">"गेमवर परत जाण्यासाठी टॅप करा"</string>
     <string name="heavy_weight_switcher_title" msgid="3861984210040100886">"गेम निवडा"</string>
-    <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"अधिक चांगल्या कामगिरीसाठी, एकावेळी यापैकी केवळ एक गेम चालू ठेवता येईल."</string>
+    <string name="heavy_weight_switcher_text" msgid="6814316627367160126">"अधिक चांगल्या कामगिरीसाठी, एकावेळी यापैकी केवळ एक गेम सुरू ठेवता येईल."</string>
     <string name="old_app_action" msgid="725331621042848590">"<xliff:g id="OLD_APP">%1$s</xliff:g> वर परत जा"</string>
     <string name="new_app_action" msgid="547772182913269801">"<xliff:g id="NEW_APP">%1$s</xliff:g> उघडा"</string>
     <string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> सेव्ह न करता बंद होईल"</string>
@@ -1262,7 +1262,7 @@
     <string name="decline" msgid="6490507610282145874">"नकार द्या"</string>
     <string name="select_character" msgid="3352797107930786979">"वर्ण घाला"</string>
     <string name="sms_control_title" msgid="4748684259903148341">"SMS मेसेज पाठवत आहे"</string>
-    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; मोठ्या संख्येने SMS मेसेज पाठवत आहे. तुम्ही या अ‍ॅप ला मेसेज पाठविणे सुरु ठेवण्याची अनुमती देऊ इच्छिता?"</string>
+    <string name="sms_control_message" msgid="6574313876316388239">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; मोठ्या संख्येने SMS मेसेज पाठवत आहे. तुम्ही या अ‍ॅप ला मेसेज पाठविणे सुरू ठेवण्याची अनुमती देऊ इच्छिता?"</string>
     <string name="sms_control_yes" msgid="4858845109269524622">"अनुमती द्या"</string>
     <string name="sms_control_no" msgid="4845717880040355570">"नकार द्या"</string>
     <string name="sms_short_code_confirm_message" msgid="1385416688897538724">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; हा &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;वर एक मेसेज पाठवू इच्छितो."</string>
@@ -1297,10 +1297,10 @@
     <string name="dlg_ok" msgid="5103447663504839312">"ठीक"</string>
     <string name="usb_charging_notification_title" msgid="1674124518282666955">"हे डिव्हाइस USB ने चार्ज करत आहे"</string>
     <string name="usb_supplying_notification_title" msgid="5378546632408101811">"USB ने चार्ज करायला ठेवलेले डिव्हाइस"</string>
-    <string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB फाइल ट्रान्सफर चालू केले"</string>
-    <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB मार्फत PTP चालू केले"</string>
-    <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB टेदरिंग चालू केले"</string>
-    <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB मार्फत MIDI चालू केले"</string>
+    <string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB फाइल ट्रान्सफर सुरू केले"</string>
+    <string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB मार्फत PTP सुरू केले"</string>
+    <string name="usb_tether_notification_title" msgid="8828527870612663771">"USB टेदरिंग सुरू केले"</string>
+    <string name="usb_midi_notification_title" msgid="7404506788950595557">"USB मार्फत MIDI सुरू केले"</string>
     <string name="usb_accessory_notification_title" msgid="1385394660861956980">"USB अ‍ॅक्सेसरी कनेक्ट केली आहे"</string>
     <string name="usb_notification_message" msgid="4715163067192110676">"अधिक पर्यायांसाठी टॅप करा."</string>
     <string name="usb_power_notification_message" msgid="7284765627437897702">"चार्जर लावलेले डिव्हाइस. आणखी पर्यायांसाठी टॅप करा"</string>
@@ -1425,10 +1425,10 @@
     <string name="vpn_title_long" msgid="6834144390504619998">"<xliff:g id="APP">%s</xliff:g> द्वारे VPN सक्रिय केले आहे"</string>
     <string name="vpn_text" msgid="2275388920267251078">"नेटवर्क व्यवस्थापित करण्यासाठी टॅप करा."</string>
     <string name="vpn_text_long" msgid="278540576806169831">"<xliff:g id="SESSION">%s</xliff:g> शी कनेक्ट केले. नेटवर्क व्यवस्थापित करण्यासाठी टॅप करा."</string>
-    <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"VPN कनेक्ट करणे नेहमी-चालू…"</string>
-    <string name="vpn_lockdown_connected" msgid="2853127976590658469">"VPN कनेक्ट केलेले नेहमी-चालू"</string>
-    <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"कायम चालू असलेल्या VPN मधून डिस्कनेक्ट केले"</string>
-    <string name="vpn_lockdown_error" msgid="4453048646854247947">"कायम चालू असलेल्या VPN शी कनेक्ट करता आले नाही"</string>
+    <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"VPN कनेक्ट करणे नेहमी-सुरू…"</string>
+    <string name="vpn_lockdown_connected" msgid="2853127976590658469">"VPN कनेक्ट केलेले नेहमी-सुरू"</string>
+    <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"कायम सुरू असलेल्या VPN मधून डिस्कनेक्ट केले"</string>
+    <string name="vpn_lockdown_error" msgid="4453048646854247947">"कायम सुरू असलेल्या VPN शी कनेक्ट करता आले नाही"</string>
     <string name="vpn_lockdown_config" msgid="8331697329868252169">"नेटवर्क किंवा VPN सेटिंग्ज बदला"</string>
     <string name="upload_file" msgid="8651942222301634271">"फाईल निवडा"</string>
     <string name="no_file_chosen" msgid="4146295695162318057">"फाईल निवडली नाही"</string>
@@ -1587,7 +1587,7 @@
     <string name="kg_sim_pin_instructions" msgid="6479401489471690359">"सिम पिन एंटर करा"</string>
     <string name="kg_pin_instructions" msgid="7355933174673539021">"पिन एंटर करा"</string>
     <string name="kg_password_instructions" msgid="7179782578809398050">"पासवर्ड एंटर करा"</string>
-    <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"सिम आता अक्षम केले आहे. सुरु ठेवण्यासाठी PUK कोड एंटर करा. तपशीलांसाठी वाहकाशी संपर्क साधा."</string>
+    <string name="kg_puk_enter_puk_hint" msgid="6696187482616360994">"सिम आता अक्षम केले आहे. सुरू ठेवण्यासाठी PUK कोड एंटर करा. तपशीलांसाठी वाहकाशी संपर्क साधा."</string>
     <string name="kg_puk_enter_pin_hint" msgid="8190982314659429770">"इच्छित पिन कोड एंटर करा"</string>
     <string name="kg_enter_confirm_pin_hint" msgid="6372557107414074580">"इच्छित पिन कोड ची पुष्टी करा"</string>
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8871937892678885545">"सिम कार्ड अनलॉक करत आहे…"</string>
@@ -1797,7 +1797,7 @@
     <string name="battery_saver_description_with_learn_more" msgid="5997766757551917769">"बॅटरीचे आयुष्य वाढवण्यासाठी बॅटरी सेव्हर:\n\n•गडद थीम सुरू करते\n•बॅकग्राउंड ॲक्टिव्हिटी, काही व्हिज्युअल इफेक्ट आणि \"Ok Google\" यांसारखी वैशिष्ट्ये बंद किंवा मर्यादित करते.\n\n"<annotation id="url">"अधिक जाणून घ्या"</annotation></string>
     <string name="battery_saver_description" msgid="8587408568232177204">"बॅटरीचे आयुष्य वाढवण्यासाठी बॅटरी सेव्हर:\n\n•गडद थीम सुरू करते\n•बॅकग्राउंड ॲक्टिव्हिटी, काही व्हिज्युअल इफेक्ट आणि \"Ok Google\" यांसारखी वैशिष्ट्ये बंद किंवा मर्यादित करते."</string>
     <string name="data_saver_description" msgid="4995164271550590517">"डेटाचा वापर कमी करण्यात मदत करण्यासाठी काही अ‍ॅप्सना बॅकग्राउंडमध्ये डेटा पाठवण्यास किंवा मिळवण्यास डेटा सर्व्हर प्रतिबंध करतो. तुम्ही सध्या वापरत असलेले अ‍ॅप डेटा अ‍ॅक्सेस करू शकते, पण तसे खूप कमी वेळा होते. याचाच अर्थ असा की, तुम्ही इमेजवर टॅप करेपर्यंत त्या डिस्प्ले होणार नाहीत असे होऊ शकते."</string>
-    <string name="data_saver_enable_title" msgid="7080620065745260137">"डेटा सेव्हर चालू करायचे?"</string>
+    <string name="data_saver_enable_title" msgid="7080620065745260137">"डेटा सेव्हर सुरू करायचे?"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"सुरू करा"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
       <item quantity="other">%1$d मिनिटांसाठी (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> पर्यंत)</item>
@@ -1890,7 +1890,7 @@
     <string name="app_suspended_unsuspend_message" msgid="1665438589450555459">"अ‍ॅप उघडा"</string>
     <string name="work_mode_off_title" msgid="5503291976647976560">"कार्य प्रोफाइल सुरू ठेवायची?"</string>
     <string name="work_mode_off_message" msgid="8417484421098563803">"तुमची कार्य अ‍ॅप्स, सूचना, डेटा आणि अन्य कार्य प्रोफाइल वैशिष्ट्ये सुरू केली जातील"</string>
-    <string name="work_mode_turn_on" msgid="3662561662475962285">"चालू करा"</string>
+    <string name="work_mode_turn_on" msgid="3662561662475962285">"सुरू करा"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"ॲप उपलब्ध नाही"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> आता उपलब्ध नाही."</string>
     <string name="deprecated_target_sdk_message" msgid="5203207875657579953">"हे अ‍ॅप Android च्या जुन्या आवृत्ती साठी तयार करण्यात आले होते आणि योग्यरितीने कार्य करू शकणार नाही. अपडेट आहेत का ते तपासून पाहा, किंवा डेव्हलपरशी संपर्क साधण्याचा प्रयत्न करा."</string>
@@ -2025,7 +2025,7 @@
     <string name="mime_type_spreadsheet_ext" msgid="8720173181137254414">"<xliff:g id="EXTENSION">%1$s</xliff:g> स्प्रेडशीट"</string>
     <string name="mime_type_presentation" msgid="1145384236788242075">"सादरीकरण"</string>
     <string name="mime_type_presentation_ext" msgid="8761049335564371468">"<xliff:g id="EXTENSION">%1$s</xliff:g> सादरीकरण"</string>
-    <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"विमान मोड दरम्यान ब्लूटूथ चालू राहील"</string>
+    <string name="bluetooth_airplane_mode_toast" msgid="2066399056595768554">"विमान मोड दरम्यान ब्लूटूथ सुरू राहील"</string>
     <string name="car_loading_profile" msgid="8219978381196748070">"लोड होत आहे"</string>
     <plurals name="file_count" formatted="false" msgid="7063513834724389247">
       <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> फायली</item>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 79d0974..d9e3b0c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -380,7 +380,7 @@
     <string name="permlab_persistentActivity" msgid="464970041740567970">"एपहरू जहिले पनि चल्ने बनाउनुहोस्"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="6055271149187369916">"यसको आफ्नै मेमोरीमा दृढ भएकोको अंश बनाउनको लागि एपलाई अनुमति दिन्छ। ट्याब्लेटलाई ढिलो गराउँदै गरेका अन्य अनुप्रयोगहरूलाई सीमित मात्रामा यसले मेमोरी उपलब्ध गराउन सक्छ।"</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="6800526387664131321">"एपलाई आफ्ना केही अंशहरू मेमोरीमा स्थायी रूपमा राख्ने अनुमति दिन्छ। यसले गर्दा अन्य अनुप्रयोगहरूका लागि मेमोरीको अभाव हुन सक्ने भएकाले तपाईंको Android TV यन्त्र सुस्त हुन सक्छ।"</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"एपलाई मेमोरीमा आफैंको निरन्तरको अंश बनाउन अनुमति दिन्छ। यसले फोनलाई ढिला बनाएर अन्य अनुप्रयोगहरूमा मेमोरी SIMित गर्न सक्दछन्।"</string>
+    <string name="permdesc_persistentActivity" product="default" msgid="1914841924366562051">"एपलाई मेमोरीमा आफैंको निरन्तरको अंश बनाउन अनुमति दिन्छ। यसले फोनलाई ढिला बनाएर अन्य एपहरूमा मेमोरी SIMित गर्न सक्दछन्।"</string>
     <string name="permlab_foregroundService" msgid="1768855976818467491">"अग्रभूमिको सेवा सञ्चालन गर्नुहोस्"</string>
     <string name="permdesc_foregroundService" msgid="8720071450020922795">"एपलाई अग्रभूमिका सेवाहरू प्रयोग गर्ने अनुमति दिन्छ।"</string>
     <string name="permlab_getPackageSize" msgid="375391550792886641">"एप भण्डारण ठाउँको मापन गर्नुहोस्"</string>
@@ -614,7 +614,7 @@
     <string name="permlab_readSyncSettings" msgid="6250532864893156277">"समीकरण सेटिङहरू पढ्नुहोस्"</string>
     <string name="permdesc_readSyncSettings" msgid="1325658466358779298">"एपलाई खाताको लागि सिंक सेटिङहरू पढ्न अनुमति दिन्छ। उदाहरणको लागि यसले व्यक्तिहरको एप खातासँग सिंक भएको नभएको निर्धारण गर्न सक्दछ।"</string>
     <string name="permlab_writeSyncSettings" msgid="6583154300780427399">"टगल सिंक खुला र बन्द"</string>
-    <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"अनुप्रयोगहरूलाई खाताको लागि सिंक सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ। उदाहरणको लागि, यो खातासँग व्यक्ति अनुप्रयोगको सिंक सक्षम गर्न प्रयोग गर्न सकिन्छ।"</string>
+    <string name="permdesc_writeSyncSettings" msgid="6029151549667182687">"अनुप्रयोगहरूलाई खाताको लागि सिंक सेटिङहरू परिमार्जन गर्न अनुमति दिन्छ। उदाहरणको लागि, यो खातासँग व्यक्ति एपको सिंक सक्षम गर्न प्रयोग गर्न सकिन्छ।"</string>
     <string name="permlab_readSyncStats" msgid="3747407238320105332">"सिंक तथ्याङ्कहरू पढ्नुहोस्"</string>
     <string name="permdesc_readSyncStats" msgid="3867809926567379434">"एपलाई खाताको लागि समीकरणको आँकडा समीकरण घटनाहरूको  इतिहास र समीकरण गरिएको डेटाको मापन समेत, पढ्न अनुमति दिन्छ।"</string>
     <string name="permlab_sdcardRead" msgid="5791467020950064920">"आफ्नो आदान प्रदान गरिएको भण्डारणको सामग्रीहरूहरू पढ्नुहोस्"</string>
@@ -1187,7 +1187,7 @@
     <string name="screen_compat_mode_hint" msgid="4032272159093750908">"प्रणाली सेटिङहरूमा यसलाई पुनःसक्षम गराउनुहोस् &gt; एपहरू &gt; डाउनलोड गरेको।"</string>
     <string name="unsupported_display_size_message" msgid="7265211375269394699">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले हालको प्रदर्शनको आकार सम्बन्धी सेटिङलाई समर्थन गर्दैन र अप्रत्याशित तरिकाले व्यवहार गर्न सक्छ।"</string>
     <string name="unsupported_display_size_show" msgid="980129850974919375">"सधैँ देखाउनुहोस्"</string>
-    <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> लाई Android OS को कुनै नमिल्दो संस्करणका लागि निर्माण गरिएको थियो र यसले अप्रत्याशित ढंगले कार्य गर्नसक्छ। उक्त अनुप्रयोगको कुनै अद्यावधिक संस्करण उपलब्ध हुनसक्छ।"</string>
+    <string name="unsupported_compile_sdk_message" msgid="7326293500707890537">"<xliff:g id="APP_NAME">%1$s</xliff:g> लाई Android OS को कुनै नमिल्दो संस्करणका लागि निर्माण गरिएको थियो र यसले अप्रत्याशित ढंगले कार्य गर्नसक्छ। उक्त एपको कुनै अद्यावधिक संस्करण उपलब्ध हुनसक्छ।"</string>
     <string name="unsupported_compile_sdk_show" msgid="1601210057960312248">"जुनसुकै बेला देखाउनुहोस्"</string>
     <string name="unsupported_compile_sdk_check_update" msgid="1103639989147664456">"अद्यावधिकका लागि जाँच गर्नुहोस्"</string>
     <string name="smv_application" msgid="3775183542777792638">"एप <xliff:g id="APPLICATION">%1$s</xliff:g> (प्रक्रिया <xliff:g id="PROCESS">%2$s</xliff:g>) ले यसको स्वयं-लागु गरिएको स्ट्रिटमोड नीति उलङ्घन गरेको छ।"</string>
@@ -1217,7 +1217,7 @@
     <string name="dump_heap_ready_notification" msgid="2302452262927390268">"<xliff:g id="PROC">%1$s</xliff:g> हिप डम्प तयार छ"</string>
     <string name="dump_heap_notification_detail" msgid="8431586843001054050">"हिप डम्प सङ्‍कलन गरियो, ट्याप गरेर सेयर गर्नुहोस्।"</string>
     <string name="dump_heap_title" msgid="4367128917229233901">"हिप डम्प साझेदारी गर्नुहुन्छ?"</string>
-    <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g>प्रक्रियाले यसको मेमोरीको सीमा <xliff:g id="SIZE">%2$s</xliff:g> नाघेको छ। तपाईंका लागि विकासकर्तासँग साझेदारी गर्न एउटा हिप डम्प उपलब्ध छ। सावधान हुनुहोला: यो हिप डम्पमा अनुप्रयोगको पहुँच भएको तपाईंको जुनसुकै व्यक्तिगत जानकारी हुन सक्छ।"</string>
+    <string name="dump_heap_text" msgid="1692649033835719336">"<xliff:g id="PROC">%1$s</xliff:g>प्रक्रियाले यसको मेमोरीको सीमा <xliff:g id="SIZE">%2$s</xliff:g> नाघेको छ। तपाईंका लागि विकासकर्तासँग साझेदारी गर्न एउटा हिप डम्प उपलब्ध छ। सावधान हुनुहोला: यो हिप डम्पमा एपको पहुँच भएको तपाईंको जुनसुकै व्यक्तिगत जानकारी हुन सक्छ।"</string>
     <string name="dump_heap_system_text" msgid="6805155514925350849">"<xliff:g id="PROC">%1$s</xliff:g> प्रक्रियाले यसको मेमोरीको सीमा <xliff:g id="SIZE">%2$s</xliff:g> नाँघेको छ। आदान प्रदान गर्नका लागि तपाईंलाई एउटा हिप डम्प उपलब्ध छ। सावधान हुनुहोस्: यस हिप डम्पमा उक्त प्रक्रियाको पहुँच भएको जुनसुकै संवेदनशील व्यक्तिगत जानकारी समावेश हुन सक्छ जसमा तपाईंले टाइप गर्नुभएका कुराहरू पर्न सक्छन्।"</string>
     <string name="dump_heap_ready_text" msgid="5849618132123045516">"तपाईंसँग आदान प्रदान गर्नका लागि <xliff:g id="PROC">%1$s</xliff:g> को प्रक्रियासम्बन्धी हिप डम्प उपलब्ध छ। सावधान हुनुहोस्: यस हिप डम्पमा उक्त प्रक्रियाको पहुँच भएको जुनसुकै संवेदनशील व्यक्तिगत जानकारी समावेश हुन सक्छ जसमा तपाईंले टाइप गर्नुभएका कुराहरू पर्न सक्छन्।"</string>
     <string name="sendText" msgid="493003724401350724">"पाठको लागि एउटा प्रकार्य छान्नुहोस्"</string>
@@ -1340,8 +1340,8 @@
     <string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="alert_windows_notification_channel_group_name" msgid="6063891141815714246">"अन्य अनुप्रयोगमा देखाउनुहोस्"</string>
-    <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> अन्य अनुप्रयोगहरूमा देखिँदैछ"</string>
-    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> अन्य अनुप्रयोगहरूमा देखिँदैछ"</string>
+    <string name="alert_windows_notification_channel_name" msgid="3437528564303192620">"<xliff:g id="NAME">%s</xliff:g> अन्य एपहरूमा देखिँदैछ"</string>
+    <string name="alert_windows_notification_title" msgid="6331662751095228536">"<xliff:g id="NAME">%s</xliff:g> अन्य एपहरूमा देखिँदैछ"</string>
     <string name="alert_windows_notification_message" msgid="6538171456970725333">"तपाईं <xliff:g id="NAME">%s</xliff:g> ले यो विशेषता प्रयोग नगरेको चाहनुहुन्न भने सेटिङहरू खोली यसलाई निष्क्रिय पार्न ट्याप गर्नुहोस्।"</string>
     <string name="alert_windows_notification_turn_off_action" msgid="7805857234839123780">"निष्क्रिय पार्नुहोस्"</string>
     <string name="ext_media_checking_notification_title" msgid="8299199995416510094">"जाँच गर्दै <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1643,7 +1643,7 @@
     <string name="accessibility_enable_service_encryption_warning" msgid="8603532708618236909">"तपाईंले <xliff:g id="SERVICE">%1$s</xliff:g> सक्रिय गर्नुभयो भने तपाईंको यन्त्रले डेटा इन्क्रिप्ट गर्ने सुविधाको स्तरोन्नति गर्न तपाईंको स्क्रिन लक सुविधाको प्रयोग गर्ने छैन।"</string>
     <string name="accessibility_service_warning_description" msgid="291674995220940133">"तपाईंलाई पहुँच राख्न आवश्यक पर्ने कुरामा सहयोग गर्ने अनुप्रयोगहरूमाथि पूर्ण नियन्त्रण गर्नु उपयुक्त हुन्छ तर अधिकांश अनुप्रयोगहरूका हकमा यस्तो नियन्त्रण उपयुक्त हुँदैन।"</string>
     <string name="accessibility_service_screen_control_title" msgid="190017412626919776">"स्क्रिन हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string>
-    <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"यसले स्क्रिनमा देखिने सबै सामग्री पढ्न सक्छ र अन्य अनुप्रयोगहरूमा उक्त सामग्री देखाउन सक्छ।"</string>
+    <string name="accessibility_service_screen_control_description" msgid="6946315917771791525">"यसले स्क्रिनमा देखिने सबै सामग्री पढ्न सक्छ र अन्य एपहरूमा उक्त सामग्री देखाउन सक्छ।"</string>
     <string name="accessibility_service_action_perform_title" msgid="779670378951658160">"कारबाहीहरू हेर्नुहोस् र तिनमा कार्य गर्नुहोस्"</string>
     <string name="accessibility_service_action_perform_description" msgid="2718852014003170558">"यसले कुनै एप वा हार्डवेयर सेन्सरसँग तपाईंले गर्ने अन्तर्क्रियाको ट्र्याक गर्न सक्छ र तपाईंका तर्फबाट एपहरूसँग अन्तर्क्रिया गर्न सक्छ।"</string>
     <string name="accessibility_dialog_button_allow" msgid="2092558122987144530">"अनुमति दिनुहोस्"</string>
@@ -1982,7 +1982,7 @@
     <string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"SIM <xliff:g id="SIMNUMBER">%d</xliff:g> लाई अनुमति छैन"</string>
     <string name="popup_window_default_title" msgid="6907717596694826919">"पपअप विन्डो"</string>
     <string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
-    <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"या त अनुप्रयोगको संस्करण स्तरह्रास गरियो वा यो यस सर्टकटसँग मिल्दो छैन"</string>
+    <string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"या त एपको संस्करण स्तरह्रास गरियो वा यो यस सर्टकटसँग मिल्दो छैन"</string>
     <string name="shortcut_restore_not_supported" msgid="4763198938588468400">"अनुप्रयोगले ब्याकअप तथा पुनर्स्थापनालाई समर्थन नगर्ने हुँदा सर्टकट पुनर्स्थापित गर्न सकिएन"</string>
     <string name="shortcut_restore_signature_mismatch" msgid="579345304221605479">"अनुप्रयोगमा प्रयोग गरिने हस्ताक्षर नमिल्ने हुँदा सर्टकट पुनर्स्थापित गर्न सकिएन"</string>
     <string name="shortcut_restore_unknown_issue" msgid="2478146134395982154">"सर्टकट पुनर्स्थापित गर्न सकिएन"</string>
@@ -2004,7 +2004,7 @@
     <string name="notification_app_name_settings" msgid="9088548800899952531">"सेटिङहरू"</string>
     <string name="notification_appops_camera_active" msgid="8177643089272352083">"क्यामेरा"</string>
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"माइक्रोफोन"</string>
-    <string name="notification_appops_overlay_active" msgid="5571732753262836481">"तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमा प्रदर्शन गरिँदै छ"</string>
+    <string name="notification_appops_overlay_active" msgid="5571732753262836481">"तपाईंको स्क्रिनका अन्य एपहरूमा प्रदर्शन गरिँदै छ"</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"दिनचर्या मोडको जानकारीमूलक सूचना"</string>
     <string name="dynamic_mode_notification_title" msgid="9205715501274608016">"प्रायः चार्ज गर्ने समय हुनुभन्दा पहिले नै ब्याट्री सकिन सक्छ"</string>
     <string name="dynamic_mode_notification_summary" msgid="4141614604437372157">"ब्याट्रीको आयु बढाउन ब्याट्री सेभर सक्रिय गरियो"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 76864e9..3db4133 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1159,7 +1159,7 @@
     <string name="aerr_application_repeated" msgid="7804378743218496566">"<xliff:g id="APPLICATION">%1$s</xliff:g> continua a falhar"</string>
     <string name="aerr_process_repeated" msgid="1153152413537954974">"<xliff:g id="PROCESS">%1$s</xliff:g> continua a falhar"</string>
     <string name="aerr_restart" msgid="2789618625210505419">"Abrir app novamente"</string>
-    <string name="aerr_report" msgid="3095644466849299308">"Enviar comentários"</string>
+    <string name="aerr_report" msgid="3095644466849299308">"Enviar feedback"</string>
     <string name="aerr_close" msgid="3398336821267021852">"Fechar"</string>
     <string name="aerr_mute" msgid="2304972923480211376">"Desativar som até o dispositivo reiniciar"</string>
     <string name="aerr_wait" msgid="3198677780474548217">"Aguardar"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index d51c36f..492a83e 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1705,7 +1705,7 @@
     <string name="accessibility_button_instructional_text" msgid="8853928358872550500">"Funkcie prepnete pridržaním tlačidla dostupnosti."</string>
     <string name="accessibility_gesture_instructional_text" msgid="9196230728837090497">"Funkcie prepnete potiahnutím dvoma prstami nahor a pridržaním."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="3425123684990193765">"Funkcie prepnete potiahnutím troma prstami nahor a pridržaním."</string>
-    <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Priblíženie"</string>
+    <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zväčšenie"</string>
     <string name="user_switched" msgid="7249833311585228097">"Aktuálny používateľ je <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Prebieha odhlásenie používateľa <xliff:g id="NAME">%1$s</xliff:g>…"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 31346ea..b083cb8 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -2087,7 +2087,7 @@
     <string name="conversation_title_fallback_group_chat" msgid="456073374993104303">"Групна конверзација"</string>
     <string name="unread_convo_overflow" msgid="920517615597353833">"<xliff:g id="MAX_UNREAD_COUNT">%1$d</xliff:g>+"</string>
     <string name="resolver_personal_tab" msgid="2051260504014442073">"Лично"</string>
-    <string name="resolver_work_tab" msgid="2690019516263167035">"Пословни"</string>
+    <string name="resolver_work_tab" msgid="2690019516263167035">"Пословно"</string>
     <string name="resolver_personal_tab_accessibility" msgid="5739524949153091224">"Лични приказ"</string>
     <string name="resolver_work_tab_accessibility" msgid="4753168230363802734">"Приказ за посао"</string>
     <string name="resolver_cant_share_with_work_apps" msgid="637686613606502219">"Не можете да делите овај садржај помоћу апликација за посао"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 7135749..327d338 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1230,7 +1230,7 @@
     <string name="volume_icon_description_media" msgid="4997633254078171233">"మీడియా వాల్యూమ్"</string>
     <string name="volume_icon_description_notification" msgid="579091344110747279">"నోటిఫికేషన్ వాల్యూమ్"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"డిఫాల్ట్ రింగ్‌టోన్"</string>
-    <string name="ringtone_default_with_actual" msgid="2709686194556159773">"డిఫాల్ట్ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+    <string name="ringtone_default_with_actual" msgid="2709686194556159773">"ఆటోమేటిక్ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="397111123930141876">"ఏదీ వద్దు"</string>
     <string name="ringtone_picker_title" msgid="667342618626068253">"రింగ్‌టోన్‌లు"</string>
     <string name="ringtone_picker_title_alarm" msgid="7438934548339024767">"అలారం ధ్వనులు"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index f817696..087c8dd 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -857,7 +857,7 @@
     <string name="lockscreen_transport_stop_description" msgid="1449552232598355348">"Зупинити"</string>
     <string name="lockscreen_transport_rew_description" msgid="7680106856221622779">"Перемотати назад"</string>
     <string name="lockscreen_transport_ffw_description" msgid="4763794746640196772">"Перемотати вперед"</string>
-    <string name="emergency_calls_only" msgid="3057351206678279851">"Лише аварійні виклики"</string>
+    <string name="emergency_calls_only" msgid="3057351206678279851">"Лише екстрені виклики"</string>
     <string name="lockscreen_network_locked_message" msgid="2814046965899249635">"Мережу заблок."</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="6618356415831082174">"SIM-карту заблоковано PUK."</string>
     <string name="lockscreen_sim_puk_locked_instructions" msgid="5307979043730860995">"Перегляньте посібник користувача чи зверніться до служби підтримки."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b92bbd6..8a4676d 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -9230,4 +9230,7 @@
     </declare-styleable>
 
     <attr name="autoSizePresetSizes" />
+
+    <attr name="iconfactoryIconSize" format="dimension"/>
+    <attr name="iconfactoryBadgeSize" format="dimension"/>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 2ac61ec..c7ad5da 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -810,7 +810,8 @@
     <dimen name="chooser_header_scroll_elevation">4dp</dimen>
     <dimen name="chooser_max_collapsed_height">288dp</dimen>
     <dimen name="chooser_direct_share_label_placeholder_max_width">72dp</dimen>
-    <dimen name="chooser_icon_size">42dp</dimen>
+    <dimen name="chooser_icon_size">56dp</dimen>
+    <dimen name="chooser_badge_size">22dp</dimen>
     <dimen name="resolver_icon_size">32dp</dimen>
     <dimen name="resolver_button_bar_spacing">8dp</dimen>
     <dimen name="resolver_badge_size">18dp</dimen>
diff --git a/core/res/res/values/dimens_car.xml b/core/res/res/values/dimens_car.xml
index bd4c484..2c4f4c8 100644
--- a/core/res/res/values/dimens_car.xml
+++ b/core/res/res/values/dimens_car.xml
@@ -16,14 +16,7 @@
 */
 -->
 <resources>
-    <dimen name="car_fullscreen_user_pod_icon_text_size">64sp</dimen>
-    <dimen name="car_fullscreen_user_pod_width">243dp</dimen>
-    <dimen name="car_fullscreen_user_pod_height">356dp</dimen>
-    <dimen name="car_fullscreen_user_pod_image_avatar_width">96dp</dimen>
-    <dimen name="car_fullscreen_user_pod_image_avatar_height">96dp</dimen>
     <dimen name="car_large_avatar_size">96dp</dimen>
-
-
     <!-- Application Bar -->
     <dimen name="car_app_bar_height">80dp</dimen>
     <!-- Margin -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f3f3d47d..54d14f8 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1475,7 +1475,7 @@
     <string name="permdesc_mediaLocation">Allows the app to read locations from your media collection.</string>
 
     <!-- Title shown when the system-provided biometric dialog is shown, asking the user to authenticate. [CHAR LIMIT=40] -->
-    <string name="biometric_dialog_default_title">Verify it\u2018s you</string>
+    <string name="biometric_dialog_default_title">Verify it\u2019s you</string>
     <!-- Message shown when biometric hardware is not available [CHAR LIMIT=50] -->
     <string name="biometric_error_hw_unavailable">Biometric hardware unavailable</string>
     <!-- Message shown when biometric authentication was canceled by the user [CHAR LIMIT=50] -->
@@ -3595,31 +3595,37 @@
 
     <!-- Notification body when new external media is detected [CHAR LIMIT=30] -->
     <string name="ext_media_new_notification_title">New <xliff:g id="name" example="SD card">%s</xliff:g></string>
+    <!-- Automotive specific notification body when new external media is detected [CHAR LIMIT=30] -->
+    <string name="ext_media_new_notification_title" product="automotive"><xliff:g id="name" example="SD card">%s</xliff:g> isn\u2019t working</string>
     <!-- Notification body when new external media is detected [CHAR LIMIT=NONE] -->
     <string name="ext_media_new_notification_message">Tap to set up</string>
-    <!-- Automotive specific notification body when new external media is detected. Empty because there is no fix action (b/151671685) [CHAR LIMIT=NONE] -->
-    <string name="ext_media_new_notification_message" product="automotive"></string>
+    <!-- Automotive specific notification body when new external media is detected. [CHAR LIMIT=NONE] -->
+    <string name="ext_media_new_notification_message" product="automotive">You may need to reformat the device. Tap to eject.</string>
 
     <!-- Notification body when external media is ready for use [CHAR LIMIT=NONE] -->
     <string name="ext_media_ready_notification_message">For transferring photos and media</string>
 
     <!-- Notification title when external media is unmountable (corrupt) [CHAR LIMIT=30] -->
     <string name="ext_media_unmountable_notification_title">Issue with <xliff:g id="name" example="SD card">%s</xliff:g></string>
+    <!-- Automotive specific notification title when external media is unmountable (corrupt) [CHAR LIMIT=30] -->
+    <string name="ext_media_unmountable_notification_title" product="automotive"><xliff:g id="name" example="SD card">%s</xliff:g> isn\u2019t working</string>
     <!-- Notification body when external media is unmountable (corrupt) [CHAR LIMIT=NONE] -->
     <string name="ext_media_unmountable_notification_message">Tap to fix</string>
     <!-- TV-specific notification body when external media is unmountable (corrupt) [CHAR LIMIT=NONE] -->
     <string name="ext_media_unmountable_notification_message" product="tv"><xliff:g id="name" example="SD card">%s</xliff:g> is corrupt. Select to fix.</string>
-    <!-- Automotive specific notification body when external media is unmountable (corrupt). Empty because there is no fix action (b/151671685) [CHAR LIMIT=NONE] -->
-    <string name="ext_media_unmountable_notification_message" product="automotive"></string>
+    <!-- Automotive specific notification body when external media is unmountable (corrupt) [CHAR LIMIT=NONE] -->
+    <string name="ext_media_unmountable_notification_message" product="automotive">You may need to reformat the device. Tap to eject.</string>
 
     <!-- Notification title when external media is unsupported [CHAR LIMIT=30] -->
     <string name="ext_media_unsupported_notification_title">Unsupported <xliff:g id="name" example="SD card">%s</xliff:g></string>
+    <!-- Automotive specific notification title when external media is unsupported [CHAR LIMIT=30] -->
+    <string name="ext_media_unsupported_notification_title" product="automotive"><xliff:g id="name" example="SD card">%s</xliff:g> isn\u2019t working</string>
     <!-- Notification body when external media is unsupported [CHAR LIMIT=NONE] -->
     <string name="ext_media_unsupported_notification_message">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Tap to set up in a supported format.</string>
     <!-- TV-specific notification body when external media is unsupported [CHAR LIMIT=NONE] -->
     <string name="ext_media_unsupported_notification_message" product="tv">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Select to set up in a supported format.</string>
-    <!-- Automotive specific notification body when external media is unsupported. No action is specified to fix (b/151671685) [CHAR LIMIT=NONE] -->
-    <string name="ext_media_unsupported_notification_message" product="automotive">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>.</string>
+    <!-- Automotive specific notification body when external media is unsupported [CHAR LIMIT=NONE] -->
+    <string name="ext_media_unsupported_notification_message" product="automotive">You may need to reformat the device</string>
 
     <!-- Notification title when external media is unsafely removed [CHAR LIMIT=30] -->
     <string name="ext_media_badremoval_notification_title"><xliff:g id="name" example="SD card">%s</xliff:g> unexpectedly removed</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 369a3e5..8347a24 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2534,6 +2534,7 @@
   <java-symbol type="style" name="TextAppearance.Material.TimePicker.TimeLabel" />
   <java-symbol type="attr" name="seekBarPreferenceStyle" />
   <java-symbol type="style" name="Theme.DeviceDefault.Resolver" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Chooser" />
   <java-symbol type="style" name="Theme.DeviceDefault.System" />
   <java-symbol type="attr" name="preferenceActivityStyle" />
   <java-symbol type="attr" name="preferenceFragmentStyle" />
@@ -2744,6 +2745,8 @@
   <java-symbol type="id" name="chooser_row_text_option" />
   <java-symbol type="dimen" name="chooser_row_text_option_translate" />
   <java-symbol type="dimen" name="chooser_preview_image_max_dimen"/>
+  <java-symbol type="drawable" name="ic_chooser_group_arrow"/>
+  <java-symbol type="drawable" name="chooser_group_background"/>
   <java-symbol type="integer" name="config_maxShortcutTargetsPerApp" />
   <java-symbol type="layout" name="resolve_grid_item" />
   <java-symbol type="id" name="day_picker_view_pager" />
@@ -3638,13 +3641,6 @@
   <java-symbol type="color" name="car_card_dark" />
   <java-symbol type="dimen" name="car_body1_size" />
   <java-symbol type="dimen" name="car_padding_4" />
-  <java-symbol type="dimen" name="car_fullscreen_user_pod_icon_text_size" />
-  <java-symbol type="dimen" name="car_fullscreen_user_pod_image_avatar_height" />
-  <java-symbol type="dimen" name="car_fullscreen_user_pod_image_avatar_width" />
-  <java-symbol type="dimen" name="car_large_avatar_size" />
-  <java-symbol type="layout" name="car_user_switching_dialog" />
-  <java-symbol type="id" name="user_loading_avatar" />
-  <java-symbol type="id" name="user_loading" />
   <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" />
 
   <java-symbol type="string" name="battery_saver_description_with_learn_more" />
@@ -3784,8 +3780,11 @@
   <!-- For Auto-Brightness -->
   <java-symbol type="string" name="config_displayLightSensorType" />
 
-  <java-symbol type="drawable" name="iconfactory_adaptive_icon_drawable_wrapper"/>
   <java-symbol type="dimen" name="notification_min_height" />
+
+  <java-symbol type="drawable" name="iconfactory_adaptive_icon_drawable_wrapper"/>
+  <java-symbol type="attr" name="iconfactoryIconSize"/>
+  <java-symbol type="attr" name="iconfactoryBadgeSize"/>
   <java-symbol type="dimen" name="resolver_icon_size"/>
   <java-symbol type="dimen" name="resolver_badge_size"/>
   <java-symbol type="dimen" name="resolver_button_bar_spacing"/>
@@ -3794,6 +3793,7 @@
   <java-symbol type="dimen" name="resolver_edge_margin"/>
   <java-symbol type="dimen" name="resolver_elevation"/>
   <java-symbol type="dimen" name="chooser_icon_size"/>
+  <java-symbol type="dimen" name="chooser_badge_size"/>
 
   <!-- For DropBox -->
   <java-symbol type="integer" name="config_dropboxLowPriorityBroadcastRateLimitPeriod" />
@@ -4019,4 +4019,5 @@
   <java-symbol type="string" name="config_pdp_reject_user_authentication_failed" />
   <java-symbol type="string" name="config_pdp_reject_service_not_subscribed" />
   <java-symbol type="string" name="config_pdp_reject_multi_conn_to_same_pdn_not_allowed" />
+
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 81ec278..1afaf4f 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1680,6 +1680,8 @@
         <item name="listPreferredItemPaddingEnd">?attr/dialogPreferredPadding</item>
         <item name="navigationBarColor">@android:color/transparent</item>
         <item name="tabWidgetStyle">@style/Widget.DeviceDefault.Resolver.TabWidget</item>
+        <item name="iconfactoryIconSize">@dimen/resolver_icon_size</item>
+        <item name="iconfactoryBadgeSize">@dimen/resolver_badge_size</item>
     </style>
 
     <style name="Widget.DeviceDefault.Resolver.TabWidget" parent="Widget.DeviceDefault.TabWidget">
@@ -1694,6 +1696,11 @@
         <item name="windowLightNavigationBar">true</item>
     </style>
 
+    <style name="Theme.DeviceDefault.Chooser" parent="Theme.DeviceDefault.Resolver">
+        <item name="iconfactoryIconSize">@dimen/chooser_icon_size</item>
+        <item name="iconfactoryBadgeSize">@dimen/chooser_badge_size</item>
+    </style>
+
     <style name="Animation.DeviceDefault.Activity.Resolver" parent="Animation.DeviceDefault.Activity">
         <item name="activityOpenEnterAnimation">@anim/resolver_launch_anim</item>
         <item name="taskOpenEnterAnimation">@anim/resolver_launch_anim</item>
diff --git a/core/tests/coretests/src/android/debug/AdbNotificationsTest.java b/core/tests/coretests/src/android/debug/AdbNotificationsTest.java
index 6c187ea..3496e2c 100644
--- a/core/tests/coretests/src/android/debug/AdbNotificationsTest.java
+++ b/core/tests/coretests/src/android/debug/AdbNotificationsTest.java
@@ -56,8 +56,11 @@
         // Verify that the adb notification for usb connections has the correct text.
         assertEquals(title, notification.extras.getCharSequence(Notification.EXTRA_TITLE, ""));
         assertEquals(message, notification.extras.getCharSequence(Notification.EXTRA_TEXT, ""));
-        // Verify the PendingIntent has an explicit intent (b/153356209).
-        assertFalse(TextUtils.isEmpty(notification.contentIntent.getIntent().getPackage()));
+        // Verify the PendingIntent has an explicit intent (b/153356209), if there is a
+        // PendingIntent attached.
+        if (notification.contentIntent != null) {
+            assertFalse(TextUtils.isEmpty(notification.contentIntent.getIntent().getPackage()));
+        }
     }
 
     @Test
@@ -73,7 +76,10 @@
         // Verify that the adb notification for usb connections has the correct text.
         assertEquals(title, notification.extras.getCharSequence(Notification.EXTRA_TITLE, ""));
         assertEquals(message, notification.extras.getCharSequence(Notification.EXTRA_TEXT, ""));
-        // Verify the PendingIntent has an explicit intent (b/153356209).
-        assertFalse(TextUtils.isEmpty(notification.contentIntent.getIntent().getPackage()));
+        // Verify the PendingIntent has an explicit intent (b/153356209), if there is a
+        // PendingIntent attached.
+        if (notification.contentIntent != null) {
+            assertFalse(TextUtils.isEmpty(notification.contentIntent.getIntent().getPackage()));
+        }
     }
 }
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 5f12bf0..8eca650 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -26,11 +26,8 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -98,8 +95,6 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        doNothing().when(mMockController).updateCompatSysUiVisibility(
-                anyInt(), anyBoolean(), anyBoolean());
         mTopLeash = new SurfaceControl.Builder(mSession)
                 .setName("testSurface")
                 .build();
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index ecc3b4f..5c16772 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -28,29 +28,23 @@
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
 
-import static org.hamcrest.Matchers.equalTo;
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assume.assumeTrue;
+import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
-import android.graphics.Insets;
-import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.view.WindowInsets.Side;
 import android.view.WindowInsets.Type;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
-import androidx.test.platform.app.InstrumentationRegistry;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
 /**
  * Tests for {@link ViewRootImpl}
  *
@@ -62,59 +56,18 @@
 @RunWith(AndroidJUnit4.class)
 public class ViewRootImplTest {
 
-    private Context mContext;
-    private ViewRootImplAccessor mViewRootImpl;
+    private ViewRootImpl mViewRootImpl;
 
     @Before
     public void setUp() throws Exception {
-        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        final Context context = getInstrumentation().getTargetContext();
 
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
-            mViewRootImpl = new ViewRootImplAccessor(
-                    new ViewRootImpl(mContext, mContext.getDisplayNoVerify()));
-        });
-    }
-
-    @Test
-    public void negativeInsets_areSetToZero() throws Exception {
-        assumeTrue(ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL);
-
-        mViewRootImpl.getAttachInfo().getContentInsets().set(-10, -20, -30 , -40);
-        mViewRootImpl.getAttachInfo().getStableInsets().set(-10, -20, -30 , -40);
-        final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
-
-        assertThat(insets.getSystemWindowInsets(), equalTo(Insets.NONE));
-        assertThat(insets.getStableInsets(), equalTo(Insets.NONE));
-    }
-
-    @Test
-    public void negativeInsets_areSetToZero_positiveAreLeftAsIs() throws Exception {
-        assumeTrue(ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL);
-
-        mViewRootImpl.getAttachInfo().getContentInsets().set(-10, 20, -30 , 40);
-        mViewRootImpl.getAttachInfo().getStableInsets().set(10, -20, 30 , -40);
-        final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
-
-        assertThat(insets.getSystemWindowInsets(), equalTo(Insets.of(0, 20, 0, 40)));
-        assertThat(insets.getStableInsets(), equalTo(Insets.of(10, 0, 30, 0)));
-    }
-
-    @Test
-    public void positiveInsets_areLeftAsIs() throws Exception {
-        assumeTrue(ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL);
-
-        mViewRootImpl.getAttachInfo().getContentInsets().set(10, 20, 30 , 40);
-        mViewRootImpl.getAttachInfo().getStableInsets().set(10, 20, 30 , 40);
-        final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
-
-        assertThat(insets.getSystemWindowInsets(), equalTo(Insets.of(10, 20, 30, 40)));
-        assertThat(insets.getStableInsets(), equalTo(Insets.of(10, 20, 30, 40)));
+        getInstrumentation().runOnMainSync(() ->
+                mViewRootImpl = new ViewRootImpl(context, context.getDisplayNoVerify()));
     }
 
     @Test
     public void adjustLayoutParamsForCompatibility_layoutFullscreen() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
         ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
@@ -125,8 +78,6 @@
 
     @Test
     public void adjustLayoutParamsForCompatibility_layoutInScreen() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.flags = FLAG_LAYOUT_IN_SCREEN;
         ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
@@ -137,8 +88,6 @@
 
     @Test
     public void adjustLayoutParamsForCompatibility_layoutHideNavigation() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
         ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
@@ -149,28 +98,22 @@
 
     @Test
     public void adjustLayoutParamsForCompatibility_toast() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_TOAST);
         ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
 
-        assertEquals(true, attrs.isFitInsetsIgnoringVisibility());
+        assertTrue(attrs.isFitInsetsIgnoringVisibility());
     }
 
     @Test
     public void adjustLayoutParamsForCompatibility_systemAlert() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_SYSTEM_ALERT);
         ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
 
-        assertEquals(true, attrs.isFitInsetsIgnoringVisibility());
+        assertTrue(attrs.isFitInsetsIgnoringVisibility());
     }
 
     @Test
     public void adjustLayoutParamsForCompatibility_fitSystemBars() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
 
@@ -180,8 +123,6 @@
 
     @Test
     public void adjustLayoutParamsForCompatibility_noAdjustLayout() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         final int types = Type.all();
         final int sides = Side.TOP | Side.LEFT;
@@ -201,11 +142,8 @@
 
     @Test
     public void adjustLayoutParamsForCompatibility_noAdjustAppearance() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
-        final ViewRootImpl viewRoot = mViewRootImpl.get();
-        final WindowInsetsController controller = viewRoot.getInsetsController();
-        final WindowManager.LayoutParams attrs = viewRoot.mWindowAttributes;
+        final WindowInsetsController controller = mViewRootImpl.getInsetsController();
+        final WindowManager.LayoutParams attrs = mViewRootImpl.mWindowAttributes;
         final int appearance = 0;
         controller.setSystemBarsAppearance(appearance, 0xffffffff);
         attrs.systemUiVisibility = SYSTEM_UI_FLAG_LOW_PROFILE
@@ -220,11 +158,8 @@
 
     @Test
     public void adjustLayoutParamsForCompatibility_noAdjustBehavior() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
-        final ViewRootImpl viewRoot = mViewRootImpl.get();
-        final WindowInsetsController controller = viewRoot.getInsetsController();
-        final WindowManager.LayoutParams attrs = viewRoot.mWindowAttributes;
+        final WindowInsetsController controller = mViewRootImpl.getInsetsController();
+        final WindowManager.LayoutParams attrs = mViewRootImpl.mWindowAttributes;
         final int behavior = BEHAVIOR_SHOW_BARS_BY_TOUCH;
         controller.setSystemBarsBehavior(behavior);
         attrs.systemUiVisibility = SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
@@ -234,59 +169,4 @@
         // setSystemBarsBehavior.
         assertEquals(behavior, controller.getSystemBarsBehavior());
     }
-
-    private static class ViewRootImplAccessor {
-
-        private final ViewRootImpl mViewRootImpl;
-
-        ViewRootImplAccessor(ViewRootImpl viewRootImpl) {
-            mViewRootImpl = viewRootImpl;
-        }
-
-        public ViewRootImpl get() {
-            return mViewRootImpl;
-        }
-
-        AttachInfoAccessor getAttachInfo() throws Exception {
-            return new AttachInfoAccessor(
-                    getField(mViewRootImpl, ViewRootImpl.class.getDeclaredField("mAttachInfo")));
-        }
-
-        WindowInsets getWindowInsets(boolean forceConstruct) throws Exception {
-            return (WindowInsets) invokeMethod(mViewRootImpl,
-                    ViewRootImpl.class.getDeclaredMethod("getWindowInsets", boolean.class),
-                    forceConstruct);
-        }
-
-        class AttachInfoAccessor {
-
-            private final Class<?> mClass;
-            private final Object mAttachInfo;
-
-            AttachInfoAccessor(Object attachInfo) throws Exception {
-                mAttachInfo = attachInfo;
-                mClass = ViewRootImpl.class.getClassLoader().loadClass(
-                        "android.view.View$AttachInfo");
-            }
-
-            Rect getContentInsets() throws Exception {
-                return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mContentInsets"));
-            }
-
-            Rect getStableInsets() throws Exception {
-                return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mStableInsets"));
-            }
-        }
-
-        private static Object getField(Object o, Field field) throws Exception {
-            field.setAccessible(true);
-            return field.get(o);
-        }
-
-        private static Object invokeMethod(Object o, Method method, Object... args)
-                throws Exception {
-            method.setAccessible(true);
-            return method.invoke(o, args);
-        }
-    }
 }
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 e23a3ca..dcecb5f 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -294,6 +294,60 @@
     }
 
     @Test
+    public void fourOptionsStackedIntoOneTarget() throws InterruptedException {
+        Intent sendIntent = createSendTextIntent();
+
+        // create 12 unique app targets to ensure the app ranking row can be filled, otherwise
+        // targets will not stack
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(12);
+
+        // next create 4 targets in a single app that should be stacked into a single target
+        String packageName = "xxx.yyy";
+        String appName = "aaa";
+        ComponentName cn = new ComponentName(packageName, appName);
+        Intent intent = new Intent("fakeIntent");
+        List<ResolvedComponentInfo> infosToStack = new ArrayList<>();
+        for (int i = 0; i < 4; i++) {
+            ResolveInfo resolveInfo = ResolverDataProvider.createResolveInfo(i,
+                    UserHandle.USER_CURRENT);
+            resolveInfo.activityInfo.applicationInfo.name = appName;
+            resolveInfo.activityInfo.applicationInfo.packageName = packageName;
+            resolveInfo.activityInfo.packageName = packageName;
+            resolveInfo.activityInfo.name = "ccc" + i;
+            infosToStack.add(new ResolvedComponentInfo(cn, intent, resolveInfo));
+        }
+        resolvedComponentInfos.addAll(infosToStack);
+
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+
+        final ChooserWrapperActivity activity = mActivityRule
+                .launchActivity(Intent.createChooser(sendIntent, null));
+        waitForIdle();
+
+        // expect 12 unique targets + 1 group + 4 ranked app targets
+        assertThat(activity.getAdapter().getCount(), is(17));
+
+        ResolveInfo[] chosen = new ResolveInfo[1];
+        sOverrides.onSafelyStartCallback = targetInfo -> {
+            chosen[0] = targetInfo.getResolveInfo();
+            return true;
+        };
+
+        onView(withText(appName)).perform(click());
+        waitForIdle();
+
+        // clicking will launch a dialog to choose the activity within the app
+        onView(withText(appName)).check(matches(isDisplayed()));
+        int i = 0;
+        for (ResolvedComponentInfo rci: infosToStack) {
+            onView(withText("ccc" + i)).check(matches(isDisplayed()));
+            ++i;
+        }
+    }
+
+    @Test
     public void updateChooserCountsAndModelAfterUserSelection() throws InterruptedException {
         Intent sendIntent = createSendTextIntent();
         List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -1872,6 +1926,33 @@
                 .check(matches(isDisplayed()));
     }
 
+    @Test
+    public void testDeduplicateCallerTargetRankedTarget() {
+        // Create 4 ranked app targets.
+        List<ResolvedComponentInfo> personalResolvedComponentInfos =
+                createResolvedComponentsForTest(4);
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class)))
+                .thenReturn(new ArrayList<>(personalResolvedComponentInfos));
+        // Create caller target which is duplicate with one of app targets
+        Intent chooserIntent = createChooserIntent(createSendTextIntent(),
+                new Intent[] {new Intent("action.fake")});
+        sOverrides.packageManager = mock(PackageManager.class);
+        ResolveInfo ri = ResolverDataProvider.createResolveInfo(0,
+                UserHandle.USER_CURRENT);
+        when(sOverrides.packageManager.resolveActivity(any(Intent.class), anyInt())).thenReturn(ri);
+        waitForIdle();
+
+        ChooserWrapperActivity activity = mActivityRule.launchActivity(chooserIntent);
+        waitForIdle();
+
+        // Total 4 targets (1 caller target, 3 ranked targets)
+        assertThat(activity.getAdapter().getCount(), is(4));
+        assertThat(activity.getAdapter().getCallerTargetCount(), is(1));
+        assertThat(activity.getAdapter().getRankedTargetCount(), is(3));
+    }
+
     private Intent createChooserIntent(Intent intent, Intent[] initialIntents) {
         Intent chooserIntent = new Intent();
         chooserIntent.setAction(Intent.ACTION_CHOOSER);
diff --git a/core/tests/overlaytests/host/Android.bp b/core/tests/overlaytests/host/Android.bp
index 2b38cca..a2fcef5 100644
--- a/core/tests/overlaytests/host/Android.bp
+++ b/core/tests/overlaytests/host/Android.bp
@@ -16,7 +16,7 @@
     name: "OverlayHostTests",
     srcs: ["src/**/*.java"],
     libs: ["tradefed"],
-    test_suites: ["device-tests"],
+    test_suites: ["general-tests"],
     target_required: [
         "OverlayHostTests_NonPlatformSignatureOverlay",
         "OverlayHostTests_PlatformSignatureStaticOverlay",
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 0389639..bdb6bcc 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -324,6 +324,7 @@
         <permission name="android.permission.MANAGE_ROLLBACKS"/>
         <permission name="android.permission.MANAGE_USB"/>
         <permission name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/>
+        <permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
         <permission name="android.permission.MODIFY_PHONE_STATE"/>
         <permission name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/>
         <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
diff --git a/data/keyboards/Vendor_28de_Product_1102.kl b/data/keyboards/Vendor_28de_Product_1102.kl
new file mode 100644
index 0000000..150a17a
--- /dev/null
+++ b/data/keyboards/Vendor_28de_Product_1102.kl
@@ -0,0 +1,74 @@
+# 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.
+
+#
+# Steam Controller - Model 1001 - USB
+#
+
+# Mapping according to https://developer.android.com/training/game-controllers/controller-input.html
+
+key 304   BUTTON_A
+key 305   BUTTON_B
+key 307   BUTTON_X
+key 308   BUTTON_Y
+
+key 310   BUTTON_L1
+key 311   BUTTON_R1
+key 312   BUTTON_L2
+key 313   BUTTON_R2
+
+# Triggers.
+axis 0x15 LTRIGGER
+axis 0x14 RTRIGGER
+
+# Left and right stick.
+axis 0x00 X
+axis 0x01 Y
+
+# Right stick / mousepad
+axis 0x03 Z
+axis 0x04 RZ
+
+key 317   BUTTON_THUMBL
+key 318   BUTTON_THUMBR
+
+# Hat.
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+# Dpad (clicks)
+key 544 DPAD_UP
+key 545 DPAD_DOWN
+key 546 DPAD_LEFT
+key 547 DPAD_RIGHT
+
+# Touching the dpad (light touch without pressing down)
+key 289 BUTTON_1
+# Touching the "right stick" / mousepad (light touch without pressing down)
+key 290 BUTTON_2
+
+# Pressing the large paddle on the back, left (linux BTN_WHEEL / BTN_GEAR_DOWN)
+key 336 BUTTON_3
+# Pressing the large paddle on the back, right (linux BTN_GEAR_UP)
+key 337 BUTTON_4
+
+
+# Mapping according to https://www.kernel.org/doc/Documentation/input/gamepad.txt
+# Left arrow
+key 314   BUTTON_SELECT
+# Right arrow
+key 315   BUTTON_START
+
+# Steam key
+key 316   BUTTON_MODE
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionHelper.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionHelper.java
index c4f11a0..c61f1ed 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionHelper.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/ExtensionHelper.java
@@ -30,6 +30,8 @@
 import android.view.DisplayInfo;
 import android.view.Surface;
 
+import androidx.annotation.Nullable;
+
 /**
  * Toolkit class for calculation of the display feature bounds within the window.
  * NOTE: This sample implementation only works for Activity windows, because there is no public APIs
@@ -84,7 +86,7 @@
 
     /** Transform rectangle from absolute coordinate space to the window coordinate space. */
     static void transformToWindowSpaceRect(Rect inOutRect, IBinder windowToken) {
-        Rect windowRect = getWindowRect(windowToken);
+        Rect windowRect = getWindowBounds(windowToken);
         if (windowRect == null) {
             inOutRect.setEmpty();
             return;
@@ -101,13 +103,12 @@
      * Get the current window bounds in absolute coordinates.
      * NOTE: Only works with Activity windows.
      */
-    private static Rect getWindowRect(IBinder windowToken) {
+    @Nullable
+    private static Rect getWindowBounds(IBinder windowToken) {
         Activity activity = ActivityThread.currentActivityThread().getActivity(windowToken);
-        final Rect windowRect = new Rect();
-        if (activity != null) {
-            activity.getWindow().getDecorView().getWindowDisplayFrame(windowRect);
-        }
-        return windowRect;
+        return activity != null
+                ? activity.getWindowManager().getCurrentWindowMetrics().getBounds()
+                : null;
     }
 
     /**
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index 98c2d7f..357c333 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -16,6 +16,7 @@
 package android.media;
 
 import android.util.IntArray;
+
 import com.android.server.LocalServices;
 
 /**
@@ -48,6 +49,18 @@
 
     public abstract void setAccessibilityServiceUids(IntArray uids);
 
+    /**
+     * Called by {@link com.android.server.inputmethod.InputMethodManagerService} to notify the UID
+     * of the currently used {@link android.inputmethodservice.InputMethodService}.
+     *
+     * <p>The caller is expected to take care of any performance implications, e.g. by using a
+     * background thread to call this method.</p>
+     *
+     * @param uid UID of the currently used {@link android.inputmethodservice.InputMethodService}.
+     *            {@link android.os.Process#INVALID_UID} if no IME is active.
+     */
+    public abstract void setInputMethodServiceUid(int uid);
+
     public interface RingerModeDelegate {
         /** Called when external ringer mode is evaluated, returns the new internal ringer mode */
         int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
diff --git a/packages/CarSystemUI/AndroidManifest.xml b/packages/CarSystemUI/AndroidManifest.xml
index 261b9f5..1dd0291 100644
--- a/packages/CarSystemUI/AndroidManifest.xml
+++ b/packages/CarSystemUI/AndroidManifest.xml
@@ -25,4 +25,6 @@
     <uses-permission android:name="android.car.permission.CAR_ENROLL_TRUST"/>
     <!-- This permission is required to get bluetooth broadcast. -->
     <uses-permission android:name="android.permission.BLUETOOTH" />
+    <!-- This permission is required to check the foreground user id. -->
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
 </manifest>
diff --git a/packages/CarSystemUI/res/layout/car_user_switching_dialog.xml b/packages/CarSystemUI/res/layout/car_user_switching_dialog.xml
new file mode 100644
index 0000000..0a29424
--- /dev/null
+++ b/packages/CarSystemUI/res/layout/car_user_switching_dialog.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fitsSystemWindows="true"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:background="@color/car_user_switching_dialog_background_color">
+  <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="vertical"
+      android:layout_gravity="center"
+      android:gravity="center_horizontal">
+    <ImageView
+        android:id="@+id/user_loading_avatar"
+        android:layout_width="@dimen/car_fullscreen_user_pod_image_avatar_width"
+        android:layout_height="@dimen/car_fullscreen_user_pod_image_avatar_height"/>
+
+    <TextView
+        android:id="@+id/user_loading"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="@dimen/car_user_switching_dialog_loading_text_margin_top"
+        android:textSize="@dimen/car_user_switching_dialog_loading_text_font_size"
+        android:textColor="@color/car_user_switching_dialog_loading_text_color"
+        android:layout_below="@id/user_loading_avatar"/>
+  </LinearLayout>
+</FrameLayout>
diff --git a/packages/CarSystemUI/res/layout/sysui_overlay_window.xml b/packages/CarSystemUI/res/layout/sysui_overlay_window.xml
index 3542323..2dc499c 100644
--- a/packages/CarSystemUI/res/layout/sysui_overlay_window.xml
+++ b/packages/CarSystemUI/res/layout/sysui_overlay_window.xml
@@ -39,4 +39,9 @@
               android:layout_height="match_parent"
               android:layout="@layout/car_fullscreen_user_switcher"/>
 
+    <ViewStub android:id="@+id/user_switching_dialog_stub"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:layout="@layout/car_user_switching_dialog"/>
+
 </FrameLayout>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml
index 3e44721..0e84d51 100644
--- a/packages/CarSystemUI/res/values/colors.xml
+++ b/packages/CarSystemUI/res/values/colors.xml
@@ -55,4 +55,7 @@
     <color name="list_divider_color">@*android:color/car_list_divider_light</color>
     <color name="car_volume_item_divider_color">@*android:color/car_list_divider</color>
     <color name="car_volume_item_background_color">@*android:color/car_card_dark</color>
+
+    <color name="car_user_switching_dialog_background_color">@android:color/black</color>
+    <color name="car_user_switching_dialog_loading_text_color">@*android:color/car_body1</color>
 </resources>
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index 67066d7..4bf0fca 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -70,11 +70,13 @@
         to a constant alpha percent value using the initial alpha. -->
     <integer name="config_finalNotificationBackgroundAlpha">100</integer>
 
-    <!-- Car System UI's OverlayViewsMediator-->
+    <!-- Car System UI's OverlayViewsMediator.
+         Whenever a new class is added, make sure to also add that class to OverlayWindowModule. -->
     <string-array name="config_carSystemUIOverlayViewsMediators" translatable="false">
         <item>@string/config_notificationPanelViewMediator</item>
         <item>com.android.systemui.car.keyguard.CarKeyguardViewMediator</item>
         <item>com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator</item>
+        <item>com.android.systemui.car.userswitcher.UserSwitchTransitionViewMediator</item>
     </string-array>
 
     <!--
diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml
index 9014eb1..ed0b485 100644
--- a/packages/CarSystemUI/res/values/dimens.xml
+++ b/packages/CarSystemUI/res/values/dimens.xml
@@ -15,6 +15,32 @@
   ~ limitations under the License
   -->
 <resources>
+    <!-- Text size for car -->
+    <dimen name="car_title_size">32sp</dimen>
+    <dimen name="car_title2_size">32sp</dimen>
+    <dimen name="car_headline1_size">45sp</dimen>
+    <dimen name="car_headline2_size">32sp</dimen>
+    <dimen name="car_headline3_size">24sp</dimen>
+    <dimen name="car_headline4_size">20sp</dimen>
+    <dimen name="car_body1_size">32sp</dimen>
+    <dimen name="car_body2_size">28sp</dimen>
+    <dimen name="car_body3_size">26sp</dimen>
+    <dimen name="car_body4_size">24sp</dimen>
+    <!-- car_body5_size is deprecated -->
+    <dimen name="car_body5_size">18sp</dimen>
+    <dimen name="car_label1_size">26sp</dimen>
+    <dimen name="car_label2_size">64sp</dimen>
+    <dimen name="car_action1_size">26sp</dimen>
+    <dimen name="car_action2_size">26sp</dimen>
+    <!-- Paddings -->
+    <dimen name="car_padding_0">4dp</dimen>
+    <dimen name="car_padding_1">8dp</dimen>
+    <dimen name="car_padding_2">16dp</dimen>
+    <dimen name="car_padding_3">24dp</dimen>
+    <dimen name="car_padding_4">32dp</dimen>
+    <dimen name="car_padding_5">64dp</dimen>
+    <dimen name="car_padding_6">96dp</dimen>
+
     <!--
        Note: status bar height and navigation bar heights are defined
        in frameworks/base/core package and thus will have no effect if
@@ -156,4 +182,10 @@
     <dimen name="car_user_switcher_container_height">420dp</dimen>
     <!-- This must be the negative of car_user_switcher_container_height for the animation. -->
     <dimen name="car_user_switcher_container_anim_height">-420dp</dimen>
+
+    <!-- dimensions for car user switching dialog -->
+    <dimen name="car_fullscreen_user_pod_image_avatar_width">96dp</dimen>
+    <dimen name="car_fullscreen_user_pod_image_avatar_height">96dp</dimen>
+    <dimen name="car_user_switching_dialog_loading_text_margin_top">@*android:dimen/car_padding_4</dimen>
+    <dimen name="car_user_switching_dialog_loading_text_font_size">@*android:dimen/car_body1_size</dimen>
 </resources>
diff --git a/packages/CarSystemUI/res/values/strings.xml b/packages/CarSystemUI/res/values/strings.xml
index 9fae4b3..67fd5bb 100644
--- a/packages/CarSystemUI/res/values/strings.xml
+++ b/packages/CarSystemUI/res/values/strings.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   -->
 
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- String to represent lowest setting of an HVAC system [CHAR LIMIT=10]-->
     <string name="hvac_min_text">Min</string>
     <!-- String to represent largest setting of an HVAC system [CHAR LIMIT=10]-->
@@ -34,4 +34,8 @@
     <string name="user_add_user_message_setup">When you add a new user, that person needs to set up their space.</string>
     <!-- Message to inform user that the newly created user will have permissions to update apps for all other users. [CHAR LIMIT=100] -->
     <string name="user_add_user_message_update">Any user can update apps for all other users.</string>
+    <!-- Message to inform user that the new user profile is loading. [CHAR LIMIT=20] -->
+    <string name="car_loading_profile">Loading</string>
+    <!-- Message to inform user that the new user profile is loading with additional information on the previous and the next user. [CHAR LIMIT=100] -->
+    <string name="car_loading_profile_developer_message">Loading user (from <xliff:g id="from_user" example="10">%1$d</xliff:g> to <xliff:g id="to_user" example="12">%2$d</xliff:g>)</string>
 </resources>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index f8729c3..fe2be1d 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -30,6 +30,7 @@
 import com.android.systemui.car.keyguard.CarKeyguardViewController;
 import com.android.systemui.car.statusbar.CarStatusBar;
 import com.android.systemui.car.statusbar.CarStatusBarKeyguardViewManager;
+import com.android.systemui.car.statusbar.DozeServiceHost;
 import com.android.systemui.car.statusbar.DummyNotificationShadeWindowController;
 import com.android.systemui.car.volume.CarVolumeDialogComponent;
 import com.android.systemui.dagger.SystemUIRootComponent;
@@ -37,6 +38,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerImpl;
+import com.android.systemui.doze.DozeHost;
 import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.EnhancedEstimates;
@@ -174,4 +176,7 @@
     @Binds
     abstract NotificationShadeWindowController bindNotificationShadeWindowController(
             DummyNotificationShadeWindowController notificationShadeWindowController);
+
+    @Binds
+    abstract DozeHost bindDozeHost(DozeServiceHost dozeServiceHost);
 }
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
index aee7643..ab61b44 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
@@ -188,7 +188,7 @@
         stop();
         getOverlayViewGlobalStateController().setWindowFocusable(/* focusable= */ false);
         mKeyguardStateController.notifyKeyguardDoneFading();
-        mViewMediatorCallback.keyguardGone();
+        mHandler.post(mViewMediatorCallback::keyguardGone);
         notifyKeyguardUpdateMonitor();
     }
 
@@ -203,6 +203,11 @@
             }
             mKeyguardUpdateMonitor.sendKeyguardReset();
             notifyKeyguardUpdateMonitor();
+        } else {
+            // This is necessary in order to address an inconsistency between the keyguard service
+            // and the keyguard views.
+            // TODO: Investigate the source of the inconsistency.
+            show(/* options= */ null);
         }
     }
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
index 893efdc..5c6472e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
@@ -16,9 +16,12 @@
 
 package com.android.systemui.car.navigationbar;
 
+import static android.view.InsetsState.ITYPE_BOTTOM_GESTURES;
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.InsetsState.ITYPE_TOP_GESTURES;
 import static android.view.InsetsState.containsType;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
@@ -34,26 +37,31 @@
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowInsetsController;
 import android.view.WindowManager;
 
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.statusbar.RegisterStatusBarResult;
+import com.android.internal.view.AppearanceRegion;
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.CarDeviceProvisionedListener;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.statusbar.AutoHideUiElement;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoHideController;
 import com.android.systemui.statusbar.phone.BarTransitions;
+import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy;
+import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
 import java.io.FileDescriptor;
@@ -69,6 +77,7 @@
 
     private final Resources mResources;
     private final CarNavigationBarController mCarNavigationBarController;
+    private final SysuiDarkIconDispatcher mStatusBarIconController;
     private final WindowManager mWindowManager;
     private final CarDeviceProvisionedController mCarDeviceProvisionedController;
     private final CommandQueue mCommandQueue;
@@ -106,6 +115,7 @@
     private boolean mDeviceIsSetUpForUser = true;
     private boolean mIsUserSetupInProgress = false;
 
+    private AppearanceRegion[] mAppearanceRegions = new AppearanceRegion[0];
     @BarTransitions.TransitionMode
     private int mStatusBarMode;
     @BarTransitions.TransitionMode
@@ -117,6 +127,9 @@
     public CarNavigationBar(Context context,
             @Main Resources resources,
             CarNavigationBarController carNavigationBarController,
+            // TODO(b/156052638): Should not need to inject LightBarController
+            LightBarController lightBarController,
+            DarkIconDispatcher darkIconDispatcher,
             WindowManager windowManager,
             CarDeviceProvisionedController deviceProvisionedController,
             CommandQueue commandQueue,
@@ -133,6 +146,7 @@
         super(context);
         mResources = resources;
         mCarNavigationBarController = carNavigationBarController;
+        mStatusBarIconController = (SysuiDarkIconDispatcher) darkIconDispatcher;
         mWindowManager = windowManager;
         mCarDeviceProvisionedController = deviceProvisionedController;
         mCommandQueue = commandQueue;
@@ -166,6 +180,9 @@
             ex.rethrowFromSystemServer();
         }
 
+        onSystemBarAppearanceChanged(mDisplayId, result.mAppearance, result.mAppearanceRegions,
+                result.mNavbarColorManagedByIme);
+
         // StatusBarManagerService has a back up of IME token and it's restored here.
         setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis,
                 result.mImeBackDisposition, result.mShowImeSwitcher);
@@ -362,7 +379,7 @@
                             | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                     PixelFormat.TRANSLUCENT);
             lp.setTitle("TopCarNavigationBar");
-            lp.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
+            lp.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR, ITYPE_TOP_GESTURES};
             lp.setFitInsetsTypes(0);
             lp.windowAnimations = 0;
             lp.gravity = Gravity.TOP;
@@ -384,7 +401,7 @@
                             | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                     PixelFormat.TRANSLUCENT);
             lp.setTitle("BottomCarNavigationBar");
-            lp.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
+            lp.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR, ITYPE_BOTTOM_GESTURES};
             lp.windowAnimations = 0;
             lp.gravity = Gravity.BOTTOM;
             mWindowManager.addView(mBottomNavigationBarWindow, lp);
@@ -447,6 +464,64 @@
     }
 
     @Override
+    public void onSystemBarAppearanceChanged(
+            int displayId,
+            @WindowInsetsController.Appearance int appearance,
+            AppearanceRegion[] appearanceRegions,
+            boolean navbarColorManagedByIme) {
+        if (displayId != mDisplayId) {
+            return;
+        }
+        boolean barModeChanged = updateStatusBarMode(
+                mStatusBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT);
+        int numStacks = appearanceRegions.length;
+        boolean stackAppearancesChanged = mAppearanceRegions.length != numStacks;
+        for (int i = 0; i < numStacks && !stackAppearancesChanged; i++) {
+            stackAppearancesChanged |= !appearanceRegions[i].equals(mAppearanceRegions[i]);
+        }
+        if (stackAppearancesChanged || barModeChanged) {
+            mAppearanceRegions = appearanceRegions;
+            updateStatusBarAppearance();
+        }
+    }
+
+    private void updateStatusBarAppearance() {
+        int numStacks = mAppearanceRegions.length;
+        int numLightStacks = 0;
+
+        // We can only have maximum one light stack.
+        int indexLightStack = -1;
+
+        for (int i = 0; i < numStacks; i++) {
+            if (isLight(mAppearanceRegions[i].getAppearance())) {
+                numLightStacks++;
+                indexLightStack = i;
+            }
+        }
+
+        // If all stacks are light, all icons become dark.
+        if (numLightStacks == numStacks) {
+            mStatusBarIconController.setIconsDarkArea(null);
+            mStatusBarIconController.getTransitionsController().setIconsDark(
+                    /* dark= */ true, /* animate= */ false);
+        } else if (numLightStacks == 0) {
+            // If no one is light, all icons become white.
+            mStatusBarIconController.getTransitionsController().setIconsDark(
+                    /* dark= */ false, /* animate= */ false);
+        } else {
+            // Not the same for every stack, update icons in area only.
+            mStatusBarIconController.setIconsDarkArea(
+                    mAppearanceRegions[indexLightStack].getBounds());
+            mStatusBarIconController.getTransitionsController().setIconsDark(
+                    /* dark= */ true, /* animate= */ false);
+        }
+    }
+
+    private static boolean isLight(int appearance) {
+        return (appearance & APPEARANCE_LIGHT_STATUS_BARS) != 0;
+    }
+
+    @Override
     public void showTransient(int displayId, int[] types) {
         if (displayId != mDisplayId) {
             return;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java
index e2eb3fb..d18eadd 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java
@@ -425,6 +425,11 @@
     }
 
     @Override
+    public void notifyBiometricAuthModeChanged() {
+        // No op.
+    }
+
+    @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         //When executing dump() function simultaneously, we need to serialize them
         //to get mStackScroller's position correctly.
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DozeServiceHost.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DozeServiceHost.java
new file mode 100644
index 0000000..d23660c
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/DozeServiceHost.java
@@ -0,0 +1,130 @@
+/*
+ * 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.systemui.car.statusbar;
+
+import com.android.systemui.doze.DozeHost;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/** No-op implementation of {@link DozeHost} for use by car sysui, which does not support dozing. */
+@Singleton
+public class DozeServiceHost implements DozeHost {
+
+    @Inject
+    public DozeServiceHost() {}
+
+    @Override
+    public void addCallback(Callback callback) {
+        // No op.
+    }
+
+    @Override
+    public void removeCallback(Callback callback) {
+        // No op.
+    }
+
+    @Override
+    public void startDozing() {
+        // No op.
+    }
+
+    @Override
+    public void pulseWhileDozing(PulseCallback callback, int reason) {
+        // No op.
+    }
+
+    @Override
+    public void stopDozing() {
+        // No op.
+    }
+
+    @Override
+    public void dozeTimeTick() {
+        // No op.
+    }
+
+    @Override
+    public boolean isPowerSaveActive() {
+        return false;
+    }
+
+    @Override
+    public boolean isPulsingBlocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isProvisioned() {
+        return false;
+    }
+
+    @Override
+    public boolean isBlockingDoze() {
+        return true;
+    }
+
+    @Override
+    public void extendPulse(int reason) {
+        // No op.
+    }
+
+    @Override
+    public void setAnimateWakeup(boolean animateWakeup) {
+        // No op.
+    }
+
+    @Override
+    public void setAnimateScreenOff(boolean animateScreenOff) {
+        // No op.
+    }
+
+    @Override
+    public void onSlpiTap(float x, float y) {
+        // No op.
+    }
+
+    @Override
+    public void setDozeScreenBrightness(int value) {
+        // No op.
+    }
+
+    @Override
+    public void prepareForGentleSleep(Runnable onDisplayOffCallback) {
+        // No op.
+    }
+
+    @Override
+    public void cancelGentleSleep() {
+        // No op.
+    }
+
+    @Override
+    public void onIgnoreTouchWhilePulsing(boolean ignore) {
+        // No op.
+    }
+
+    @Override
+    public void stopPulsing() {
+        // No op.
+    }
+
+    @Override
+    public boolean isDozeSuppressed() {
+        return true;
+    }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java
index 346c38c..8b399f8 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java
@@ -34,16 +34,19 @@
     private final StatusBarStateController mStatusBarStateController;
     private final FullScreenUserSwitcherViewController mFullScreenUserSwitcherViewController;
     private final CarKeyguardViewController mCarKeyguardViewController;
+    private final UserSwitchTransitionViewController mUserSwitchTransitionViewController;
 
     @Inject
     public FullscreenUserSwitcherViewMediator(
             StatusBarStateController statusBarStateController,
             CarKeyguardViewController carKeyguardViewController,
+            UserSwitchTransitionViewController userSwitchTransitionViewController,
             FullScreenUserSwitcherViewController fullScreenUserSwitcherViewController) {
 
         mStatusBarStateController = statusBarStateController;
-        mFullScreenUserSwitcherViewController = fullScreenUserSwitcherViewController;
         mCarKeyguardViewController = carKeyguardViewController;
+        mUserSwitchTransitionViewController = userSwitchTransitionViewController;
+        mFullScreenUserSwitcherViewController = fullScreenUserSwitcherViewController;
     }
 
     @Override
@@ -74,6 +77,11 @@
     private void onUserSelected(UserGridRecyclerView.UserRecord record) {
         if (record.mType != UserGridRecyclerView.UserRecord.FOREGROUND_USER) {
             mCarKeyguardViewController.hideKeyguardToPrepareBouncer();
+            // If guest user, we cannot use record.mInfo.id and should listen to the User lifecycle
+            // event instead.
+            if (record.mType != UserGridRecyclerView.UserRecord.START_GUEST) {
+                mUserSwitchTransitionViewController.handleShow(record.mInfo.id);
+            }
         }
 
         hide();
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
new file mode 100644
index 0000000..775ef81
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewController.java
@@ -0,0 +1,126 @@
+/*
+ * 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.systemui.car.userswitcher;
+
+import static android.car.settings.CarSettings.Global.ENABLE_USER_SWITCH_DEVELOPER_MESSAGE;
+
+import android.annotation.UserIdInt;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.settingslib.drawable.CircleFramedDrawable;
+import com.android.systemui.R;
+import com.android.systemui.car.window.OverlayViewController;
+import com.android.systemui.car.window.OverlayViewGlobalStateController;
+import com.android.systemui.dagger.qualifiers.Main;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Handles showing and hiding UserSwitchTransitionView that is mounted to SystemUiOverlayWindow.
+ */
+@Singleton
+public class UserSwitchTransitionViewController extends OverlayViewController {
+    private static final String TAG = "UserSwitchTransitionViewController";
+    private static final String ENABLE_DEVELOPER_MESSAGE_TRUE = "true";
+
+    private final Context mContext;
+    private final Handler mHandler;
+    private final Resources mResources;
+    private final UserManager mUserManager;
+
+    @GuardedBy("this")
+    private boolean mShowing;
+    private int mPreviousUserId = UserHandle.USER_NULL;
+
+    @Inject
+    public UserSwitchTransitionViewController(
+            Context context,
+            @Main Handler handler,
+            @Main Resources resources,
+            UserManager userManager,
+            OverlayViewGlobalStateController overlayViewGlobalStateController) {
+
+        super(R.id.user_switching_dialog_stub, overlayViewGlobalStateController);
+
+        mContext = context;
+        mHandler = handler;
+        mResources = resources;
+        mUserManager = userManager;
+    }
+
+    /**
+     * Makes the user switch transition view appear and draws the content inside of it if a user
+     * that is different from the previous user is provided and if the dialog is not already
+     * showing.
+     */
+    void handleShow(@UserIdInt int newUserId) {
+        if (mPreviousUserId == newUserId || mShowing) return;
+        mShowing = true;
+        mHandler.post(() -> {
+            start();
+            populateDialog(mPreviousUserId, newUserId);
+            // next time a new user is selected, this current new user will be the previous user.
+            mPreviousUserId = newUserId;
+        });
+    }
+
+    void handleHide() {
+        if (!mShowing) return;
+        mShowing = false;
+        mHandler.post(this::stop);
+    }
+
+    private void populateDialog(@UserIdInt int previousUserId, @UserIdInt int newUserId) {
+        drawUserIcon(newUserId);
+        populateLoadingText(previousUserId, newUserId);
+    }
+
+    private void drawUserIcon(int newUserId) {
+        Bitmap bitmap = mUserManager.getUserIcon(newUserId);
+        if (bitmap != null) {
+            CircleFramedDrawable drawable = CircleFramedDrawable.getInstance(mContext, bitmap);
+            ((ImageView) getLayout().findViewById(R.id.user_loading_avatar))
+                    .setImageDrawable(drawable);
+        }
+    }
+
+    private void populateLoadingText(@UserIdInt int previousUserId, @UserIdInt int newUserId) {
+        TextView msgView = getLayout().findViewById(R.id.user_loading);
+
+        boolean showInfo = ENABLE_DEVELOPER_MESSAGE_TRUE.equals(
+                Settings.Global.getString(mContext.getContentResolver(),
+                        ENABLE_USER_SWITCH_DEVELOPER_MESSAGE));
+
+        if (showInfo && mPreviousUserId != UserHandle.USER_NULL) {
+            msgView.setText(
+                    mResources.getString(R.string.car_loading_profile_developer_message,
+                            previousUserId, newUserId));
+        } else {
+            msgView.setText(mResources.getString(R.string.car_loading_profile));
+        }
+    }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
new file mode 100644
index 0000000..aea6914
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediator.java
@@ -0,0 +1,85 @@
+/*
+ * 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.systemui.car.userswitcher;
+
+import android.app.ActivityManager;
+import android.car.Car;
+import android.car.user.CarUserManager;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.car.CarServiceProvider;
+import com.android.systemui.car.window.OverlayViewMediator;
+
+import javax.inject.Inject;
+
+/**
+ * Registers listeners that subscribe to events that show or hide CarUserSwitchingDialog that is
+ * mounted to SystemUiOverlayWindow.
+ */
+public class UserSwitchTransitionViewMediator implements OverlayViewMediator,
+        CarUserManager.UserSwitchUiCallback {
+    private static final String TAG = "UserSwitchTransitionViewMediator";
+
+    private final CarServiceProvider mCarServiceProvider;
+    private final UserSwitchTransitionViewController mUserSwitchTransitionViewController;
+
+    @Inject
+    public UserSwitchTransitionViewMediator(
+            CarServiceProvider carServiceProvider,
+            UserSwitchTransitionViewController userSwitchTransitionViewController) {
+        mCarServiceProvider = carServiceProvider;
+        mUserSwitchTransitionViewController = userSwitchTransitionViewController;
+    }
+
+    @Override
+    public void registerListeners() {
+        mCarServiceProvider.addListener(car -> {
+            CarUserManager carUserManager =
+                    (CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE);
+
+            if (carUserManager != null) {
+                carUserManager.setUserSwitchUiCallback(this);
+                carUserManager.addListener(Runnable::run, this::handleUserLifecycleEvent);
+            } else {
+                Log.e(TAG, "registerListeners: CarUserManager could not be obtained.");
+            }
+        });
+    }
+
+    @Override
+    public void setupOverlayContentViewControllers() {
+        // no-op.
+    }
+
+    @Override
+    public void showUserSwitchDialog(int userId) {
+        mUserSwitchTransitionViewController.handleShow(userId);
+    }
+
+    @VisibleForTesting
+    void handleUserLifecycleEvent(CarUserManager.UserLifecycleEvent event) {
+        if (event.getEventType() == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING
+                && ActivityManager.getCurrentUser() == event.getUserId()) {
+            mUserSwitchTransitionViewController.handleShow(event.getUserId());
+        }
+
+        if (event.getEventType() == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
+            mUserSwitchTransitionViewController.handleHide();
+        }
+    }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java
index 2bdb85f..03b61e0 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/VolumeUI.java
@@ -52,6 +52,15 @@
             new CarAudioManager.CarVolumeCallback() {
                 @Override
                 public void onGroupVolumeChanged(int zoneId, int groupId, int flags) {
+                    initVolumeDialogComponent();
+                }
+
+                @Override
+                public void onMasterMuteChanged(int zoneId, int flags) {
+                    initVolumeDialogComponent();
+                }
+
+                private void initVolumeDialogComponent() {
                     if (mVolumeDialogComponent == null) {
                         mMainHandler.post(() -> {
                             mVolumeDialogComponent = mVolumeDialogComponentLazy.get();
@@ -60,11 +69,6 @@
                         mCarAudioManager.unregisterCarVolumeCallback(mVolumeChangeCallback);
                     }
                 }
-
-                @Override
-                public void onMasterMuteChanged(int zoneId, int flags) {
-                    // ignored
-                }
             };
 
     private boolean mEnabled;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java
index ac574ed..3e7b4a2 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java
@@ -23,6 +23,9 @@
 
     /**
      * Register listeners that could use ContentVisibilityAdjuster to show/hide content.
+     *
+     * Note that we do not unregister listeners because SystemUI components are expected to live
+     * for the lifecycle of the device.
      */
     void registerListeners();
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java
index 484aa63..5a16efa 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java
@@ -21,6 +21,7 @@
 import com.android.systemui.car.notification.NotificationPanelViewMediator;
 import com.android.systemui.car.notification.TopNotificationPanelViewMediator;
 import com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator;
+import com.android.systemui.car.userswitcher.UserSwitchTransitionViewMediator;
 
 import dagger.Binds;
 import dagger.Module;
@@ -67,4 +68,11 @@
     @ClassKey(FullscreenUserSwitcherViewMediator.class)
     public abstract OverlayViewMediator bindFullscreenUserSwitcherViewsMediator(
             FullscreenUserSwitcherViewMediator overlayViewsMediator);
+
+    /** Injects CarUserSwitchingDialogMediator. */
+    @Binds
+    @IntoMap
+    @ClassKey(UserSwitchTransitionViewMediator.class)
+    public abstract OverlayViewMediator bindUserSwitchTransitionViewMediator(
+            UserSwitchTransitionViewMediator userSwitchTransitionViewMediator);
 }
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
index 1b4621f..38836d8 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
@@ -32,6 +32,8 @@
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 
+import androidx.test.filters.SmallTest;
+
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
@@ -58,6 +60,7 @@
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
+@SmallTest
 public class CarKeyguardViewControllerTest extends SysuiTestCase {
 
     private TestableCarKeyguardViewController mCarKeyguardViewController;
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
index 77eecac..04e0a73 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
@@ -18,6 +18,8 @@
 
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_STATUS_BARS;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -25,6 +27,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.graphics.Rect;
 import android.os.Handler;
 import android.os.RemoteException;
 import android.testing.AndroidTestingRunner;
@@ -44,8 +47,11 @@
 import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LightBarTransitionsController;
 import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.SysuiDarkIconDispatcher;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.concurrency.FakeExecutor;
 import com.android.systemui.util.time.FakeSystemClock;
@@ -69,6 +75,12 @@
     @Mock
     private CarNavigationBarController mCarNavigationBarController;
     @Mock
+    private LightBarController mLightBarController;
+    @Mock
+    private SysuiDarkIconDispatcher mStatusBarIconController;
+    @Mock
+    private LightBarTransitionsController mLightBarTransitionsController;
+    @Mock
     private WindowManager mWindowManager;
     @Mock
     private CarDeviceProvisionedController mDeviceProvisionedController;
@@ -88,6 +100,7 @@
     private StatusBarIconController mIconController;
 
     private RegisterStatusBarResult mBarResult;
+    private AppearanceRegion[] mAppearanceRegions;
     private FakeExecutor mUiBgExecutor;
 
     @Before
@@ -96,11 +109,16 @@
         mTestableResources = mContext.getOrCreateTestableResources();
         mHandler = Handler.getMain();
         mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
+        when(mStatusBarIconController.getTransitionsController()).thenReturn(
+                mLightBarTransitionsController);
+        mAppearanceRegions = new AppearanceRegion[] {
+                new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, new Rect())
+        };
         mBarResult = new RegisterStatusBarResult(
                 /* icons= */ new ArrayMap<>(),
                 /* disabledFlags1= */ 0,
                 /* appearance= */ 0,
-                /* appearanceRegions= */ new AppearanceRegion[]{},
+                mAppearanceRegions,
                 /* imeWindowVis= */ 0,
                 /* imeBackDisposition= */ 0,
                 /* showImeSwitcher= */ false,
@@ -116,10 +134,11 @@
             e.printStackTrace();
         }
         mCarNavigationBar = new CarNavigationBar(mContext, mTestableResources.getResources(),
-                mCarNavigationBarController, mWindowManager, mDeviceProvisionedController,
-                new CommandQueue(mContext), mAutoHideController, mButtonSelectionStateListener,
-                mHandler, mUiBgExecutor, mBarService, () -> mKeyguardStateController,
-                mButtonSelectionStateController, () -> mIconPolicy,  () -> mIconController);
+                mCarNavigationBarController, mLightBarController, mStatusBarIconController,
+                mWindowManager, mDeviceProvisionedController, new CommandQueue(mContext),
+                mAutoHideController, mButtonSelectionStateListener, mHandler, mUiBgExecutor,
+                mBarService, () -> mKeyguardStateController, mButtonSelectionStateController,
+                () -> mIconPolicy, () -> mIconController);
     }
 
     @Test
@@ -186,6 +205,26 @@
     }
 
     @Test
+    public void restartNavBars_lightAppearance_darkensAllIcons() {
+        mAppearanceRegions[0] = new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, new Rect());
+
+        mCarNavigationBar.start();
+
+        verify(mLightBarTransitionsController).setIconsDark(
+                /* dark= */ true, /* animate= */ false);
+    }
+
+    @Test
+    public void restartNavBars_opaqueAppearance_lightensAllIcons() {
+        mAppearanceRegions[0] = new AppearanceRegion(APPEARANCE_OPAQUE_STATUS_BARS, new Rect());
+
+        mCarNavigationBar.start();
+
+        verify(mLightBarTransitionsController).setIconsDark(
+                /* dark= */ false, /* animate= */ false);
+    }
+
+    @Test
     public void showTransient_wrongDisplayId_transientModeNotUpdated() {
         mTestableResources.addOverride(R.bool.config_enableTopNavigationBar, true);
         mTestableResources.addOverride(R.bool.config_enableBottomNavigationBar, true);
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
new file mode 100644
index 0000000..eab381c
--- /dev/null
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewControllerTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.systemui.car.userswitcher;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Handler;
+import android.os.UserManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableResources;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.car.window.OverlayViewGlobalStateController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class UserSwitchTransitionViewControllerTest extends SysuiTestCase {
+    private static final int TEST_USER_1 = 100;
+    private static final int TEST_USER_2 = 110;
+
+    private TestableUserSwitchTransitionViewController mCarUserSwitchingDialogController;
+    private TestableResources mTestableResources;
+    @Mock
+    private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mTestableResources = mContext.getOrCreateTestableResources();
+        mCarUserSwitchingDialogController = new TestableUserSwitchTransitionViewController(
+                mContext,
+                Handler.getMain(),
+                mTestableResources.getResources(),
+                (UserManager) mContext.getSystemService(Context.USER_SERVICE),
+                mOverlayViewGlobalStateController
+        );
+
+        mCarUserSwitchingDialogController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
+                R.layout.sysui_overlay_window, /* root= */ null));
+    }
+
+    @Test
+    public void onHandleShow_newUserSelected_showsDialog() {
+        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+
+        verify(mOverlayViewGlobalStateController).showView(eq(mCarUserSwitchingDialogController),
+                any());
+    }
+
+    @Test
+    public void onHandleShow_alreadyShowing_ignoresRequest() {
+        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_2);
+
+        // Verify that the request was processed only once.
+        verify(mOverlayViewGlobalStateController).showView(eq(mCarUserSwitchingDialogController),
+                any());
+    }
+
+    @Test
+    public void onHandleShow_sameUserSelected_ignoresRequest() {
+        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleHide();
+        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+
+        // Verify that the request was processed only once.
+        verify(mOverlayViewGlobalStateController).showView(eq(mCarUserSwitchingDialogController),
+                any());
+    }
+
+    @Test
+    public void onHide_currentlyShowing_hidesDialog() {
+        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleHide();
+
+        verify(mOverlayViewGlobalStateController).hideView(eq(mCarUserSwitchingDialogController),
+                any());
+    }
+
+    @Test
+    public void onHide_notShowing_ignoresRequest() {
+        mCarUserSwitchingDialogController.handleShow(/* currentUserId= */ TEST_USER_1);
+        mCarUserSwitchingDialogController.handleHide();
+        mCarUserSwitchingDialogController.handleHide();
+
+        // Verify that the request was processed only once.
+        verify(mOverlayViewGlobalStateController).hideView(eq(mCarUserSwitchingDialogController),
+                any());
+    }
+
+    private final class TestableUserSwitchTransitionViewController extends
+            UserSwitchTransitionViewController {
+
+        private final Handler mHandler;
+
+        TestableUserSwitchTransitionViewController(Context context, Handler handler,
+                Resources resources, UserManager userManager,
+                OverlayViewGlobalStateController overlayViewGlobalStateController) {
+            super(context, handler, resources, userManager, overlayViewGlobalStateController);
+            mHandler = handler;
+        }
+
+        @Override
+        public void handleShow(int currentUserId) {
+            super.handleShow(currentUserId);
+            waitForIdleSync(mHandler);
+        }
+
+        @Override
+        public void handleHide() {
+            super.handleHide();
+            waitForIdleSync(mHandler);
+        }
+    }
+}
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
new file mode 100644
index 0000000..a808e2d
--- /dev/null
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/userswitcher/UserSwitchTransitionViewMediatorTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.systemui.car.userswitcher;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.car.user.CarUserManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.car.CarServiceProvider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class UserSwitchTransitionViewMediatorTest {
+    private static final int TEST_USER = 100;
+
+    private UserSwitchTransitionViewMediator mUserSwitchTransitionViewMediator;
+    @Mock
+    private CarServiceProvider mCarServiceProvider;
+    @Mock
+    private UserSwitchTransitionViewController mUserSwitchTransitionViewController;
+    @Mock
+    private CarUserManager.UserLifecycleEvent mUserLifecycleEvent;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mUserSwitchTransitionViewMediator = new UserSwitchTransitionViewMediator(
+                mCarServiceProvider, mUserSwitchTransitionViewController);
+
+    }
+
+    @Test
+    public void onUserLifecycleEvent_userStarting_callsHandleShow() {
+        when(mUserLifecycleEvent.getEventType()).thenReturn(
+                CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING);
+        when(mUserLifecycleEvent.getUserId()).thenReturn(TEST_USER);
+        mUserSwitchTransitionViewMediator.handleUserLifecycleEvent(mUserLifecycleEvent);
+
+        verify(mUserSwitchTransitionViewController).handleShow(TEST_USER);
+    }
+
+    @Test
+    public void onUserLifecycleEvent_userSwitching_callsHandleHide() {
+        when(mUserLifecycleEvent.getEventType()).thenReturn(
+                CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING);
+        mUserSwitchTransitionViewMediator.handleUserLifecycleEvent(mUserLifecycleEvent);
+
+        verify(mUserSwitchTransitionViewController).handleHide();
+    }
+}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm b/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm
index eec9d27..96445a4 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm
@@ -258,9 +258,9 @@
 }
 
 key SEMICOLON {
-    label:                              '\u010d'
-    base:                               '\u010c'
-    shift, capslock:                    '\u010d'
+    label:                              '\u010c'
+    base:                               '\u010d'
+    shift, capslock:                    '\u010c'
 }
 
 key APOSTROPHE {
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
index d5faac2..60934b1 100644
--- a/packages/PackageInstaller/res/values-ne/strings.xml
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -24,8 +24,8 @@
     <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> स्थापना गर्दै…"</string>
     <string name="install_done" msgid="5987363587661783896">"एप स्थापना गरियो।"</string>
     <string name="install_confirm_question" msgid="8176284075816604590">"तपाईं यो एप स्थापना गर्न चाहनुहुन्छ?"</string>
-    <string name="install_confirm_question_update" msgid="7942235418781274635">"तपाईं यो पहिलेदेखि नै विद्यमान अनुप्रयोगको साटो यसको अद्यावधिक संस्करण स्थापना गर्न चाहनुहुन्छ? तपाईंको विद्यमान डेटा गुम्ने छैन।"</string>
-    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"तपाईं यो अन्तर्निर्मित अनुप्रयोगको साटो यसको अद्यावधिक संस्करण स्थापना गर्न चाहनुहुन्छ? तपाईंको विद्यमान डेटा गुम्ने छैन।"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"तपाईं यो पहिलेदेखि नै विद्यमान एपको साटो यसको अद्यावधिक संस्करण स्थापना गर्न चाहनुहुन्छ? तपाईंको विद्यमान डेटा गुम्ने छैन।"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"तपाईं यो अन्तर्निर्मित एपको साटो यसको अद्यावधिक संस्करण स्थापना गर्न चाहनुहुन्छ? तपाईंको विद्यमान डेटा गुम्ने छैन।"</string>
     <string name="install_failed" msgid="5777824004474125469">"एप स्थापना गरिएन।"</string>
     <string name="install_failed_blocked" msgid="8512284352994752094">"यो प्याकेज स्थापना गर्ने क्रममा अवरोध गरियो।"</string>
     <string name="install_failed_conflict" msgid="3493184212162521426">"प्याकेजका रूपमा स्थापना नगरिएको एप विद्यमान प्याकेजसँग मेल खाँदैन।"</string>
@@ -49,16 +49,16 @@
     <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"अनुमति छैन"</string>
     <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"हालका प्रयोगकर्तालाई यो स्थापना रद्द गर्ने कार्य गर्ने अनुमति छैन।"</string>
     <string name="generic_error_dlg_title" msgid="5863195085927067752">"त्रुटि"</string>
-    <string name="generic_error_dlg_text" msgid="5287861443265795232">"अनुप्रयोगको स्थापना रद्द गर्न सकिएन।"</string>
-    <string name="uninstall_application_title" msgid="4045420072401428123">"अनुप्रयोगको स्थापना रद्द गर्नु…"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"एपको स्थापना रद्द गर्न सकिएन।"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"एपको स्थापना रद्द गर्नु…"</string>
     <string name="uninstall_update_title" msgid="824411791011583031">"अद्यावधिकको स्थापना रद्द गर्नु…"</string>
-    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> निम्न अनुप्रयोगको अंश हो:"</string>
-    <string name="uninstall_application_text" msgid="3816830743706143980">"तपाईं यो अनुप्रयोगको स्थापना रद्द गर्न चाहनुहुन्छ?"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> निम्न एपको अंश हो:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"तपाईं यो एपको स्थापना रद्द गर्न चाहनुहुन्छ?"</string>
     <string name="uninstall_application_text_all_users" msgid="575491774380227119">"तपाईं "<b>"सबै"</b>" प्रयोगकर्ताका लागि यो एपको स्थापना रद्द गर्न चाहनुहुन्छ? यन्त्रका "<b>"सबै"</b>" प्रयोगकर्ताहरूबाट उक्त एप र यसको डेटा हटाइने छ।"</string>
-    <string name="uninstall_application_text_user" msgid="498072714173920526">"तपाईं प्रयोगकर्ता <xliff:g id="USERNAME">%1$s</xliff:g> का लागि यो अनुप्रयोगको स्थापना रद्द गर्न चाहनुहुन्छ?"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"तपाईं प्रयोगकर्ता <xliff:g id="USERNAME">%1$s</xliff:g> का लागि यो एपको स्थापना रद्द गर्न चाहनुहुन्छ?"</string>
     <string name="uninstall_update_text" msgid="863648314632448705">"यस एपलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइने छ।"</string>
     <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"यस एपलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइने छ। यसले यस यन्त्रका कार्य प्रोफाइल भएका लगायत सबै प्रयोगकर्ताहरूमा असर पार्छ।"</string>
-    <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> अनुप्रयोगको डेटा राख्नुहोस्।"</string>
+    <string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> एपको डेटा राख्नुहोस्।"</string>
     <string name="uninstalling_notification_channel" msgid="840153394325714653">"चलिरहेका स्थापना रद्द गर्ने कार्यहरू"</string>
     <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"असफल भएका स्थापना रद्द गर्ने कार्यहरू"</string>
     <string name="uninstalling" msgid="8709566347688966845">"स्थापना रद्द गर्दै…"</string>
@@ -67,12 +67,12 @@
     <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गरियो"</string>
     <string name="uninstall_failed" msgid="1847750968168364332">"स्थापना रद्द गर्न सकिएन।"</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्ने कार्य असफल भयो।"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"यन्त्रको सक्रिय प्रशासकीय अनुप्रयोगको स्थापना रद्द गर्न मिल्दैन"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"<xliff:g id="USERNAME">%1$s</xliff:g> को यन्त्रको सक्रिय प्रशासकीय अनुप्रयोगको स्थापना रद्द गर्न मिल्दैन"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"अन्य प्रयोगकर्ताहरूका लागि यस अनुप्रयोगको स्थापना रद्द गरे पनि केही प्रयोगकर्ता वा प्रोफाइलहरूलाई यसको आवश्यकता पर्दछ"</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"यन्त्रको सक्रिय प्रशासकीय एपको स्थापना रद्द गर्न मिल्दैन"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"<xliff:g id="USERNAME">%1$s</xliff:g> को यन्त्रको सक्रिय प्रशासकीय एपको स्थापना रद्द गर्न मिल्दैन"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"अन्य प्रयोगकर्ताहरूका लागि यस एपको स्थापना रद्द गरे पनि केही प्रयोगकर्ता वा प्रोफाइलहरूलाई यसको आवश्यकता पर्दछ"</string>
     <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"यो एप तपाईंको प्रोफाइलका लागि आवश्यक छ र यसको स्थापना रद्द गर्न सकिँदैन।"</string>
     <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"यो एप तपाईंको यन्त्रका प्रशासकका लागि आवश्यक छ र यसको स्थापना रद्द गर्न सकिँदैन।"</string>
-    <string name="manage_device_administrators" msgid="3092696419363842816">"यन्त्रका व्यवस्थापकीय अनुप्रयोगको व्यवस्थापन गर्नु…"</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"यन्त्रका व्यवस्थापकीय एपको व्यवस्थापन गर्नु…"</string>
     <string name="manage_users" msgid="1243995386982560813">"प्रयोगकर्ताहरूको व्यवस्थापन गर्नुहोस्"</string>
     <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> को स्थापना रद्द गर्न सकिएन।"</string>
     <string name="Parse_error_dlg_text" msgid="1661404001063076789">"प्याकेजलाई पार्स गर्ने क्रममा समस्या भयो।"</string>
@@ -89,7 +89,7 @@
     <string name="anonymous_source_continue" msgid="4375745439457209366">"जारी राख्नुहोस्"</string>
     <string name="external_sources_settings" msgid="4046964413071713807">"सेटिङहरू"</string>
     <string name="wear_app_channel" msgid="1960809674709107850">"वेयर एपहरूको स्थापना/स्थापना रद्द गर्दै"</string>
-    <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"अनुप्रयोगको स्थापना गरिएको सूचना"</string>
+    <string name="app_installed_notification_channel_description" msgid="2695385797601574123">"एपको स्थापना गरिएको सूचना"</string>
     <string name="notification_installation_success_message" msgid="6450467996056038442">"सफलतापूर्वक स्थापना गरियो"</string>
     <string name="notification_installation_success_status" msgid="3172502643504323321">"“<xliff:g id="APPNAME">%1$s</xliff:g>” सफलतापूर्वक स्थापना गरियो"</string>
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index 1d06df0..008a433 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -475,5 +475,10 @@
         public void onRequestFailed(int reason) {
             dispatchOnRequestFailed(reason);
         }
+
+        @Override
+        public void onSessionUpdated(RoutingSessionInfo sessionInfo) {
+            dispatchDataChanged();
+        }
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index 887a49b..a860ff1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -25,6 +25,7 @@
 import android.util.Log;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settingslib.bluetooth.A2dpProfile;
@@ -65,6 +66,7 @@
     }
 
     private final Collection<DeviceCallback> mCallbacks = new CopyOnWriteArrayList<>();
+    private final Object mMediaDevicesLock = new Object();
     @VisibleForTesting
     final MediaDeviceCallback mMediaDeviceCallback = new MediaDeviceCallback();
 
@@ -145,7 +147,14 @@
      * @param connectDevice the MediaDevice
      */
     public void connectDevice(MediaDevice connectDevice) {
-        final MediaDevice device = getMediaDeviceById(mMediaDevices, connectDevice.getId());
+        MediaDevice device = null;
+        synchronized (mMediaDevicesLock) {
+            device = getMediaDeviceById(mMediaDevices, connectDevice.getId());
+        }
+        if (device == null) {
+            Log.w(TAG, "connectDevice() connectDevice not in the list!");
+            return;
+        }
         if (device instanceof BluetoothMediaDevice) {
             final CachedBluetoothDevice cachedDevice =
                     ((BluetoothMediaDevice) device).getCachedDevice();
@@ -184,15 +193,18 @@
      * Start scan connected MediaDevice
      */
     public void startScan() {
-        mMediaDevices.clear();
+        synchronized (mMediaDevicesLock) {
+            mMediaDevices.clear();
+        }
         mInfoMediaManager.registerCallback(mMediaDeviceCallback);
         mInfoMediaManager.startScan();
     }
 
     void dispatchDeviceListUpdate() {
-        Collections.sort(mMediaDevices, COMPARATOR);
+        final List<MediaDevice> mediaDevices = new ArrayList<>(mMediaDevices);
+        Collections.sort(mediaDevices, COMPARATOR);
         for (DeviceCallback callback : getCallbacks()) {
-            callback.onDeviceListUpdate(new ArrayList<>(mMediaDevices));
+            callback.onDeviceListUpdate(mediaDevices);
         }
     }
 
@@ -241,9 +253,11 @@
      * @return MediaDevice
      */
     public MediaDevice getMediaDeviceById(String id) {
-        for (MediaDevice mediaDevice : mMediaDevices) {
-            if (TextUtils.equals(mediaDevice.getId(), id)) {
-                return mediaDevice;
+        synchronized (mMediaDevicesLock) {
+            for (MediaDevice mediaDevice : mMediaDevices) {
+                if (TextUtils.equals(mediaDevice.getId(), id)) {
+                    return mediaDevice;
+                }
             }
         }
         Log.i(TAG, "Unable to find device " + id);
@@ -255,6 +269,7 @@
      *
      * @return MediaDevice
      */
+    @Nullable
     public MediaDevice getCurrentConnectedDevice() {
         return mCurrentConnectedDevice;
     }
@@ -367,17 +382,19 @@
     }
 
     private MediaDevice updateCurrentConnectedDevice() {
-        MediaDevice phoneMediaDevice = null;
-        for (MediaDevice device : mMediaDevices) {
-            if (device instanceof  BluetoothMediaDevice) {
-                if (isActiveDevice(((BluetoothMediaDevice) device).getCachedDevice())) {
+        synchronized (mMediaDevicesLock) {
+            for (MediaDevice device : mMediaDevices) {
+                if (device instanceof BluetoothMediaDevice) {
+                    if (isActiveDevice(((BluetoothMediaDevice) device).getCachedDevice())) {
+                        return device;
+                    }
+                } else if (device instanceof PhoneMediaDevice) {
                     return device;
                 }
-            } else if (device instanceof PhoneMediaDevice) {
-                phoneMediaDevice = device;
             }
         }
-        return mMediaDevices.contains(phoneMediaDevice) ? phoneMediaDevice : null;
+        Log.w(TAG, "updateCurrentConnectedDevice() can't found current connected device");
+        return null;
     }
 
     private boolean isActiveDevice(CachedBluetoothDevice device) {
@@ -392,17 +409,26 @@
     class MediaDeviceCallback implements MediaManager.MediaDeviceCallback {
         @Override
         public void onDeviceAdded(MediaDevice device) {
-            if (!mMediaDevices.contains(device)) {
-                mMediaDevices.add(device);
+            boolean isAdded = false;
+            synchronized (mMediaDevicesLock) {
+                if (!mMediaDevices.contains(device)) {
+                    mMediaDevices.add(device);
+                    isAdded = true;
+                }
+            }
+
+            if (isAdded) {
                 dispatchDeviceListUpdate();
             }
         }
 
         @Override
         public void onDeviceListAdded(List<MediaDevice> devices) {
-            mMediaDevices.clear();
-            mMediaDevices.addAll(devices);
-            mMediaDevices.addAll(buildDisconnectedBluetoothDevice());
+            synchronized (mMediaDevicesLock) {
+                mMediaDevices.clear();
+                mMediaDevices.addAll(devices);
+                mMediaDevices.addAll(buildDisconnectedBluetoothDevice());
+            }
 
             final MediaDevice infoMediaDevice = mInfoMediaManager.getCurrentConnectedDevice();
             mCurrentConnectedDevice = infoMediaDevice != null
@@ -469,30 +495,42 @@
 
         @Override
         public void onDeviceRemoved(MediaDevice device) {
-            if (mMediaDevices.contains(device)) {
-                mMediaDevices.remove(device);
+            boolean isRemoved = false;
+            synchronized (mMediaDevicesLock) {
+                if (mMediaDevices.contains(device)) {
+                    mMediaDevices.remove(device);
+                    isRemoved = true;
+                }
+            }
+            if (isRemoved) {
                 dispatchDeviceListUpdate();
             }
         }
 
         @Override
         public void onDeviceListRemoved(List<MediaDevice> devices) {
-            mMediaDevices.removeAll(devices);
+            synchronized (mMediaDevicesLock) {
+                mMediaDevices.removeAll(devices);
+            }
             dispatchDeviceListUpdate();
         }
 
         @Override
         public void onConnectedDeviceChanged(String id) {
-            MediaDevice connectDevice = getMediaDeviceById(mMediaDevices, id);
+            MediaDevice connectDevice = null;
+            synchronized (mMediaDevicesLock) {
+                connectDevice = getMediaDeviceById(mMediaDevices, id);
+            }
             connectDevice = connectDevice != null
                     ? connectDevice : updateCurrentConnectedDevice();
-            if (connectDevice != null) {
-                connectDevice.setState(MediaDeviceState.STATE_CONNECTED);
-            }
 
             mCurrentConnectedDevice = connectDevice;
-            dispatchSelectedDeviceStateChanged(mCurrentConnectedDevice,
-                    MediaDeviceState.STATE_CONNECTED);
+            if (connectDevice != null) {
+                connectDevice.setState(MediaDeviceState.STATE_CONNECTED);
+
+                dispatchSelectedDeviceStateChanged(mCurrentConnectedDevice,
+                        MediaDeviceState.STATE_CONNECTED);
+            }
         }
 
         @Override
@@ -502,9 +540,11 @@
 
         @Override
         public void onRequestFailed(int reason) {
-            for (MediaDevice device : mMediaDevices) {
-                if (device.getState() == MediaDeviceState.STATE_CONNECTING) {
-                    device.setState(MediaDeviceState.STATE_CONNECTING_FAILED);
+            synchronized (mMediaDevicesLock) {
+                for (MediaDevice device : mMediaDevices) {
+                    if (device.getState() == MediaDeviceState.STATE_CONNECTING) {
+                        device.setState(MediaDeviceState.STATE_CONNECTING_FAILED);
+                    }
                 }
             }
             dispatchOnRequestFailed(reason);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index 99c568a..734866f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -625,6 +625,15 @@
     }
 
     @Test
+    public void onSessionUpdated_shouldDispatchDataChanged() {
+        mInfoMediaManager.registerCallback(mCallback);
+
+        mInfoMediaManager.mMediaRouterCallback.onSessionUpdated(mock(RoutingSessionInfo.class));
+
+        verify(mCallback).onDeviceAttributesChanged();
+    }
+
+    @Test
     public void addMediaDevice_verifyDeviceTypeCanCorrespondToMediaDevice() {
         final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
         final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 29c31ea..e537b76 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -588,8 +588,9 @@
                     Settings.Global.POWER_BUTTON_VERY_LONG_PRESS,
                     Settings.Global.SHOW_MEDIA_ON_QUICK_SETTINGS, // Temporary for R beta
                     Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER,
-                    Settings.Global.ADVANCED_BATTERY_USAGE_AMOUNT,
-                    Settings.Global.CACHED_APPS_FREEZER_ENABLED);
+                    Settings.Global.CACHED_APPS_FREEZER_ENABLED,
+                    Settings.Global.APP_INTEGRITY_VERIFICATION_TIMEOUT,
+                    Settings.Global.ADVANCED_BATTERY_USAGE_AMOUNT);
 
     private static final Set<String> BACKUP_BLACKLISTED_SECURE_SETTINGS =
              newHashSet(
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 96caf31..83d7218 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -233,6 +233,9 @@
     <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
     <uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"/>
 
+    <!-- Permission required for CTS test - BatterySaverTest -->
+    <uses-permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
+
     <!-- Permission required for CTS test - UiModeManagerTest -->
     <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
 
diff --git a/packages/Shell/res/values-ar/strings.xml b/packages/Shell/res/values-ar/strings.xml
index b81a904..302971f 100644
--- a/packages/Shell/res/values-ar/strings.xml
+++ b/packages/Shell/res/values-ar/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"اختر لمشاركة تقرير الأخطاء بدون لقطة شاشة أو انتظر حتى انتهاء لقطة الشاشة"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"انقر لمشاركة تقرير الأخطاء بدون لقطة شاشة أو انتظر حتى انتهاء لقطة الشاشة"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"انقر لمشاركة تقرير الأخطاء بدون لقطة شاشة أو انتظر حتى انتهاء لقطة الشاشة"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"تحتوي تقارير الأخطاء على بيانات من عدة ملفات سجلات في النظام، بما في ذلك بيانات قد ترى أنها حساسة (مثل بيانات استخدام التطبيقات وبيانات الموقع). ولذلك احرص على عدم مشاركة تقارير الأخطاء إلا مع من تثق به من الأشخاص والتطبيقات."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"تحتوي تقارير الأخطاء على بيانات من عدة ملفات سجلات في النظام، بما قد يشمل بيانات تعتبرها حساسة (مثل بيانات استخدام التطبيقات وبيانات الموقع الجغرافي). ولذلك احرص على عدم مشاركة تقارير الأخطاء إلا مع من تثق به من الأشخاص والتطبيقات."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"عدم الإظهار مرة أخرى"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"تقارير الأخطاء"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"تعذرت قراءة ملف تقرير الخطأ."</string>
diff --git a/packages/Shell/res/values-az/strings.xml b/packages/Shell/res/values-az/strings.xml
index 40800bb..1522f3f 100644
--- a/packages/Shell/res/values-az/strings.xml
+++ b/packages/Shell/res/values-az/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Baq hesabatını skrinşot olmadan paylaşmaq üçün seçin, skrinşotun tamamlanması üçün isə gözləyin"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"baq hesabatınızı skrinşot olmadan paylaşmaq üçün tıklayın, skrinşotun tamamlanması üçün isə gözləyin"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"baq hesabatınızı skrinşot olmadan paylaşmaq üçün tıklayın, skrinşotun tamamlanması üçün isə gözləyin"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Baq raportları sistemin müxtəlif jurnal fayllarından həssas təyin etdiyiniz data (tətbiq istifadəsi və məkan datası kimi) içərir. Baq raportlarını yalnız inandığınız tətbiq və adamlarla paylaşın."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Baq hesabatları sistemin müxtəlif jurnal fayllarından həssas təyin etdiyiniz data (tətbiq istifadəsi və məkan datası kimi) içərir. Baq raportlarını yalnız inandığınız tətbiq və adamlarla paylaşın."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Daha göstərməyin"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Baq hesabatları"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Baq hesabat faylı oxunmur"</string>
diff --git a/packages/Shell/res/values-be/strings.xml b/packages/Shell/res/values-be/strings.xml
index bea1c30..ce369c3 100644
--- a/packages/Shell/res/values-be/strings.xml
+++ b/packages/Shell/res/values-be/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Выберыце, каб абагуліць справаздачу пра памылку без здымка экрана, або чакайце атрымання здымка"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Краніце, каб абагуліць справаздачу пра памылку без здымка экрана, або чакайце атрымання здымка."</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Краніце, каб абагуліць справаздачу пра памылку без здымка экрана, або чакайце атрымання здымка."</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Справаздачы пра памылкі ўтрымліваюць даныя з розных файлаў журналаў сістэмы, якія могуць уключаць даныя, што вы лічыце канфідэнцыяльнымі (напрыклад, пра выкарыстанне праграм і даныя аб месцазнаходжанні). Абагульвайце справаздачы пра памылкі толькі з тымі людзьмі і праграмамі, якім вы давяраеце."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Справаздачы пра памылкі ўтрымліваюць інфармацыю з розных файлаў журналаў сістэмы, у тым ліку і канфідэнцыяльную (напрыклад, даныя, якія датычацца выкарыстання праграм і месцазнаходжання прылады). Абагульвайце справаздачы пра памылкі толькі з тымі людзьмі і праграмамі, якім вы давяраеце."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Не паказваць зноў"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Справадзачы пра памылкі"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Немагчыма прачытаць файл справаздачы пра памылкі"</string>
diff --git a/packages/Shell/res/values-da/strings.xml b/packages/Shell/res/values-da/strings.xml
index d9bf877..c23efc3 100644
--- a/packages/Shell/res/values-da/strings.xml
+++ b/packages/Shell/res/values-da/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Vælg for at dele din fejlrapport uden et screenshot, eller vent på, at et screenshot er klar"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tryk for at dele din fejlrapport uden et screenshot, eller vent på, at screenshott fuldføres"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tryk for at dele din fejlrapport uden et screenshot, eller vent på, at screenshott fuldføres"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Fejlrapporter indeholder data fra systemets forskellige logfiler, som kan være data, du mener er følsomme, f.eks. appforbrug og placeringsdata. Del kun fejlrapporter med personer og apps, du har tillid til."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Fejlrapporter indeholder data fra systemets forskellige logfiler, og der kan være følsomme data imellem (f.eks. appforbrug og placeringsdata). Del kun fejlrapporter med personer og apps, du har tillid til."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Vis ikke igen"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Fejlrapporter"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Fejlrapportfilen kunne ikke læses"</string>
diff --git a/packages/Shell/res/values-eu/strings.xml b/packages/Shell/res/values-eu/strings.xml
index 2957dab..5d32cab 100644
--- a/packages/Shell/res/values-eu/strings.xml
+++ b/packages/Shell/res/values-eu/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Hautatu hau akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Errore-txostenek sistemaren erregistro-fitxategietako datuak dauzkate eta, haietan, kontuzkotzat jotzen duzun informazioa ager daiteke (adibidez, aplikazioen erabilera eta kokapen-datuak). Errore-txostenak partekatzen badituzu, partekatu soilik pertsona eta aplikazio fidagarriekin."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Errore-txostenek sistemaren erregistro-fitxategietako datuak dauzkate, eta, haietan, kontuzkotzat jotzen duzun informazioa ager daiteke (adibidez, aplikazioen erabilera eta kokapen-datuak). Errore-txostenak partekatzen badituzu, partekatu soilik pertsona eta aplikazio fidagarriekin."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ez erakutsi berriro"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Akatsen txostenak"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Ezin izan da irakurri akatsen txostena"</string>
diff --git a/packages/Shell/res/values-fr/strings.xml b/packages/Shell/res/values-fr/strings.xml
index 6fa6f6e..3933557 100644
--- a/packages/Shell/res/values-fr/strings.xml
+++ b/packages/Shell/res/values-fr/strings.xml
@@ -28,9 +28,9 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Sélectionner pour partager le rapport de bug sans capture d\'écran ou attendre la fin de la capture"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Appuyer pour partager rapport de bug sans capture d\'écran ou attendre finalisation capture d\'écran"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Appuyer pour partager rapport de bug sans capture d\'écran ou attendre finalisation capture d\'écran"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Les rapports de bug contiennent des données des fichiers journaux du système, y compris des informations que vous considérez sensibles concernant, par exemple, la consommation par application et la localisation. Nous vous recommandons de ne partager ces rapports qu\'avec des personnes et des applications que vous estimez fiables."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Les rapports de bugs contiennent des données des fichiers journaux du système, y compris des informations que vous considérez sensibles concernant, par exemple, la consommation par application et la localisation. Nous vous recommandons de ne partager ces rapports qu\'avec des personnes et des applications que vous estimez fiables."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ne plus afficher"</string>
-    <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports d\'erreur"</string>
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports de bugs"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Impossible de lire le fichier de rapport de bug."</string>
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Impossible d\'ajouter les détails du rapport de bug au fichier .zip"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"sans nom"</string>
diff --git a/packages/Shell/res/values-hr/strings.xml b/packages/Shell/res/values-hr/strings.xml
index 9cbc09d..4764d17 100644
--- a/packages/Shell/res/values-hr/strings.xml
+++ b/packages/Shell/res/values-hr/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Odaberite za dijeljenje izvješća o pogrešci bez snimke zaslona ili pričekajte da se izradi snimka"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite za dijeljenje izvješća o pogrešci bez snimke zaslona ili pričekajte da se izradi snimka"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite za dijeljenje izvješća o pogrešci bez snimke zaslona ili pričekajte da se izradi snimka"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Izvješća o programskim pogreškama sadržavaju podatke iz različitih datoteka zapisnika sustava, što može uključivati podatke koje smatrate osjetljivima (na primjer podatke o upotrebi aplikacije i lokaciji). Izvješća o programskim pogreškama dijelite samo s osobama i aplikacijama koje smatrate pouzdanima."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Izvješća o programskim pogreškama sadržavaju podatke iz različitih datoteka zapisnika sustava, što može uključivati podatke koje smatrate osjetljivim (na primjer podatke o upotrebi aplikacije i lokaciji). Izvješća o programskim pogreškama dijelite samo s osobama i aplikacijama koje smatrate pouzdanim."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ne prikazuj ponovo"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvj. o prog. pogreš."</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Izvješće o programskoj pogrešci nije pročitano"</string>
diff --git a/packages/Shell/res/values-is/strings.xml b/packages/Shell/res/values-is/strings.xml
index b8c0412..4989e87 100644
--- a/packages/Shell/res/values-is/strings.xml
+++ b/packages/Shell/res/values-is/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Veldu að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Ýttu til að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Ýttu til að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Villutilkynningar innihalda gögn úr ýmsum annálaskrám kerfisins, sem gætu innihaldið upplýsingar sem þú telur viðkvæmar (eins og um notkun forrita og staðsetningarupplýsingar). Deildu villutilkynningum bara með fólki og forritum sem þú treystir."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Villutilkynningar innihalda gögn úr ýmsum annálaskrám kerfisins sem gætu innihaldið upplýsingar sem þú telur viðkvæmar (til dæmis notkun forrita og staðsetningarupplýsingar). Deildu villutilkynningum bara með fólki og forritum sem þú treystir."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Ekki sýna þetta aftur"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Villutilkynningar"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Ekki var hægt að lesa úr villuskýrslunni"</string>
diff --git a/packages/Shell/res/values-km/strings.xml b/packages/Shell/res/values-km/strings.xml
index ec75687..0ab3b68 100644
--- a/packages/Shell/res/values-km/strings.xml
+++ b/packages/Shell/res/values-km/strings.xml
@@ -28,9 +28,9 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"ជ្រើសរើស​ដើម្បី​ចែករំលែក​របាយការណ៍​អំពី​បញ្ហា​របស់​អ្នក​ដោយ​មិនចាំបាច់​មាន​រូបថត​អេក្រង់ ឬ​រង់ចាំ​រូបថត​អេក្រង់ដើម្បីបញ្ចប់"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ប៉ះដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នកដោយមិនចាំបាច់មានរូបថតអេក្រង់ ឬរង់ចាំការបញ្ចប់ការថតអេក្រង់"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ប៉ះដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នកដោយមិនចាំបាច់មានរូបថតអេក្រង់ ឬរង់ចាំការបញ្ចប់ការថតអេក្រង់"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"របាយការណ៍ផ្ទុកទិន្នន័យពីឯកសារកំណត់ហេតុផ្សេងៗរបស់ប្រព័ន្ធ ដែលអាចមានផ្ទុកទិន្នន័យដែលអ្នកចាត់ទុកថាជាទិន្នន័យរសើប (ដូចជាការប្រើប្រាស់កម្មវិធី និងទិន្នន័យទីតាំង)។ ចែករំលែករបាយការណ៍កំហុសជាមួយមនុស្ស និងកម្មវិធីដែលអ្នកជឿជាក់ប៉ុណ្ណោះ។"</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"របាយការណ៍អំពីបញ្ហាផ្ទុកទិន្នន័យពីឯកសារកំណត់ហេតុផ្សេងៗរបស់ប្រព័ន្ធ ដែលអាចរួមបញ្ចូលទិន្នន័យដែលអ្នកចាត់ទុកថាមានលក្ខណៈរសើប (ដូចជាការប្រើប្រាស់កម្មវិធី និងទិន្នន័យទីតាំង)។ ចែករំលែករបាយការណ៍អំពីបញ្ហាជាមួយមនុស្ស និងកម្មវិធីដែលអ្នកជឿជាក់តែប៉ុណ្ណោះ។"</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"កុំបង្ហាញម្ដងទៀត"</string>
-    <string name="bugreport_storage_title" msgid="5332488144740527109">"រាយការណ៍ពីកំហុស"</string>
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"របាយការណ៍អំពីបញ្ហា"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"មិនអាចអានឯកសាររបាយកាណ៍កំហុសបានទេ"</string>
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"មិនអាចបន្ថែមព័ត៌មានលម្អិតនៃរបាយការណ៍កំហុសទៅឯកសារ zip បានទេ"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"គ្មានឈ្មោះ"</string>
diff --git a/packages/Shell/res/values-ko/strings.xml b/packages/Shell/res/values-ko/strings.xml
index 68d4139..545dfa7 100644
--- a/packages/Shell/res/values-ko/strings.xml
+++ b/packages/Shell/res/values-ko/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"스크린샷 없이 버그 신고를 공유하려면 선택하고 그렇지 않으면 스크린샷이 완료될 때까지 기다려 주세요."</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"스크린샷 없이 버그 신고서를 공유하려면 탭하고 그렇지 않으면 스크린샷이 완료될 때까지 기다려 주세요."</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"스크린샷 없이 버그 신고서를 공유하려면 탭하고 그렇지 않으면 스크린샷이 완료될 때까지 기다려 주세요."</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"버그 신고서에는 시스템의 다양한 로그 파일 데이터가 포함되며 여기에는 사용자가 중요하다고 생각하는 데이터(예: 앱 사용 및 위치 데이터)가 포함되었을 수 있습니다. 신뢰할 수 있는 앱과 사용자에게만 버그 신고서를 공유하세요."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"버그 신고서에는 시스템의 다양한 로그 파일 데이터가 포함되며 여기에는 사용자가 민감하다고 생각하는 데이터(예: 앱 사용 및 위치 데이터)가 포함되었을 수 있습니다. 신뢰할 수 있는 앱과 사용자에게만 버그 신고서를 공유하세요."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"다시 표시 안함"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"버그 신고"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"버그 신고 파일을 읽을 수 없습니다."</string>
diff --git a/packages/Shell/res/values-ky/strings.xml b/packages/Shell/res/values-ky/strings.xml
index 2499aba..969e9ed 100644
--- a/packages/Shell/res/values-ky/strings.xml
+++ b/packages/Shell/res/values-ky/strings.xml
@@ -30,7 +30,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Мүчүлүштүк тууралуу билдирүүңүздү скриншотсуз бөлүшүү үчүн таптап коюңуз же скриншот даяр болгуча күтө туруңуз"</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"Мүчүлүштүктөр тууралуу билдирүүлөрдө тутумдун ар кандай таржымалдарынан алынган дайындар, ошондой эле купуя маалымат камтылышы мүмкүн (мисалы, жайгашкан жер сыяктуу). Мындай билдирүүлөрдү бир гана ишеничтүү адамдар жана колдонмолор менен бөлүшүңүз."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Экинчи көрсөтүлбөсүн"</string>
-    <string name="bugreport_storage_title" msgid="5332488144740527109">"Мүчүлүштүктөрдү кабарлоолор"</string>
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"Мүчүлүштүктөрдү кабарлоо"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Мүчүлүштүк тууралуу кабарлаган файл окулбай койду"</string>
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"Мүчүлүштүктөр жөнүндө кабардын чоо-жайы zip файлына кошулбай койду"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"аталышы жок"</string>
diff --git a/packages/Shell/res/values-ml/strings.xml b/packages/Shell/res/values-ml/strings.xml
index 5c1842a..78b43bb 100644
--- a/packages/Shell/res/values-ml/strings.xml
+++ b/packages/Shell/res/values-ml/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ ബഗ് റിപ്പോർട്ട് പങ്കിടുക"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"ബഗ് റിപ്പോർട്ടുകളിൽ സിസ്റ്റത്തിന്റെ നിരവധി ലോഗ് ഫയലുകളിൽ നിന്നുള്ള വിവരങ്ങൾ അടങ്ങിയിരിക്കുന്നു, ഇതിൽ നിങ്ങൾ രഹസ്വസ്വഭാവമുള്ളവയായി പരിഗണിക്കുന്ന വിവരങ്ങളും (ആപ്പ് ഉപയോഗ വിവരങ്ങൾ, ലൊക്കേഷൻ വിവരങ്ങൾ എന്നിവ പോലെ) ഉൾപ്പെടാം. നിങ്ങൾ വിശ്വസിക്കുന്ന ആപ്‌സിനും ആളുകൾക്കും മാത്രം ബഗ് റിപ്പോർട്ടുകൾ പങ്കിടുക."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"ബഗ് റിപ്പോർട്ടുകളിൽ സിസ്റ്റത്തിന്റെ നിരവധി ലോഗ് ഫയലുകളിൽ നിന്നുള്ള വിവരങ്ങൾ അടങ്ങിയിരിക്കുന്നു, ഇതിൽ നിങ്ങൾ രഹസ്യ സ്വഭാവമുള്ളവയായി പരിഗണിക്കുന്ന വിവരങ്ങളും (ആപ്പ് ഉപയോഗ വിവരങ്ങൾ, ലൊക്കേഷൻ വിവരങ്ങൾ എന്നിവ പോലെ) ഉൾപ്പെടാം. നിങ്ങൾ വിശ്വസിക്കുന്ന ആപ്പുകൾക്കും ആളുകൾക്കും മാത്രം ബഗ് റിപ്പോർട്ടുകൾ പങ്കിടുക."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"വീണ്ടും കാണിക്കരുത്"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"ബഗ് റിപ്പോർട്ടുകൾ"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"ബഗ് റിപ്പോർട്ട് ഫയൽ വായിക്കാനായില്ല"</string>
diff --git a/packages/Shell/res/values-ne/strings.xml b/packages/Shell/res/values-ne/strings.xml
index 7cc2e6b..3c58796 100644
--- a/packages/Shell/res/values-ne/strings.xml
+++ b/packages/Shell/res/values-ne/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"तपाईंको बग रिपोर्ट स्क्रिनसट बिना आदान प्रदान गर्नाका लागि चयन गर्नुहोस् वा स्क्रिनसट लिने प्रक्रिया पूरा हुने प्रतीक्षा गर्नुहोस्"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"तपाईँको बग रिपोर्टलाई स्क्रिनसट बिना साझेदारी गर्नाका लागि ट्याप गर्नुहोस् वा स्क्रिनसट लिने प्रक्रिया पूरा हुन प्रतीक्षा गर्नुहोस्"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"तपाईँको बग रिपोर्टलाई स्क्रिनसट बिना साझेदारी गर्नाका लागि ट्याप गर्नुहोस् वा स्क्रिनसट लिने प्रक्रिया पूरा हुन प्रतीक्षा गर्नुहोस्"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"बग रिपोर्टमा प्रणालीका विभिन्न लग फाइलहरूको डेटा हुन्छ। यस रिपोर्टमा (अनुप्रयोगको प्रयोग र स्थानसम्बन्धी डेटा जस्ता) जसमा तपाईंका संवेदनशील डेटा समावेश हुन सक्छ । आफूले विश्वास गर्ने व्यक्ति र अनुप्रयोगहरूसँग मात्र बग रिपोर्ट सेयर गर्नुहोस्।"</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"बग रिपोर्टमा प्रणालीका विभिन्न लग फाइलहरूको डेटा हुन्छ। यस रिपोर्टमा (एपको प्रयोग र स्थानसम्बन्धी डेटा जस्ता) जसमा तपाईंका संवेदनशील डेटा समावेश हुन सक्छ । आफूले विश्वास गर्ने व्यक्ति र अनुप्रयोगहरूसँग मात्र बग रिपोर्ट सेयर गर्नुहोस्।"</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"फेरि नदेखाउनुहोस्"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"बग रिपोर्टहरू"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"बग रिपोर्ट फाइल पढ्न सकिएन"</string>
diff --git a/packages/Shell/res/values-pa/strings.xml b/packages/Shell/res/values-pa/strings.xml
index 8894814..d0c2905 100644
--- a/packages/Shell/res/values-pa/strings.xml
+++ b/packages/Shell/res/values-pa/strings.xml
@@ -30,7 +30,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੇ ਬਿਨਾਂ ਆਪਣੀ ਬੱਗ ਰਿਪੋਰਟ ਨੂੰ ਸਾਂਝੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਜਾਂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੇ ਪੂਰੇ ਹੋਣ ਦੀ ਉਡੀਕ ਕਰੋ"</string>
     <string name="bugreport_confirm" msgid="5917407234515812495">"ਬੱਗ ਰਿਪੋਰਟਾਂ ਵਿੱਚ ਸਿਸਟਮ ਦੀਆਂ ਵੱਖ-ਵੱਖ ਲੌਗ ਫ਼ਾਈਲਾਂ ਦਾ ਡਾਟਾ ਸ਼ਾਮਲ ਹੁੰਦਾ ਹੈ, ਜਿਸ ਵਿੱਚ ਉਹ ਡਾਟਾ ਸ਼ਾਮਲ ਹੋ ਸਕਦਾ ਹੈ ਜਿਸ ਨੂੰ ਤੁਸੀਂ ਸੰਵੇਦਨਸ਼ੀਲ ਮੰਨਦੇ ਹੋ (ਜਿਵੇਂ ਕਿ ਐਪ-ਵਰਤੋਂ ਅਤੇ ਟਿਕਾਣਾ ਡਾਟਾ)। ਬੱਗ ਰਿਪੋਰਟਾਂ ਨੂੰ ਸਿਰਫ਼ ਆਪਣੇ ਭਰੋਸੇਯੋਗ ਲੋਕਾਂ ਅਤੇ ਐਪਾਂ ਨਾਲ ਸਾਂਝਾ ਕਰੋ।"</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"ਦੁਬਾਰਾ ਨਾ  ਦਿਖਾਓ"</string>
-    <string name="bugreport_storage_title" msgid="5332488144740527109">"ਬਗ ਰਿਪੋਰਟਾਂ"</string>
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"ਬੱਗ ਰਿਪੋਰਟਾਂ"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"ਬਗ ਰਿਪੋਰਟ ਫ਼ਾਈਲ ਪੜ੍ਹੀ ਨਹੀਂ ਜਾ ਸਕੀ"</string>
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"ਬੱਗ ਰਿਪੋਰਟ ਵੇਰਵਿਆਂ ਨੂੰ ਜ਼ਿਪ ਫ਼ਾਈਲ ਵਿੱਚ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"ਬਿਨਾਂ-ਨਾਮ"</string>
diff --git a/packages/Shell/res/values-pt-rPT/strings.xml b/packages/Shell/res/values-pt-rPT/strings.xml
index 3d11d4d..34013fa 100644
--- a/packages/Shell/res/values-pt-rPT/strings.xml
+++ b/packages/Shell/res/values-pt-rPT/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Selecione para partilhar o relatório de erro sem uma captura de ecrã ou aguarde a conclusão da mesma"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toque para partilhar o relatório de erro sem uma captura de ecrã ou aguarde a conclusão da mesma"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toque para partilhar o relatório de erro sem uma captura de ecrã ou aguarde a conclusão da mesma"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Os relatórios de erros contêm dados de vários ficheiros de registo do sistema, que podem incluir dados que considere confidenciais (tais como dados de utilização de aplicações e de localização). Partilhe os relatórios de erros apenas com aplicações fidedignas e pessoas em quem confia."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Os relatórios de erros contêm dados de vários ficheiros de registo do sistema, que podem incluir dados que considere confidenciais (tais como dados de utilização de apps e de localização). Partilhe os relatórios de erros apenas com apps fidedignas e pessoas em quem confia."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Não mostrar de novo"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de erros"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Não foi possível ler o ficheiro de relatório de erro"</string>
diff --git a/packages/Shell/res/values-sk/strings.xml b/packages/Shell/res/values-sk/strings.xml
index 61a2467..ecceb55 100644
--- a/packages/Shell/res/values-sk/strings.xml
+++ b/packages/Shell/res/values-sk/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"Klepnutím zdieľajte hlásenie chyby bez snímky obrazovky alebo počkajte na dokončenie snímky obrazovky"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Klepnutím zdieľajte hlásenie chyby bez snímky obrazovky alebo počkajte na dokončenie snímky obrazovky"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Klepnutím zdieľajte hlásenie chyby bez snímky obrazovky alebo počkajte na dokončenie snímky obrazovky"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"Hlásenia chýb obsahujú údaje z rôznych súborov denníkov systému, ktoré môžu zahŕňať údaje považované za citlivé (napr. údaje o využití aplikácie a polohe). Zdieľajte ich preto iba s dôveryhodnými ľuďmi a aplikáciami."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"Hlásenia chýb obsahujú údaje z rôznych denníkov systému a môžu zahŕňať údaje, ktoré považujete za citlivé (napríklad údaje o využití aplikácií a polohe). Zdieľajte hlásenia chýb iba s ľuďmi a aplikáciami, ktorým dôverujete."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"Nabudúce nezobrazovať"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"Hlásenia chýb"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"Súbor s hlásením chyby sa nepodarilo prečítať"</string>
diff --git a/packages/Shell/res/values-te/strings.xml b/packages/Shell/res/values-te/strings.xml
index bb0496a..6050c1f 100644
--- a/packages/Shell/res/values-te/strings.xml
+++ b/packages/Shell/res/values-te/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="3701846017049540910">"షెల్"</string>
-    <string name="bugreport_notification_channel" msgid="2574150205913861141">"బగ్ నివేదికలు"</string>
+    <string name="bugreport_notification_channel" msgid="2574150205913861141">"బగ్ రిపోర్ట్స్"</string>
     <string name="bugreport_in_progress_title" msgid="4311705936714972757">"బగ్ నివేదిక <xliff:g id="ID">#%d</xliff:g> ఉత్పాదించబడుతోంది"</string>
     <string name="bugreport_finished_title" msgid="4429132808670114081">"బగ్ నివేదిక <xliff:g id="ID">#%d</xliff:g> సంగ్రహించబడింది"</string>
     <string name="bugreport_updating_title" msgid="4423539949559634214">"బగ్ నివేదికకు వివరాలను జోడిస్తోంది"</string>
@@ -28,9 +28,9 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"స్క్రీన్‌షాట్ లేకుండా మీ బగ్ నివేదికను భాగస్వామ్యం చేయడానికి ఎంచుకోండి లేదా స్క్రీన్‌షాట్ ముగిసేదాకా వేచి ఉండండి"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"స్క్రీన్‌షాట్ లేకుండా మీ బగ్ నివే. భాగ. చేయడానికి నొక్కండి లేదా స్క్రీన్‌షాట్ ముగిసేదాకా వేచి ఉండండి"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"స్క్రీన్‌షాట్ లేకుండా మీ బగ్ నివే. భాగ. చేయడానికి నొక్కండి లేదా స్క్రీన్‌షాట్ ముగిసేదాకా వేచి ఉండండి"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"బగ్ నివేదికల్లో మీరు గోప్యమైనదిగా పరిగణించే (యాప్ వినియోగం, లొకేష‌న్‌ డేటా వంటి) డేటాతో పాటు సిస్టమ్‌కు సంబంధించిన విభిన్న లాగ్ ఫైల్‌ల డేటా ఉంటుంది. బగ్ నివేదికలను మీరు విశ్వసించే యాప్‌లు, వ్యక్తులతో మాత్రమే షేర్ చేయండి."</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"బగ్ రిపోర్ట్స్‌లో మీరు గోప్యమైనదిగా పరిగణించే (యాప్ వినియోగం, లొకేష‌న్‌ డేటా వంటి) డేటాతో పాటు సిస్టమ్‌కు సంబంధించిన విభిన్న లాగ్ ఫైల్‌ల డేటా ఉంటుంది. బగ్ నివేదికలను మీరు విశ్వసించే యాప్‌లు, వ్యక్తులతో మాత్రమే షేర్ చేయండి."</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"మళ్లీ చూపవద్దు"</string>
-    <string name="bugreport_storage_title" msgid="5332488144740527109">"బగ్ నివేదికలు"</string>
+    <string name="bugreport_storage_title" msgid="5332488144740527109">"బగ్ రిపోర్ట్స్"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"బగ్ నివేదిక ఫైల్‌ను చదవడం సాధ్యపడలేదు"</string>
     <string name="bugreport_add_details_to_zip_failed" msgid="1302931926486712371">"బగ్ నివేదిక వివరాలను జిప్ ఫైల్‌కు జోడించడం సాధ్యపడలేదు"</string>
     <string name="bugreport_unnamed" msgid="2800582406842092709">"పేరు లేనివి"</string>
diff --git a/packages/Shell/res/values-zh-rHK/strings.xml b/packages/Shell/res/values-zh-rHK/strings.xml
index 8298d15..ccbea4d 100644
--- a/packages/Shell/res/values-zh-rHK/strings.xml
+++ b/packages/Shell/res/values-zh-rHK/strings.xml
@@ -28,7 +28,7 @@
     <string name="bugreport_finished_pending_screenshot_text" product="tv" msgid="2343263822812016950">"選擇以分享錯誤報告 (不包含螢幕擷取畫面),或等待螢幕畫面擷取完成"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕按以分享錯誤報告 (不包含螢幕擷圖),或等待螢幕畫面擷取完成"</string>
     <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕按以分享錯誤報告 (不包含螢幕擷圖),或等待螢幕畫面擷取完成"</string>
-    <string name="bugreport_confirm" msgid="5917407234515812495">"錯誤報告包含來自系統各個記錄檔案的資料,並可能涉及敏感資料 (例如應用程式使用情況和位置資料)。您只應與信任的人和應用程式分享錯誤報告。"</string>
+    <string name="bugreport_confirm" msgid="5917407234515812495">"錯誤報告包含來自系統多個記錄檔案的資料,並可能涉及對您而言敏感的資料 (例如應用程式使用情況和位置資料)。您只應與信任的人和應用程式分享錯誤報告。"</string>
     <string name="bugreport_confirm_dont_repeat" msgid="6179945398364357318">"不要再顯示"</string>
     <string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string>
     <string name="bugreport_unreadable_text" msgid="586517851044535486">"無法讀取錯誤報告檔案"</string>
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 61b1e30..c4ea2e9 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -259,6 +259,9 @@
     <!-- Permission to register process observer -->
     <uses-permission android:name="android.permission.SET_ACTIVITY_WATCHER"/>
 
+    <!-- Restore settings (used by QS) even if they have been modified -->
+    <uses-permission android:name="android.permission.MODIFY_SETTINGS_OVERRIDEABLE_BY_RESTORE" />
+
     <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
     <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index aeedc16..e246917 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -66,14 +66,6 @@
 
     void destroy();
 
-    /**
-      * return true if the tile supports detail views, and not
-      * only boolean states
-      */
-    default boolean supportsDetailView() {
-        return false;
-    }
-
     CharSequence getTileLabel();
 
     State getState();
diff --git a/packages/SystemUI/res/drawable/control_no_favorites_background.xml b/packages/SystemUI/res/drawable/control_no_favorites_background.xml
index 947c77b..d895dd0 100644
--- a/packages/SystemUI/res/drawable/control_no_favorites_background.xml
+++ b/packages/SystemUI/res/drawable/control_no_favorites_background.xml
@@ -16,7 +16,22 @@
 * limitations under the License.
 */
 -->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-  <stroke android:width="1dp" android:color="@*android:color/foreground_material_dark"/>
-  <corners android:radius="@dimen/control_corner_radius" />
-</shape>
+<!-- Should be kept in sync with the wallet plugin, as both share a similar
+     design: packages/apps/QuickAccessWallet -->
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?android:attr/colorControlHighlight">
+    <item android:id="@android:id/mask">
+        <shape android:shape="rectangle">
+            <solid android:color="#000000" />
+            <corners android:radius="@dimen/control_corner_radius" />
+        </shape>
+    </item>
+    <item>
+        <shape>
+            <stroke
+                android:width="1dp"
+                android:color="#4DFFFFFF" />
+            <corners android:radius="@dimen/control_corner_radius"/>
+        </shape>
+    </item>
+</ripple>
diff --git a/packages/SystemUI/res/drawable/ic_screen_record_background.xml b/packages/SystemUI/res/drawable/ic_screen_record_background.xml
index 9195305..59eb023 100644
--- a/packages/SystemUI/res/drawable/ic_screen_record_background.xml
+++ b/packages/SystemUI/res/drawable/ic_screen_record_background.xml
@@ -13,13 +13,11 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:tint="?android:attr/colorError"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0">
-    <path
-        android:pathData="M10,0L14,0A10,10 0,0 1,24 10L24,10A10,10 0,0 1,14 20L10,20A10,10 0,0 1,0 10L0,10A10,10 0,0 1,10 0z"
-        android:fillColor="@android:color/white"/>
-</vector>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+        android:shape="rectangle">
+    <solid
+        android:color="@color/screenrecord_status_color"
+        android:width="@dimen/screenrecord_status_icon_width"
+        android:height="@dimen/screenrecord_status_icon_height" />
+    <corners android:radius="@dimen/screenrecord_status_icon_bg_radius" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_screenrecord.xml b/packages/SystemUI/res/drawable/ic_screenrecord.xml
index 6d8bd0d..d4f807a 100644
--- a/packages/SystemUI/res/drawable/ic_screenrecord.xml
+++ b/packages/SystemUI/res/drawable/ic_screenrecord.xml
@@ -1,7 +1,7 @@
 <!--
-    Copyright (C) 2020 The Android Open Source Project
+Copyright (C) 2020 The Android Open Source Project
 
-    Licensed under the Apache License, Version 2.0 (the "License");
+   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
 
@@ -14,12 +14,12 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="24dp"
-    android:height="24dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0"
-    android:tint="?android:attr/colorControlNormal">
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
     <path
-        android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"
-        android:fillColor="#FFFFFFFF"/>
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12,16c-2.21,0 -4,-1.79 -4,-4c0,-2.21 1.79,-4 4,-4c2.21,0 4,1.79 4,4C16,14.21 14.21,16 12,16zM11.99,1.99c-2.22,0 -4.26,0.73 -5.92,1.96l1.44,1.44c1.28,-0.87 2.82,-1.39 4.49,-1.39c1.67,0 3.21,0.52 4.5,1.4l1.44,-1.44C16.26,2.72 14.22,1.99 11.99,1.99zM16.48,18.6c-1.28,0.87 -2.82,1.39 -4.49,1.39c-1.66,0 -3.2,-0.52 -4.47,-1.39l-1.44,1.44c1.66,1.22 3.7,1.95 5.91,1.95c2.22,0 4.26,-0.73 5.92,-1.95L16.48,18.6zM5.39,16.49c-0.88,-1.28 -1.4,-2.83 -1.4,-4.5c0,-1.66 0.52,-3.21 1.39,-4.49L3.95,6.07c-1.22,1.66 -1.95,3.7 -1.95,5.92c0,2.22 0.73,4.27 1.96,5.93L5.39,16.49zM20.04,6.08l-1.44,1.44c0.87,1.28 1.39,2.82 1.39,4.47c0,1.66 -0.52,3.2 -1.39,4.49l1.44,1.44c1.22,-1.66 1.96,-3.7 1.96,-5.92C21.99,9.78 21.26,7.73 20.04,6.08z"/>
 </vector>
diff --git a/packages/SystemUI/res/layout-land/global_screenshot_preview.xml b/packages/SystemUI/res/layout-land/global_screenshot_preview.xml
new file mode 100644
index 0000000..b1f4cb7
--- /dev/null
+++ b/packages/SystemUI/res/layout-land/global_screenshot_preview.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+<ImageView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/global_screenshot_preview"
+    android:layout_width="wrap_content"
+    android:layout_height="@dimen/global_screenshot_x_scale"
+    android:layout_gravity="center"
+    android:layout_marginStart="@dimen/screenshot_offset_x"
+    android:layout_marginBottom="@dimen/screenshot_offset_y"
+    android:scaleType="fitStart"
+    android:elevation="@dimen/screenshot_preview_elevation"
+    android:visibility="gone"
+    android:background="@drawable/screenshot_rounded_corners"
+    android:adjustViewBounds="true"
+    android:contentDescription="@string/screenshot_preview_description"
+    app:layout_constraintBottom_toBottomOf="parent"
+    app:layout_constraintStart_toStartOf="parent"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/bubble_overflow_view.xml b/packages/SystemUI/res/layout/bubble_overflow_view.xml
index 1ed1f07..1218fba 100644
--- a/packages/SystemUI/res/layout/bubble_overflow_view.xml
+++ b/packages/SystemUI/res/layout/bubble_overflow_view.xml
@@ -30,9 +30,8 @@
 
     <TextView
         android:id="@+id/bubble_view_name"
-        android:fontFamily="@*android:string/config_bodyFontFamily"
-        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"
-        android:textColor="?android:attr/textColorSecondary"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem"
+        android:textSize="13sp"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:maxLines="1"
diff --git a/packages/SystemUI/res/layout/controls_dialog_pin.xml b/packages/SystemUI/res/layout/controls_dialog_pin.xml
index 832c48e..170b32b 100644
--- a/packages/SystemUI/res/layout/controls_dialog_pin.xml
+++ b/packages/SystemUI/res/layout/controls_dialog_pin.xml
@@ -26,6 +26,7 @@
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:minHeight="48dp"
+      android:longClickable="false"
       android:inputType="numberPassword" />
   <CheckBox
       android:id="@+id/controls_pin_use_alpha"
diff --git a/packages/SystemUI/res/layout/controls_icon.xml b/packages/SystemUI/res/layout/controls_icon.xml
index cc46ced..12bc5f6 100644
--- a/packages/SystemUI/res/layout/controls_icon.xml
+++ b/packages/SystemUI/res/layout/controls_icon.xml
@@ -19,8 +19,8 @@
 
 <ImageView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="28dp"
-    android:layout_height="28dp"
+    android:layout_width="24dp"
+    android:layout_height="24dp"
     android:scaleType="fitCenter"
-    android:layout_marginLeft="2dp"
-    android:layout_marginRight="2dp" />
+    android:layout_marginLeft="5dp"
+    android:layout_marginRight="5dp" />
diff --git a/packages/SystemUI/res/layout/controls_no_favorites.xml b/packages/SystemUI/res/layout/controls_no_favorites.xml
index 4128230..1b24ee9 100644
--- a/packages/SystemUI/res/layout/controls_no_favorites.xml
+++ b/packages/SystemUI/res/layout/controls_no_favorites.xml
@@ -24,11 +24,10 @@
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:orientation="vertical"
-      android:paddingTop="40dp"
-      android:paddingBottom="40dp"
-      android:layout_marginLeft="10dp"
-      android:layout_marginRight="10dp"
-      android:layout_marginTop="@dimen/controls_top_margin"
+      android:paddingVertical="@dimen/controls_setup_vertical_padding"
+      android:layout_marginLeft="@dimen/global_actions_side_margin"
+      android:layout_marginRight="@dimen/global_actions_side_margin"
+      android:layout_marginTop="@dimen/controls_setup_top_margin"
       android:background="@drawable/control_no_favorites_background">
 
     <LinearLayout
@@ -37,7 +36,7 @@
         android:layout_height="wrap_content"
         android:layout_gravity="center"
         android:orientation="horizontal"
-        android:paddingBottom="8dp" />
+        android:layout_marginBottom="16dp" />
 
     <TextView
         style="@style/TextAppearance.ControlSetup.Title"
diff --git a/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml
index 477ec6a..1b42ceb 100644
--- a/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml
@@ -20,51 +20,35 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="0dp"
     android:layout_weight="1"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    android:paddingTop="@dimen/global_actions_grid_item_vertical_margin"
-    android:paddingBottom="@dimen/global_actions_grid_item_vertical_margin"
+    android:layout_height="98dp"
+    android:gravity="bottom|center_horizontal"
+    android:orientation="vertical"
+    android:paddingTop="12dp"
+    android:paddingBottom="12dp"
     android:paddingLeft="@dimen/global_actions_grid_item_side_margin"
     android:paddingRight="@dimen/global_actions_grid_item_side_margin"
     android:layout_marginRight="@dimen/control_base_item_margin"
     android:layout_marginLeft="@dimen/control_base_item_margin"
     android:stateListAnimator="@anim/control_state_list_animator"
     android:background="@drawable/control_background">
-    <LinearLayout
-        android:layout_width="@dimen/global_actions_grid_item_width"
-        android:layout_height="@dimen/global_actions_grid_item_height"
-        android:gravity="top|center_horizontal"
-        android:orientation="vertical">
         <ImageView
             android:id="@*android:id/icon"
-            android:layout_width="@dimen/global_actions_grid_item_icon_width"
-            android:layout_height="@dimen/global_actions_grid_item_icon_height"
-            android:layout_marginTop="@dimen/global_actions_grid_item_icon_top_margin"
-            android:layout_marginBottom="@dimen/global_actions_grid_item_icon_bottom_margin"
-            android:layout_marginLeft="@dimen/global_actions_grid_item_icon_side_margin"
-            android:layout_marginRight="@dimen/global_actions_grid_item_icon_side_margin"
+            android:layout_width="20dp"
+            android:layout_height="20dp"
+            android:layout_marginBottom="14dp"
             android:scaleType="centerInside"
-            android:tint="@color/control_default_foreground" />
-
+            android:tint="@color/control_primary_text" />
         <TextView
             android:id="@*android:id/message"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:ellipsize="marquee"
             android:marqueeRepeatLimit="marquee_forever"
-            android:singleLine="true"
+            android:maxLines="2"
+            android:textSize="12sp"
             android:gravity="center"
-            android:textSize="12dp"
-            android:textColor="@color/control_default_foreground"
+            android:textColor="@color/control_primary_text"
+            android:breakStrategy="high_quality"
+            android:hyphenationFrequency="full"
             android:textAppearance="?android:attr/textAppearanceSmall" />
-
-        <TextView
-            android:visibility="gone"
-            android:id="@*android:id/status"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            android:textColor="@color/control_default_foreground"
-            android:textAppearance="?android:attr/textAppearanceSmall" />
-    </LinearLayout>
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml
index 1dbb38d..d469e0f 100644
--- a/packages/SystemUI/res/layout/global_screenshot.xml
+++ b/packages/SystemUI/res/layout/global_screenshot.xml
@@ -71,21 +71,7 @@
         android:elevation="@dimen/screenshot_preview_elevation"
         android:background="@drawable/screenshot_rounded_corners"
         android:adjustViewBounds="true"/>
-    <ImageView
-        android:id="@+id/global_screenshot_preview"
-        android:layout_width="@dimen/global_screenshot_x_scale"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center"
-        android:layout_marginStart="@dimen/screenshot_offset_x"
-        android:layout_marginBottom="@dimen/screenshot_offset_y"
-        android:scaleType="fitEnd"
-        android:elevation="@dimen/screenshot_preview_elevation"
-        android:visibility="gone"
-        android:background="@drawable/screenshot_rounded_corners"
-        android:adjustViewBounds="true"
-        android:contentDescription="@string/screenshot_preview_description"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"/>
+    <include layout="@layout/global_screenshot_preview"/>
     <FrameLayout
         android:id="@+id/global_screenshot_dismiss_button"
         android:layout_width="@dimen/screenshot_dismiss_button_tappable_size"
diff --git a/packages/SystemUI/res/layout/global_screenshot_preview.xml b/packages/SystemUI/res/layout/global_screenshot_preview.xml
new file mode 100644
index 0000000..e6295f5
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_screenshot_preview.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2011 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<ImageView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/global_screenshot_preview"
+    android:layout_width="@dimen/global_screenshot_x_scale"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:layout_marginStart="@dimen/screenshot_offset_x"
+    android:layout_marginBottom="@dimen/screenshot_offset_y"
+    android:scaleType="fitEnd"
+    android:elevation="@dimen/screenshot_preview_elevation"
+    android:visibility="gone"
+    android:background="@drawable/screenshot_rounded_corners"
+    android:adjustViewBounds="true"
+    android:contentDescription="@string/screenshot_preview_description"
+    app:layout_constraintBottom_toBottomOf="parent"
+    app:layout_constraintStart_toStartOf="parent"/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/partial_conversation_info.xml b/packages/SystemUI/res/layout/partial_conversation_info.xml
index 2401dfb..a261114 100644
--- a/packages/SystemUI/res/layout/partial_conversation_info.xml
+++ b/packages/SystemUI/res/layout/partial_conversation_info.xml
@@ -144,25 +144,36 @@
         android:clipToPadding="false"
         android:orientation="vertical">
 
-        <LinearLayout
+        <com.android.systemui.statusbar.notification.row.ButtonLinearLayout
+            android:id="@+id/settings_link"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:clipChildren="false"
-            android:clipToPadding="false"
-            android:orientation="horizontal">
-            <ImageView
-                android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:contentDescription="@null"
-                android:src="@drawable/ic_info"
-                android:tint="?android:attr/textColorPrimary"
-                android:layout_marginEnd="8dp"/>
-            <TextView
-                android:id="@+id/non_configurable_text"
+            android:padding="@dimen/notification_importance_button_padding"
+            android:clickable="true"
+            android:focusable="true"
+            android:background="@drawable/notification_guts_priority_button_bg"
+            android:orientation="vertical">
+
+            <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                style="@style/TextAppearance.NotificationImportanceChannelGroup" />
-        </LinearLayout>
+                android:clipChildren="false"
+                android:clipToPadding="false"
+                android:orientation="horizontal">
+                <ImageView
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:contentDescription="@null"
+                    android:src="@drawable/ic_info"
+                    android:tint="?android:attr/textColorPrimary"
+                    android:layout_marginEnd="8dp"/>
+                <TextView
+                    android:id="@+id/non_configurable_text"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    style="@style/TextAppearance.NotificationImportanceChannelGroup" />
+            </LinearLayout>
+        </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
 
         <RelativeLayout
             android:id="@+id/bottom_buttons"
diff --git a/packages/SystemUI/res/layout/qs_media_panel.xml b/packages/SystemUI/res/layout/qs_media_panel.xml
index 9ad380d..bf06242 100644
--- a/packages/SystemUI/res/layout/qs_media_panel.xml
+++ b/packages/SystemUI/res/layout/qs_media_panel.xml
@@ -49,6 +49,7 @@
             android:layout_height="wrap_content"
             android:layout_alignParentLeft="true"
             android:fontFamily="@*android:string/config_bodyFontFamily"
+            android:textColor="@color/media_primary_text"
             android:gravity="left"
             android:textSize="14sp" />
 
@@ -58,6 +59,7 @@
             android:layout_height="wrap_content"
             android:layout_alignParentRight="true"
             android:fontFamily="@*android:string/config_bodyFontFamily"
+            android:textColor="@color/media_primary_text"
             android:gravity="right"
             android:textSize="14sp" />
     </FrameLayout>
@@ -116,6 +118,7 @@
             android:layout_width="@dimen/qs_seamless_icon_size"
             android:layout_height="@dimen/qs_seamless_icon_size"
             android:layout_marginRight="8dp"
+            android:tint="@color/media_primary_text"
             android:src="@*android:drawable/ic_media_seamless" />
 
         <TextView
@@ -125,6 +128,7 @@
             android:fontFamily="@*android:string/config_bodyFontFamily"
             android:singleLine="true"
             android:text="@*android:string/ext_media_seamless_action"
+            android:textColor="@color/media_primary_text"
             android:textSize="14sp" />
     </LinearLayout>
 
@@ -138,11 +142,15 @@
         android:maxHeight="3dp"
         android:paddingTop="16dp"
         android:paddingBottom="16dp"
+        android:thumbTint="@color/media_primary_text"
+        android:progressTint="@color/media_seekbar_progress"
+        android:progressBackgroundTint="@color/media_disabled"
         android:splitTrack="false" />
 
     <!-- App name -->
     <TextView
         android:id="@+id/app_name"
+        android:textColor="@color/media_primary_text"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:singleLine="true"
@@ -155,6 +163,7 @@
         android:layout_height="wrap_content"
         android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
         android:singleLine="true"
+        android:textColor="@color/media_primary_text"
         android:textSize="18sp" />
 
     <!-- Artist name -->
@@ -164,10 +173,12 @@
         android:layout_height="wrap_content"
         android:fontFamily="@*android:string/config_bodyFontFamily"
         android:singleLine="true"
+        android:textColor="@color/media_primary_text"
         android:textSize="14sp" />
 
     <com.android.internal.widget.CachingIconView
         android:id="@+id/icon"
+        android:tint="@color/media_primary_text"
         android:layout_width="16dp"
         android:layout_height="16dp" />
 
diff --git a/packages/SystemUI/res/layout/qs_media_panel_options.xml b/packages/SystemUI/res/layout/qs_media_panel_options.xml
index 46655e7..e72c0e8 100644
--- a/packages/SystemUI/res/layout/qs_media_panel_options.xml
+++ b/packages/SystemUI/res/layout/qs_media_panel_options.xml
@@ -36,6 +36,7 @@
             android:layout_height="18dp"
             android:id="@+id/remove_icon"
             android:layout_marginEnd="16dp"
+            android:tint="@color/media_primary_text"
             android:src="@drawable/ic_clear"/>
         <TextView
             android:layout_width="wrap_content"
@@ -43,6 +44,7 @@
             android:id="@+id/remove_text"
             android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
             android:singleLine="true"
+            android:textColor="@color/media_primary_text"
             android:text="@string/controls_media_close_session" />
     </LinearLayout>
     <TextView
@@ -54,5 +56,6 @@
         android:layout_gravity="end|bottom"
         android:gravity="bottom"
         android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+        android:textColor="@android:color/white"
         android:text="@string/cancel" />
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout/qs_tile_detail_text.xml b/packages/SystemUI/res/layout/qs_tile_detail_text.xml
deleted file mode 100644
index bcbf826..0000000
--- a/packages/SystemUI/res/layout/qs_tile_detail_text.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2019 The Android Open Source Project
-
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<!-- use 'dp' instead of 'sp' as we do not want the text to increase
-     if the user scales the font size -->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="bottom|center_horizontal"
-    android:text="..."
-    android:textSize="16dp"
-    android:fontFamily="@*android:string/config_headlineFontFamily"
-    android:singleLine="true"
-    android:visibility="gone"
-    android:paddingBottom="@dimen/qs_tile_detail_padding"
-    android:clickable="false"
-    android:focusable="false" />
-
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index e341f56..4d128ce 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Maak skermkiekie toe"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Skermkiekievoorskou"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skermopnemer"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Verwerk tans skermopname"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Deurlopende kennisgewing vir \'n skermopnamesessie"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Begin opname?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Terwyl dit opneem, kan die Android-stelsel enige sensitiewe inligting wat op jou skerm sigbaar is of wat op jou toestel gespeel word, vasvang. Dit sluit wagwoorde, betalinginligting, foto\'s, boodskappe en oudio in."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Vee alles uit"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Bestuur"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Geskiedenis"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Inkomend"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Stil kennisgewings"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Opletkennisgewings"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Gesprekke"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Titelloos"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tik om hierdie program te herbegin en maak volskerm oop."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Instellings vir <xliff:g id="APP_NAME">%1$s</xliff:g>-borrels"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Oorloop"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Voeg terug op stapel"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Bestuur"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> vanaf <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> van <xliff:g id="APP_NAME">%2$s</xliff:g> en <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> meer af"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 85e06c3..f811dc7 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ቅጽበታዊ ገጽ እይታን አሰናብት"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"የቅጽበታዊ ገጽ ዕይታ ቅድመ-ዕይታ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"የማያ መቅጃ"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"የማያ ገጽ ቀረጻን በማሰናዳት ላይ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ለአንድ የማያ ገጽ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"መቅረጽ ይጀመር?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"እየቀረጹ ሳለ የAndroid ስርዓት በማያ ገጽዎ ላይ የሚታይ ወይም በመሣሪያዎ ላይ የሚጫወት ማንኛውም ሚስጥራዊነት ያለው መረጃን መያዝ ይችላል። ይህ የይለፍ ቃላትን፣ የክፍያ መረጃን፣ ፎቶዎችን፣ መልዕክቶችን እና ኦዲዮን ያካትታል።"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ሁሉንም አጽዳ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ያቀናብሩ"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ታሪክ"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"ገቢ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ጸጥ ያሉ ማሳወቂያዎች"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"የማንቂያ ማሳወቂያዎች"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ውይይቶች"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"ርዕስ የለም"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ይህን መተግበሪያ እንደገና ለማስጀመር መታ ያድርጉ እና ወደ ሙሉ ማያ ገጽ ይሂዱ።"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"ቅንብሮች ለ <xliff:g id="APP_NAME">%1$s</xliff:g> አረፋዎች"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ትርፍ ፍሰት"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ወደ ቁልል መልሰው ያክሉ"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"ያቀናብሩ"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ከ<xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ከ <xliff:g id="APP_NAME">%2$s</xliff:g> እና <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ተጨማሪ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index e6388e9..749241d 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"إغلاق لقطة الشاشة"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"معاينة لقطة الشاشة"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"مسجّل الشاشة"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"جارٍ معالجة تسجيل الشاشة"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"إشعار مستمر لجلسة تسجيل شاشة"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"هل تريد بدء التسجيل؟"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"‏أثناء التسجيل، يمكن أن يسجّل نظام Android أي معلومات حساسة مرئية على شاشتك أو يتم تشغيلها على جهازك. ويشمل ذلك كلمات المرور ومعلومات الدفع والصور والرسائل والمقاطع الصوتية."</string>
@@ -523,8 +522,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"محو الكل"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"إدارة"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"السجلّ"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"الإشعارات الواردة"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"الإشعارات الصامتة"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"إشعارات التنبيه"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"المحادثات"</string>
@@ -1011,10 +1009,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"بلا عنوان"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"انقر لإعادة تشغيل هذا التطبيق والانتقال إلى وضع ملء الشاشة."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"إعدادات فقاعات المحادثات على <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"القائمة الكاملة"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"إضافة دعم إلى الحزم"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"إدارة"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> من <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> من <xliff:g id="APP_NAME">%2$s</xliff:g> و<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> أيضًا"</string>
@@ -1063,10 +1059,8 @@
     <string name="controls_favorite_load_error" msgid="2533215155804455348">"تعذّر تحميل قائمة كل عناصر التحكّم."</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"غير ذلك"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"إضافة إلى أدوات التحكم بالجهاز"</string>
-    <!-- no translation found for controls_dialog_ok (2770230012857881822) -->
-    <skip />
-    <!-- no translation found for controls_dialog_message (342066938390663844) -->
-    <skip />
+    <string name="controls_dialog_ok" msgid="2770230012857881822">"إضافة"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"اقتراح من <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"تم تعديل عناصر التحكّم."</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"يشتمل رقم التعريف الشخصي على أحرف أو رموز."</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"إثبات ملكية <xliff:g id="DEVICE">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index df62189c..92be0fe 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"স্ক্ৰীনশ্বট অগ্ৰাহ্য কৰক"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"স্ক্ৰীনশ্বটৰ পূৰ্বদৰ্শন"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্ৰীন ৰেকৰ্ডাৰ"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রীন ৰেকৰ্ডিঙৰ প্ৰক্ৰিয়াকৰণ হৈ আছে"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রীণ ৰেকৰ্ডিং ছেশ্বন চলি থকা সময়ত পোৱা জাননী"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"ৰেকৰ্ড কৰা আৰম্ভ কৰিবনে?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"ৰেকৰ্ড কৰি থাকোঁতে, Android Systemএ আপোনাৰ স্ক্রীনত দৃশ্যমান হোৱা অথবা আপোনাৰ ডিভাইচত প্লে’ হৈ থকা যিকোনো সংবেনদশীল তথ্য কেপচাৰ কৰিব পাৰে। এইটোত পাছৱর্ড, পৰিশোধৰ তথ্য, ফট’, বার্তাসমূহ আৰু অডিঅ’ অন্তর্ভুক্ত হয়।"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"সকলো মচক"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"পৰিচালনা"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ইতিহাস"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"অন্তৰ্গামী"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"নীৰৱ জাননীসমূহ"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"সতৰ্কতামূলক জাননীসমূহ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"বাৰ্তালাপ"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"কোনো শিৰোনাম নাই"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"এপ্‌টো ৰিষ্টাৰ্ট কৰক আৰু পূৰ্ণ স্ক্ৰীণ ব্যৱহাৰ কৰক।"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ bubblesৰ ছেটিংসমূহ"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"অভাৰফ্ল’"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ষ্টেকত পুনৰ যোগ দিয়ক"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"পৰিচালনা কৰক"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>ৰ পৰা <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> আৰু<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>টাৰ পৰা <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index f09a6d6..9230d4c 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ekran şəklini ötürün"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekran şəklinə önbaxış"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Yazıcısı"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran çəkilişi emal edilir"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekranın video çəkimi ərzində silinməyən bildiriş"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Yazmağa başlanılsın?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Yazarkən Android Sistemi ekranınızda görünən və ya cihazınızda göstərilən istənilən həssas məlumatı qeydə ala bilər. Buraya parollar, ödəniş məlumatı, fotolar, mesajlar və audio daxildir."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Hamısını silin"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"İdarə edin"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Tarixçə"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Gələn"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Səssiz bildirişlər"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Xəbərdarlıq bildirişləri"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Söhbətlər"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıq yoxdur"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Bu tətbiqi sıfırlayaraq tam ekrana keçmək üçün klikləyin."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> yumrucuqları üçün ayarlar"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Kənara çıxma"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Yenidən dəstəyə əlavə edin"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"İdarə edin"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> tətbiqindən <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> tətbiqindən <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> və daha <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> qabarcıq"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index b9af5e9..b633bb6 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Odbacite snimak ekrana"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimka ekrana"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Želite da započnete snimanje?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Tokom snimanja Android sistem može da snimi osetljive informacije koje su vidljive na ekranu ili koje se puštaju na uređaju. To obuhvata lozinke, informacije o plaćanju, slike, poruke i zvuk."</string>
@@ -514,8 +513,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Obriši sve"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Upravljajte"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Istorija"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Dolazno"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Nečujna obaveštenja"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Obaveštenja koja privlače pažnju"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzacije"</string>
@@ -996,10 +994,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Dodirnite da biste restartovali aplikaciju i prešli u režim celog ekrana."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Podešavanja za <xliff:g id="APP_NAME">%1$s</xliff:g> oblačiće"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Preklapanje"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Dodaj ponovo u grupu"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Upravljajte"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iz aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g> i još <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
@@ -1019,10 +1015,10 @@
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Navigacija sistema je ažurirana. Da biste uneli izmene, idite u Podešavanja."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Idite u Podešavanja da biste ažurirali navigaciju sistema"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Stanje pripravnosti"</string>
-    <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuju se u vrhu odeljka za konverzacije"</string>
-    <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuju sliku profila na zaključanom ekranu"</string>
+    <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Prikazuje se u vrhu odeljka za konverzacije"</string>
+    <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Prikazuje sliku profila na zaključanom ekranu"</string>
     <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Prikazuju se plutajući oblačići preko aplikacija"</string>
-    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ometaju podešavanje Ne uznemiravaj"</string>
+    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ometa podešavanje Ne uznemiravaj"</string>
     <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Važi"</string>
     <string name="magnification_overlay_title" msgid="6584179429612427958">"Preklopni prozor za uvećanje"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Prozor za uvećanje"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 0f3f537..df9a660 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Адхіліць здымак экрана"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Перадпрагляд здымка экрана"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Запіс экрана"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Апрацоўваецца запіс экрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Бягучае апавяшчэнне для сеанса запісу экрана"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Пачаць запіс?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Падчас запісу сістэма Android можа збіраць канфідэнцыяльную інфармацыю, якая адлюстроўваецца на экране вашай прылады ці прайграецца на ёй. Гэта могуць быць паролі, плацежная інфармацыя, фота, паведамленні і аўдыяданыя."</string>
@@ -517,8 +516,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Ачысціць усё"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Кіраваць"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Гісторыя"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Уваходныя"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Апавяшчэнні без гуку"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Апавяшчэнні з абвесткамі"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Размовы"</string>
@@ -1001,10 +999,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без назвы"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Націсніце, каб перазапусціць гэту праграму і перайсці ў поўнаэкранны рэжым."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Налады ўсплывальных апавяшчэнняў у праграме \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Дадатковае меню"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Зноў дадаць у стос"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Кіраваць"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ад праграмы \"<xliff:g id="APP_NAME">%2$s</xliff:g>\""</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ад праграмы \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" і яшчэ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 50781e1..31e47da 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Отхвърляне на екранната снимка"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Визуализация на екранната снимка"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Запис на екрана"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Записът на екрана се обработва"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущо известие за сесия за записване на екрана"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Да се стартира ли записът?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"По време на записване системата Android може да прихване поверителна информация, която е показана на екрана или възпроизвеждана на устройството ви. Това включва пароли, данни за плащане, снимки, съобщения и аудио."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Изчистване на всички"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Управление"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"История"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Входящи"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Беззвучни известия"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Известия за сигнализиране"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Няма заглавие"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Докоснете, за да рестартирате това приложение в режим на цял екран."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Настройки за балончетата за <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Препълване"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Добавяне обратно към стека"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Управление"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> от <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ от<xliff:g id="APP_NAME">%2$s</xliff:g> и още <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 50a88f25..08826e4 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"স্ক্রিনশট বাতিল করুন"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"স্ক্রিনশটের প্রিভিউ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"স্ক্রিন রেকর্ডার"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"স্ক্রিন রেকর্ডিং প্রসেস হচ্ছে"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"রেকর্ডিং শুরু করবেন?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"রেকর্ড করার সময়, আপনার স্ক্রিনে দেখানো বা ডিভাইসে চালানো যেকোনও ধরনের সংবেদনশীল তথ্য Android সিস্টেম ক্যাপচার করতে পারে। এর মধ্যে পাসওয়ার্ড, পেমেন্টের তথ্য, ফটো, মেসেজ এবং অডিও সম্পর্কিত তথ্য থাকে।"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"সবকিছু সাফ করুন"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"পরিচালনা করুন"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ইতিহাস"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"ইনকামিং"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"নীরব বিজ্ঞপ্তি"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"বিজ্ঞপ্তি সংক্রান্ত সতর্কতা"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"কথোপকথন"</string>
@@ -969,7 +967,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"পটভূমিতে অ্যাপ চালু আছে"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"ব্যাটারি এবং ডেটার ব্যবহারের বিশদ বিবরণের জন্য ট্যাপ করুন"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"মোবাইল ডেটা বন্ধ করবেন?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"আপনি <xliff:g id="CARRIER">%s</xliff:g>-এর মাধ্যমে ডেটা অথবা ইন্টারনেট অ্যাক্সেস করতে পারবেন না। শুধুমাত্র ওয়াই-ফাইয়ের মাধ্যমেই ইন্টারনেট অ্যাক্সেস করা যাবে।"</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"আপনি \'<xliff:g id="CARRIER">%s</xliff:g>\'-এর মাধ্যমে ডেটা অথবা ইন্টারনেট অ্যাক্সেস করতে পারবেন না। শুধুমাত্র ওয়াই-ফাইয়ের মাধ্যমেই ইন্টারনেট অ্যাক্সেস করা যাবে।"</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"আপনার পরিষেবা প্রদানকারী"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"একটি অ্যাপ কোনও অনুমোদনের অনুরোধকে ঢেকে দিচ্ছে, তাই সেটিংস থেকে আপনার প্রতিক্রিয়া যাচাই করা যাচ্ছে না।"</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_0">%1$s</xliff:g> অ্যাপটিকে <xliff:g id="APP_2">%2$s</xliff:g> এর অংশ দেখানোর অনুমতি দেবেন?"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"কোনও শীর্ষক নেই"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"এই অ্যাপ রিস্টার্ট করতে ট্যাপ করুন ও ফুল-স্ক্রিন ব্যবহার করুন।"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> বাবলের জন্য সেটিংস"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ওভারফ্লো"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"স্ট্যাকে আবার যোগ করুন"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"ম্যানেজ করা"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> অ্যাপ থেকে <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> অ্যাপ এবং আরও <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>টি থেকে <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1039,10 +1035,8 @@
     <string name="controls_favorite_load_error" msgid="2533215155804455348">"সব কন্ট্রোলের তালিকা লোড করা যায়নি।"</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"অন্য"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"ডিভাইস কন্ট্রোলে যোগ করুন"</string>
-    <!-- no translation found for controls_dialog_ok (2770230012857881822) -->
-    <skip />
-    <!-- no translation found for controls_dialog_message (342066938390663844) -->
-    <skip />
+    <string name="controls_dialog_ok" msgid="2770230012857881822">"যোগ করুন"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> সাজেস্ট করেছে"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"কন্ট্রোল আপডেট করা হয়েছে"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"পিন-এ অক্ষর বা চিহ্ন রয়েছে"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> যাচাই করুন"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index d334f3c..28a2930 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -89,10 +89,10 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Odbacite snimak ekrana"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pregled snimka ekrana"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Snimač ekrana"</string>
-    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrada snimanja zaslona"</string>
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađivanje snimka ekrana"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obavještenje za sesiju snimanja ekrana je u toku"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Započeti snimanje?"</string>
-    <string name="screenrecord_description" msgid="1123231719680353736">"Prilikom snimanja, Android sistem može snimiti sve osjetljive informacije koje su vidljive na vašem ekranu ili koje reproducirate na uređaju. To uključuje lozinke, informacije za plaćanje, fotografije, poruke i zvuk."</string>
+    <string name="screenrecord_description" msgid="1123231719680353736">"Prilikom snimanja, sistem Android može snimiti sve osjetljive informacije koje su vidljive na vašem ekranu ili koje reproducirate na uređaju. To uključuje lozinke, informacije za plaćanje, fotografije, poruke i zvuk."</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Snimi zvučni zapis"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk uređaja"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk s vašeg uređaja, naprimjer muzika, pozivi i melodije zvona"</string>
@@ -974,7 +974,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije koje rade u pozadini"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dodirnite za detalje o potrošnji baterije i prijenosa podataka"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Isključiti prijenos podataka na mobilnoj mreži?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ili internetu putem mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo putem WiFi mreže."</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nećete imati pristup podacima ni internetu putem mobilnog operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo putem WiFi mreže."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"vaš operater"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Postavke ne mogu potvrditi vaš odgovor jer aplikacija zaklanja zahtjev za odobrenje."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Dozvoliti aplikaciji <xliff:g id="APP_0">%1$s</xliff:g> prikazivanje isječaka aplikacije <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
@@ -996,8 +996,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez naslova"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Dodirnite da ponovo pokrenete ovu aplikaciju i aktivirate prikaz preko cijelog ekrana."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Postavke za oblačiće aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Dodatno"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Dodajte natrag u nizove"</string>
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Preklapanje"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Dodaj nazad u grupu"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Upravljaj"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> od aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"Obavještenje <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> aplikacije <xliff:g id="APP_NAME">%2$s</xliff:g> i još <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index ed3bb8d..15cc8d3 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ignora la captura de pantalla"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Previsualització de la captura de pantalla"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravació de pantalla"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Processant gravació de pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificació en curs d\'una sessió de gravació de la pantalla"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Vols iniciar la gravació?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Quan graves contingut, el sistema Android pot capturar qualsevol informació sensible que es mostri a la pantalla o que es reprodueixi al dispositiu. Això inclou les contrasenyes, la informació de pagament, les fotos, els missatges i l\'àudio."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Esborra-ho tot"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gestiona"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Entrants"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificacions silencioses"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notificacions d\'alerta"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Converses"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sense títol"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Toca per reiniciar l\'aplicació i passar a pantalla completa."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Configuració de les bombolles: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menú addicional"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Torna a afegir a la pila"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Gestiona"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de: <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (<xliff:g id="APP_NAME">%2$s</xliff:g>) i <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> més"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 73378dd..e3d9e384 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Zavřít snímek obrazovky"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Náhled snímku obrazovky"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Záznam obrazovky se zpracovává"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Spustit nahrávání?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Při nahrávání může systém Android zaznamenávat citlivé údaje, které jsou viditelné na obrazovce nebo které jsou přehrávány na zařízení. Týká se to hesel, údajů o platbě, fotek, zpráv a zvuků."</string>
@@ -402,7 +401,7 @@
     <string name="quick_settings_tethering_label" msgid="5257299852322475780">"Sdílené připojení"</string>
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Hotspot"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Zapínání…"</string>
-    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Spořič dat je zapnutý"</string>
+    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Spořič dat zapnut"</string>
     <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
       <item quantity="few">%d zařízení</item>
       <item quantity="many">%d zařízení</item>
@@ -517,8 +516,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Smazat vše"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Spravovat"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historie"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Příchozí"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Tichá oznámení"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Oznámení s upozorněním"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzace"</string>
@@ -1001,10 +999,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Klepnutím aplikaci restartujete a přejdete na režim celé obrazovky"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Nastavení bublin aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Rozbalovací nabídka"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Přidat zpět do sady"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Spravovat"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"Oznámení <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikace <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikace <xliff:g id="APP_NAME">%2$s</xliff:g> a dalších (<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>)"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 88b74de..3d244cc 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Luk screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning af screenshot"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skærmoptagelse"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skærmoptagelse"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Konstant notifikation om skærmoptagelse"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Vil du starte optagelse?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Når du optager, kan Android-systemet registrere følsomme oplysninger, der er synlige på din skærm, eller som afspilles på din enhed. Dette inkluderer adgangskoder, betalingsoplysninger, fotos, meddelelser og lyd."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Ryd alle"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historik"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Indgående"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Lydløse notifikationer"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notifikationer med vibration eller lyd"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tryk for at genstarte denne app, og gå til fuld skærm."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Indstillinger for <xliff:g id="APP_NAME">%1$s</xliff:g>-bobler"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overløb"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Føj til stak igen"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Administrer"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> fra <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> fra <xliff:g id="APP_NAME">%2$s</xliff:g> og <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> andre"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index acfdd47..8ef83bd 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Screenshot schließen"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Screenshotvorschau"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Bildschirmaufzeichnung"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Bildschirmaufzeichnung…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Aufzeichnung starten?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Beim Aufnehmen kann das Android-System vertrauliche Informationen erfassen, die auf deinem Bildschirm angezeigt oder von deinem Gerät wiedergegeben werden. Das können Passwörter, Zahlungsinformationen, Fotos, Nachrichten und Audioinhalte sein."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Alle löschen"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Verwalten"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Verlauf"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Neue Benachrichtigungen"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Lautlose Benachrichtigungen"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Laut gestellte Benachrichtigungen"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Unterhaltungen"</string>
@@ -821,7 +819,7 @@
     <string name="accessibility_long_click_tile" msgid="210472753156768705">"Einstellungen öffnen"</string>
     <string name="accessibility_status_bar_headphones" msgid="1304082414912647414">"Mit Kopfhörer verbunden"</string>
     <string name="accessibility_status_bar_headset" msgid="2699275863720926104">"Mit Headset verbunden"</string>
-    <string name="data_saver" msgid="3484013368530820763">"Datenverbrauch reduzieren"</string>
+    <string name="data_saver" msgid="3484013368530820763">"Datensparmodus"</string>
     <string name="accessibility_data_saver_on" msgid="5394743820189757731">"Datensparmodus aktiviert"</string>
     <string name="accessibility_data_saver_off" msgid="58339669022107171">"Datensparmodus deaktiviert"</string>
     <string name="switch_bar_on" msgid="1770868129120096114">"An"</string>
@@ -854,7 +852,7 @@
     <string name="right_keycode" msgid="2480715509844798438">"Rechter Keycode"</string>
     <string name="left_icon" msgid="5036278531966897006">"Linkes Symbol"</string>
     <string name="right_icon" msgid="1103955040645237425">"Rechtes Symbol"</string>
-    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Zum Hinzufügen von Kacheln Kachel halten und ziehen"</string>
+    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Zum Hinzufügen Kachel halten und ziehen"</string>
     <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Zum Verschieben Kachel halten und ziehen"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Zum Entfernen hierher ziehen"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Du brauchst mindestens <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> Kacheln"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Kein Titel"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tippe, um die App im Vollbildmodus neu zu starten."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Einstellungen für <xliff:g id="APP_NAME">%1$s</xliff:g>-Bubbles"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Mehr anzeigen"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Wieder dem Stapel hinzufügen"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Verwalten"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> von <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> aus <xliff:g id="APP_NAME">%2$s</xliff:g> und <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> weiteren"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 7ef57f8..e7d6878 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -89,10 +89,9 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Descartar captura de pantalla"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Vista previa de la captura de pantalla"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Grabadora de pantalla"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación constante para una sesión de grabación de pantalla"</string>
-    <string name="screenrecord_start_label" msgid="1750350278888217473">"¿Comenzar grabación?"</string>
+    <string name="screenrecord_start_label" msgid="1750350278888217473">"¿Comenzar a grabar?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Durante la grabación, el sistema de Android puede capturar la información sensible que aparezca en la pantalla o que se reproduzca en el dispositivo. Se incluyen contraseñas, información de pago, fotos, mensajes y audio."</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Grabar audio"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio del dispositivo"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Administrar"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Entrante"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificaciones silenciosas"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notificaciones de alerta"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Presiona para reiniciar esta app y acceder al modo de pantalla completa."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Configuración para burbujas de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menú ampliado"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Volver a agregar a la pila"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Administrar"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> y <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> más"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 1c59325..d1f5198 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Cerrar captura de pantalla"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Vista previa de captura de pantalla"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Grabación de pantalla"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando grabación de pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación continua de una sesión de grabación de la pantalla"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"¿Empezar a grabar?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Mientras grabas, el sistema Android puede capturar información sensible que se muestre o se reproduzca en tu dispositivo, como contraseñas, datos de pago, fotos, mensajes y audio."</string>
@@ -400,7 +399,7 @@
     <string name="quick_settings_tethering_label" msgid="5257299852322475780">"Compartir conexión"</string>
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Zona Wi-Fi"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Activando…"</string>
-    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ahorro de datos: sí"</string>
+    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Ahorro de datos activado"</string>
     <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
       <item quantity="other">%d dispositivos</item>
       <item quantity="one">%d dispositivo</item>
@@ -430,8 +429,8 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"El NFC está desactivado"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"El NFC está activado"</string>
-    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Grabación de la pantalla"</string>
-    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Inicio"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Grabar pantalla"</string>
+    <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Iniciar"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Detener"</string>
     <string name="media_seamless_remote_device" msgid="177033467332920464">"Dispositivo"</string>
     <string name="recents_swipe_up_onboarding" msgid="2820265886420993995">"Desliza el dedo hacia arriba para cambiar de aplicación"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Borrar todo"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gestionar"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Entrantes"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificaciones silenciadas"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notificaciones de alerta"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversaciones"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sin título"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Toca para reiniciar esta aplicación e ir a la pantalla completa."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Ajustes de las burbujas de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Menú adicional"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Volver a añadir a la pila"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Gestionar"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> y <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> más"</string>
@@ -1014,10 +1010,10 @@
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Se ha actualizado la navegación del sistema. Para hacer cambios, ve a Ajustes."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Ve a Ajustes para actualizar la navegación del sistema"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"En espera"</string>
-    <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Aparecen arriba de la sección de conversaciones"</string>
-    <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Muestran imagen de perfil en pantalla de bloqueo"</string>
+    <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Se muestran en la parte superior de la sección de conversaciones"</string>
+    <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Muestran tu imagen de perfil en la pantalla de bloqueo"</string>
     <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Aparecen como burbuja sobre las aplicaciones"</string>
-    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrumpen No molestar"</string>
+    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Interrumpen el modo No molestar"</string>
     <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Entendido"</string>
     <string name="magnification_overlay_title" msgid="6584179429612427958">"Ventana de superposición de ampliación"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Ventana de ampliación"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index dce209c0..c1b4b79 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Sule ekraanipilt"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekraanipildi eelvaade"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekraanisalvesti"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekraanisalvestuse töötlemine"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pooleli märguanne ekraanikuva salvestamise seansi puhul"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Kas alustada salvestamist?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Heli salvestamise ajal võib Androidi süsteem jäädvustada tundlikku teavet, mis on ekraanikuval nähtav või mida seadmes esitatakse. See hõlmab paroole, makseteavet, fotosid, sõnumeid ja heli."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Tühjenda kõik"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Haldamine"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Ajalugu"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Sissetulevad"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Hääletud märguanded"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Hoiatusmärguanded"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Vestlused"</string>
@@ -717,7 +715,7 @@
     <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Hoiab teie tähelepanu hõljuva otseteega selle sisu juurde."</string>
     <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Kuvatakse vestluste jaotise ülaosas mullina."</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"Seaded"</string>
-    <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteet"</string>
+    <string name="notification_priority_title" msgid="2079708866333537093">"Prioriteetne"</string>
     <string name="no_shortcut" msgid="7176375126961212514">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei toeta vestluspõhiseid seadeid"</string>
     <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"Hiljutisi mulle pole"</string>
     <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"Siin kuvatakse hiljutised ja suletud mullid."</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Pealkiri puudub"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Puudutage rakenduse taaskäivitamiseks ja täisekraanrežiimi aktiveerimiseks."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> mullide seaded"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Ületäide"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Lisa tagasi virna"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Halda"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> rakendusest <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> rakenduselt <xliff:g id="APP_NAME">%2$s</xliff:g> ja veel <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
@@ -1017,7 +1013,7 @@
     <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Kuvatakse vestluste jaotise kohal"</string>
     <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Lukustuskuval kuvatakse profiilipilt"</string>
     <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Kuvatakse rakenduste kohal hõljuva mullina"</string>
-    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Funktsiooni Mitte segada katkestamine"</string>
+    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Funktsioon Mitte segada katkestatakse"</string>
     <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Selge"</string>
     <string name="magnification_overlay_title" msgid="6584179429612427958">"Suurendamisakna ülekate"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Suurendamisaken"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 6172462..944b07b 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -65,7 +65,7 @@
     <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu USB bidezko arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira."</string>
     <string name="wifi_debugging_title" msgid="7300007687492186076">"Hari gabeko arazketa onartu nahi duzu sare honetan?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"Sarearen izena (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWifi-helbidea (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
-    <string name="wifi_debugging_always" msgid="2968383799517975155">"Onartu beti sare honetan"</string>
+    <string name="wifi_debugging_always" msgid="2968383799517975155">"Baimendu beti sare honetan"</string>
     <string name="wifi_debugging_allow" msgid="4573224609684957886">"Baimendu"</string>
     <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"Ez da onartzen hari gabeko arazketa"</string>
     <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"Gailu honetan saioa hasita daukan erabiltzaileak ezin du aktibatu hari gabeko arazketa. Eginbide hori erabiltzeko, aldatu erabiltzaile nagusira."</string>
@@ -852,8 +852,8 @@
     <string name="right_keycode" msgid="2480715509844798438">"Eskuineko teklaren kodea"</string>
     <string name="left_icon" msgid="5036278531966897006">"Ezkerreko ikonoa"</string>
     <string name="right_icon" msgid="1103955040645237425">"Eskuineko ikonoa"</string>
-    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Lauzak gehitzeko, eduki sakatuta eta arrastatu"</string>
-    <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Lauzak antolatzeko, eduki sakatuta eta arrastatu"</string>
+    <string name="drag_to_add_tiles" msgid="8933270127508303672">"Lauzak gehitzeko, eduki itzazu sakatuta, eta arrastatu"</string>
+    <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Lauzak antolatzeko, eduki itzazu sakatuta, eta arrastatu"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Kentzeko, arrastatu hona"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> lauza behar dituzu gutxienez"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Editatu"</string>
@@ -990,7 +990,7 @@
     <string name="restart_button_description" msgid="6916116576177456480">"Berrabiarazi aplikazio hau eta ezarri pantaila osoko modua."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren ezarpenen burbuilak"</string>
     <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Gainezkatzea"</string>
-    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Gehitu berriro sortan"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Gehitu berriro errenkadan"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Kudeatu"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (<xliff:g id="APP_NAME">%2$s</xliff:g>)"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioaren \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\" jakinarazpena, eta beste <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 17e3ad7..64b3f8c 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"رد کردن نماگرفت"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"پیش‌نمایش نماگرفت"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ضبط‌کننده صفحه‌نمایش"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"درحال پردازش ضبط صفحه‌نمایش"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اعلان درحال انجام برای جلسه ضبط صفحه‌نمایش"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"ضبط شروع شود؟"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"‏هنگام ضبط، «سیستم Android» می‌تواند هر اطلاعات حساسی را که روی صفحه‌نمایش شما نشان داده می‌شود یا روی دستگاه شما پخش می‌شود ضبط کند. این شامل گذرواژه‌ها، اطلاعات پرداخت، عکس‌ها، پیام‌ها، و صدا می‌شود."</string>
@@ -196,7 +195,7 @@
     <string name="accessibility_data_signal_full" msgid="283507058258113551">"قدرت سیگنال داده کامل است."</string>
     <string name="accessibility_wifi_name" msgid="4863440268606851734">"به <xliff:g id="WIFI">%s</xliff:g> متصل شد."</string>
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"به <xliff:g id="BLUETOOTH">%s</xliff:g> متصل شد."</string>
-    <string name="accessibility_cast_name" msgid="7344437925388773685">"متصل به <xliff:g id="CAST">%s</xliff:g>."</string>
+    <string name="accessibility_cast_name" msgid="7344437925388773685">"به <xliff:g id="CAST">%s</xliff:g> متصل شد."</string>
     <string name="accessibility_no_wimax" msgid="2014864207473859228">"‏WiMAX وجود ندارد."</string>
     <string name="accessibility_wimax_one_bar" msgid="2996915709342221412">"‏WiMAX یک نوار دارد."</string>
     <string name="accessibility_wimax_two_bars" msgid="7335485192390018939">"‏WiMAX دو نوار دارد."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"پاک کردن همه موارد"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"مدیریت"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"سابقه"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"ورودی"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"اعلان‌های بی‌صدا"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"اعلان‌های هشداردهنده"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"مکالمه‌ها"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"بدون عنوان"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"برای بازراه‌اندازی این برنامه و تغییر به حالت تمام‌صفحه، ضربه بزنید."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"تنظیم برای ابزارک‌های اعلان <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"لبریزشده"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"افزودن برگشت به پشته"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"مدیریت"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> از <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> از <xliff:g id="APP_NAME">%2$s</xliff:g> و <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> مورد بیشتر"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 62779904..a3c1e5e 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Hylkää kuvakaappaus"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Kuvakaappauksen esikatselu"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Näytön tallentaja"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Näytön tallennusta käsitellään"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pysyvä ilmoitus näytön tallentamisesta"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Aloitetaanko tallennus?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Tallennuksen aikana Android-järjestelmä voi tallentaa mitä tahansa näytöllä näkyvää tai laitteen toistamaa arkaluontoista tietoa. Näitä tietoja ovat esimerkiksi salasanat, maksutiedot, kuvat, viestit ja äänisisältö."</string>
@@ -430,7 +429,7 @@
     <string name="quick_settings_nfc_label" msgid="1054317416221168085">"NFC"</string>
     <string name="quick_settings_nfc_off" msgid="3465000058515424663">"NFC on poistettu käytöstä"</string>
     <string name="quick_settings_nfc_on" msgid="1004976611203202230">"NFC on käytössä"</string>
-    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Näytön tallentaminen"</string>
+    <string name="quick_settings_screen_record_label" msgid="1594046461509776676">"Tallennus"</string>
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Aloita"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Lopeta"</string>
     <string name="media_seamless_remote_device" msgid="177033467332920464">"Laite"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Poista kaikki"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Muuta asetuksia"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Saapuvat"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Hiljaiset ilmoitukset"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Ääni-ilmoitukset"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Keskustelut"</string>
@@ -855,7 +853,7 @@
     <string name="left_icon" msgid="5036278531966897006">"Vasen kuvake"</string>
     <string name="right_icon" msgid="1103955040645237425">"Oikea kuvake"</string>
     <string name="drag_to_add_tiles" msgid="8933270127508303672">"Lisää osioita koskettamalla pitkään ja vetämällä"</string>
-    <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Järjestele osioita koskettamalla pitkään ja vetämällä"</string>
+    <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"Järjestele koskettamalla pitkään ja vetämällä"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Poista vetämällä tähän."</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kiekkoa on vähimmäismäärä"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Muokkaa"</string>
@@ -968,8 +966,8 @@
     <string name="qs_dnd_replace" msgid="7712119051407052689">"Korvaa"</string>
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Sovelluksia käynnissä taustalla"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Katso lisätietoja akun ja datan käytöstä napauttamalla"</string>
-    <string name="mobile_data_disable_title" msgid="5366476131671617790">"Poistetaanko mobiilidata käytöstä?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"<xliff:g id="CARRIER">%s</xliff:g> ei voi enää tarjota sinulle internetyhteyttä. Internetyhteys voidaan muodostaa vain Wi-Fi-verkossa."</string>
+    <string name="mobile_data_disable_title" msgid="5366476131671617790">"Laitetaanko mobiilidata pois päältä?"</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"<xliff:g id="CARRIER">%s</xliff:g> ei enää tarjoa pääsyä dataan eikä internetyhteyttä, joka on saatavilla vain Wi-Fin kautta."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"operaattorisi"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Sovellus peittää käyttöoikeuspyynnön, joten Asetukset ei voi vahvistaa valintaasi."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Saako <xliff:g id="APP_0">%1$s</xliff:g> näyttää osia sovelluksesta <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ei nimeä"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Napauta, niin sovellus käynnistyy uudelleen ja siirtyy koko näytön tilaan."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Kuplien asetukset: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Ylivuoto"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Lisää takaisin pinoon"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Ylläpidä"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>: <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (<xliff:g id="APP_NAME">%2$s</xliff:g>) ja <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> muuta"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 7140c5b..1ec0411 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -36,7 +36,7 @@
     <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"Activer l\'économiseur de batterie ?"</string>
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"À propos de l\'économiseur de batterie"</string>
     <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"Activer"</string>
-    <string name="battery_saver_start_action" msgid="4553256017945469937">"Activer l\'économiseur de batterie ?"</string>
+    <string name="battery_saver_start_action" msgid="4553256017945469937">"Activer l\'économiseur de batterie"</string>
     <string name="status_bar_settings_settings_button" msgid="534331565185171556">"Paramètres"</string>
     <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Rotation automatique de l\'écran"</string>
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Fermer la capture d\'écran"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Aperçu de la capture d\'écran"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Enregistreur d\'écran"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Enregistrement de l\'écran…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notification en cours pour une session d\'enregistrement de l\'écran"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Démarrer l\'enregistrement ?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Pendant l\'enregistrement, le système Android peut capturer toute information sensible affichée à l\'écran ou lue sur votre appareil. Ceci inclut les mots de passe, les informations de paiement, les photos, les messages et les contenus audio."</string>
@@ -102,7 +101,7 @@
     <string name="screenrecord_start" msgid="330991441575775004">"Démarrer"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Enregistrement de l\'écran"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Enregistrement de l\'écran et des contenus audio"</string>
-    <string name="screenrecord_taps_label" msgid="1595690528298857649">"Afficher les points de l\'écran touchés"</string>
+    <string name="screenrecord_taps_label" msgid="1595690528298857649">"Afficher les points touchés sur l\'écran"</string>
     <string name="screenrecord_stop_text" msgid="6549288689506057686">"Appuyez ici pour arrêter"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"Arrêter"</string>
     <string name="screenrecord_pause_label" msgid="6004054907104549857">"Pause"</string>
@@ -400,7 +399,7 @@
     <string name="quick_settings_tethering_label" msgid="5257299852322475780">"Partage de connexion"</string>
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Point d\'accès"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Activation…"</string>
-    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Économ. données activé"</string>
+    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Écon. données activé"</string>
     <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
       <item quantity="one">%d appareil</item>
       <item quantity="other">%d appareils</item>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Tout effacer"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gérer"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historique"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Notifications entrantes"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notifications silencieuses"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notifications d\'alerte"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversations"</string>
@@ -702,7 +700,7 @@
     <string name="inline_block_button" msgid="479892866568378793">"Bloquer"</string>
     <string name="inline_keep_button" msgid="299631874103662170">"Continuer d\'afficher les notifications"</string>
     <string name="inline_minimize_button" msgid="1474436209299333445">"Réduire"</string>
-    <string name="inline_silent_button_silent" msgid="525243786649275816">"Mode silencieux"</string>
+    <string name="inline_silent_button_silent" msgid="525243786649275816">"Silencieux"</string>
     <string name="inline_silent_button_stay_silent" msgid="2129254868305468743">"Notifications silencieuses"</string>
     <string name="inline_silent_button_alert" msgid="5705343216858250354">"Alertes"</string>
     <string name="inline_silent_button_keep_alerting" msgid="6577845442184724992">"Continuer de m\'avertir"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sans titre"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Appuyez pour redémarrer cette application et activer le mode plein écran."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Paramètres des bulles de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Dépassement"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Ajouter à nouveau l\'élément à la pile"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Gérer"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de l\'application <xliff:g id="APP_NAME">%2$s</xliff:g> et <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> autres"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index a86c768..0095bcc 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -76,7 +76,7 @@
     <string name="learn_more" msgid="4690632085667273811">"Máis información"</string>
     <string name="compat_mode_on" msgid="4963711187149440884">"Ampliar ata ocupar todo"</string>
     <string name="compat_mode_off" msgid="7682459748279487945">"Estirar ata ocupar todo"</string>
-    <string name="global_action_screenshot" msgid="2760267567509131654">"Crear captura"</string>
+    <string name="global_action_screenshot" msgid="2760267567509131654">"Facer captura"</string>
     <string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou unha imaxe"</string>
     <string name="screenshot_saving_ticker" msgid="6519186952674544916">"Gardando captura de pantalla…"</string>
     <string name="screenshot_saving_title" msgid="2298349784913287333">"Gardando captura de pantalla…"</string>
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ignora a captura de pantalla"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Vista previa da captura de pantalla"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Gravadora da pantalla"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Procesando gravación pantalla"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificación en curso sobre unha sesión de gravación de pantalla"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Queres iniciar a gravación?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Durante a gravación, o sistema Android pode captar información confidencial visible na pantalla ou reproducila no dispositivo. Isto inclúe contrasinais, información de pago, fotos, mensaxes e audio."</string>
@@ -382,7 +381,7 @@
     <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wifi activada"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Non hai redes wifi dispoñibles"</string>
     <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Activando…"</string>
-    <string name="quick_settings_cast_title" msgid="2279220930629235211">"Emisión da pantalla"</string>
+    <string name="quick_settings_cast_title" msgid="2279220930629235211">"Emitir pantalla"</string>
     <string name="quick_settings_casting" msgid="1435880708719268055">"Emitindo"</string>
     <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"Dispositivo sen nome"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"Listo para emitir"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Eliminar todas"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Xestionar"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historial"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Entrantes"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificacións silenciadas"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notificación de alerta"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversas"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Sen título"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Toca o botón para reiniciar esta aplicación e abrila en pantalla completa."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Configuración das burbullas de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Mostrar menú adicional"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Engadir de novo á pilla"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Xestionar"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de <xliff:g id="APP_NAME">%2$s</xliff:g> e <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> máis"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index e381551..6d2dec8 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"સ્ક્રીનશૉટ છોડી દો"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"સ્ક્રીનશૉટનો પ્રીવ્યૂ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"સ્ક્રીન રેકૉર્ડર"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"સ્ક્રીન રેકૉર્ડિંગ ચાલુ છે"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"રેકૉર્ડિંગ શરૂ કરીએ?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"રેકૉર્ડ કરતી વખતે, Android System તમારી સ્ક્રીન પર દેખાતી હોય અથવા તમારા ડિવાઇસ પર ચલાવવામાં આવતી હોય તેવી કોઈપણ સંવેદનશીલ માહિતીને કૅપ્ચર કરી શકે છે. આમાં પાસવર્ડ, ચુકવણીની માહિતી, ફોટા, સંદેશા અને ઑડિયોનો સમાવેશ થાય છે."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"બધુ સાફ કરો"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"મેનેજ કરો"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ઇતિહાસ"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"ઇનકમિંગ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"સાઇલન્ટ નોટિફિકેશન"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"નોટિફિકેશન બદલી રહ્યાં છીએ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"વાતચીત"</string>
@@ -805,7 +803,7 @@
     <string name="keyboard_shortcut_group_applications" msgid="7386239431100651266">"ઍપ્લિકેશનો"</string>
     <string name="keyboard_shortcut_group_applications_assist" msgid="771606231466098742">"સહાય"</string>
     <string name="keyboard_shortcut_group_applications_browser" msgid="2776211137869809251">"બ્રાઉઝર"</string>
-    <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"સંપર્કો"</string>
+    <string name="keyboard_shortcut_group_applications_contacts" msgid="2807268086386201060">"Contacts"</string>
     <string name="keyboard_shortcut_group_applications_email" msgid="7852376788894975192">"ઇમેઇલ"</string>
     <string name="keyboard_shortcut_group_applications_sms" msgid="6912633831752843566">"SMS"</string>
     <string name="keyboard_shortcut_group_applications_music" msgid="9032078456666204025">"સંગીત"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"કોઈ શીર્ષક નથી"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"આ ઍપ ફરીથી ચાલુ કરવા માટે ટૅપ કરીને પૂર્ણ સ્ક્રીન કરો."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> બબલ માટેનાં સેટિંગ"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ઓવરફ્લો"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"સ્ટૅકમાં ફરી ઉમેરો"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"મેનેજ કરો"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> તરફથી <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> અને વધુ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> તરફથી <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1039,10 +1035,8 @@
     <string name="controls_favorite_load_error" msgid="2533215155804455348">"બધા નિયંત્રણોની સૂચિ લોડ કરી શકાઈ નથી."</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"અન્ય"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"ડિવાઇસનાં નિયંત્રણોમાં ઉમેરો"</string>
-    <!-- no translation found for controls_dialog_ok (2770230012857881822) -->
-    <skip />
-    <!-- no translation found for controls_dialog_message (342066938390663844) -->
-    <skip />
+    <string name="controls_dialog_ok" msgid="2770230012857881822">"ઉમેરો"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> દ્વારા સૂચન કરેલા"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"નિયંત્રણ અપડેટ કર્યા"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"પિનમાં અક્ષરો અથવા પ્રતીકોનો સમાવેશ થાય છે"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g>ને ચકાસો"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 3e4beac..c7211f7 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"स्क्रीनशॉट खारिज करें"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रीनशॉट की झलक"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रिकॉर्डर"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"रिकॉर्डिंग शुरू करना चाहते हैं?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"रिकॉर्ड करते समय, Android सिस्टम आपकी स्क्रीन पर दिखने वाली या चलाई जाने वाली संवेदनशील जानकारी को कैप्चर कर सकता है. इसमें पासवर्ड, पैसे चुकाने से जुड़ी जानकारी, फ़ोटो, मैसेज, और ऑडियो शामिल हैं."</string>
@@ -357,7 +356,7 @@
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"ऑडियो"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"हेडसेट"</string>
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"इनपुट"</string>
-    <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"सुनने में मददगार डिवाइस"</string>
+    <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"कान की मशीन"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ब्लूटूथ चालू हो रहा है…"</string>
     <string name="quick_settings_brightness_label" msgid="680259653088849563">"स्क्रीन की रोशनी"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"अपने-आप घूमना"</string>
@@ -513,8 +512,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"सभी को हटाएं"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"प्रबंधित करें"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"हाल ही में मिली सूचनाएं"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"बिना आवाज़ या वाइब्रेशन वाली सूचनाएं"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"आवाज़ या वाइब्रेशन वाली सूचनाएं"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"बातचीत"</string>
@@ -590,7 +588,7 @@
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"साउंड सेटिंग"</string>
     <string name="accessibility_volume_expand" msgid="7653070939304433603">"विस्तार करें"</string>
     <string name="accessibility_volume_collapse" msgid="2746845391013829996">"छोटा करें"</string>
-    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"ऑडियो-वीडियो पहचानकर अपने-आप कैप्शन बनना"</string>
+    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"ऑडियो-वीडियो से अपने-आप कैप्शन बनना"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"कैप्शन सलाह बंद करें"</string>
     <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"कैप्शन ऊपर लगाएं"</string>
     <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"चालू करें"</string>
@@ -993,10 +991,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"कोई शीर्षक नहीं"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"इस ऐप्लिकेशन को रीस्टार्ट करने और फ़ुल स्क्रीन चालू करने के लिए टैप करें."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> बबल्स की सेटिंग"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ओवरफ़्लो"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"स्टैक में वापस जोड़ें"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"प्रबंधित करें"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> से <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> और <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> अन्य ऐप्लिकेशन से <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1042,7 +1038,7 @@
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"अन्य"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"डिवाइस कंट्रोल में जोड़ें"</string>
     <string name="controls_dialog_ok" msgid="2770230012857881822">"जोड़ें"</string>
-    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ने सुझाव दिया"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> से मिला सुझाव"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"कंट्रोल अपडेट किए गए"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"पिन में अक्षर या चिह्न शामिल होते हैं"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> की पुष्टि करें"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 0c0f4de..34f9b7a 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -63,7 +63,7 @@
     <string name="usb_debugging_allow" msgid="1722643858015321328">"Dopusti"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"Otklanjanje pogrešaka putem USB-a nije dopušteno"</string>
     <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"Korisnik koji je trenutačno prijavljen na ovaj uređaj ne može uključiti otklanjanje pogrešaka putem USB-a. Da biste upotrebljavali tu značajku, prijeđite na primarnog korisnika."</string>
-    <string name="wifi_debugging_title" msgid="7300007687492186076">"Želite li dopustiti bežično otklanjanje pogrešaka na ovoj mreži?"</string>
+    <string name="wifi_debugging_title" msgid="7300007687492186076">"Dopuštate li bežično otklanjanje pogrešaka na ovoj mreži?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"Naziv mreže (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nAdresa Wi‑Fija (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
     <string name="wifi_debugging_always" msgid="2968383799517975155">"Uvijek dopusti na ovoj mreži"</string>
     <string name="wifi_debugging_allow" msgid="4573224609684957886">"Dopusti"</string>
@@ -416,7 +416,7 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"<xliff:g id="DATA_USED">%s</xliff:g> iskorišteno"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Ograničenje od <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Upozorenje <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <string name="quick_settings_work_mode_label" msgid="2754212289804324685">"Radni profil"</string>
+    <string name="quick_settings_work_mode_label" msgid="2754212289804324685">"Poslovni profil"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Noćno svjetlo"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Uključuje se u suton"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Do izlaska sunca"</string>
@@ -654,7 +654,7 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Prikaži demo način"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
-    <string name="status_bar_work" msgid="5238641949837091056">"Radni profil"</string>
+    <string name="status_bar_work" msgid="5238641949837091056">"Poslovni profil"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Način rada u zrakoplovu"</string>
     <string name="add_tile" msgid="6239678623873086686">"Dodavanje pločice"</string>
     <string name="broadcast_tile" msgid="5224010633596487481">"Emitiranje pločice"</string>
@@ -664,7 +664,7 @@
     <string name="alarm_template_far" msgid="3561752195856839456">"u <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_detail" msgid="544463655956179791">"Brze postavke, <xliff:g id="TITLE">%s</xliff:g>."</string>
     <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Žarišna točka"</string>
-    <string name="accessibility_managed_profile" msgid="4703836746209377356">"Radni profil"</string>
+    <string name="accessibility_managed_profile" msgid="4703836746209377356">"Poslovni profil"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Zabava za neke, ali ne za sve"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Ugađanje korisničkog sučelja sustava pruža vam dodatne načine za prilagodbu korisničkog sučelja Androida. Te se eksperimentalne značajke mogu promijeniti, prekinuti ili nestati u budućim izdanjima. Nastavite uz oprez."</string>
     <string name="tuner_persistent_warning" msgid="230466285569307806">"Te se eksperimentalne značajke mogu promijeniti, prekinuti ili nestati u budućim izdanjima. Nastavite uz oprez."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 63f0f3f..45462d4 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Képernyőkép elvetése"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Képernyőkép előnézete"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Képernyőrögzítő"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Képernyőrögzítés feldolgozása"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Folyamatban lévő értesítés képernyőrögzítési munkamenethez"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Elindítja a felvételt?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"A felvétel készítése során az Android rendszer rögzítheti az eszközön lejátszott, illetve a képernyőjén megjelenő bizalmas információkat. Ide tartoznak például a jelszavak, a fizetési információk, a fotók, az üzenetek és az audiotartalmak is."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Az összes törlése"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Kezelés"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Előzmények"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Bejövő"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Néma értesítések"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Figyelemfelkeltő értesítések"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Beszélgetések"</string>
@@ -969,7 +967,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"A háttérben még futnak alkalmazások"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Koppintson az akkumulátor- és adathasználat részleteinek megtekintéséhez"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Kikapcsolja a mobiladatokat?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nem lesz adat-, illetve internet-hozzáférése a(z) <xliff:g id="CARRIER">%s</xliff:g> szolgáltatón keresztül. Az internethez csak Wi-Fi-n keresztül csatlakozhat."</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Nem lesz adat-, illetve internet-hozzáférése a <xliff:g id="CARRIER">%s</xliff:g> szolgáltatón keresztül. Az internethez csak Wi-Fi-n keresztül csatlakozhat."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"saját mobilszolgáltató"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Mivel az egyik alkalmazás eltakarja az engedélykérést, a Beállítások alkalmazás nem tudja ellenőrizni az Ön válaszát."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Engedélyezi a(z) <xliff:g id="APP_0">%1$s</xliff:g> alkalmazásnak, hogy részleteket mutasson a(z) <xliff:g id="APP_2">%2$s</xliff:g> alkalmazásból?"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nincs cím"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Koppintson az alkalmazás újraindításához és a teljes képernyős mód elindításához."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g>-buborékok beállításai"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"További elemeket tartalmazó menü"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Visszaküldés a verembe"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Kezelés"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> a(z) <xliff:g id="APP_NAME">%2$s</xliff:g> alkalmazásból és <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> további"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index b7343be..33cf2a3 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Փակել սքրինշոթը"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Սքրինշոթի նախադիտում"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Էկրանի տեսագրիչ"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Էկրանի տեսագրության մշակում"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Սկսե՞լ տեսագրումը"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Տեսագրման ընթացքում Android-ի համակարգը կարող է գրանցել անձնական տեղեկություններ, որոնք տեսանելի են էկրանին կամ նվագարկվում են ձեր սարքում։ Սա ներառում է այնպիսի տեղեկություններ, ինչպիսիք են, օրինակ, գաղտնաբառերը, վճարային տվյալները, լուսանկարները, հաղորդագրությունները և նվագարկվող աուդիո ֆայլերը։"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Մաքրել բոլորը"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Կառավարել"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Պատմություն"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Մուտքային"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Անձայն ծանուցումներ"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Նախազգուշացնող ծանուցումներ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Խոսակցություններ"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Անանուն"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Հպեք՝ հավելվածը վերագործարկելու և լիաէկրան ռեժիմին անցնելու համար։"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ի ամպիկների կարգավորումներ"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Լրացուցիչ ընտրացանկ"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Նորից ավելացնել զտիչներում"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Կառավարել"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>՝ <xliff:g id="APP_NAME">%2$s</xliff:g>-ից"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>` <xliff:g id="APP_NAME">%2$s</xliff:g>-ից ու ևս <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ամպիկ"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index f3ac8d1..35aabc7 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Menutup screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pratinjau screenshot"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Perekam Layar"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses perekaman layar"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifikasi yang sedang berjalan untuk sesi rekaman layar"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Mulai Merekam?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Saat merekam, Sistem Android dapat ikut merekam informasi sensitif yang terlihat di layar atau diputar di perangkat Anda. Informasi ini mencakup sandi, info pembayaran, foto, pesan, dan audio."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Hapus semua"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Kelola"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Histori"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Masuk"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notifikasi senyap"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notifikasi aktif"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Percakapan"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Tanpa judul"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Ketuk untuk memulai ulang aplikasi ini dan membuka layar penuh."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Setelan untuk balon <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Tambahan"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Tambahkan kembali ke stack"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Kelola"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> dari <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> dari <xliff:g id="APP_NAME">%2$s</xliff:g> dan <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> lainnya"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index d133ed0..52d63b0 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Loka skjámynd"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Forskoðun skjámyndar"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skjáupptaka"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Vinnur úr skjáupptöku"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Áframhaldandi tilkynning fyrir skjáupptökulotu"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Hefja upptöku?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Á meðan tekið er upp getur Android kerfið fangað viðkvæmar upplýsingar sem sjást á skjánum eða spilast í tækinu. Þar á meðal eru upplýsingar á borð við aðgangsorð, greiðsluupplýsingar, myndir, skilaboð og hljóð."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Hreinsa allt"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Stjórna"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Ferill"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Mótteknar"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Þöglar tilkynningar"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Viðvörunartilkynningar"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtöl"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Enginn titill"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Ýttu til að endurræsa forritið og sýna það á öllum skjánum."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Stillingar fyrir blöðrur frá <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Yfirflæði"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Bæta aftur í stafla"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Stjórna"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> frá <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ frá <xliff:g id="APP_NAME">%2$s</xliff:g> og <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> í viðbót"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 2ca52df..1a71d91 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ignora screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Anteprima screenshot"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Registrazione dello schermo"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Elaboraz. registraz. schermo"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notifica costante per una sessione di registrazione dello schermo"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Avviare la registrazione?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Durante la registrazione, il sistema Android può acquisire dati sensibili visibili sullo schermo o riprodotti sul tuo dispositivo, tra cui password, dati di pagamento, foto, messaggi e audio."</string>
@@ -299,8 +298,8 @@
     <string name="accessibility_quick_settings_flashlight_on" msgid="3785616827729850766">"Torcia accesa."</string>
     <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3782375441381402599">"Torcia disattivata."</string>
     <string name="accessibility_quick_settings_flashlight_changed_on" msgid="4747870681508334200">"Torcia attivata."</string>
-    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="7548045840282925393">"Inversione colori disattivata."</string>
-    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="4711141858364404084">"Inversione colori attivata."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="7548045840282925393">"Inversione dei colori disattivata."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="4711141858364404084">"Inversione dei colori attivata."</string>
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"Hotspot mobile disattivato."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"Hotspot mobile attivato."</string>
     <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Trasmissione dello schermo interrotta."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Cancella tutto"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gestisci"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Cronologia"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"In arrivo"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notifiche silenziose"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notifiche di avviso"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversazioni"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Senza titolo"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tocca per riavviare l\'app e passare a schermo intero."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Impostazioni per bolle <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Altre"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Aggiungi di nuovo all\'elenco"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Gestisci"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> da <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> da <xliff:g id="APP_NAME">%2$s</xliff:g> e altre <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 9dfadfb..121f9bb 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"סגירת צילום מסך"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"תצוגה מקדימה של צילום מסך"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"מקליט המסך"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"מתבצע עיבוד של הקלטת מסך"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"התראה מתמשכת לסשן הקלטת מסך"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"להתחיל את ההקלטה?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"‏בזמן ההקלטה, מערכת Android יכולה לתעד מידע רגיש שגלוי במסך או מופעל במכשיר שלך. מידע זה כולל סיסמאות, פרטי תשלום, תמונות, הודעות ואודיו."</string>
@@ -517,8 +516,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ניקוי הכל"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ניהול"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"היסטוריה"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"התקבלו"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"התראות שקטות"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"התראות עם צלילים או רטט"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"שיחות"</string>
@@ -1001,10 +999,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"ללא שם"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"צריך להקיש כדי להפעיל מחדש את האפליקציה הזו ולעבור למסך מלא."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"הגדרות בשביל בועות של <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"גלישה"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"הוספה בחזרה לערימה"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"ניהול"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> מהאפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> מ-<xliff:g id="APP_NAME">%2$s</xliff:g> ועוד <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 15508ac..42ecb64 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"スクリーンショットを閉じます"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"スクリーンショットのプレビュー"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"スクリーン レコーダー"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"画面の録画を処理しています"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"画面の録画セッション中の通知"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"録画を開始しますか?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"録画中に機密情報が画面に表示されたりデバイスで再生されたりした場合、Android システムでキャプチャされることがあります。これには、パスワード、お支払い情報、写真、メッセージ、音声などが含まれます。"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"すべて消去"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"履歴"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"新着"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"サイレント通知"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"バイブレーションまたは音を伴う通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"会話"</string>
@@ -969,7 +967,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"バックグラウンドで実行中のアプリ"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"タップして電池やデータの使用量を確認"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"モバイルデータを OFF にしますか?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"<xliff:g id="CARRIER">%s</xliff:g> でデータやインターネットにアクセスできなくなります。インターネットには Wi-Fi からのみ接続できます。"</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"<xliff:g id="CARRIER">%s</xliff:g>でデータやインターネットにアクセスできなくなります。インターネットには Wi-Fi からのみ接続できます。"</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"携帯通信会社"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"アプリが許可リクエストを隠しているため、設定側でユーザーの応答を確認できません。"</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"「<xliff:g id="APP_2">%2$s</xliff:g>」のスライスの表示を「<xliff:g id="APP_0">%1$s</xliff:g>」に許可しますか?"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"タイトルなし"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"タップしてこのアプリを再起動すると、全画面表示になります。"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> のバブルの設定"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"オーバーフロー"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"スタックに戻す"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"管理"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>(<xliff:g id="APP_NAME">%2$s</xliff:g>)"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>(<xliff:g id="APP_NAME">%2$s</xliff:g>)、他 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> 件"</string>
@@ -1032,7 +1028,7 @@
       <item quantity="one"><xliff:g id="NUMBER_0">%s</xliff:g> 件のコントロールを追加しました。</item>
     </plurals>
     <string name="controls_favorite_default_title" msgid="967742178688938137">"コントロール"</string>
-    <string name="controls_favorite_subtitle" msgid="6604402232298443956">"電源メニューからアクセスするコントロールを選択する"</string>
+    <string name="controls_favorite_subtitle" msgid="6604402232298443956">"電源ボタン メニューからアクセスするコントロールを選択する"</string>
     <string name="controls_favorite_rearrange" msgid="5616952398043063519">"コントロールを並べ替えるには長押ししてドラッグします"</string>
     <string name="controls_favorite_removed" msgid="5276978408529217272">"すべてのコントロールを削除しました"</string>
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"変更が保存されていません"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 4f24828..53ead8e 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Скриншотты жабу"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотты алдын ала қарау"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Экран жазғыш"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экран жазғыш бейнесін өңдеу"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Жазу басталсын ба?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Жазу кезінде Android жүйесі экранда көрсетілетін немесе құрылғыда ойнатылатын құпия ақпаратты пайдалана алады. Ол ақпаратқа құпия сөздер, төлеу ақпараты, фотосуреттер, хабарлар және аудио жатады."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Барлығын тазалау"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Басқару"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Тарих"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Кіріс"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Дыбыссыз хабарландырулар"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Ескертуші хабарландлырулар"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Әңгімелер"</string>
@@ -588,7 +586,7 @@
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Дыбыс параметрлері"</string>
     <string name="accessibility_volume_expand" msgid="7653070939304433603">"Жаю"</string>
     <string name="accessibility_volume_collapse" msgid="2746845391013829996">"Жию"</string>
-    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Автоматты субтитр медиасы"</string>
+    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Автоматты субтитр қосу"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Субтитрлер кеңесі"</string>
     <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Субтитр қою"</string>
     <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"қосу"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Атауы жоқ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Бұл қолданбаны қайта қосып, толық экранға өту үшін түртіңіз."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> қалқыма хабарларының параметрлері"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Қосымша мәзір"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Стекке қайта енгізу"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Басқару"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> жіберген хабарландыру: <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасы жіберген <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> және тағы <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 11b7514c..a33b9f5 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ច្រានចោល​រូបថត​អេក្រង់"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ការមើល​រូបថត​អេក្រង់​សាកល្បង"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"មុខងារថត​អេក្រង់"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"កំពុង​ដំណើរការ​ការថតអេក្រង់"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ការជូនដំណឹង​ដែល​កំពុង​ដំណើរការ​សម្រាប់​រយៈពេលប្រើ​ការថត​សកម្មភាព​អេក្រង់"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"ចាប់ផ្តើម​ថត​ឬ?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"នៅពេល​កំពុងថត ប្រព័ន្ធ Android អាច​ថត​ព័ត៌មាន​រសើប​ដែលអាច​មើលឃើញ​នៅលើ​អេក្រង់​របស់អ្នក ឬដែល​បានចាក់​នៅលើ​ឧបករណ៍​របស់អ្នក។ ព័ត៌មាននេះ​រួមមាន​ពាក្យសម្ងាត់ ព័ត៌មាន​អំពី​ការបង់ប្រាក់ រូបថត សារ និងសំឡេង។"</string>
@@ -369,7 +368,7 @@
     <string name="quick_settings_location_off_label" msgid="7923929131443915919">"ទីតាំង​បាន​បិទ"</string>
     <string name="quick_settings_media_device_label" msgid="8034019242363789941">"ឧបករណ៍​មេឌៀ"</string>
     <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
-    <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"សម្រាប់​តែ​ការ​ហៅ​ពេល​អាសន្ន"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"ការហៅទៅលេខសង្គ្រោះបន្ទាន់​តែប៉ុណ្ណោះ"</string>
     <string name="quick_settings_settings_label" msgid="2214639529565474534">"ការ​កំណត់"</string>
     <string name="quick_settings_time_label" msgid="3352680970557509303">"ពេលវេលា"</string>
     <string name="quick_settings_user_label" msgid="1253515509432672496">"ខ្ញុំ"</string>
@@ -382,7 +381,7 @@
     <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"Wi-Fi បានបើក"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"គ្មានបណ្តាញ Wi-Fi ទេ"</string>
     <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"កំពុង​បើក..."</string>
-    <string name="quick_settings_cast_title" msgid="2279220930629235211">"ការថតវីដេអូ​នៅលើអេក្រង់"</string>
+    <string name="quick_settings_cast_title" msgid="2279220930629235211">"ការបញ្ចាំងអេក្រង់"</string>
     <string name="quick_settings_casting" msgid="1435880708719268055">"ការ​ចាត់​ថ្នាក់"</string>
     <string name="quick_settings_cast_device_default_name" msgid="6988469571141331700">"ឧបករណ៍​​ដែល​មិន​មាន​ឈ្មោះ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2580520859212250265">"ត្រៀម​រួចរាល់​ដើម្បី​ចាត់​ថ្នាក់"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"សម្អាត​ទាំងអស់"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"គ្រប់គ្រង"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ប្រវត្តិ"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"មក​ដល់"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ការជូនដំណឹង​ស្ងាត់"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"ការជូនដំណឹង​ញ័រ ឬរោទ៍"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ការសន្ទនា"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"គ្មាន​ចំណងជើង"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ចុចដើម្បី​ចាប់ផ្ដើម​កម្មវិធី​នេះឡើងវិញ រួចចូលប្រើ​ពេញអេក្រង់។"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"ការកំណត់​សម្រាប់​ពពុះ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ម៉ឺនុយបន្ថែម"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"បញ្ចូល​ទៅក្នុង​គំនរវិញ"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"គ្រប់គ្រង"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ពី <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ពី <xliff:g id="APP_NAME">%2$s</xliff:g> និង <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ទៀត"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index fc0844a..cca8c6b7 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ಸ್ಕ್ರೀನ್‍ಶಾಟ್‍ನ ಪೂರ್ವವೀಕ್ಷಣೆ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡರ್"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಆಗುತ್ತಿದೆ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್‌ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಅಧಿಸೂಚನೆ"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"ರೆಕಾರ್ಡಿಂಗ್ ಪ್ರಾರಂಭಿಸಬೇಕೆ?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"ರೆಕಾರ್ಡಿಂಗ್ ಸಮಯದಲ್ಲಿ, ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಗೋಚರಿಸುವ ಅಥವಾ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲಾದ ಸೂಕ್ಷ್ಮ ಮಾಹಿತಿಯನ್ನು Android ಸಿಸ್ಟಂ ಕ್ಯಾಪ್ಚರ್ ಮಾಡಬಹುದು. ಇದು ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ಮಾಹಿತಿ, ಫೋಟೋಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಆಡಿಯೋವನ್ನು ಒಳಗೊಂಡಿದೆ."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ನಿರ್ವಹಿಸಿ"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ಇತಿಹಾಸ"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"ಒಳಬರುವ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ನಿಶ್ಶಬ್ಧ ಅಧಿಸೂಚನೆಗಳು"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"ಎಚ್ಚರಿಸುವ ಅಧಿಸೂಚನೆಗಳು"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ಸಂಭಾಷಣೆಗಳು"</string>
@@ -985,16 +983,14 @@
     <string name="auto_saver_enabled_text" msgid="7889491183116752719">"ಬ್ಯಾಟರಿ <xliff:g id="PERCENTAGE">%d</xliff:g>%% ಗಿಂತ ಕಡಿಮೆ ಆದಾಗ ಬ್ಯಾಟರಿ ಸೇವರ್‌ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆನ್‌ ಆಗುತ್ತದೆ."</string>
     <string name="open_saver_setting_action" msgid="2111461909782935190">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="auto_saver_okay_action" msgid="7815925750741935386">"ಅರ್ಥವಾಯಿತು"</string>
-    <string name="heap_dump_tile_name" msgid="2464189856478823046">"SysUI ಹೀಪ್ ಡಂಪ್ ಮಾಡಿ"</string>
+    <string name="heap_dump_tile_name" msgid="2464189856478823046">"Dump SysUI Heap"</string>
     <string name="sensor_privacy_mode" msgid="4462866919026513692">"ಸೆನ್ಸರ್‌ಗಳು ಆಫ್"</string>
     <string name="device_services" msgid="1549944177856658705">"ಸಾಧನ ಸೇವೆಗಳು"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"ಯಾವುದೇ ಶೀರ್ಷಿಕೆಯಿಲ್ಲ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ಈ ಆ್ಯಪ್ ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಲು ಮತ್ತು ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ನೋಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಬಬಲ್ಸ್‌ಗಾಗಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ಓವರ್‌ಫ್ಲೋ"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ಸ್ಟ್ಯಾಕ್‌ಗೆ ಪುನಃ ಸೇರಿಸಿ"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"ನಿರ್ವಹಿಸಿ"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> ಆ್ಯಪ್‌ನ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> ಮತ್ತು <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ಹೆಚ್ಚಿನವುಗಳ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index cca8adb..60ecdb7 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"스크린샷 닫기"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"스크린샷 미리보기"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"화면 녹화"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"화면 녹화 처리 중"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"화면 녹화 세션에 관한 지속적인 알림"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"녹화를 시작하시겠습니까?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Android 시스템이 녹화 중에 화면에 표시되거나 기기에서 재생되는 민감한 정보를 캡처할 수 있습니다. 여기에는 비밀번호, 결제 정보, 사진, 메시지 및 오디오가 포함됩니다."</string>
@@ -400,7 +399,7 @@
     <string name="quick_settings_tethering_label" msgid="5257299852322475780">"테더링"</string>
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"핫스팟"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"켜는 중..."</string>
-    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"데이터 절약 모드 사용 중"</string>
+    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"데이터 절약 모드"</string>
     <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
       <item quantity="other">기기 %d대</item>
       <item quantity="one">기기 %d대</item>
@@ -490,7 +489,7 @@
     <string name="user_logout_notification_title" msgid="3644848998053832589">"사용자 로그아웃"</string>
     <string name="user_logout_notification_text" msgid="7441286737342997991">"현재 사용자 로그아웃"</string>
     <string name="user_logout_notification_action" msgid="7974458760719361881">"사용자 로그아웃"</string>
-    <string name="user_add_user_title" msgid="4172327541504825032">"새 사용자를 추가할까요?"</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_limit_reached_title" msgid="2429229448830346057">"사용자 제한 도달"</string>
     <plurals name="user_limit_reached_message" formatted="false" msgid="2573535787802908398">
@@ -511,13 +510,12 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"모두 지우기"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"관리"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"기록"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"최근 알림"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"무음 알림"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"소리 알림"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"대화"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"무음 알림 모두 삭제"</string>
-    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"방해 금지 모드로 일시중지된 알림"</string>
+    <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"방해 금지 모드로 알림이 일시중지됨"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"시작하기"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"알림 없음"</string>
     <string name="profile_owned_footer" msgid="2756770645766113964">"프로필이 모니터링될 수 있음"</string>
@@ -969,7 +967,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"백그라운드에서 실행 중인 앱"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"탭하여 배터리 및 데이터 사용량 확인"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"모바일 데이터를 사용 중지하시겠습니까?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"<xliff:g id="CARRIER">%s</xliff:g>을(를) 통해 데이터 또는 인터넷에 액세스할 수 없습니다. 인터넷은 Wi-Fi를 통해서만 사용할 수 있습니다."</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"<xliff:g id="CARRIER">%s</xliff:g>을(를) 통해 데이터 또는 인터넷에 액세스할 수 없게 됩니다. 인터넷은 Wi-Fi를 통해서만 사용할 수 있습니다."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"이동통신사"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"앱이 권한 요청을 가리고 있기 때문에 설정에서 내 응답을 확인할 수 없습니다."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_0">%1$s</xliff:g>에서 <xliff:g id="APP_2">%2$s</xliff:g>의 슬라이스를 표시하도록 허용하시겠습니까?"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"제목 없음"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"탭하여 이 앱을 다시 시작하고 전체 화면으로 이동합니다."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> 대화창 설정"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"더보기"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"스택에 다시 추가"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"관리"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>의 <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> 외 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>개의 <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 15e53cd..6893e8f 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Скриншотту четке кагуу"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Скриншотту алдын ала көрүү"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"экрандан видео жаздырып алуу"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Экрандан жаздырылып алынган видео иштетилүүдө"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Жаздырып баштайсызбы?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Жаздыруу учурунда Android тутуму экраныңызда көрүнүп турган жана түзмөктө ойноп жаткан бардык купуя маалыматты жаздырып алат. Буга сырсөздөр, төлөм маалыматы, сүрөттөр, билдирүүлөр жана аудио файлдар кирет."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Баарын тазалап салуу"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Башкаруу"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Таржымал"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Кирүүчү"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Үнсүз билдирмелер"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Эскертүүлөр"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Жазышуулар"</string>
@@ -711,7 +709,7 @@
     <string name="notification_silence_title" msgid="8608090968400832335">"Үнсүз"</string>
     <string name="notification_alert_title" msgid="7629202599338071971">"Шашылыш билдирүү"</string>
     <string name="notification_bubble_title" msgid="8330481035191903164">"Көбүк"</string>
-    <string name="notification_channel_summary_low" msgid="7300447764759926720">"Үн же дирилдөөсүз ой топтоого жардам берет."</string>
+    <string name="notification_channel_summary_low" msgid="7300447764759926720">"Билдирмелер келгенде, үн чыкпайт же дирилдебейт."</string>
     <string name="notification_channel_summary_default" msgid="3539949463907902037">"Билдирүүдөн үн чыгат же дирилдейт."</string>
     <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Билдирүүдөн үн чыгат же дирилдейт. <xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосундагы жазышуулар демейки жөндөө боюнча калкып чыкма билдирмелер болуп көрүнөт."</string>
     <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Калкыма ыкчам баскыч менен көңүлүңүздү бул мазмунга буруп турат."</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Аталышы жок"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Бул колдонмону өчүрүп күйгүзүп, толук экранга өтүү үчүн, таптап коюңуз."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> калкып чыкма билдирмелер жөндөөлөрү"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Кошумча меню"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Кайра топтомго кошуу"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Башкаруу"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> колдонмосунан <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> жана дагы <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> колдонмодон <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 0c403db2..2514b3e 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4811759950673118541">"ສ່ວນຕິດຕໍ່ຜູ່ໃຊ້ຂອງລະບົບ"</string>
+    <string name="app_label" msgid="4811759950673118541">"ສ່ວນຕິດຕໍ່ຜູ້ໃຊ້ຂອງລະບົບ"</string>
     <string name="status_bar_clear_all_button" msgid="2491321682873657397">"ລຶບ"</string>
     <string name="status_bar_no_notifications_title" msgid="7812479124981107507">"ບໍ່ມີການແຈ້ງເຕືອນ"</string>
     <string name="status_bar_ongoing_events_title" msgid="3986169317496615446">"ດຳເນີນຢູ່"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 95570bc..4f016d3 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Praleisti ekrano kopiją"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekrano kopijos peržiūra"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrano vaizdo įrašytuvas"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Apdorojam. ekrano vaizdo įraš."</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Šiuo metu rodomas ekrano įrašymo sesijos pranešimas"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Pradėti įrašymą?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Įrašant „Android“ sistema gali fiksuoti bet kokią neskelbtiną informaciją, rodomą ekrane ar leidžiamą įrenginyje. Tai apima slaptažodžius, išsamią mokėjimo informaciją, nuotraukas, pranešimus ir garso įrašus."</string>
@@ -517,8 +516,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Viską išvalyti"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Tvarkyti"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Istorija"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Gaunami"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Tylieji pranešimai"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Įspėjamieji pranešimai"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Pokalbiai"</string>
@@ -1001,10 +999,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nėra pavadinimo"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Palieskite, kad paleistumėte iš naujo šią programą arba įjungtumėte viso ekrano režimą."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ burbulų nustatymai"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Perpildymas"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Pridėti atgal į krūvą"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Tvarkyti"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ iš „<xliff:g id="APP_NAME">%2$s</xliff:g>“"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ iš „<xliff:g id="APP_NAME">%2$s</xliff:g>“ ir dar <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 3a01e0e..5cc696c 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Nerādīt ekrānuzņēmumu"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekrānuzņēmuma priekšskatījums"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrāna ierakstītājs"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekrāna ieraksta apstrāde"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Vai sākt ierakstīšanu?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Ierakstīšanas laikā Android sistēmā var tikt tverta jebkura sensitīvā informācija, kas ir redzama jūsu ekrānā vai tiek atskaņota jūsu ierīcē. Šī informācija ir paroles, maksājumu informācija, fotoattēli, ziņojumi un audio."</string>
@@ -514,8 +513,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Dzēst visu"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Pārvaldīt"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Vēsture"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Ienākošie"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Klusie paziņojumi"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Paziņojumi ar skaņu vai vibrāciju"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Sarunas"</string>
@@ -996,10 +994,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nav nosaukuma"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Pieskarieties, lai restartētu šo lietotni un pārietu pilnekrāna režīmā."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> burbuļu iestatījumi"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Pārpilde"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Pievienot atpakaļ kopai"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Pārvaldīt"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> no: <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> no lietotnes “<xliff:g id="APP_NAME">%2$s</xliff:g>” un vēl <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 7aab7f6..64f614f 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Отфрлете ја сликата од екранот"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Преглед на слика од екранот"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Снимач на екран"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Се обработува снимка од екран"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Да се започне со снимање?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"При снимањето, системот Android може да ги сними сите чувствителни податоци што се видливи на вашиот екран или пуштени на уредот. Ова вклучува лозинки, податоци за плаќање, фотографии, пораки и аудио."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Избриши сѐ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Управувајте"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Историја"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Дојдовни"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Тивки известувања"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Известувања за предупредување"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Разговори"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслов"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Допрете за да ја рестартирате апликацијава и да ја отворите на цел екран."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Поставки за балончињата за <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Прелевање"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Додајте назад во stack"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Управување"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> од <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> од <xliff:g id="APP_NAME">%2$s</xliff:g> и уште <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 466d6d4..bee7e91 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"സ്ക്രീൻഷോട്ട് ഡിസ്‌മിസ് ചെയ്യുക"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"സ്‌ക്രീൻഷോട്ട് പ്രിവ്യു"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"സ്ക്രീൻ റെക്കോർഡർ"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"സ്ക്രീൻ റെക്കോർഡിംഗ് പ്രോസസുചെയ്യുന്നു"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"റെക്കോർഡിംഗ് ആരംഭിക്കണോ?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"റെക്കോർഡ് ചെയ്യുമ്പോൾ, നിങ്ങളുടെ സ്‌ക്രീനിൽ ദൃശ്യമാകുന്നതോ ഉപകരണത്തിൽ പ്ലേ ചെയ്യുന്നതോ ആയ ഏത് തന്ത്രപ്രധാന വിവരങ്ങളും Android സിസ്റ്റത്തിന് പകർത്താനാവും. പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിവരം, ഫോട്ടോകൾ, സന്ദേശങ്ങൾ, ഓഡിയോ എന്നിവ ഇതിൽ ഉൾപ്പെടുന്നു."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"എല്ലാം മായ്‌ക്കുക"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"മാനേജ് ചെയ്യുക"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ചരിത്രം"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"ഇൻകമിംഗ്"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"നിശബ്‌ദ അറിയിപ്പുകൾ"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"മുന്നറിയിപ്പ് നൽകുന്ന അറിയിപ്പുകൾ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"സംഭാഷണങ്ങൾ"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"പേരില്ല"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ഈ ആപ്പ് റീസ്‌റ്റാർട്ട് ചെയ്യാനും പൂർണ്ണ സ്‌ക്രീനാവാനും ടാപ്പ് ചെയ്യുക."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ബബിളുകളുടെ ക്രമീകരണം"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ഓവർഫ്ലോ"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"അടുക്കുകളിലേക്ക് തിരിച്ച് ചേർക്കുക"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"മാനേജ് ചെയ്യുക"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>-ൽ നിന്നുള്ള <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> എന്നതിൽ നിന്നുള്ള <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> കൂടുതലും"</string>
@@ -1039,10 +1035,8 @@
     <string name="controls_favorite_load_error" msgid="2533215155804455348">"എല്ലാ നിയന്ത്രണങ്ങളുടെയും ലിസ്റ്റ് ലോഡ് ചെയ്യാനായില്ല."</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"മറ്റുള്ളവ"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"ഉപകരണ നിയന്ത്രണങ്ങളിലേക്ക് ചേർക്കുക"</string>
-    <!-- no translation found for controls_dialog_ok (2770230012857881822) -->
-    <skip />
-    <!-- no translation found for controls_dialog_message (342066938390663844) -->
-    <skip />
+    <string name="controls_dialog_ok" msgid="2770230012857881822">"ചേർക്കുക"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> നിർദ്ദേശിച്ചത്"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"നിയന്ത്രണങ്ങൾ അപ്ഡേറ്റ് ചെയ്തു"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"പിന്നിൽ അക്ഷരങ്ങളോ ചിഹ്നങ്ങളോ അടങ്ങിയിരിക്കുന്നു"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> പരിശോധിച്ചുറപ്പിക്കുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index dcff600..9e915e0 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -45,7 +45,7 @@
     <string name="status_bar_settings_notifications" msgid="5285316949980621438">"Мэдэгдэл"</string>
     <string name="bluetooth_tethered" msgid="4171071193052799041">"Блютүүтыг модем болгож байна"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="2972273031043777851">"Оруулах аргыг тохируулах"</string>
-    <string name="status_bar_use_physical_keyboard" msgid="4849251850931213371">"Бодит гар"</string>
+    <string name="status_bar_use_physical_keyboard" msgid="4849251850931213371">"Биет гар"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"<xliff:g id="APPLICATION">%1$s</xliff:g>-г <xliff:g id="USB_DEVICE">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"<xliff:g id="APPLICATION">%1$s</xliff:g>-д <xliff:g id="USB_DEVICE">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?\nЭнэ аппад бичих зөвшөөрөл олгогдоогүй ч USB төхөөрөмжөөр дамжуулан аудио бичиж чадсан."</string>
     <string name="usb_accessory_permission_prompt" msgid="717963550388312123">"<xliff:g id="APPLICATION">%1$s</xliff:g>-г <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>-д хандахыг зөвшөөрөх үү?"</string>
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Дэлгэцийн агшныг хаах"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Дэлгэцийн агшныг урьдчилан үзэх"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Дэлгэцийн үйлдэл бичигч"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Дэлгэц бичлэг боловсруулж байна"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Бичлэгийг эхлүүлэх үү?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Бичих үед Андройд систем нь таны дэлгэц дээр харагдах эсвэл төхөөрөмж дээрээ тоглуулсан аливаа эмзэг мэдээллийг авах боломжтой. Үүнд нууц үг, төлбөрийн мэдээлэл, зураг, зурвас болон аудио багтана."</string>
@@ -299,8 +298,8 @@
     <string name="accessibility_quick_settings_flashlight_on" msgid="3785616827729850766">"Флаш гэрэл ассан."</string>
     <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3782375441381402599">"Флаш гэрлийг унтраасан."</string>
     <string name="accessibility_quick_settings_flashlight_changed_on" msgid="4747870681508334200">"Флаш гэрлийг асаасан."</string>
-    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="7548045840282925393">"Өнгө урвуулагчийг унтраасан."</string>
-    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="4711141858364404084">"Өнгө урвуулагчийг асаасан."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="7548045840282925393">"Өнгө хувиргалтыг унтраасан."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="4711141858364404084">"Өнгө хувиргалтыг асаасан."</string>
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"Мобайл хотспотыг унтраасан."</string>
     <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"Мобайл хотспотыг асаасан."</string>
     <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"Дэлгэц дамжуулалт зогссон."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Бүгдийг арилгах"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Удирдах"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Түүх"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Ирж буй"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Чимээгүй мэдэгдэл"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Сэрэмжлүүлэх мэдэгдэл"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Харилцан яриа"</string>
@@ -695,7 +693,7 @@
     <string name="notification_channel_unsilenced" msgid="94878840742161152">"Эдгээр мэдэгдлийг танд мэдэгдэнэ"</string>
     <string name="inline_blocking_helper" msgid="2891486013649543452">"Та эдгээр мэдэгдлийг ихэвчлэн хаадаг. \nЭдгээрийг харуулсан хэвээр байх уу?"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Болсон"</string>
-    <string name="inline_ok_button" msgid="603075490581280343">"Хаах"</string>
+    <string name="inline_ok_button" msgid="603075490581280343">"Ашиглах"</string>
     <string name="inline_keep_showing" msgid="8736001253507073497">"Эдгээр мэдэгдлийг харуулсан хэвээр байх уу?"</string>
     <string name="inline_stop_button" msgid="2453460935438696090">"Мэдэгдлийг зогсоох"</string>
     <string name="inline_deliver_silently_button" msgid="2714314213321223286">"Дуугүй хүргэх"</string>
@@ -712,7 +710,7 @@
     <string name="notification_alert_title" msgid="7629202599338071971">"Дуутай"</string>
     <string name="notification_bubble_title" msgid="8330481035191903164">"Бөмбөлөг"</string>
     <string name="notification_channel_summary_low" msgid="7300447764759926720">"Дуу эсвэл чичиргээгүйгээр танд төвлөрөхөд тусална."</string>
-    <string name="notification_channel_summary_default" msgid="3539949463907902037">"Дуу эсвэл чичиргээгүйгээр таны анхаарлыг татна."</string>
+    <string name="notification_channel_summary_default" msgid="3539949463907902037">"Дуу эсвэл чичиргээгээр таны анхаарлыг татна."</string>
     <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Дуу эсвэл чичиргээгээр таны анхаарлыг татна. <xliff:g id="APP_NAME">%1$s</xliff:g>-н харилцан яриаг өгөгдмөл тохиргоогоор бөмбөлөг болгоно."</string>
     <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Энэ контентын хөвөн гарч ирэх товчлолтойгоор таны анхаарлыг татдаг."</string>
     <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Харилцан ярианы хэсгийн дээд талд, бөмбөлөг хэлбэрээр харагдана."</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Гарчиггүй"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Энэ аппыг дахин эхлүүлж, бүтэн дэлгэцэд орохын тулд товшино уу."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н бөмбөлгүүдийн тохиргоо"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Халих"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Өрөлтөд буцааж нэмэх"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Удирдах"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>-н <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g>-н <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> болон бусад <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 5497d70..d0730c0 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -22,7 +22,7 @@
     <string name="app_label" msgid="4811759950673118541">"सिस्टम UI"</string>
     <string name="status_bar_clear_all_button" msgid="2491321682873657397">"साफ करा"</string>
     <string name="status_bar_no_notifications_title" msgid="7812479124981107507">"सूचना नाहीत"</string>
-    <string name="status_bar_ongoing_events_title" msgid="3986169317496615446">"सुरु असलेले"</string>
+    <string name="status_bar_ongoing_events_title" msgid="3986169317496615446">"सुरू असलेले"</string>
     <string name="status_bar_latest_events_title" msgid="202755896454005436">"सूचना"</string>
     <string name="battery_low_title" msgid="6891106956328275225">"बॅटरी लवकर संपू शकते"</string>
     <string name="battery_low_percent_format" msgid="4276661262843170964">"<xliff:g id="PERCENTAGE">%s</xliff:g> शिल्लक"</string>
@@ -35,7 +35,7 @@
     <string name="battery_low_why" msgid="2056750982959359863">"सेटिंग्ज"</string>
     <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"बॅटरी सेव्हर सुरू करायचा का?"</string>
     <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"बॅटरी सेव्हर बाबत"</string>
-    <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"चालू करा"</string>
+    <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"सुरू करा"</string>
     <string name="battery_saver_start_action" msgid="4553256017945469937">"बॅटरी सेव्हर सुरू करा"</string>
     <string name="status_bar_settings_settings_button" msgid="534331565185171556">"सेटिंग्ज"</string>
     <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"वाय-फाय"</string>
@@ -62,7 +62,7 @@
     <string name="usb_debugging_always" msgid="4003121804294739548">"या संगणकावरून नेहमी अनुमती द्या"</string>
     <string name="usb_debugging_allow" msgid="1722643858015321328">"अनुमती द्या"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB डीबग करण्‍यास अनुमती नाही"</string>
-    <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"सध्‍या या डीव्हाइसमध्‍ये साइन इन केलेला वापरकर्ता USB डीबग करणे चालू करू शकत नाही. हे वैशिष्‍ट्य वापरण्‍यासाठी, प्राथमिक वापरकर्त्‍यावर स्विच करा."</string>
+    <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"सध्‍या या डीव्हाइसमध्‍ये साइन इन केलेला वापरकर्ता USB डीबग करणे सुरू करू शकत नाही. हे वैशिष्‍ट्य वापरण्‍यासाठी, प्राथमिक वापरकर्त्‍यावर स्विच करा."</string>
     <string name="wifi_debugging_title" msgid="7300007687492186076">"या नेटवर्कवर वायरलेस डीबगिंग करण्याला अनुमती द्यायची का?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"नेटवर्कचे नाव (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nवाय-फाय ॲड्रेस (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
     <string name="wifi_debugging_always" msgid="2968383799517975155">"या नेटवर्कवर नेहमी अनुमती द्या"</string>
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"स्क्रीनशॉट डिसमिस करा"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रीनशॉटचे पूर्वावलोकन"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रीन रेकॉर्डर"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रेकॉर्डिंग प्रोसेस सुरू"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"रेकॉर्डिंग सुरू करायचे आहे का?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"रेकॉर्डिंग करताना, Android सिस्टम तुमच्या स्क्रीनवर दिसणारी किंवा तुमच्या डिव्हाइसवर प्ले केलेली कोणतीही संवेदनशील माहिती कॅप्चर करू शकते. यात पासवर्ड, पेमेंट माहिती, फोटो, मेसेज आणि ऑडिओचा समावेश आहे."</string>
@@ -211,7 +210,7 @@
     <string name="accessibility_two_bars" msgid="1335676987274417121">"दोन बार."</string>
     <string name="accessibility_three_bars" msgid="819417766606501295">"तीन बार."</string>
     <string name="accessibility_signal_full" msgid="5920148525598637311">"सिग्नल पूर्ण."</string>
-    <string name="accessibility_desc_on" msgid="2899626845061427845">"चालू."</string>
+    <string name="accessibility_desc_on" msgid="2899626845061427845">"सुरू."</string>
     <string name="accessibility_desc_off" msgid="8055389500285421408">"बंद."</string>
     <string name="accessibility_desc_connected" msgid="3082590384032624233">"कनेक्‍ट केले."</string>
     <string name="accessibility_desc_connecting" msgid="8011433412112903614">"कनेक्ट करत आहे."</string>
@@ -236,7 +235,7 @@
     <string name="cell_data_off" msgid="4886198950247099526">"बंद"</string>
     <string name="accessibility_bluetooth_tether" msgid="6327291292208790599">"ब्लूटूथ टेदरिंग."</string>
     <string name="accessibility_airplane_mode" msgid="1899529214045998505">"विमान मोड."</string>
-    <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN चालू."</string>
+    <string name="accessibility_vpn_on" msgid="8037549696057288731">"VPN सुरू."</string>
     <string name="accessibility_no_sims" msgid="5711270400476534667">"सिम कार्ड नाही."</string>
     <string name="carrier_network_change_mode" msgid="5174141476991149918">"वाहक नेटवर्क बदलत आहे"</string>
     <string name="accessibility_battery_details" msgid="6184390274150865789">"बॅटरी तपशील उघडा"</string>
@@ -267,13 +266,13 @@
     <string name="accessibility_desc_close" msgid="8293708213442107755">"बंद करा"</string>
     <string name="accessibility_quick_settings_wifi" msgid="167707325133803052">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
     <string name="accessibility_quick_settings_wifi_changed_off" msgid="2230487165558877262">"Wifi बंद झाले."</string>
-    <string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"Wifi चालू झाले."</string>
+    <string name="accessibility_quick_settings_wifi_changed_on" msgid="1490362586009027611">"Wifi सुरू झाले."</string>
     <string name="accessibility_quick_settings_mobile" msgid="1817825313718492906">"मोबाईल <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
     <string name="accessibility_quick_settings_battery" msgid="533594896310663853">"बॅटरी <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane_off" msgid="1275658769368793228">"विमान मोड बंद."</string>
-    <string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"विमान मोड चालू."</string>
+    <string name="accessibility_quick_settings_airplane_on" msgid="8106176561295294255">"विमान मोड सुरू."</string>
     <string name="accessibility_quick_settings_airplane_changed_off" msgid="8880183481476943754">"विमान मोड बंद केला."</string>
-    <string name="accessibility_quick_settings_airplane_changed_on" msgid="6327378061894076288">"विमान मोड चालू केला."</string>
+    <string name="accessibility_quick_settings_airplane_changed_on" msgid="6327378061894076288">"विमान मोड सुरू केला."</string>
     <string name="accessibility_quick_settings_dnd_none_on" msgid="3235552940146035383">"संपूर्ण शांतता"</string>
     <string name="accessibility_quick_settings_dnd_alarms_on" msgid="3375848309132140014">"फक्‍त अलार्म"</string>
     <string name="accessibility_quick_settings_dnd" msgid="2415967452264206047">"व्यत्यय आणू नका."</string>
@@ -281,35 +280,35 @@
     <string name="accessibility_quick_settings_dnd_changed_on" msgid="186315911607486129">"व्यत्यय आणू नका सुरू केले आहे."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="8250942386687551283">"ब्लूटूथ."</string>
     <string name="accessibility_quick_settings_bluetooth_off" msgid="3795983516942423240">"ब्लूटूथ बंद."</string>
-    <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ब्लूटूथ चालू."</string>
+    <string name="accessibility_quick_settings_bluetooth_on" msgid="3819082137684078013">"ब्लूटूथ सुरू."</string>
     <string name="accessibility_quick_settings_bluetooth_connecting" msgid="7362294657419149294">"ब्लूटूथ कनेक्ट करत आहे."</string>
     <string name="accessibility_quick_settings_bluetooth_connected" msgid="5237625393869747261">"ब्लूटूथ कनेक्‍ट केले."</string>
     <string name="accessibility_quick_settings_bluetooth_changed_off" msgid="3344226652293797283">"ब्लूटूथ बंद केले."</string>
-    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="1263282011749437549">"ब्लूटूथ चालू केले."</string>
+    <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="1263282011749437549">"ब्लूटूथ सुरू केले."</string>
     <string name="accessibility_quick_settings_location_off" msgid="6122523378294740598">"स्थान अहवाल बंद."</string>
-    <string name="accessibility_quick_settings_location_on" msgid="6869947200325467243">"स्थान अहवाल चालू."</string>
+    <string name="accessibility_quick_settings_location_on" msgid="6869947200325467243">"स्थान अहवाल सुरू."</string>
     <string name="accessibility_quick_settings_location_changed_off" msgid="5132776369388699133">"स्थान अहवाल बंद केला."</string>
-    <string name="accessibility_quick_settings_location_changed_on" msgid="7159115433070112154">"स्थान अहवाल चालू केला."</string>
+    <string name="accessibility_quick_settings_location_changed_on" msgid="7159115433070112154">"स्थान अहवाल सुरू केला."</string>
     <string name="accessibility_quick_settings_alarm" msgid="558094529584082090">"<xliff:g id="TIME">%s</xliff:g> साठी अलार्म सेट केला."</string>
     <string name="accessibility_quick_settings_close" msgid="2974895537860082341">"पॅनेल बंद करा."</string>
     <string name="accessibility_quick_settings_more_time" msgid="7646479831704665284">"अधिक वेळ."</string>
     <string name="accessibility_quick_settings_less_time" msgid="9110364286464977870">"कमी वेळ."</string>
     <string name="accessibility_quick_settings_flashlight_off" msgid="7606563260714825190">"फ्लॅशलाइट बंद."</string>
     <string name="accessibility_quick_settings_flashlight_unavailable" msgid="7458591827288347635">"फ्लॅशलाइट अनुपलब्ध आहे."</string>
-    <string name="accessibility_quick_settings_flashlight_on" msgid="3785616827729850766">"फ्लॅशलाइट चालू."</string>
+    <string name="accessibility_quick_settings_flashlight_on" msgid="3785616827729850766">"फ्लॅशलाइट सुरू."</string>
     <string name="accessibility_quick_settings_flashlight_changed_off" msgid="3782375441381402599">"फ्लॅशलाइट बंद केला."</string>
-    <string name="accessibility_quick_settings_flashlight_changed_on" msgid="4747870681508334200">"फ्लॅशलाइट चालू केला."</string>
+    <string name="accessibility_quick_settings_flashlight_changed_on" msgid="4747870681508334200">"फ्लॅशलाइट सुरू केला."</string>
     <string name="accessibility_quick_settings_color_inversion_changed_off" msgid="7548045840282925393">"रंग उत्क्रमण बंद केले."</string>
-    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="4711141858364404084">"रंग उत्क्रमण चालू केले."</string>
+    <string name="accessibility_quick_settings_color_inversion_changed_on" msgid="4711141858364404084">"रंग उत्क्रमण सुरू केले."</string>
     <string name="accessibility_quick_settings_hotspot_changed_off" msgid="7002061268910095176">"मोबाईल हॉटस्पॉट बंद केला."</string>
-    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"मोबाईल हॉटस्पॉट चालू केला."</string>
+    <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2576895346762408840">"मोबाईल हॉटस्पॉट सुरू केला."</string>
     <string name="accessibility_casting_turned_off" msgid="1387906158563374962">"स्क्रीन कास्ट करणे थांबले."</string>
     <string name="accessibility_quick_settings_work_mode_off" msgid="562749867895549696">"कार्य मोड बंद."</string>
-    <string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"कार्य मोड चालू."</string>
+    <string name="accessibility_quick_settings_work_mode_on" msgid="2779253456042059110">"कार्य मोड सुरू."</string>
     <string name="accessibility_quick_settings_work_mode_changed_off" msgid="6256690740556798683">"कार्य मोड बंद केला."</string>
-    <string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"कार्य मोड चालू केला."</string>
+    <string name="accessibility_quick_settings_work_mode_changed_on" msgid="1105258550138313384">"कार्य मोड सुरू केला."</string>
     <string name="accessibility_quick_settings_data_saver_changed_off" msgid="4910847127871603832">"डेटा सर्व्हर बंद केला."</string>
-    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"डेटा सर्व्हर चालू केला."</string>
+    <string name="accessibility_quick_settings_data_saver_changed_on" msgid="6370606590802623078">"डेटा सर्व्हर सुरू केला."</string>
     <string name="accessibility_quick_settings_sensor_privacy_changed_off" msgid="7608378211873807353">"सेन्सर गोपनीयता बंद केली आहे."</string>
     <string name="accessibility_quick_settings_sensor_privacy_changed_on" msgid="4267393685085328801">"सेन्सर गोपनीयता सुरू केली आहे."</string>
     <string name="accessibility_brightness" msgid="5391187016177823721">"डिस्प्ले चमक"</string>
@@ -319,7 +318,7 @@
     <string name="data_usage_disabled_dialog_mobile_title" msgid="2286843518689837719">"मोबाइल डेटा थांबवला आहे"</string>
     <string name="data_usage_disabled_dialog_title" msgid="9131615296036724838">"डेटास विराम दिला आहे"</string>
     <string name="data_usage_disabled_dialog" msgid="7933201635215099780">"तुम्ही सेट केलेली डेटा मर्यादा संपली. आता तुमचे मोबाइल डेटा वापरणे बंद आहे.\n\nतुम्ही ते पुन्हा सुरू केल्यास, डेटा वापरासाठी शुल्क लागू होईल."</string>
-    <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"पुन्हा सुरु करा"</string>
+    <string name="data_usage_disabled_dialog_enable" msgid="2796648546086408937">"पुन्हा सुरू करा"</string>
     <string name="gps_notification_searching_text" msgid="231304732649348313">"GPS शोधत आहे"</string>
     <string name="gps_notification_found_text" msgid="3145873880174658526">"GPS द्वारे स्थान सेट केले"</string>
     <string name="accessibility_location_active" msgid="2845747916764660369">"स्थान विनंत्या सक्रिय"</string>
@@ -379,7 +378,7 @@
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"कनेक्ट केले नाही"</string>
     <string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"नेटवर्क नाही"</string>
     <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"वाय-फाय बंद"</string>
-    <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"वाय-फाय चालू"</string>
+    <string name="quick_settings_wifi_on_label" msgid="2489928193654318511">"वाय-फाय सुरू"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"वाय-फाय नेटवर्क उपलब्‍ध नाहीत"</string>
     <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"सुरू करत आहे…"</string>
     <string name="quick_settings_cast_title" msgid="2279220930629235211">"स्क्रीन कास्ट करा"</string>
@@ -417,9 +416,9 @@
     <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"<xliff:g id="DATA_LIMIT">%s</xliff:g> चेतावणी"</string>
     <string name="quick_settings_work_mode_label" msgid="2754212289804324685">"कार्य प्रोफाइल"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"रात्रीचा प्रकाश"</string>
-    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"संध्याकाळी चालू असते"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"संध्याकाळी सुरू असते"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"सूर्योदयापर्यंत"</string>
-    <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"<xliff:g id="TIME">%s</xliff:g> वाजता चालू"</string>
+    <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"<xliff:g id="TIME">%s</xliff:g> वाजता सुरू"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"<xliff:g id="TIME">%s</xliff:g> पर्यंत"</string>
     <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"गडद थीम"</string>
     <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"बॅटरी सेव्‍हर"</string>
@@ -481,9 +480,9 @@
     <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"या सत्रातील सर्व अ‍ॅप्स आणि डेटा हटवला जाईल."</string>
     <string name="guest_exit_guest_dialog_remove" msgid="7505817591242703757">"काढा"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"अतिथी, तुमचे पुन्‍हा स्‍वागत आहे!"</string>
-    <string name="guest_wipe_session_message" msgid="3393823610257065457">"तुम्ही तुमचे सत्र सुरु ठेवू इच्छिता?"</string>
+    <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_wipe_session_dontwipe" msgid="3211052048269304205">"होय, सुरू ठेवा"</string>
     <string name="guest_notification_title" msgid="4434456703930764167">"अतिथी वापरकर्ता"</string>
     <string name="guest_notification_text" msgid="4202692942089571351">"अ‍ॅप्स आणि डेटा हटविण्‍यासाठी, अतिथी वापरकर्ता काढा"</string>
     <string name="guest_notification_remove_action" msgid="4153019027696868099">"अतिथी काढा"</string>
@@ -511,10 +510,9 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"सर्व साफ करा"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थापित करा"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"आलेल्या"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"सायलंट सूचना"</string>
-    <string name="notification_section_header_alerting" msgid="3168140660646863240">"लक्ष वेधून घेणाऱ्या सूचना"</string>
+    <string name="notification_section_header_alerting" msgid="3168140660646863240">"इशारा देणाऱ्या सूचना"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"संभाषणे"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"सर्व सायलंट सूचना साफ करा"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"व्यत्यय आणून नकाद्वारे सूचना थांबवल्या"</string>
@@ -552,7 +550,7 @@
     <string name="monitoring_description_management_ca_certificate" msgid="7785013130658110130">"आपल्या संस्थेने या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
     <string name="monitoring_description_managed_profile_ca_certificate" msgid="7904323416598435647">"आपल्या संस्थेने आपल्या कार्य प्रोफाइलवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
     <string name="monitoring_description_ca_certificate" msgid="448923057059097497">"या डिव्हाइसवर प्रमाणपत्र अधिकार इंस्टॉल केला आहे. आपल्या सुरक्षित नेटवर्क रहदारीचे परीक्षण केले जाऊ शकते किंवा ती सुधारली जाऊ शकते."</string>
-    <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"आपल्या प्रशासकाने नेटवर्क लॉगिंग चालू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे परीक्षण करते."</string>
+    <string name="monitoring_description_management_network_logging" msgid="216983105036994771">"आपल्या प्रशासकाने नेटवर्क लॉगिंग सुरू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे परीक्षण करते."</string>
     <string name="monitoring_description_named_vpn" msgid="5749932930634037027">"तुम्‍ही <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसहित आपल्‍या नेटवर्क क्रिया मॉनिटर करू शकते."</string>
     <string name="monitoring_description_two_named_vpns" msgid="3516830755681229463">"तुम्‍ही <xliff:g id="VPN_APP_0">%1$s</xliff:g> आणि <xliff:g id="VPN_APP_1">%2$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसहित आपल्‍या नेटवर्क क्रिया मॉनिटर करू शकते."</string>
     <string name="monitoring_description_managed_profile_named_vpn" msgid="368812367182387320">"तुमचे कार्य प्रोफाइल <xliff:g id="VPN_APP">%1$s</xliff:g> शी कनेक्‍ट केले आहे, जे ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्‍या नेटवर्क क्रियाकलापाचे परीक्षण करू शकते."</string>
@@ -567,7 +565,7 @@
     <string name="monitoring_description_vpn_settings" msgid="5264167033247632071">"VPN सेटिंग्ज उघडा"</string>
     <string name="monitoring_description_ca_cert_settings_separator" msgid="7107390013344435439">" "</string>
     <string name="monitoring_description_ca_cert_settings" msgid="8329781950135541003">"विश्वासू क्रेडेंशियल उघडा"</string>
-    <string name="monitoring_description_network_logging" msgid="577305979174002252">"आपल्या प्रशासकाने नेटवर्क लॉगिंग चालू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे निरीक्षण करते.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
+    <string name="monitoring_description_network_logging" msgid="577305979174002252">"आपल्या प्रशासकाने नेटवर्क लॉगिंग सुरू केले आहे, जे आपल्या डिव्हाइसवरील रहदारीचे निरीक्षण करते.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा."</string>
     <string name="monitoring_description_vpn" msgid="1685428000684586870">"तुम्ही VPN कनेक्शन सेट करण्यासाठी अ‍ॅपला परवानगी दिली.\n\nहा अ‍ॅप ईमेल, अ‍ॅप्स आणि वेबसाइटसह, तुमच्या डिव्हाइस आणि नेटवर्क ॲक्टिव्हिटीचे परीक्षण करू शकतो."</string>
     <string name="monitoring_description_vpn_profile_owned" msgid="4964237035412372751">"तुमचे कार्य प्रोफाइल <xliff:g id="ORGANIZATION">%1$s</xliff:g> द्वारे व्यवस्थापित केले जाते.\n\nतुमचा प्रशासक ईमेल, अ‍ॅप्स आणि वेबसाइटसह आपल्या नेटवर्क ॲक्टिव्हिटीचे निरीक्षण करण्यास सक्षम आहे.\n\nअधिक माहितीसाठी आपल्या प्रशासकाशी संपर्क साधा.\n\nतुम्ही VPN शी देखील कनेक्ट आहात, जे आपल्या नेटवर्क ॲक्टिव्हिटीचे निरीक्षण करू शकते."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
@@ -608,7 +606,7 @@
     <string name="screen_pinning_start" msgid="5695091877402422575">"स्क्रीन पिन केला"</string>
     <string name="screen_pinning_exit" msgid="5114993350662745840">"स्क्रीन अनपिन केला"</string>
     <string name="quick_settings_reset_confirmation_title" msgid="463533331480997595">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> लपवायचे?"</string>
-    <string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"तुम्ही सेटिंग्जमध्ये ते पुढील वेळी चालू कराल तेव्हा ते पुन्हा दिसेल."</string>
+    <string name="quick_settings_reset_confirmation_message" msgid="2320586180785674186">"तुम्ही सेटिंग्जमध्ये ते पुढील वेळी सुरू कराल तेव्हा ते पुन्हा दिसेल."</string>
     <string name="quick_settings_reset_confirmation_button" msgid="3341477479055016776">"लपवा"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"कॉल करा"</string>
     <string name="stream_system" msgid="7663148785370565134">"सिस्टम"</string>
@@ -638,7 +636,7 @@
     <string name="output_title" msgid="3938776561655668350">"मीडिया आउटपुट"</string>
     <string name="output_calls_title" msgid="7085583034267889109">"फोन कॉल आउटपुट"</string>
     <string name="output_none_found" msgid="5488087293120982770">"कोणतीही डिव्हाइस सापडली नाहीत"</string>
-    <string name="output_none_found_service_off" msgid="935667567681386368">"कोणतीही डिव्हाइस सापडली नाहीत. <xliff:g id="SERVICE">%1$s</xliff:g> चालू करून पाहा"</string>
+    <string name="output_none_found_service_off" msgid="935667567681386368">"कोणतीही डिव्हाइस सापडली नाहीत. <xliff:g id="SERVICE">%1$s</xliff:g> सुरू करून पाहा"</string>
     <string name="output_service_bt" msgid="4315362133973911687">"ब्लूटूथ"</string>
     <string name="output_service_wifi" msgid="9003667810868222134">"वाय-फाय"</string>
     <string name="output_service_bt_wifi" msgid="7186882540475524124">"ब्लूटूथ आणि वाय-फाय"</string>
@@ -665,7 +663,7 @@
     <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"हॉटस्पॉट"</string>
     <string name="accessibility_managed_profile" msgid="4703836746209377356">"कार्य प्रोफाईल"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"सर्वांसाठी नाही तर काहींसाठी मजेदार असू शकते"</string>
-    <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम UI ट्युनर आपल्‍याला Android वापरकर्ता इंटरफेस ट्विक आणि कस्टमाइझ करण्‍याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्‍ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्‍यातील रिलीज मध्‍ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरु ठेवा."</string>
+    <string name="tuner_warning" msgid="1861736288458481650">"सिस्टम UI ट्युनर आपल्‍याला Android वापरकर्ता इंटरफेस ट्विक आणि कस्टमाइझ करण्‍याचे अनेक प्रकार देते. ही प्रयोगात्मक वैशिष्‍ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्‍यातील रिलीज मध्‍ये कदाचित दिसणार नाहीत. सावधगिरी बाळगून पुढे सुरू ठेवा."</string>
     <string name="tuner_persistent_warning" msgid="230466285569307806">"ही प्रयोगात्मक वैशिष्‍ट्ये बदलू शकतात, खंडित होऊ शकतात किंवा भविष्‍यातील रिलीज मध्‍ये कदाचित दिसणार नाहीत."</string>
     <string name="got_it" msgid="477119182261892069">"समजले"</string>
     <string name="tuner_toast" msgid="3812684836514766951">"अभिनंदन! सिस्टम UI ट्युनर सेटिंग्जमध्‍ये जोडले गेले आहे"</string>
@@ -678,14 +676,14 @@
     <string name="show_brightness" msgid="6700267491672470007">"द्रुत सेटिंग्जमध्‍ये चमक दर्शवा"</string>
     <string name="experimental" msgid="3549865454812314826">"प्रायोगिक"</string>
     <string name="enable_bluetooth_title" msgid="866883307336662596">"ब्लूटूथ सुरू करायचे?"</string>
-    <string name="enable_bluetooth_message" msgid="6740938333772779717">"तुमचा कीबोर्ड तुमच्या टॅबलेटसह कनेक्ट करण्यासाठी, तुम्ही प्रथम ब्लूटूथ चालू करणे आवश्यक आहे."</string>
-    <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"चालू करा"</string>
+    <string name="enable_bluetooth_message" msgid="6740938333772779717">"तुमचा कीबोर्ड तुमच्या टॅबलेटसह कनेक्ट करण्यासाठी, तुम्ही प्रथम ब्लूटूथ सुरू करणे आवश्यक आहे."</string>
+    <string name="enable_bluetooth_confirmation_ok" msgid="2866408183324184876">"सुरू करा"</string>
     <string name="show_silently" msgid="5629369640872236299">"सूचना शांतपणे दर्शवा"</string>
     <string name="block" msgid="188483833983476566">"सर्व सूचना ब्लॉक करा"</string>
     <string name="do_not_silence" msgid="4982217934250511227">"शांत करू नका"</string>
     <string name="do_not_silence_block" msgid="4361847809775811849">"शांत किंवा अवरोधित करू नका"</string>
     <string name="tuner_full_importance_settings" msgid="1388025816553459059">"पॉवर सूचना नियंत्रणे"</string>
-    <string name="tuner_full_importance_settings_on" msgid="917981436602311547">"चालू"</string>
+    <string name="tuner_full_importance_settings_on" msgid="917981436602311547">"सुरू"</string>
     <string name="tuner_full_importance_settings_off" msgid="5580102038749680829">"बंद"</string>
     <string name="power_notification_controls_description" msgid="1334963837572708952">"पॉवर सूचना नियंत्रणांच्या साहाय्याने तुम्ही अ‍ॅप सूचनांसाठी 0 ते 5 असे महत्त्व स्तर सेट करू शकता. \n\n"<b>"स्तर 5"</b>" \n- सूचना सूचीच्या शीर्षस्थानी दाखवा \n- फुल स्क्रीन व्यत्ययास अनुमती द्या \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 4"</b>\n" - फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 3"</b>" \n- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n\n"<b>"स्तर 2"</b>" \n- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n\n"<b>"स्तर 1"</b>\n"- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n- लॉक स्क्रीन आणि स्टेटस बार मधून लपवा \n- सूचना सूचीच्या तळाशी दर्शवा \n\n"<b>"स्तर 0"</b>" \n- अ‍ॅपमधील सर्व सूचना ब्लॉक करा"</string>
     <string name="notification_header_default_channel" msgid="225454696914642444">"सूचना"</string>
@@ -921,7 +919,7 @@
     <string name="pip_skip_to_prev" msgid="3742589641443049237">"डावलून मागे जा"</string>
     <string name="thermal_shutdown_title" msgid="2702966892682930264">"तापल्‍यामुळे फोन बंद झाला"</string>
     <string name="thermal_shutdown_message" msgid="7432744214105003895">"तुमचा फोन आता व्‍यवस्थित सुरू आहे"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तुमचा फोन खूप तापलाय, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा फोन आता व्‍यवस्थित सुरू आहे.\n\nतुम्ही असे केल्यास तुमचा फोन खूप तापेल:\n	•संसाधन केंद्रित अ‍ॅप वापरणे (गेमिंग, व्हिडिओ किंवा नेव्हिगेशन अ‍ॅप यासारखे)\n	•मोठ्या फायली डाउनलोड किंवा अपलोड करणे\n	•उच्च तापमानामध्ये तुमचा फोन वापरणे"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="6745684238183492031">"तुमचा फोन खूप तापलाय, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा फोन आता व्‍यवस्थित सुरू आहे.\n\nतुम्ही असे केल्यास तुमचा फोन खूप तापेल:\n	•संसाधन केंद्रित अ‍ॅप वापरणे (गेमिंग, व्हिडिओ किंवा नेव्हिगेशन अ‍ॅप यासारखे)\n	•मोठ्या फाइल डाउनलोड किंवा अपलोड करणे\n	•उच्च तापमानामध्ये तुमचा फोन वापरणे"</string>
     <string name="high_temp_title" msgid="2218333576838496100">"फोन ऊष्ण होत आहे"</string>
     <string name="high_temp_notif_message" msgid="163928048626045592">"फोन थंड होत असताना काही वैशिष्‍ट्ये मर्यादित असतात"</string>
     <string name="high_temp_dialog_message" msgid="3793606072661253968">"तुमचा फोन स्वयंचलितपणे थंड होईल. तुम्ही अद्यापही तुमचा फोन वापरू शकता परंतु तो कदाचित धीमेपणे कार्य करेल.\n\nतुमचा फोन एकदा थंड झाला की, तो सामान्यपणे कार्य करेल."</string>
@@ -960,9 +958,9 @@
     <string name="wifi_is_off" msgid="5389597396308001471">"वाय-फाय बंद आहे"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"ब्लूटूथ बंद आहे"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"व्यत्यय आणू नका बंद आहे"</string>
-    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"व्यत्यय आणू नका एका <xliff:g id="ID_1">%s</xliff:g> स्वयंचलित नियमाने चालू केले."</string>
-    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"व्यत्यय आणू नका (<xliff:g id="ID_1">%s</xliff:g>) ॲपने चालू केले."</string>
-    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"व्यत्यय आणू नका एका स्वयंचलित नियमाने किंवा ॲपने चालू केले."</string>
+    <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"व्यत्यय आणू नका एका <xliff:g id="ID_1">%s</xliff:g> स्वयंचलित नियमाने सुरू केले."</string>
+    <string name="qs_dnd_prompt_app" msgid="4027984447935396820">"व्यत्यय आणू नका (<xliff:g id="ID_1">%s</xliff:g>) ॲपने सुरू केले."</string>
+    <string name="qs_dnd_prompt_auto_rule_app" msgid="1841469944118486580">"व्यत्यय आणू नका एका स्वयंचलित नियमाने किंवा ॲपने सुरू केले."</string>
     <string name="qs_dnd_until" msgid="7844269319043747955">"<xliff:g id="ID_1">%s</xliff:g> पर्यंत"</string>
     <string name="qs_dnd_keep" msgid="3829697305432866434">"ठेवा"</string>
     <string name="qs_dnd_replace" msgid="7712119051407052689">"पुनर्स्थित करा"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक नाही"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"हे अ‍ॅप रीस्टार्ट करण्यासाठी आणि फुल स्क्रीन करण्यासाठी टॅप करा."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> बबलसाठी सेटिंग्ज"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ओव्हरफ्लो"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"स्टॅकमध्ये परत जोडा"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"व्यवस्थापित करा"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> कडून <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> आणि आणखी <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> कडून <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1039,10 +1035,8 @@
     <string name="controls_favorite_load_error" msgid="2533215155804455348">"सर्व नियंत्रणांची सूची लोड करता आली नाही."</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"इतर"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"डिव्हाइस नियंत्रणांमध्ये जोडा"</string>
-    <!-- no translation found for controls_dialog_ok (2770230012857881822) -->
-    <skip />
-    <!-- no translation found for controls_dialog_message (342066938390663844) -->
-    <skip />
+    <string name="controls_dialog_ok" msgid="2770230012857881822">"जोडा"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ने सुचवले आहे"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"नियंत्रणे अपडेट केली आहेत"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"पिनमध्ये अक्षरांचा किंवा चिन्हांचा समावेश असतो"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ची पडताळणी करा"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index e394480..94b5ad3 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ketepikan tangkapan skrin"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pratonton tangkapan skrin"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Perakam Skrin"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses rakaman skrin"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Mula Merakam?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Semasa merakam, Sistem Android dapat menangkap mana-mana maklumat sensitif yang kelihatan pada skrin anda atau yang dimainkan pada peranti anda. Ini termasuklah kata laluan, maklumat pembayaran, foto, mesej dan audio."</string>
@@ -390,7 +389,7 @@
     <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Wi-Fi tidak disambungkan"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Kecerahan"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"AUTO"</string>
-    <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Terbalikkan warna"</string>
+    <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Songsangkan warna"</string>
     <string name="quick_settings_color_space_label" msgid="537528291083575559">"Mod pembetulan warna"</string>
     <string name="quick_settings_more_settings" msgid="2878235926753776694">"Lagi tetapan"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Selesai"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Kosongkan semua"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Urus"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Sejarah"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Masuk"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Pemberitahuan senyap"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Pemberitahuan memaklumi"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Perbualan"</string>
@@ -588,7 +586,7 @@
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Tetapan bunyi"</string>
     <string name="accessibility_volume_expand" msgid="7653070939304433603">"Kembangkan"</string>
     <string name="accessibility_volume_collapse" msgid="2746845391013829996">"Runtuhkan"</string>
-    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Kapsyen media automatik"</string>
+    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Sari kata media automatik"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Petua sari kata"</string>
     <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Tindanan kapsyen"</string>
     <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"dayakan"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Tiada tajuk"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Ketik untuk memulakan semula apl ini dan menggunakan skrin penuh."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Tetapan untuk gelembung <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Limpahan"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Tambah kembali pada tindanan"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Urus"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> daripada <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> daripada <xliff:g id="APP_NAME">%2$s</xliff:g> dan <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> lagi"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 8a0a615..58160fc 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ဖန်သားပြင်ဓာတ်ပုံ ပယ်ရန်"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ဖန်သားပြင်ဓာတ်ပုံ အစမ်းကြည့်ရှုခြင်း"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ဖန်သားပြင် ရိုက်ကူးမှု"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ဖန်သားပြင်ရိုက်ကူးနေသည်"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"စတင် ရိုက်ကူးမလား။"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"ရိုက်ကူးနေစဉ်အတွင်း Android စနစ်သည် သင့်မျက်နှာပြင်ပေါ်တွင် မြင်နိုင်သော သို့မဟုတ် သင့်စက်ပစ္စည်းတွင် ဖွင့်ထားသော အရေးကြီးသည့် အချက်အလက်မှန်သမျှကို ရိုက်ကူးနိုင်သည်။ ၎င်းတွင် စကားဝှက်များ၊ ငွေပေးချေမှု အချက်အလက်၊ ဓာတ်ပုံများ၊ မက်ဆေ့ဂျ်များနှင့် အသံများ ပါဝင်သည်။"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"အားလုံး ဖယ်ရှားရန်"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"စီမံရန်"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"မှတ်တမ်း"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"အဝင်"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"အကြောင်းကြားချက်များကို အသံတိတ်ခြင်း"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"အကြောင်းကြားချက်များကို သတိပေးခြင်း"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"စကားဝိုင်းများ"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"ခေါင်းစဉ် မရှိပါ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ဤအက်ပ်ကို ပြန်စတင်ပြီး မျက်နှာပြင်အပြည့်လုပ်ရန် တို့ပါ။"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ပူဖောင်းကွက်အတွက် ဆက်တင်များ"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"အပိုများပြရန်"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ပူဖေါင်းတန်းသို့ ပြန်ထည့်ရန်"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"စီမံရန်"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> မှ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> နှင့် နောက်ထပ် <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ခုမှ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 2c57ed2..0c21879 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Avvis skjermdumpen"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Forhåndsvisning av skjermdump"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skjermopptaker"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandler skjermopptaket"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Vedvarende varsel for et skjermopptak"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Vil du starte opptaket?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Under opptak kan Android-systemet registrere all sensitiv informasjon som er synlig på skjermen eller spilles av på enheten. Dette inkluderer passord, betalingsinformasjon, bilder, meldinger og lyd."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Fjern alt"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Administrer"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Logg"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Innkommende"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Lydløse varsler"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Varsler med varsling"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Samtaler"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen tittel"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Trykk for å starte denne appen på nytt og vise den i fullskjerm."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Innstillinger for <xliff:g id="APP_NAME">%1$s</xliff:g>-bobler"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overflyt"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Legg tilbake i stabelen"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Administrer"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> fra <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> fra <xliff:g id="APP_NAME">%2$s</xliff:g> og <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> flere"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 8d0adc0..6a0423c7 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"स्क्रिनसट हटाउनुहोस्"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"स्क्रिनसटको पूर्वावलोकन"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"स्क्रिन रेकर्डर"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रिन रेकर्डिङको प्रक्रिया अघि बढाइँदै"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"रेकर्ड गर्न थाल्ने हो?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"रेकर्ड गर्दा, Android प्रणालीले तपाईंको स्क्रिनमा देखिने वा तपाईंको यन्त्रमा प्ले गरिने सबै संवेदनशील जानकारी रेकर्ड गर्न सक्छ। यो जानकारीमा पासवर्ड, भुक्तानीसम्बन्धी जानकारी, फोटो, सन्देश र अडियो समावेश हुन्छ।"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"सबै हटाउनुहोस्"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"व्यवस्थित गर्नुहोस्"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"इतिहास"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"हालसालै प्राप्त भएका सूचनाहरू"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"मौन सूचनाहरू"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"कम्पन वा आवाजसहितका सूचनाहरू"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"वार्तालापहरू"</string>
@@ -971,7 +969,7 @@
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"मोबाइल डेटा निष्क्रिय पार्ने हो?"</string>
     <string name="mobile_data_disable_message" msgid="8604966027899770415">"तपाईं <xliff:g id="CARRIER">%s</xliff:g> मार्फत डेटा वा इन्टरनेट प्रयोग गर्न सक्नुहुने छैन। Wi-Fi मार्फत मात्र इन्टरनेट उपलब्ध हुने छ।"</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"तपाईंको सेवा प्रदायक"</string>
-    <string name="touch_filtered_warning" msgid="8119511393338714836">"कुनै अनुप्रयोगको कारणले अनुमतिसम्बन्धी अनुरोध बुझ्न गाह्रो भइरहेकोले सेटिङहरूले तपाईंको प्रतिक्रिया प्रमाणित गर्न सक्दैनन्।"</string>
+    <string name="touch_filtered_warning" msgid="8119511393338714836">"कुनै एपको कारणले अनुमतिसम्बन्धी अनुरोध बुझ्न गाह्रो भइरहेकोले सेटिङहरूले तपाईंको प्रतिक्रिया प्रमाणित गर्न सक्दैनन्।"</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_0">%1$s</xliff:g> लाई <xliff:g id="APP_2">%2$s</xliff:g> का स्लाइसहरू देखाउन अनुमति दिने हो?"</string>
     <string name="slice_permission_text_1" msgid="6675965177075443714">"- यसले <xliff:g id="APP">%1$s</xliff:g> बाट जानकारी पढ्न सक्छ"</string>
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- यसले <xliff:g id="APP">%1$s</xliff:g> भित्र कारबाही गर्न सक्छ"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक छैन"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"यो एप पुनः सुरु गर्न ट्याप गर्नुहोस् र फुल स्क्रिन मोडमा जानुहोस्।"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> का बबलसम्बन्धी सेटिङहरू"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ओभरफ्लो देखाउनुहोस्"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"स्ट्याकमा फेरि थप्नुहोस्"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"व्यवस्थापन गर्नुहोस्"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> को <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> का <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> र थप <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
@@ -1039,10 +1035,8 @@
     <string name="controls_favorite_load_error" msgid="2533215155804455348">"सबै नियन्त्रणहरूको सूची लोड गर्न सकिएन।"</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"अन्य"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"यन्त्र नियन्त्रण गर्ने विजेटहरूको सूचीमा थप्नुहोस्"</string>
-    <!-- no translation found for controls_dialog_ok (2770230012857881822) -->
-    <skip />
-    <!-- no translation found for controls_dialog_message (342066938390663844) -->
-    <skip />
+    <string name="controls_dialog_ok" msgid="2770230012857881822">"थप्नुहोस्"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ले सिफारिस गरेको"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"नियन्त्रण सुविधाहरू अद्यावधिक गरिए"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN मा अक्षर वा चिन्हहरू समाविष्ट हुन्छन्"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> पुष्टि गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 13798af..ef753b8 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ସ୍କ୍ରିନସଟ୍ ଖାରଜ କରନ୍ତୁ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ସ୍କ୍ରିନସଟର ପ୍ରିଭ୍ୟୁ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ସ୍କ୍ରିନ୍ ରେକର୍ଡର୍"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ସ୍କ୍ରିନ ରେକର୍ଡିଂର ପ୍ରକ୍ରିୟାକରଣ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ଏକ ସ୍କ୍ରି‍ନ୍‍ ରେକର୍ଡ୍‍ ସେସନ୍‍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"ରେକର୍ଡିଂ ଆରମ୍ଭ କରିବେ?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"ରେକର୍ଡିଂ ସମୟରେ, Android ସିଷ୍ଟମ୍ ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ଚାଲୁଥିବା ଯେ କୌଣସି ସମ୍ବେଦନଶୀଳ ସୂଚନାକୁ କ୍ୟାପଚର୍ କରିପାରିବ। ଏଥିରେ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ସୂଚନା, ଫଟୋ, ମେସେଜ ଏବଂ ଅଡିଓ ଅନ୍ତର୍ଭୁକ୍ତ।"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ସମସ୍ତ ଖାଲି କରନ୍ତୁ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ଇତିହାସ"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"ଇନକମିଂ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ନୀରବ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"ଆଲର୍ଟ କରିବା ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ"</string>
@@ -977,7 +975,7 @@
     <string name="slice_permission_text_2" msgid="6758906940360746983">"- ଏହା <xliff:g id="APP">%1$s</xliff:g> ଭିତରେ କାମ କରିପାରିବ"</string>
     <string name="slice_permission_checkbox" msgid="4242888137592298523">"ଯେକୌଣସି ଆପ୍‌ରେ ସ୍ଲାଇସ୍‌କୁ ଦେଖାଇବା ପାଇଁ <xliff:g id="APP">%1$s</xliff:g>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="slice_permission_allow" msgid="6340449521277951123">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
-    <string name="slice_permission_deny" msgid="6870256451658176895">"ଅସ୍ଵୀକାର କରନ୍ତୁ"</string>
+    <string name="slice_permission_deny" msgid="6870256451658176895">"ଅଗ୍ରାହ୍ୟ କରନ୍ତୁ"</string>
     <string name="auto_saver_title" msgid="6873691178754086596">"ବ୍ୟାଟେରୀ ସେଭର୍‌ ଅନ୍‌ ହେବାର ସମୟ ସେଟ୍‌ କରିବାକୁ ଟାପ୍‌ କରନ୍ତୁ"</string>
     <string name="auto_saver_text" msgid="3214960308353838764">"ବ୍ୟାଟେରୀ ସରିବାକୁ ଥିବା ସମୟରେ ଚାଲୁ କରନ୍ତୁ"</string>
     <string name="no_auto_saver_action" msgid="7467924389609773835">"ନାହିଁ, ଥାଉ"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"କୌଣସି ଶୀର୍ଷକ ନାହିଁ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ଏହି ଆପ୍‌କୁ ରିଷ୍ଟାର୍ଟ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ ଏବଂ ଫୁଲ୍‌ସ୍କ୍ରିନ୍‌କୁ ଯାଆନ୍ତୁ।"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ବବଲ୍‌ଗୁଡ଼ିକ ପାଇଁ ସେଟିଂସ୍"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ଓଭରଫ୍ଲୋ"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ଷ୍ଟାକରେ ପୁଣି ଯୋଗ କରନ୍ତୁ"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"ପରିଚାଳନା କରନ୍ତୁ"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>ରୁ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> ଏବଂ ଅଧିକ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>ଟିରୁ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1017,7 +1013,7 @@
     <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"ବାର୍ତ୍ତାଳାପ ବିଭାଗର ଶୀର୍ଷରେ ଦେଖାନ୍ତୁ"</string>
     <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"ଲକ୍ ସ୍କ୍ରିନରେ ପ୍ରୋଫାଇଲ୍ ଛବି ଦେଖାନ୍ତୁ"</string>
     <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"ଆପଗୁଡ଼ିକ ଉପରେ ଫ୍ଲୋଟିଂ ବବଲ୍ ପରି ଦେଖାଯିବ"</string>
-    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\' ମୋଡରେ ବାଧା ଉପୁଯାଇପାରିବ"</string>
+    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"\'ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\' ମୋଡରେ ବାଧା"</string>
     <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"ବୁଝିଗଲି"</string>
     <string name="magnification_overlay_title" msgid="6584179429612427958">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ଓଭର୍‌ଲେ ୱିଣ୍ଡୋ"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"ମ୍ୟାଗ୍ନିଫିକେସନ୍ ୱିଣ୍ଡୋ"</string>
@@ -1039,10 +1035,8 @@
     <string name="controls_favorite_load_error" msgid="2533215155804455348">"ସବୁ ନିୟନ୍ତ୍ରଣର ତାଲିକା ଲୋଡ୍ କରିପାରିଲା ନାହିଁ।"</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ଅନ୍ୟ"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକରେ ଯୋଗ କରନ୍ତୁ"</string>
-    <!-- no translation found for controls_dialog_ok (2770230012857881822) -->
-    <skip />
-    <!-- no translation found for controls_dialog_message (342066938390663844) -->
-    <skip />
+    <string name="controls_dialog_ok" msgid="2770230012857881822">"ଯୋଗ କରନ୍ତୁ"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> ଦ୍ଵାରା ପ୍ରସ୍ତାବିତ"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଅପଡେଟ୍ କରାଯାଇଛି"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PINରେ ଅକ୍ଷର କିମ୍ୱା ସଙ୍କେତଗୁଡ଼ିକ ଥାଏ"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> ଯାଞ୍ଚ କରନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 0981f3c..b9db02a 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਖਾਰਜ ਕਰੋ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਪੂਰਵ-ਝਲਕ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਰ"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਜਾਰੀ ਹੈ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"ਕੀ ਰਿਕਾਰਡਿੰਗ ਸ਼ੁਰੂ ਕਰਨੀ ਹੈ?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"ਰਿਕਾਰਡਿੰਗ ਕਰਨ ਵੇਲੇ, Android ਸਿਸਟਮ ਕੋਈ ਵੀ ਅਜਿਹੀ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਕੈਪਚਰ ਕਰ ਸਕਦਾ ਹੈ ਜੋ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਖਣਯੋਗ ਹੈ ਜਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਜਾਂਦੀ ਹੈ। ਇਸ ਵਿੱਚ ਪਾਸਵਰਡ, ਭੁਗਤਾਨ ਵੇਰਵੇ, ਫ਼ੋਟੋਆਂ, ਸੁਨੇਹੇ ਅਤੇ ਆਡੀਓ ਸ਼ਾਮਲ ਹਨ।"</string>
@@ -358,7 +357,7 @@
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="3003338571871392293">"ਸੁਣਨ ਦੇ ਸਾਧਨ"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ਚਾਲੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
     <string name="quick_settings_brightness_label" msgid="680259653088849563">"ਚਮਕ"</string>
-    <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ਸਵੈ-ਘੁੰਮਾਓ"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ਸਵੈ-ਘੁਮਾਓ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ਸਕ੍ਰੀਨ ਨੂੰ ਆਪਣੇ ਆਪ ਘੁੰਮਾਓ"</string>
     <string name="accessibility_quick_settings_rotation_value" msgid="2916484894750819251">"<xliff:g id="ID_1">%s</xliff:g> ਮੋਡ"</string>
     <string name="quick_settings_rotation_locked_label" msgid="4420863550666310319">"ਰੋਟੇਸ਼ਨ  ਲਾਕ  ਕੀਤੀ"</string>
@@ -369,7 +368,7 @@
     <string name="quick_settings_location_off_label" msgid="7923929131443915919">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਬੰਦ"</string>
     <string name="quick_settings_media_device_label" msgid="8034019242363789941">"ਮੀਡੀਆ ਡੀਵਾਈਸ"</string>
     <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
-    <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"ਕੇਵਲ ਐਮਰਜੈਂਸੀ ਕਾਲਾਂ"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"ਸਿਰਫ਼ ਸੰਕਟਕਾਲੀਨ ਕਾਲਾਂ"</string>
     <string name="quick_settings_settings_label" msgid="2214639529565474534">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="quick_settings_time_label" msgid="3352680970557509303">"ਸਮਾਂ"</string>
     <string name="quick_settings_user_label" msgid="1253515509432672496">"ਮੈਂ"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ਇਤਿਹਾਸ"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"ਇਨਕਮਿੰਗ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ਸ਼ਾਂਤ ਸੂਚਨਾਵਾਂ"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"ਸੁਚੇਤ ਕਰਨ ਵਾਲੀਆਂ ਸੂਚਨਾਵਾਂ"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"ਗੱਲਾਂਬਾਤਾਂ"</string>
@@ -854,7 +852,7 @@
     <string name="right_keycode" msgid="2480715509844798438">"ਸੱਜਾ ਕੀ-ਕੋਡ"</string>
     <string name="left_icon" msgid="5036278531966897006">"ਖੱਬਾ ਪ੍ਰਤੀਕ"</string>
     <string name="right_icon" msgid="1103955040645237425">"ਸੱਜਾ ਪ੍ਰਤੀਕ"</string>
-    <string name="drag_to_add_tiles" msgid="8933270127508303672">"ਟਾਇਲਾਂ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਫੜ੍ਹ ਕੇ ਰੱਖੋ ਅਤੇ ਘਸੀਟੋ"</string>
+    <string name="drag_to_add_tiles" msgid="8933270127508303672">"ਟਾਇਲਾਂ ਸ਼ਾਮਲ ਕਰਨ ਲਈ ਫੜ੍ਹ ਕੇ ਘਸੀਟੋ"</string>
     <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"ਟਾਇਲਾਂ ਨੂੰ ਮੁੜ-ਵਿਵਸਥਿਤ ਕਰਨ ਲਈ ਫੜ੍ਹ ਕੇ ਘਸੀਟੋ"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ਹਟਾਉਣ ਲਈ ਇੱਥੇ ਘਸੀਟੋ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"ਤੁਹਾਨੂੰ ਘੱਟੋ-ਘੱਟ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ਟਾਇਲਾਂ ਦੀ ਲੋੜ ਪਵੇਗੀ"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"ਕੋਈ ਸਿਰਲੇਖ ਨਹੀਂ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ਇਸ ਐਪ ਨੂੰ ਮੁੜ-ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਪੂਰੀ-ਸਕ੍ਰੀਨ ਮੋਡ \'ਤੇ ਜਾਓ।"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਬਬਲ ਲਈ ਸੈਟਿੰਗਾਂ"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ਓਵਰਫ਼ਲੋ"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"ਸਟੈਕ ਵਿੱਚ ਵਾਪਸ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> ਤੋਂ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> ਅਤੇ <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ਹੋਰਾਂ ਤੋਂ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index e510b0e..19d9a6e 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Zamknij zrzut ekranu"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Podgląd zrzutu ekranu"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Nagrywanie ekranu"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Rozpocząć nagrywanie?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Podczas nagrywania system Android może rejestrować wszelkie informacje poufne wyświetlane na ekranie lub odtwarzane na urządzeniu. Dotyczy to m.in. haseł, szczegółów płatności, zdjęć, wiadomości i odtwarzanych dźwięków."</string>
@@ -419,7 +418,7 @@
     <string name="quick_settings_cellular_detail_data_used" msgid="6798849610647988987">"Wykorzyst.: <xliff:g id="DATA_USED">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_limit" msgid="1791389609409211628">"Limit <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
     <string name="quick_settings_cellular_detail_data_warning" msgid="7957253810481086455">"Ostrzeżenie: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
-    <string name="quick_settings_work_mode_label" msgid="2754212289804324685">"Profil do pracy"</string>
+    <string name="quick_settings_work_mode_label" msgid="2754212289804324685">"Profil służbowy"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Podświetlenie nocne"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Włącz o zachodzie"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Do wschodu słońca"</string>
@@ -517,8 +516,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Usuń wszystkie"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Zarządzaj"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Przychodzące"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Ciche powiadomienia"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Alerty"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Rozmowy"</string>
@@ -659,7 +657,7 @@
     <string name="show_demo_mode" msgid="3677956462273059726">"Pokaż tryb demonstracyjny"</string>
     <string name="status_bar_ethernet" msgid="5690979758988647484">"Ethernet"</string>
     <string name="status_bar_alarm" msgid="87160847643623352">"Alarm"</string>
-    <string name="status_bar_work" msgid="5238641949837091056">"Profil do pracy"</string>
+    <string name="status_bar_work" msgid="5238641949837091056">"Profil służbowy"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Tryb samolotowy"</string>
     <string name="add_tile" msgid="6239678623873086686">"Dodaj nazwę"</string>
     <string name="broadcast_tile" msgid="5224010633596487481">"Rozgłaszana nazwa"</string>
@@ -669,7 +667,7 @@
     <string name="alarm_template_far" msgid="3561752195856839456">"w: <xliff:g id="WHEN">%1$s</xliff:g>"</string>
     <string name="accessibility_quick_settings_detail" msgid="544463655956179791">"Szybkie ustawienia, <xliff:g id="TITLE">%s</xliff:g>."</string>
     <string name="accessibility_status_bar_hotspot" msgid="2888479317489131669">"Hotspot"</string>
-    <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil do pracy"</string>
+    <string name="accessibility_managed_profile" msgid="4703836746209377356">"Profil służbowy"</string>
     <string name="tuner_warning_title" msgid="7721976098452135267">"Dobra zabawa, ale nie dla każdego"</string>
     <string name="tuner_warning" msgid="1861736288458481650">"Kalibrator System UI udostępnia dodatkowe sposoby dostrajania i dostosowywania interfejsu Androida. Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string>
     <string name="tuner_persistent_warning" msgid="230466285569307806">"Te eksperymentalne funkcje mogą się zmienić, popsuć lub zniknąć w przyszłych wersjach. Zachowaj ostrożność."</string>
@@ -1001,10 +999,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez tytułu"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Kliknij, by uruchomić tę aplikację ponownie i przejść w tryb pełnoekranowy."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Ustawienia dymków aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Przepełnienie"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Dodaj ponownie do stosu"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Zarządzaj"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikacji <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikacji <xliff:g id="APP_NAME">%2$s</xliff:g> i jeszcze <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 8388b48..ce8b05f 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Închideți captura de ecran"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Previzualizare a capturii de ecran"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Recorder pentru ecran"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Se procesează înregistrarea"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Notificare în curs pentru o sesiune de înregistrare a ecranului"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Începeți înregistrarea?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"În timpul înregistrării, sistemul Android poate captura informațiile sensibile vizibile pe ecran sau redate pe dispozitiv. Aici sunt incluse parole, informații de plată, fotografii, mesaje și conținut audio."</string>
@@ -514,8 +513,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Ștergeți toate notificările"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Gestionați"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Istoric"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Primite"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Notificări silențioase"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Notificări de alertare"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Conversații"</string>
@@ -996,10 +994,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Fără titlu"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Atingeți ca să reporniți aplicația și să treceți în modul ecran complet."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Setări pentru baloanele <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Suplimentar"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Adăugați înapoi în stivă"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Gestionați"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de la <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de la <xliff:g id="APP_NAME">%2$s</xliff:g> și încă <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 2832d89..38d8874 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -88,9 +88,8 @@
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Не удалось сделать скриншот: нет разрешения от приложения или организации."</string>
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Закрыть скриншот"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Предварительный просмотр скриншота"</string>
-    <string name="screenrecord_name" msgid="2596401223859996572">"Создание скриншотов"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_name" msgid="2596401223859996572">"Запись видео с экрана"</string>
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обработка записи с экрана…"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Текущее уведомление для записи видео с экрана"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Начать запись?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Во время записи система Android может получить доступ к конфиденциальной информации, которая видна на экране или воспроизводится на устройстве, в том числе к паролям, сведениям о платежах, фотографиям, сообщениям и аудиозаписям."</string>
@@ -101,7 +100,7 @@
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Звук с устройства и микрофон"</string>
     <string name="screenrecord_start" msgid="330991441575775004">"Начать"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Идет запись видео с экрана."</string>
-    <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Идет запись видео с экрана и звука."</string>
+    <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Идет запись видео с экрана и звука"</string>
     <string name="screenrecord_taps_label" msgid="1595690528298857649">"Показывать прикосновения к экрану"</string>
     <string name="screenrecord_stop_text" msgid="6549288689506057686">"Нажмите, чтобы остановить"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"Остановить"</string>
@@ -517,8 +516,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Очистить все"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Настроить"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"История"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Входящие"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Беззвучные уведомления"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Оповещения"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Разговоры"</string>
@@ -1001,10 +999,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без названия"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Нажмите, чтобы перезапустить приложение и перейти в полноэкранный режим."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Настройки всплывающих чатов от приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Дополнительное меню"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Добавить обратно в стек"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Настроить"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из приложения \"<xliff:g id="APP_NAME">%2$s</xliff:g>\""</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> от приложения \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" и ещё <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index fb87a0b..abe2dc2 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"තිර රුව ඉවත ලන්න"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"තිර රූ පෙර දසුන"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"තිර රෙකෝඩරය"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"තිර පටිගත කිරීම සකසමින්"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"තිර පටිගත කිරීමේ සැසියක් සඳහා කෙරෙන දැනුම් දීම"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"පටිගත කිරීම ආරම්භ කරන්නද?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"පටිගත කරන අතරතුර, Android පද්ධතියට ඔබේ තිරයේ පෙනෙන හෝ ඔබේ උපාංගයේ වාදනය කරන ඕනෑම සංවේදී තොරතුරක් ග්‍රහණය කර ගැනීමට හැකිය. මෙයට මුරපද, ගෙවීම් තොරතුරු, ඡායාරූප, පණිවිඩ සහ ඕඩියෝ ඇතුළත් වේ."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"සියල්ල හිස් කරන්න"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"කළමනාකරණය කරන්න"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ඉතිහාසය"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"එන"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"නිහඬ දැනුම්දීම්"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"ඇඟවීමේ දැනුම් දීම්"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"සංවාද"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"මාතෘකාවක් නැත"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"මෙම යෙදුම යළි ඇරඹීමට සහ පූර්ණ තිරයට යාමට තට්ටු කරන්න"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> බුබුළු සඳහා සැකසීම්"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"පිටාර යාම"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"අට්ටිය වෙත ආපසු එක් කරන්න"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"කළමනා කරන්න"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> වෙතින් <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> වෙතින් <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> සහ තවත් <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ක්"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index c835809..f9535fa 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Zavrieť snímku obrazovky"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ukážka snímky obrazovky"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Rekordér obrazovky"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Spracúva sa záznam obrazovky"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Zobrazuje sa upozornenie týkajúce sa relácie záznamu obrazovky"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Chcete spustiť nahrávanie?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Počas nahrávania zaznamená systém Android všetky citlivé údaje, ktoré sa zobrazia na obrazovke alebo prehrajú v zariadení. Zahrnuje to heslá, platobné údaje, fotky, správy a zvuky."</string>
@@ -517,8 +516,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Vymazať všetko"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Spravovať"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"História"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Prichádzajúce"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Tiché upozornenia"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Varovné upozornenia"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konverzácie"</string>
@@ -1001,10 +999,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Bez názvu"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Klepnutím reštartujete túto aplikáciu a prejdete do režimu celej obrazovky."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Nastavenia bublín aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Rozšírená ponuka"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Pridať späť do zásobníka"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Spravovať"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikácie <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> z aplikácie <xliff:g id="APP_NAME">%2$s</xliff:g> a ďalšie (<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>)"</string>
@@ -1032,9 +1028,9 @@
     <string name="magnification_overlay_title" msgid="6584179429612427958">"Okno prekrytia priblíženia"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Okno priblíženia"</string>
     <string name="magnification_controls_title" msgid="8421106606708891519">"Ovládacie prvky okna priblíženia"</string>
-    <string name="quick_controls_title" msgid="6839108006171302273">"Ovládanie zariadenia"</string>
+    <string name="quick_controls_title" msgid="6839108006171302273">"Ovládanie zariadení"</string>
     <string name="quick_controls_subtitle" msgid="1667408093326318053">"Pridajte ovládacie prvky pre svoje pripojené zariadenia"</string>
-    <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavenie ovládania zariadenia"</string>
+    <string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavenie ovládania zariadení"</string>
     <string name="quick_controls_setup_subtitle" msgid="1681506617879773824">"Pridržaním vypínača získate prístup k ovládacím prvkom"</string>
     <string name="controls_providers_title" msgid="6879775889857085056">"Výberom aplikácie pridajte ovládacie prvky"</string>
     <plurals name="controls_number_of_favorites" formatted="false" msgid="1057347832073807380">
@@ -1050,7 +1046,7 @@
     <string name="controls_favorite_toast_no_changes" msgid="7094494210840877931">"Zmeny neboli uložené"</string>
     <string name="controls_favorite_load_error" msgid="2533215155804455348">"Zoznam všetkých ovl. prvkov sa nepodarilo načítať."</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Iné"</string>
-    <string name="controls_dialog_title" msgid="2343565267424406202">"Pridanie do ovládania zariadenia"</string>
+    <string name="controls_dialog_title" msgid="2343565267424406202">"Pridanie do ovládania zariadení"</string>
     <string name="controls_dialog_ok" msgid="2770230012857881822">"Pridať"</string>
     <string name="controls_dialog_message" msgid="342066938390663844">"Navrhuje <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"Ovládanie bolo aktualizované"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 038b3b6..cbfee80 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -391,7 +391,7 @@
     <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Povezava Wi-Fi ni vzpostavljena"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"Svetlost"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"SAMODEJNO"</string>
-    <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Obrni barve"</string>
+    <string name="quick_settings_inversion_label" msgid="5078769633069667698">"Inverzija barv"</string>
     <string name="quick_settings_color_space_label" msgid="537528291083575559">"Način popravljanja barv"</string>
     <string name="quick_settings_more_settings" msgid="2878235926753776694">"Več nastavitev"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"Končano"</string>
@@ -977,7 +977,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Aplikacije, ki se izvajajo v ozadju"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Dotaknite se za prikaz podrobnosti porabe baterije in prenosa podatkov"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Želite izklopiti prenos podatkov v mobilnih omrežjih?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Prek operaterja <xliff:g id="CARRIER">%s</xliff:g> ne boste imeli dostopa do podatkovne povezave ali interneta. Internet bo na voljo samo prek povezave Wi-Fi."</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Prek operaterja »<xliff:g id="CARRIER">%s</xliff:g>« ne boste imeli dostopa do podatkovne povezave ali interneta. Internet bo na voljo samo prek povezave Wi-Fi."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"svojega operaterja"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Ker aplikacija zakriva zahtevo za dovoljenje, z nastavitvami ni mogoče preveriti vašega odziva."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Želite dovoliti, da aplikacija <xliff:g id="APP_0">%1$s</xliff:g> prikaže izreze aplikacije <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index f7e2bf2..ea66526 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Hiq pamjen e ekranit"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Pamja paraprake e imazhit"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Regjistruesi i ekranit"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Regjistrimi i ekranit po përpunohet"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Të nis regjistrimi?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Gjatë regjistrimit, sistemi Android mund të regjistrojë çdo informacion delikat që është i dukshëm në ekranin tënd ose që luhet në pajisje. Kjo përfshin fjalëkalimet, informacionin e pagesave, fotografitë, mesazhet dhe audion."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Pastroji të gjitha"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Menaxho"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historiku"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Hyrëse"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Njoftimet në heshtje"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Njoftimet sinjalizuese"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Bisedat"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Pa titull"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Trokit për ta rinisur këtë aplikacion dhe për të kaluar në ekranin e plotë."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Cilësimet për flluskat e <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Tejkalo"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Shto përsëri te stiva"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Menaxho"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> nga <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> nga <xliff:g id="APP_NAME">%2$s</xliff:g> dhe <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> të tjera"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index d61b36c..17a01b2 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Одбаците снимак екрана"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Преглед снимка екрана"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Снимач екрана"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Желите да започнете снимање?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Током снимања Android систем може да сними осетљиве информације које су видљиве на екрану или које се пуштају на уређају. То обухвата лозинке, информације о плаћању, слике, поруке и звук."</string>
@@ -514,8 +513,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Обриши све"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Управљајте"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Историја"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Долазно"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Нечујна обавештења"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Обавештења која привлаче пажњу"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Конверзације"</string>
@@ -996,10 +994,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без наслова"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Додирните да бисте рестартовали апликацију и прешли у режим целог екрана."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Подешавања за <xliff:g id="APP_NAME">%1$s</xliff:g> облачиће"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Преклапање"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Додај поново у групу"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Управљајте"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из апликације <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> из апликације <xliff:g id="APP_NAME">%2$s</xliff:g> и још <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
@@ -1019,10 +1015,10 @@
     <string name="notification_content_system_nav_changed" msgid="5077913144844684544">"Навигација система је ажурирана. Да бисте унели измене, идите у Подешавања."</string>
     <string name="notification_content_gesture_nav_available" msgid="4431460803004659888">"Идите у Подешавања да бисте ажурирали навигацију система"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"Стање приправности"</string>
-    <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Приказују се у врху одељка за конверзације"</string>
-    <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Приказују слику профила на закључаном екрану"</string>
+    <string name="priority_onboarding_show_at_top_text" msgid="1678400241025513541">"Приказује се у врху одељка за конверзације"</string>
+    <string name="priority_onboarding_show_avatar_text" msgid="5756291381124091508">"Приказује слику профила на закључаном екрану"</string>
     <string name="priority_onboarding_appear_as_bubble_text" msgid="4227039772250263122">"Приказују се плутајући облачићи преко апликација"</string>
-    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Ометају подешавање Не узнемиравај"</string>
+    <string name="priority_onboarding_ignores_dnd_text" msgid="2918952762719600529">"Омета подешавање Не узнемиравај"</string>
     <string name="priority_onboarding_done_button_title" msgid="4569550984286506007">"Важи"</string>
     <string name="magnification_overlay_title" msgid="6584179429612427958">"Преклопни прозор за увећање"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"Прозор за увећање"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index a2ef8b6..7ff1f84 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Stäng skärmdump"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Förhandsgranskning av skärmdump"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Skärminspelare"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Behandlar skärminspelning"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Avisering om att skärminspelning pågår"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Vill du starta inspelningen?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"När du spelar in kan Android-systemet registrera alla känsliga uppgifter som visas på skärmen eller spelas upp på enheten. Detta omfattar lösenord, betalningsuppgifter, foton, meddelanden och ljud."</string>
@@ -400,7 +399,7 @@
     <string name="quick_settings_tethering_label" msgid="5257299852322475780">"Internetdelning"</string>
     <string name="quick_settings_hotspot_label" msgid="1199196300038363424">"Surfzon"</string>
     <string name="quick_settings_hotspot_secondary_label_transient" msgid="7585604088079160564">"Aktiverar …"</string>
-    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Databesparing är på"</string>
+    <string name="quick_settings_hotspot_secondary_label_data_saver_enabled" msgid="1280433136266439372">"Databesparing på"</string>
     <plurals name="quick_settings_hotspot_secondary_label_num_devices" formatted="false" msgid="3142308865165871976">
       <item quantity="other">%d enheter</item>
       <item quantity="one">%d enhet</item>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Rensa alla"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Hantera"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historik"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Inkommande"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Ljudlösa aviseringar"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Aviseringar med vibration eller ljud"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Konversationer"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Ingen titel"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Tryck för att starta om appen i helskärmsläge."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Inställningar för <xliff:g id="APP_NAME">%1$s</xliff:g>-bubblor"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Fler menyalternativ"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Lägg tillbaka på stack"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Hantera"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> från <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> från <xliff:g id="APP_NAME">%2$s</xliff:g> och <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> fler"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index cc9d9b2..51d1a17 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -89,11 +89,10 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ondoa picha ya skrini"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Onyesho la kukagua picha ya skrini"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Kinasa Skrini"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Inachakata rekodi ya skrini"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Arifa inayoendelea ya kipindi cha kurekodi skrini"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Ungependa kuanza kurekodi?"</string>
-    <string name="screenrecord_description" msgid="1123231719680353736">"Inaporekodi, Mfumo wa Android unaweza kurekodi maelezo yoyote nyeti yanayoonekana kwenye skrini au yanayochezwa kwenye kifaa chako. Hii ni pamoja na manenosiri, maelezo ya malipo, picha, ujumbe na sauti."</string>
+    <string name="screenrecord_description" msgid="1123231719680353736">"Wakati wa kurekodi, Mfumo wa Android unaweza kusana maelezo yoyote nyeti yanayoonekana kwenye skrini au yanayochezwa kwenye kifaa chako. Hii ni pamoja na manenosiri, maelezo ya malipo, picha, ujumbe na sauti."</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Rekodi sauti"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Sauti ya kifaa"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Sauti kutoka kwenye kifaa chako, kama vile muziki, simu na milio ya simu"</string>
@@ -511,10 +510,9 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Futa zote"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Dhibiti"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Historia"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Simu inayoingia"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Arifa zisizo na sauti"</string>
-    <string name="notification_section_header_alerting" msgid="3168140660646863240">"Arifa za ilani"</string>
+    <string name="notification_section_header_alerting" msgid="3168140660646863240">"Arifa za kuarifu"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Mazungumzo"</string>
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"Futa arifa zote zisizo na sauti"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"Kipengele cha Usinisumbue kimesitisha arifa"</string>
@@ -712,7 +710,7 @@
     <string name="notification_alert_title" msgid="7629202599338071971">"Kutoa arifa"</string>
     <string name="notification_bubble_title" msgid="8330481035191903164">"Kiputo"</string>
     <string name="notification_channel_summary_low" msgid="7300447764759926720">"Hukusaidia kuwa makini bila sauti au mtetemo."</string>
-    <string name="notification_channel_summary_default" msgid="3539949463907902037">"Hupata umakinifu wako kwa sauti na mtetemo."</string>
+    <string name="notification_channel_summary_default" msgid="3539949463907902037">"Hupata umakinifu wako kwa sauti au mtetemo."</string>
     <string name="notification_channel_summary_default_with_bubbles" msgid="6298026344552480458">"Hupata umakinifu wako kwa sauti au mtetemo. Mazungumzo kutoka kiputo cha <xliff:g id="APP_NAME">%1$s</xliff:g> kwa chaguomsingi."</string>
     <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"Huweka umakinifu wako kwenye maudhui haya kwa kutumia njia ya mkato ya kuelea."</string>
     <string name="notification_channel_summary_priority" msgid="7415770044553264622">"Huonyeshwa sehemu ya juu ya mazungumzo na huonekana kama kiputo."</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Wimbo hauna jina"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Gusa ili uzime na uwashe upya programu hii kisha nenda kwenye skrini nzima."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Mipangilio ya viputo vya <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Vipengee vya ziada"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Rejesha kwenye rafu"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Dhibiti"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> kutoka kwa <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> kutoka kwa <xliff:g id="APP_NAME">%2$s</xliff:g> na nyingine<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index fc19d6e..1bea16e 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ஸ்கிரீன்ஷாட்டை நிராகரி"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ஸ்கிரீன்ஷாட்டின் மாதிரிக்காட்சி"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"ஸ்கிரீன் ரெக்கார்டர்"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"ஸ்க்ரீன் ரெக்கார்டிங் செயலாக்கப்படுகிறது"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"ரெக்கார்டிங்கைத் தொடங்கவா?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"ரெக்கார்டு செய்யும்போது, உங்கள் திரையில் தோன்றக்கூடிய அல்லது சாதனத்தில் பிளே ஆகக்கூடிய ஏதேனும் அதிமுக்கியத் தகவலை Android சிஸ்டம் படமெடுக்க முடியும். கடவுச்சொற்கள், பேமெண்ட் தகவல், படங்கள், மெசேஜ்கள், ஆடியோ ஆகியவை இதில் அடங்கும்."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"எல்லாவற்றையும் அழி"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"அறிவிப்புகளை நிர்வகி"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"வரலாறு"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"உள்வருவது"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"ஒலியில்லாத அறிவிப்புகள்"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"விழிப்பூட்டல் அறிவிப்புகள்"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"உரையாடல்கள்"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"தலைப்பு இல்லை"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"தட்டுவதன் மூலம் இந்த ஆப்ஸை மீண்டும் தொடங்கலாம், முழுத்திரையில் பார்க்கலாம்."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> குமிழ்களுக்கான அமைப்புகள்"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ஓவர்ஃப்லோ"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"மீண்டும் ஸ்டேக்கில் சேர்க்கவும்"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"நிர்வகி"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> இலிருந்து <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> மற்றும் மேலும் <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ஆப்ஸிலிருந்து வந்துள்ள அறிவிப்பு: <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index a2b3dec..42afdcf 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -63,8 +63,8 @@
     <string name="usb_debugging_allow" msgid="1722643858015321328">"అనుమతించు"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"USB డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
     <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"ఈ పరికరానికి ప్రస్తుతం సైన్ ఇన్ చేసిన వినియోగదారు USB డీబగ్గింగ్ ఆన్ చేయలేరు. ఈ ఫీచర్ ఉపయోగించడానికి, ప్రాథమిక వినియోగదారుకి మారాలి."</string>
-    <string name="wifi_debugging_title" msgid="7300007687492186076">"ఈ నెట్‌వర్క్ పై వైర్‌లెస్ డీబగ్గింగ్‌ను అనుమతిస్తారా?"</string>
-    <string name="wifi_debugging_message" msgid="5461204211731802995">"నెట్‌వర్క్ పేరు (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi చిరునామా (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
+    <string name="wifi_debugging_title" msgid="7300007687492186076">"ఈ నెట్‌వర్క్ ద్వారా వైర్‌లెస్ డీబగ్గింగ్‌ను అనుమతించాలా?"</string>
+    <string name="wifi_debugging_message" msgid="5461204211731802995">"నెట్‌వర్క్ పేరు (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi అడ్రస్ (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
     <string name="wifi_debugging_always" msgid="2968383799517975155">"ఈ నెట్‌వర్క్ నుండి ఎల్లప్పుడూ అనుమతించు"</string>
     <string name="wifi_debugging_allow" msgid="4573224609684957886">"అనుమతించు"</string>
     <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"వైర్‌లెస్ డీబగ్గింగ్‌కి అనుమతి లేదు"</string>
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"స్క్రీన్‌షాట్‌ను మూసివేస్తుంది"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"స్క్రీన్‌షాట్ ప్రివ్యూ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"స్క్రీన్ రికార్డర్"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"స్క్రీన్ రికార్డింగ్ అవుతోంది"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్‌గోయింగ్ నోటిఫికేషన్"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"రికార్డింగ్‌ను ప్రారంభించాలా?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"రికార్డ్ చేస్తున్నప్పుడు, Android సిస్టమ్ మీ స్క్రీన్‌పై ప్రదర్శించబడిన లేదా మీ పరికరం నుండి ప్లే చేయబడిన ఏ సున్నితమైన సమాచారాన్నైనా క్యాప్చర్ చేయగలదు. ఈ సమాచారంలో, పాస్‌వర్డ్‌లు, చెల్లింపు వివరాలు, ఫోటోలు, మెసేజ్‌లు, ఆడియో ఉంటాయి."</string>
@@ -99,7 +98,7 @@
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"మీ పరికరం నుండి వచ్చే సంగీతం, కాల్‌లు, రింగ్‌టోన్‌ల వంటి ధ్వనులు"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"మైక్రోఫోన్"</string>
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"పరికరం ఆడియో, మైక్రోఫోన్"</string>
-    <string name="screenrecord_start" msgid="330991441575775004">"ప్రారంభం"</string>
+    <string name="screenrecord_start" msgid="330991441575775004">"ప్రారంభించు"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"స్క్రీన్ రికార్డింగ్ చేయబడుతోంది"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"స్క్రీన్, ఆడియో రికార్డింగ్ చేయబడుతున్నాయి"</string>
     <string name="screenrecord_taps_label" msgid="1595690528298857649">"స్క్రీన్‌పై తాకే స్థానాలను చూపు"</string>
@@ -369,7 +368,7 @@
     <string name="quick_settings_location_off_label" msgid="7923929131443915919">"స్థానం ఆఫ్‌లో ఉంది"</string>
     <string name="quick_settings_media_device_label" msgid="8034019242363789941">"ప్రసార మాధ్యమ పరికరం"</string>
     <string name="quick_settings_rssi_label" msgid="3397615415140356701">"RSSI"</string>
-    <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"అత్యవసర కాల్‌లు మాత్రమే"</string>
+    <string name="quick_settings_rssi_emergency_only" msgid="7499207215265078598">"ఎమర్జెన్సీ కాల్స్ మాత్రమే"</string>
     <string name="quick_settings_settings_label" msgid="2214639529565474534">"సెట్టింగ్‌లు"</string>
     <string name="quick_settings_time_label" msgid="3352680970557509303">"సమయం"</string>
     <string name="quick_settings_user_label" msgid="1253515509432672496">"నేను"</string>
@@ -390,7 +389,7 @@
     <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"Wi‑Fi కనెక్ట్ కాలేదు"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ప్రకాశం"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"ఆటోమేటిక్"</string>
-    <string name="quick_settings_inversion_label" msgid="5078769633069667698">"రంగుల‌ను అటుఇటు మార్చు"</string>
+    <string name="quick_settings_inversion_label" msgid="5078769633069667698">"కలర్ మార్పిడి"</string>
     <string name="quick_settings_color_space_label" msgid="537528291083575559">"రంగు సవరణ మోడ్"</string>
     <string name="quick_settings_more_settings" msgid="2878235926753776694">"మరిన్ని సెట్టింగ్‌లు"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"పూర్తయింది"</string>
@@ -421,7 +420,7 @@
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"సూర్యోదయం వరకు"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"<xliff:g id="TIME">%s</xliff:g>కి"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"<xliff:g id="TIME">%s</xliff:g> వరకు"</string>
-    <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"ముదురు రంగు థీమ్"</string>
+    <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"ముదురు రంగు రూపం"</string>
     <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"బ్యాటరీ సేవర్"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"సూర్యాస్తమయానికి"</string>
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"సూర్యోదయం వరకు"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"అన్నీ క్లియర్ చేయండి"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"నిర్వహించండి"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"చరిత్ర"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"ఇన్‌కమింగ్"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"నిశ్శబ్ద నోటిఫికేషన్‌లు"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"అలర్ట్ చేసే నోటిఫికేషన్‌లు"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"సంభాషణలు"</string>
@@ -858,7 +856,7 @@
     <string name="drag_to_rearrange_tiles" msgid="2143204300089638620">"టైల్‌ల క్రమం మార్చడానికి వాటిని పట్టుకుని, లాగండి"</string>
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"తీసివేయడానికి ఇక్కడికి లాగండి"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"మీ వద్ద కనీసం <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> టైల్‌లు ఉండాలి"</string>
-    <string name="qs_edit" msgid="5583565172803472437">"సవరించు"</string>
+    <string name="qs_edit" msgid="5583565172803472437">"ఎడిట్ చేయండి"</string>
     <string name="tuner_time" msgid="2450785840990529997">"సమయం"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"గంటలు, నిమిషాలు మరియు సెకన్లను చూపు"</item>
@@ -969,7 +967,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"నేపథ్యంలో అమలు అవుతున్న ఆప్‌లు"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"బ్యాటరీ మరియు డేటా వినియోగ వివరాల కోసం నొక్కండి"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"మొబైల్ డేటాను ఆఫ్ చేయాలా?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"మీకు <xliff:g id="CARRIER">%s</xliff:g> ద్వారా డేటా లేదా ఇంటర్నెట్‌కు యాక్సెస్ ఉండదు. Wi-Fi ద్వారా మాత్రమే ఇంటర్నెట్ అందుబాటులో ఉంటుంది."</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"\"<xliff:g id="CARRIER">%s</xliff:g>\" ద్వారా మీకు డేటా లేదా ఇంటర్నెట్‌కు యాక్సెస్ ఉండదు. Wi-Fi ద్వారా మాత్రమే ఇంటర్నెట్ అందుబాటులో ఉంటుంది."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"మీ క్యారియర్"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"అనుమతి అభ్యర్థనకు ఒక యాప్ అడ్డు తగులుతున్నందున సెట్టింగ్‌లు మీ ప్రతిస్పందనను ధృవీకరించలేకపోయాయి."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"<xliff:g id="APP_2">%2$s</xliff:g> స్లైస్‌లను చూపించడానికి <xliff:g id="APP_0">%1$s</xliff:g>ని అనుమతించండి?"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"శీర్షిక లేదు"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"ఈ యాప్‌ను పునఃప్రారంభించేలా నొక్కి, ఆపై పూర్తి స్క్రీన్‌‍లోకి వెళ్లండి."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> బబుల్స్ సెట్టింగ్‌లు"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"ఓవర్‌ఫ్లో"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"స్ట్యాక్‌కు తిరిగి జోడించండి"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"నిర్వహించండి"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> నుండి <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> నుండి <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> మరియు మరో <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-te/strings_tv.xml b/packages/SystemUI/res/values-te/strings_tv.xml
index ded2f50..df8b06d 100644
--- a/packages/SystemUI/res/values-te/strings_tv.xml
+++ b/packages/SystemUI/res/values-te/strings_tv.xml
@@ -19,7 +19,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="notification_channel_tv_pip" msgid="844249465483874817">"చిత్రంలో చిత్రం"</string>
+    <string name="notification_channel_tv_pip" msgid="844249465483874817">"పిక్చర్-ఇన్-పిక్చర్"</string>
     <string name="pip_notification_unknown_title" msgid="4413256731340767259">"(శీర్షిక లేని ప్రోగ్రామ్)"</string>
     <string name="pip_close" msgid="5775212044472849930">"PIPని మూసివేయి"</string>
     <string name="pip_fullscreen" msgid="3877997489869475181">"పూర్తి స్క్రీన్"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 8d9d151..ee6b422 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -38,7 +38,7 @@
     <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"เปิด"</string>
     <string name="battery_saver_start_action" msgid="4553256017945469937">"เปิดโหมดประหยัดแบตเตอรี่"</string>
     <string name="status_bar_settings_settings_button" msgid="534331565185171556">"การตั้งค่า"</string>
-    <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"WiFi"</string>
+    <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"หมุนหน้าจออัตโนมัติ"</string>
     <string name="status_bar_settings_mute_label" msgid="914392730086057522">"ปิดเสียง"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="2151934479226017725">"อัตโนมัติ"</string>
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"ปิดภาพหน้าจอ"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"ตัวอย่างภาพหน้าจอ"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"โปรแกรมอัดหน้าจอ"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"กำลังประมวลผลการอัดหน้าจอ"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"เริ่มบันทึกเลยไหม"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"ขณะบันทึก ระบบ Android จะบันทึกข้อมูลที่ละเอียดอ่อนที่ปรากฏบนหน้าจอหรือเล่นในอุปกรณ์ได้ ซึ่งรวมถึงรหัสผ่าน ข้อมูลการชำระเงิน รูปภาพ ข้อความ และเสียง"</string>
@@ -375,7 +374,7 @@
     <string name="quick_settings_user_label" msgid="1253515509432672496">"ฉัน"</string>
     <string name="quick_settings_user_title" msgid="8673045967216204537">"ผู้ใช้"</string>
     <string name="quick_settings_user_new_user" msgid="3347905871336069666">"ผู้ใช้ใหม่"</string>
-    <string name="quick_settings_wifi_label" msgid="2879507532983487244">"WiFi"</string>
+    <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_wifi_not_connected" msgid="4071097522427039160">"ไม่ได้เชื่อมต่อ"</string>
     <string name="quick_settings_wifi_no_network" msgid="6003178398713839313">"ไม่มีเครือข่าย"</string>
     <string name="quick_settings_wifi_off_label" msgid="4003379736176547594">"ปิด WiFi"</string>
@@ -390,7 +389,7 @@
     <string name="quick_settings_cast_no_wifi" msgid="6980194769795014875">"ไม่ได้เชื่อมต่อ Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="4980669966716685588">"ความสว่าง"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="2325362583903258677">"อัตโนมัติ"</string>
-    <string name="quick_settings_inversion_label" msgid="5078769633069667698">"สลับสี"</string>
+    <string name="quick_settings_inversion_label" msgid="5078769633069667698">"กลับสี"</string>
     <string name="quick_settings_color_space_label" msgid="537528291083575559">"โหมดการแก้ไขสี"</string>
     <string name="quick_settings_more_settings" msgid="2878235926753776694">"การตั้งค่าเพิ่มเติม"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"เสร็จสิ้น"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"ล้างทั้งหมด"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"จัดการ"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"ประวัติ"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"เข้ามาใหม่"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"การแจ้งเตือนแบบไม่มีเสียง"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"มีการแจ้งเตือน"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"การสนทนา"</string>
@@ -969,7 +967,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"แอปที่กำลังทำงานในเบื้องหลัง"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"แตะเพื่อดูรายละเอียดเกี่ยวกับแบตเตอรี่และปริมาณการใช้อินเทอร์เน็ต"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"ปิดอินเทอร์เน็ตมือถือไหม"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"คุณจะใช้เน็ตมือถือหรืออินเทอร์เน็ตผ่าน <xliff:g id="CARRIER">%s</xliff:g> ไม่ได้ แต่จะใช้ผ่าน Wi-Fi ได้เท่านั้น"</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"คุณจะใช้เน็ตมือถือหรืออินเทอร์เน็ตผ่าน \"<xliff:g id="CARRIER">%s</xliff:g>\" ไม่ได้ แต่จะใช้ผ่าน Wi-Fi ได้เท่านั้น"</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"ผู้ให้บริการของคุณ"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"เนื่องจากแอปหนึ่งได้บดบังคำขอสิทธิ์ ระบบจึงไม่สามารถยืนยันคำตอบของคุณสำหรับการตั้งค่าได้"</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"อนุญาตให้ <xliff:g id="APP_0">%1$s</xliff:g> แสดงส่วนต่างๆ ของ <xliff:g id="APP_2">%2$s</xliff:g>"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"ไม่มีชื่อ"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"แตะเพื่อรีสตาร์ทแอปนี้และแสดงแบบเต็มหน้าจอ"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"การตั้งค่าบับเบิล <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"รายการเพิ่มเติม"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"เพิ่มกลับไปที่สแต็ก"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"จัดการ"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> จาก <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> จาก <xliff:g id="APP_NAME">%2$s</xliff:g> และอีก <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> รายการ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index cfb8d54..db26407 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"I-dismiss ang screenshot"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Preview ng screenshot"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Recorder ng Screen"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Pinoproseso screen recording"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Kasalukuyang notification para sa session ng pag-record ng screen"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Simulang Mag-record?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Habang nagre-record, puwedeng ma-capture ng Android System ang anumang sensitibong impormasyong nakikita sa iyong screen o nagpe-play sa device mo. Kasama dito ang mga password, impormasyon sa pagbabayad, mga larawan, mensahe, at audio."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"I-clear lahat"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Pamahalaan"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"History"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Papasok"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Mga silent na notification"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Mga nag-aalertong notification"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Mga Pag-uusap"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Walang pamagat"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"I-tap para i-restart ang app na ito at mag-full screen."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Mga setting para sa mga bubble ng <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Overflow"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Idagdag ulit sa stack"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Pamahalaan"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> mula sa <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> mula sa <xliff:g id="APP_NAME">%2$s</xliff:g> at <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> pa"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 3b6ad40..1077905 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Ekran görüntüsünü kapat"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ekran görüntüsü önizlemesi"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekran Kaydedicisi"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran kaydı işleniyor"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekran kaydı oturumu için devam eden bildirim"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Kayıt Başlatılsın mı?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Kayıt sırasında Android Sistemi, ekranınızda görünen veya cihazınızda oynatılan hassas bilgileri yakalayabilir. Buna şifreler, ödeme bilgileri, fotoğraflar, mesajlar ve sesler dahildir."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Tümünü temizle"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Yönet"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Geçmiş"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Gelen"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Sessiz bildirimler"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Uyaran bildirimler"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Görüşmeler"</string>
@@ -954,7 +952,7 @@
     <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Uygulama yüklenmeden açıldı. Daha fazla bilgi için dokunun."</string>
     <string name="app_info" msgid="5153758994129963243">"Uygulama bilgisi"</string>
     <string name="go_to_web" msgid="636673528981366511">"Tarayıcıya git"</string>
-    <string name="mobile_data" msgid="4564407557775397216">"Mobil veriler"</string>
+    <string name="mobile_data" msgid="4564407557775397216">"Mobil veri"</string>
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>, <xliff:g id="CARRIER_NAME">%1$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"Kablosuz bağlantı kapalı"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Başlıksız"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Bu uygulamayı yeniden başlatmak ve tam ekrana geçmek için dokunun."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> baloncukları için ayarlar"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Taşma"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Yığına geri ekle"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Yönet"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> uygulamasından <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> uygulamasından <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ve diğer <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 11aba0b..2ad5465 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -88,9 +88,8 @@
     <string name="screenshot_failed_to_capture_text" msgid="7818288545874407451">"Додаток або адміністратор вашої організації не дозволяють робити знімки екрана"</string>
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Закрити знімок екрана"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Перегляд знімка екрана"</string>
-    <string name="screenrecord_name" msgid="2596401223859996572">"Створення знімків екрана"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_name" msgid="2596401223859996572">"Відеозапис екрана"</string>
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обробка записування екрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Сповіщення про сеанс запису екрана"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Почати запис?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Під час запису система Android може фіксувати будь-яку конфіденційну інформацію, яка з\'являється на екрані або відтворюється на пристрої, зокрема паролі, платіжну інформацію, фотографії, повідомлення та звуки."</string>
@@ -517,8 +516,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Очистити все"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Керувати"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Історія"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Нові"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Беззвучні сповіщення"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Сповіщення зі звуком чи вібрацією"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Розмови"</string>
@@ -1001,10 +999,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Без назви"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Натисніть, щоб перезапустити додаток і перейти в повноекранний режим."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Налаштування спливаючих чатів від додатка <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Додаткове меню"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Додати в список"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Налаштувати"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"Cповіщення \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\" від додатка <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"Сповіщення \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\" від додатка <xliff:g id="APP_NAME">%2$s</xliff:g> (і ще <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g>)"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index cacfb3e..b8c0172 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"اسکرین شاٹ برخاست کریں"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"اسکرین شاٹ کا پیش منظر"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"سکرین ریکارڈر"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"سکرین ریکارڈنگ پروسیس ہورہی ہے"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"ریکارڈنگ شروع کریں؟"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"‏ریکارڈ کرنے کے دوران، Android سسٹم آپ کی اسکرین پر نظر آنے والی یا آپ کے آلہ پر چلنے والی کسی بھی حساس معلومات کو کیپچر کر سکتا ہے۔ اس میں پاس ورڈز، ادائیگی کی معلومات، تصاویر، پیغامات اور آڈیو شامل ہیں۔"</string>
@@ -101,7 +100,7 @@
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"آلہ کا آڈیو اور مائیکروفون"</string>
     <string name="screenrecord_start" msgid="330991441575775004">"شروع کریں"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"ریکارڈنگ اسکرین"</string>
-    <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"ریکارڈنگ اسکرین اور آڈیو"</string>
+    <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"اسکرین اور آڈیو کی ریکارڈنگ ہو رہی ہے"</string>
     <string name="screenrecord_taps_label" msgid="1595690528298857649">"اسکرین پر کئے گئے ٹچز دکھائیں"</string>
     <string name="screenrecord_stop_text" msgid="6549288689506057686">"روکنے کے لیے تھپتھپائیں"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"روکیں"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"سبھی کو صاف کریں"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"نظم کریں"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"سرگزشت"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"اِن کمنگ"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"اطلاعات خاموش کریں"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"متنبہ کرنے کی اطلاعات"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"گفتگوئیں"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"کوئی عنوان نہیں ہے"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"یہ ایپ دوبارہ شروع کرنے کے لیے تھپتھپائیں اور پوری اسکرین پر جائیں۔"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> بلبلوں کے لیے ترتیبات"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"اوورفلو"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"انبار میں واپس شامل کریں"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"نظم کریں"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g> کی جانب سے <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> اور <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> مزید سے <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
@@ -1039,10 +1035,8 @@
     <string name="controls_favorite_load_error" msgid="2533215155804455348">"تمام کنٹرولز کی فہرست لوڈ نہیں کی جا سکی۔"</string>
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"دیگر"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"آلہ کے کنٹرولز میں شامل کریں"</string>
-    <!-- no translation found for controls_dialog_ok (2770230012857881822) -->
-    <skip />
-    <!-- no translation found for controls_dialog_message (342066938390663844) -->
-    <skip />
+    <string name="controls_dialog_ok" msgid="2770230012857881822">"شامل کریں"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> کی طرف سے تجویز کردہ"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"کنٹرولز اپ ڈیٹ کیے گئے"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"‏PIN میں حروف یا علامات شامل ہیں"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> کی تصدیق کریں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 9ec17d7..1d91bb7 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Skrinshotni yopish"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Skrinshotga razm solish"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Ekrandan yozib olish"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Ekran yozib olinmoqda"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Yozib olish boshlansinmi?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Yozib olishda Android tizimi ekraningizda koʻringan yoki qurilmangizda ijro etilgan maxfiy axborotni ham yozib olishi mumkin. Bunga parollar, toʻlovga oid axborot, suratlar, xabarlar va audio kiradi."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Hammasini tozalash"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Boshqarish"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Tarix"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Kiruvchi"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Sokin bildirishnomalar"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Bildirishnomalarning yuborilishi"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Suhbatlar"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Nomsiz"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Bu ilovani qaytadan ishga tushirish va butun ekranga ochish uchun bosing."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g> bulutchalari uchun sozlamalar"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Kengaytirilgan"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Yana toʻplamga kiritish"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Boshqarish"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g> ilovasidan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> va yana <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ta bildirishnoma"</string>
@@ -1040,7 +1036,7 @@
     <string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"Boshqa"</string>
     <string name="controls_dialog_title" msgid="2343565267424406202">"Qurilma boshqaruv elementlariga kiritish"</string>
     <string name="controls_dialog_ok" msgid="2770230012857881822">"Kiritish"</string>
-    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> tomonidan taklif etilgan"</string>
+    <string name="controls_dialog_message" msgid="342066938390663844">"<xliff:g id="APP">%s</xliff:g> taklif etgan"</string>
     <string name="controls_dialog_confirmation" msgid="586517302736263447">"Boshqaruv elementlari yangilandi"</string>
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN kod harflar va belgilardan iborat boʻladi"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"Tekshirish: <xliff:g id="DEVICE">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 73101b2..44f1497 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Đóng ảnh chụp màn hình"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Xem trước ảnh chụp màn hình"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Trình ghi màn hình"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Đang xử lý video ghi màn hình"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Thông báo đang diễn ra về phiên ghi màn hình"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Bắt đầu ghi?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Trong khi ghi, Hệ thống Android có thể ghi lại mọi thông tin nhạy cảm hiển thị trên màn hình hoặc phát trên thiết bị của bạn. Những thông tin này bao gồm mật khẩu, thông tin thanh toán, ảnh, thông báo và âm thanh."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Xóa tất cả"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Quản lý"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Lịch sử"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Hiển thị gần đây"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Thông báo im lặng"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Thông báo cảnh báo"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Cuộc trò chuyện"</string>
@@ -969,7 +967,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"Ứng dụng đang chạy trong nền"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"Nhấn để biết chi tiết về mức sử dụng dữ liệu và pin"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"Tắt dữ liệu di động?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Bạn sẽ không có quyền sử dụng dữ liệu hoặc truy cập Internet thông qua <xliff:g id="CARRIER">%s</xliff:g>. Bạn chỉ có thể truy cập Internet thông qua Wi-Fi."</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"Bạn sẽ không có quyền sử dụng dữ liệu hoặc truy cập Internet thông qua chế độ <xliff:g id="CARRIER">%s</xliff:g>. Bạn chỉ có thể truy cập Internet thông qua Wi-Fi."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"nhà mạng của bạn"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"Vì ứng dụng đang che khuất yêu cầu cấp quyền nên Cài đặt không thể xác minh câu trả lời của bạn."</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"Cho phép <xliff:g id="APP_0">%1$s</xliff:g> hiển thị các lát của <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Không có tiêu đề"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Nhấn để khởi động lại ứng dụng này và xem ở chế độ toàn màn hình."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Tùy chọn cài đặt cho bong bóng trò chuyện <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Trình đơn mục bổ sung"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Thêm lại vào ngăn xếp"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Quản lý"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> của <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> từ <xliff:g id="APP_NAME">%2$s</xliff:g> và <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> bong bóng khác"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 8ea00ae..0ed76b7 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -63,7 +63,7 @@
     <string name="usb_debugging_allow" msgid="1722643858015321328">"允许"</string>
     <string name="usb_debugging_secondary_user_title" msgid="7843050591380107998">"不允许使用 USB 调试功能"</string>
     <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"目前已登录此设备的用户无法开启 USB 调试功能。要使用此功能,请切换为主要用户的帐号。"</string>
-    <string name="wifi_debugging_title" msgid="7300007687492186076">"要在此网络上允许无线调试吗?"</string>
+    <string name="wifi_debugging_title" msgid="7300007687492186076">"要允许在此网络上进行无线调试吗?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"网络名称 (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWLAN 地址 (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
     <string name="wifi_debugging_always" msgid="2968383799517975155">"在此网络上始终允许"</string>
     <string name="wifi_debugging_allow" msgid="4573224609684957886">"允许"</string>
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"关闭屏幕截图"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"屏幕截图预览"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"屏幕录制器"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在处理屏幕录制视频"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持续显示屏幕录制会话通知"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"要开始录制吗?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"在录制内容时,Android 系统可以捕捉到您屏幕上显示或设备中播放的敏感信息,其中包括密码、付款信息、照片、消息和音频。"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"历史记录"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"收到的通知"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"无声通知"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"提醒通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"对话"</string>
@@ -717,7 +715,7 @@
     <string name="notification_channel_summary_bubble" msgid="7235935211580860537">"通过可链接到这项内容的浮动快捷方式吸引您的注意。"</string>
     <string name="notification_channel_summary_priority" msgid="7415770044553264622">"以对话泡形式显示在对话部分顶部。"</string>
     <string name="notification_conversation_channel_settings" msgid="2409977688430606835">"设置"</string>
-    <string name="notification_priority_title" msgid="2079708866333537093">"优先级"</string>
+    <string name="notification_priority_title" msgid="2079708866333537093">"优先"</string>
     <string name="no_shortcut" msgid="7176375126961212514">"<xliff:g id="APP_NAME">%1$s</xliff:g>不支持对话专用设置"</string>
     <string name="bubble_overflow_empty_title" msgid="3120029421991510842">"最近没有对话泡"</string>
     <string name="bubble_overflow_empty_subtitle" msgid="2030874469510497397">"此处会显示最近的对话泡和已关闭的对话泡"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"无标题"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"点按即可重启此应用并进入全屏模式。"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"<xliff:g id="APP_NAME">%1$s</xliff:g>对话泡的设置"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"菜单"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"重新加入叠放"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"管理"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>:<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"<xliff:g id="APP_NAME">%2$s</xliff:g>和另外 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> 个应用:<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 751767a..9a7d951 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -65,7 +65,7 @@
     <string name="usb_debugging_secondary_user_message" msgid="3740347841470403244">"目前登入此裝置的使用者無法啟用 USB 偵錯功能。如要使用此功能,請切換至主要使用者。"</string>
     <string name="wifi_debugging_title" msgid="7300007687492186076">"要在此網絡上允許無線偵錯功能嗎?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"網絡名稱 (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nWi‑Fi 地址 (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
-    <string name="wifi_debugging_always" msgid="2968383799517975155">"在此網絡上永遠允許"</string>
+    <string name="wifi_debugging_always" msgid="2968383799517975155">"一律允許在此網絡上執行"</string>
     <string name="wifi_debugging_allow" msgid="4573224609684957886">"允許"</string>
     <string name="wifi_debugging_secondary_user_title" msgid="2493201475880517725">"不允許無線偵錯功能"</string>
     <string name="wifi_debugging_secondary_user_message" msgid="4492383073970079751">"目前登入此裝置的使用者無法啟用無線偵錯功能。如要使用此功能,請切換至主要使用者。"</string>
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"關閉螢幕截圖"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"螢幕截圖預覽"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"螢幕畫面錄影工具"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"正在處理螢幕錄影內容"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示錄影畫面工作階段通知"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"要開始錄影嗎?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"錄影時,Android 系統可擷取螢幕上顯示或裝置播放的任何敏感資料,包括密碼、付款資料、相片、訊息和音訊。"</string>
@@ -101,7 +100,7 @@
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"裝置音訊和麥克風"</string>
     <string name="screenrecord_start" msgid="330991441575775004">"開始"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"正在錄影螢幕畫面"</string>
-    <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"錄影螢幕畫面和音訊"</string>
+    <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"正在錄製螢幕畫面和音訊"</string>
     <string name="screenrecord_taps_label" msgid="1595690528298857649">"顯示輕觸螢幕的位置"</string>
     <string name="screenrecord_stop_text" msgid="6549288689506057686">"輕按即可停止"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"停止"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"記錄"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"收到的通知"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"靜音通知"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"提醒通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
@@ -969,7 +967,7 @@
     <string name="running_foreground_services_title" msgid="5137313173431186685">"正在背景中執行的應用程式"</string>
     <string name="running_foreground_services_msg" msgid="3009459259222695385">"輕按即可查看電池和數據用量詳情"</string>
     <string name="mobile_data_disable_title" msgid="5366476131671617790">"要關閉流動數據嗎?"</string>
-    <string name="mobile_data_disable_message" msgid="8604966027899770415">"您將無法透過「<xliff:g id="CARRIER">%s</xliff:g>」使用流動數據或互聯網,只可透過 Wi-Fi 才能連接互聯網。"</string>
+    <string name="mobile_data_disable_message" msgid="8604966027899770415">"您無法透過「<xliff:g id="CARRIER">%s</xliff:g>」使用流動數據或互聯網。如要使用互聯網,您必須連接 Wi-Fi。"</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6496033312431658238">"您的流動網絡供應商"</string>
     <string name="touch_filtered_warning" msgid="8119511393338714836">"由於某個應用程式已阻擋權限要求畫面,因此「設定」應用程式無法驗證您的回應。"</string>
     <string name="slice_permission_title" msgid="3262615140094151017">"要允許「<xliff:g id="APP_0">%1$s</xliff:g>」顯示「<xliff:g id="APP_2">%2$s</xliff:g>」的快訊嗎?"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"輕按即可重新開啟此應用程式並放大至全螢幕。"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」小視窗設定"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"顯示更多"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"加回堆疊"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"管理"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"來自「<xliff:g id="APP_NAME">%2$s</xliff:g>」的 <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"來自「<xliff:g id="APP_NAME">%2$s</xliff:g>」及另外 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> 個應用程式的<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 6f825de..b1ba86a 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"關閉螢幕截圖"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"螢幕截圖預覽"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"螢幕錄影器"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"處理螢幕錄影內容"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示螢幕畫面錄製工作階段通知"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"要開始錄製嗎?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"錄製螢幕畫面時,Android 系統可擷取螢幕上顯示或裝置播放的任何機密資訊,包括密碼、付款資訊、相片、訊息和音訊。"</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"全部清除"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"管理"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"記錄"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"收到的通知"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"靜音通知"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"快訊通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"對話"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"無標題"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"輕觸即可重新啟動這個應用程式並進入全螢幕模式。"</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」對話框的設定"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"溢位"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"重新加入堆疊"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"管理"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"<xliff:g id="APP_NAME">%2$s</xliff:g>:<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"「<xliff:g id="APP_NAME">%2$s</xliff:g>」和其他 <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> 個應用程式:<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index a02cfa2..2fe904a 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -89,8 +89,7 @@
     <string name="screenshot_dismiss_ui_description" msgid="934736855340147968">"Cashisa isithombe-skrini"</string>
     <string name="screenshot_preview_description" msgid="7606510140714080474">"Ukubuka kuqala isithombe-skrini"</string>
     <string name="screenrecord_name" msgid="2596401223859996572">"Irekhoda yesikrini"</string>
-    <!-- no translation found for screenrecord_background_processing_label (7244617554884238898) -->
-    <skip />
+    <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Icubungula okokuqopha iskrini"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Isaziso esiqhubekayo seseshini yokurekhoda isikrini"</string>
     <string name="screenrecord_start_label" msgid="1750350278888217473">"Qala ukurekhoda?"</string>
     <string name="screenrecord_description" msgid="1123231719680353736">"Ngenkathi irekhoda, Isistimu ye-Android ingathatha noma iluphi ulwazi olubucayi olubonakal kusikrini sakho noma oludlalwa kudivayisi yakho. Lokhu kufaka phakathi amaphasiwedi, ulwazi lokukhokha, izithombe, imilayezo, nomsindo."</string>
@@ -511,8 +510,7 @@
     <string name="clear_all_notifications_text" msgid="348312370303046130">"Sula konke"</string>
     <string name="manage_notifications_text" msgid="6885645344647733116">"Phatha"</string>
     <string name="manage_notifications_history_text" msgid="57055985396576230">"Umlando"</string>
-    <!-- no translation found for notification_section_header_incoming (5295312809341711367) -->
-    <skip />
+    <string name="notification_section_header_incoming" msgid="5295312809341711367">"Okungenayo"</string>
     <string name="notification_section_header_gentle" msgid="3044910806569985386">"Thulisa izaziso"</string>
     <string name="notification_section_header_alerting" msgid="3168140660646863240">"Izaziso zokuxwayisa"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"Izingxoxo"</string>
@@ -991,10 +989,8 @@
     <string name="music_controls_no_title" msgid="4166497066552290938">"Asikho isihloko"</string>
     <string name="restart_button_description" msgid="6916116576177456480">"Thepha ukuze uqale kabusha lolu hlelo lokusebenza uphinde uye kusikrini esigcwele."</string>
     <string name="bubbles_settings_button_description" msgid="7324245408859877545">"Izilungiselelo zamabhamuza e-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <!-- no translation found for bubble_overflow_button_content_description (5523744621434300510) -->
-    <skip />
-    <!-- no translation found for bubble_accessibility_action_add_back (6217995665917123890) -->
-    <skip />
+    <string name="bubble_overflow_button_content_description" msgid="5523744621434300510">"Ukuphuphuma"</string>
+    <string name="bubble_accessibility_action_add_back" msgid="6217995665917123890">"Engeza emuva kusitaki"</string>
     <string name="manage_bubbles_text" msgid="6856830436329494850">"Phatha"</string>
     <string name="bubble_content_description_single" msgid="5175160674436546329">"I-<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> kusuka ku-<xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
     <string name="bubble_content_description_stack" msgid="7907610717462651870">"I-<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> kusukela ku-<xliff:g id="APP_NAME">%2$s</xliff:g> nokungu-<xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> ngaphezulu"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index b677600..837627c 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -239,9 +239,14 @@
 
     <color name="magnification_border_color">#FF9900</color>
 
+    <!-- media -->
+    <color name="media_primary_text">@android:color/white</color>
+    <color name="media_seekbar_progress">#c0ffffff</color>
+    <color name="media_disabled">#80ffffff</color>
+
     <!-- controls -->
-    <color name="control_primary_text">@color/GM2_grey_100</color>
-    <color name="control_secondary_text">@color/GM2_grey_500</color>
+    <color name="control_primary_text">#E6FFFFFF</color>
+    <color name="control_secondary_text">#99FFFFFF</color>
     <color name="control_default_foreground">@color/GM2_grey_500</color>
     <color name="control_default_background">@color/GM2_grey_900</color>
     <color name="control_list_popup_background">@*android:color/background_floating_material_dark</color>
@@ -257,4 +262,6 @@
 
     <!-- Docked misalignment message -->
     <color name="misalignment_text_color">#F28B82</color>
+
+    <color name="screenrecord_status_color">#E94235</color>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b4a05c6..a3d32c1 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -314,7 +314,7 @@
     <dimen name="screenshot_dismiss_button_margin">8dp</dimen>
     <dimen name="screenshot_action_container_offset_y">32dp</dimen>
     <dimen name="screenshot_action_container_corner_radius">10dp</dimen>
-    <dimen name="screenshot_action_container_padding_vertical">10dp</dimen>
+    <dimen name="screenshot_action_container_padding_vertical">16dp</dimen>
     <dimen name="screenshot_action_container_margin_horizontal">8dp</dimen>
     <dimen name="screenshot_action_container_padding_left">96dp</dimen>
     <dimen name="screenshot_action_container_padding_right">8dp</dimen>
@@ -502,7 +502,6 @@
     <dimen name="qs_page_indicator_width">16dp</dimen>
     <dimen name="qs_page_indicator_height">8dp</dimen>
     <dimen name="qs_tile_icon_size">24dp</dimen>
-    <dimen name="qs_tile_detail_padding">3dp</dimen>
     <dimen name="qs_tile_text_size">12sp</dimen>
     <dimen name="qs_tile_divider_height">1dp</dimen>
     <dimen name="qs_panel_padding">16dp</dimen>
@@ -1281,6 +1280,10 @@
     <dimen name="control_status_padding">3dp</dimen>
     <fraction name="controls_toggle_bg_intensity">5%</fraction>
     <fraction name="controls_dimmed_alpha">40%</fraction>
+    <dimen name="controls_setup_top_margin">16dp</dimen>
+    <dimen name="controls_setup_title">22sp</dimen>
+    <dimen name="controls_setup_subtitle">14sp</dimen>
+    <dimen name="controls_setup_vertical_padding">52dp</dimen>
 
     <!-- Home Controls activity view detail panel-->
     <dimen name="controls_activity_view_top_offset">100dp</dimen>
@@ -1323,7 +1326,10 @@
     <dimen name="screenrecord_dialog_padding">18dp</dimen>
     <dimen name="screenrecord_logo_size">24dp</dimen>
     <dimen name="screenrecord_status_text_size">14sp</dimen>
-    <dimen name="screenrecord_status_icon_radius">5dp</dimen>
+    <dimen name="screenrecord_status_icon_radius">7dp</dimen>
+    <dimen name="screenrecord_status_icon_width">21dp</dimen>
+    <dimen name="screenrecord_status_icon_height">17.5dp</dimen>
+    <dimen name="screenrecord_status_icon_bg_radius">8dp</dimen>
 
     <dimen name="kg_user_switcher_text_size">16sp</dimen>
 
diff --git a/packages/SystemUI/res/values/integers.xml b/packages/SystemUI/res/values/integers.xml
index f35f351..b1e91c8 100644
--- a/packages/SystemUI/res/values/integers.xml
+++ b/packages/SystemUI/res/values/integers.xml
@@ -33,11 +33,6 @@
     <!-- Maximum number of bubbles we allow in overflow before we dismiss the oldest one. -->
     <integer name="bubbles_max_overflow">16</integer>
 
-    <!-- Ratio of "left" end of status bar that will swipe to QQS. -->
-    <integer name="qqs_split_fraction">3</integer>
-    <!-- Ratio of "right" end of status bar that will swipe to QS. -->
-    <integer name="qs_split_fraction">2</integer>
-
     <integer name="magnification_default_scale">2</integer>
 
     <!-- The position of the volume dialog on the screen.
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index ec29622..8c10f61 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2698,6 +2698,20 @@
         <item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> controls added.</item>
     </plurals>
 
+    <!-- Removed control in management screen [CHAR LIMIT=20] -->
+    <string name="controls_removed">Removed</string>
+
+    <!-- a11y state description for a control that is currently favorited [CHAR LIMIT=NONE] -->
+    <string name="accessibility_control_favorite">Favorited</string>
+    <!-- a11y state description for a control that is currently favorited with its position [CHAR LIMIT=NONE] -->
+    <string name="accessibility_control_favorite_position">Favorited, position <xliff:g id="number" example="1">%d</xliff:g></string>
+    <!-- a11y state description for a control that is currently not favorited [CHAR LIMIT=NONE] -->
+    <string name="accessibility_control_not_favorite">Unfavorited</string>
+    <!-- a11y action to favorite a control. It will read as "Double-tap to favorite" in screen readers [CHAR LIMIT=NONE] -->
+    <string name="accessibility_control_change_favorite">favorite</string>
+    <!-- a11y action to unfavorite a control. It will read as "Double-tap to unfavorite" in screen readers [CHAR LIMIT=NONE] -->
+    <string name="accessibility_control_change_unfavorite">unfavorite</string>
+
     <!-- Controls management controls screen default title [CHAR LIMIT=30] -->
     <string name="controls_favorite_default_title">Controls</string>
     <!-- Controls management controls screen subtitle [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index f0edd63..b461295 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -622,6 +622,7 @@
 
     <style name="MediaPlayer.Button" parent="@android:style/Widget.Material.Button.Borderless.Small">
         <item name="android:background">@null</item>
+        <item name="android:tint">@android:color/white</item>
     </style>
 
     <!-- Used to style charging animation AVD animation -->
@@ -765,11 +766,11 @@
     </style>
 
     <style name="TextAppearance.ControlSetup.Title">
-        <item name="android:textSize">25sp</item>
+        <item name="android:textSize">@dimen/controls_setup_title</item>
     </style>
 
     <style name="TextAppearance.ControlSetup.Subtitle">
-        <item name="android:textSize">16sp</item>
+        <item name="android:textSize">@dimen/controls_setup_subtitle</item>
     </style>
 
     <!-- The attributes used for title (textAppearanceLarge) and message (textAppearanceMedium)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java
index 8bd7c79..30156a0 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SurfaceViewRequestReceiver.java
@@ -58,7 +58,7 @@
      */
     public void onReceive(Context context, Bundle bundle, View view, Size viewSize) {
         if (mSurfaceControlViewHost != null) {
-            mSurfaceControlViewHost.die();
+            mSurfaceControlViewHost.release();
         }
 
         SurfaceControl surfaceControl = SurfaceViewRequestUtils.getSurfaceControl(bundle);
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 0106609..b1e1434 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -19,8 +19,6 @@
 import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
 import static android.telephony.PhoneStateListener.LISTEN_NONE;
 
-import static com.android.systemui.DejankUtils.whitelistIpcs;
-
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -47,6 +45,7 @@
 
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import javax.inject.Inject;
 
@@ -61,9 +60,11 @@
 
     private final boolean mIsEmergencyCallCapable;
     private final Handler mMainHandler;
+    private final Handler mBgHandler;
     private boolean mTelephonyCapable;
     private boolean mShowMissingSim;
     private boolean mShowAirplaneMode;
+    private final AtomicBoolean mNetworkSupported = new AtomicBoolean();
     @VisibleForTesting
     protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private WifiManager mWifiManager;
@@ -78,12 +79,14 @@
             new WakefulnessLifecycle.Observer() {
                 @Override
                 public void onFinishedWakingUp() {
-                    if (mCarrierTextCallback != null) mCarrierTextCallback.finishedWakingUp();
+                    final CarrierTextCallback callback = mCarrierTextCallback;
+                    if (callback != null) callback.finishedWakingUp();
                 }
 
                 @Override
                 public void onStartedGoingToSleep() {
-                    if (mCarrierTextCallback != null) mCarrierTextCallback.startedGoingToSleep();
+                    final CarrierTextCallback callback = mCarrierTextCallback;
+                    if (callback != null) callback.startedGoingToSleep();
                 }
             };
 
@@ -131,7 +134,7 @@
         @Override
         public void onActiveDataSubscriptionIdChanged(int subId) {
             mActiveMobileDataSubscription = subId;
-            if (mKeyguardUpdateMonitor != null) {
+            if (mNetworkSupported.get() && mCarrierTextCallback != null) {
                 updateCarrierText();
             }
         }
@@ -173,6 +176,17 @@
         mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
         mSimErrorState = new boolean[mSimSlotsNumber];
         mMainHandler = Dependency.get(Dependency.MAIN_HANDLER);
+        mBgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
+        mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
+        mBgHandler.post(() -> {
+            boolean supported = ConnectivityManager.from(mContext).isNetworkSupported(
+                    ConnectivityManager.TYPE_MOBILE);
+            if (supported && mNetworkSupported.compareAndSet(false, supported)) {
+                // This will set/remove the listeners appropriately. Note that it will never double
+                // add the listeners.
+                handleSetListening(mCarrierTextCallback);
+            }
+        });
     }
 
     private TelephonyManager getTelephonyManager() {
@@ -221,48 +235,51 @@
     }
 
     /**
-     * Sets the listening status of this controller. If the callback is null, it is set to
-     * not listening
+     * This may be called internally after retrieving the correct value of {@code mNetworkSupported}
+     * (assumed false to start). In that case, the following happens:
+     * <ul>
+     *     <li> If there was a registered callback, and the network is supported, it will register
+     *          listeners.
+     *     <li> If there was not a registered callback, it will try to remove unregistered listeners
+     *          which is a no-op
+     * </ul>
      *
-     * @param callback Callback to provide text updates
+     * This call will always be processed in a background thread.
      */
-    public void setListening(CarrierTextCallback callback) {
+    private void handleSetListening(CarrierTextCallback callback) {
         TelephonyManager telephonyManager = getTelephonyManager();
         if (callback != null) {
             mCarrierTextCallback = callback;
-            // TODO(b/140034799)
-            if (whitelistIpcs(() -> ConnectivityManager.from(mContext).isNetworkSupported(
-                    ConnectivityManager.TYPE_MOBILE))) {
-                mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
+            if (mNetworkSupported.get()) {
                 // Keyguard update monitor expects callbacks from main thread
-                mMainHandler.post(() -> {
-                    if (mKeyguardUpdateMonitor != null) {
-                        mKeyguardUpdateMonitor.registerCallback(mCallback);
-                    }
-                });
+                mMainHandler.post(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
                 mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
                 telephonyManager.listen(mPhoneStateListener,
                         LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
             } else {
                 // Don't listen and clear out the text when the device isn't a phone.
-                mKeyguardUpdateMonitor = null;
-                callback.updateCarrierInfo(new CarrierTextCallbackInfo("", null, false, null));
+                mMainHandler.post(() -> callback.updateCarrierInfo(
+                        new CarrierTextCallbackInfo("", null, false, null)
+                ));
             }
         } else {
             mCarrierTextCallback = null;
-            if (mKeyguardUpdateMonitor != null) {
-                // Keyguard update monitor expects callbacks from main thread
-                mMainHandler.post(() -> {
-                    if (mKeyguardUpdateMonitor != null) {
-                        mKeyguardUpdateMonitor.removeCallback(mCallback);
-                    }
-                });
-                mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
-            }
+            mMainHandler.post(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
+            mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
             telephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
         }
     }
 
+    /**
+     * Sets the listening status of this controller. If the callback is null, it is set to
+     * not listening.
+     *
+     * @param callback Callback to provide text updates
+     */
+    public void setListening(CarrierTextCallback callback) {
+        mBgHandler.post(() -> handleSetListening(callback));
+    }
+
     protected List<SubscriptionInfo> getSubscriptionInfo() {
         return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
     }
@@ -500,7 +517,7 @@
      */
     private CarrierTextController.StatusMode getStatusForIccState(int simState) {
         final boolean missingAndNotProvisioned =
-                !Dependency.get(KeyguardUpdateMonitor.class).isDeviceProvisioned()
+                !mKeyguardUpdateMonitor.isDeviceProvisioned()
                         && (simState == TelephonyManager.SIM_STATE_ABSENT
                         || simState == TelephonyManager.SIM_STATE_PERM_DISABLED);
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index f771cc6..0db713e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -33,6 +33,7 @@
 
 import android.annotation.AnyThread;
 import android.annotation.MainThread;
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.AlarmManager;
@@ -247,8 +248,7 @@
     // Battery status
     private BatteryStatus mBatteryStatus;
 
-    @VisibleForTesting
-    protected StrongAuthTracker mStrongAuthTracker;
+    private StrongAuthTracker mStrongAuthTracker;
 
     private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
             mCallbacks = Lists.newArrayList();
@@ -1512,6 +1512,16 @@
         mUserTrustIsUsuallyManaged.delete(userId);
     }
 
+    @VisibleForTesting
+    protected void setStrongAuthTracker(@NonNull StrongAuthTracker tracker) {
+        if (mStrongAuthTracker != null) {
+            mLockPatternUtils.unregisterStrongAuthTracker(mStrongAuthTracker);
+        }
+
+        mStrongAuthTracker = tracker;
+        mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
+    }
+
     private void registerRingerTracker() {
         mRingerModeTracker.getRingerMode().observeForever(mRingerModeObserver);
     }
@@ -1525,7 +1535,8 @@
             DumpManager dumpManager,
             RingerModeTracker ringerModeTracker,
             @Background Executor backgroundExecutor,
-            StatusBarStateController statusBarStateController) {
+            StatusBarStateController statusBarStateController,
+            LockPatternUtils lockPatternUtils) {
         mContext = context;
         mSubscriptionManager = SubscriptionManager.from(context);
         mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
@@ -1534,6 +1545,7 @@
         mBroadcastDispatcher = broadcastDispatcher;
         mRingerModeTracker = ringerModeTracker;
         mStatusBarStateController = statusBarStateController;
+        mLockPatternUtils = lockPatternUtils;
         dumpManager.registerDumpable(getClass().getName(), this);
 
         mHandler = new Handler(mainLooper) {
@@ -1702,8 +1714,8 @@
 
         mTrustManager = context.getSystemService(TrustManager.class);
         mTrustManager.registerTrustListener(this);
-        mLockPatternUtils = new LockPatternUtils(context);
-        mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
+
+        setStrongAuthTracker(mStrongAuthTracker);
 
         mDreamManager = IDreamManager.Stub.asInterface(
                 ServiceManager.getService(DreamService.DREAM_SERVICE));
@@ -2847,6 +2859,9 @@
         mBroadcastDispatcher.unregisterReceiver(mBroadcastAllReceiver);
         mRingerModeTracker.getRingerMode().removeObserver(mRingerModeObserver);
 
+        mLockPatternUtils.unregisterStrongAuthTracker(mStrongAuthTracker);
+        mTrustManager.unregisterTrustListener(this);
+
         mHandler.removeCallbacksAndMessages(null);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 9d1dfa7..1dd6409 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -34,7 +34,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.WindowInsets.Type;
 import android.view.WindowManager;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
@@ -635,7 +634,6 @@
         lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
         lp.setTitle("BiometricPrompt");
         lp.token = windowToken;
-        lp.setFitInsetsTypes(lp.getFitInsetsTypes() & ~Type.statusBars());
         return lp;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 0dbee66..f044389 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -16,6 +16,7 @@
 package com.android.systemui.bubbles;
 
 
+import static android.app.Notification.FLAG_BUBBLE;
 import static android.os.AsyncTask.Status.FINISHED;
 import static android.view.Display.INVALID_DISPLAY;
 
@@ -27,6 +28,7 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
@@ -55,6 +57,11 @@
 class Bubble implements BubbleViewProvider {
     private static final String TAG = "Bubble";
 
+    /**
+     * NotificationEntry associated with the bubble. A null value implies this bubble is loaded
+     * from disk.
+     */
+    @Nullable
     private NotificationEntry mEntry;
     private final String mKey;
     private final String mGroupId;
@@ -95,22 +102,68 @@
     private Bitmap mBadgedImage;
     private int mDotColor;
     private Path mDotPath;
+    private int mFlags;
 
-
+    /**
+     * Extract GroupId from {@link NotificationEntry}. See also {@link #groupId(ShortcutInfo)}.
+     */
     public static String groupId(NotificationEntry entry) {
         UserHandle user = entry.getSbn().getUser();
         return user.getIdentifier() + "|" + entry.getSbn().getPackageName();
     }
 
+    /**
+     * Extract GroupId from {@link ShortcutInfo}. This should match the one generated from
+     * {@link NotificationEntry}. See also {@link #groupId(NotificationEntry)}.
+     */
+    @NonNull
+    public static String groupId(@NonNull final ShortcutInfo shortcutInfo) {
+        return shortcutInfo.getUserId() + "|" + shortcutInfo.getPackage();
+    }
+
+    /**
+     * Generate a unique identifier for this bubble based on given {@link NotificationEntry}. If
+     * {@link ShortcutInfo} was found in the notification entry, the identifier would be generated
+     * from {@link ShortcutInfo} instead. See also {@link #key(ShortcutInfo)}.
+     */
+    @NonNull
+    public static String key(@NonNull final NotificationEntry entry) {
+        final ShortcutInfo shortcutInfo = entry.getRanking().getShortcutInfo();
+        if (shortcutInfo != null) return key(shortcutInfo);
+        return entry.getKey();
+    }
+
+    /**
+     * Generate a unique identifier for this bubble based on given {@link ShortcutInfo}.
+     * See also {@link #key(NotificationEntry)}.
+     */
+    @NonNull
+    public static String key(@NonNull final ShortcutInfo shortcutInfo) {
+        return shortcutInfo.getUserId() + "|" + shortcutInfo.getPackage() + "|"
+                + shortcutInfo.getId();
+    }
+
+    /**
+     * Create a bubble with limited information based on given {@link ShortcutInfo}.
+     * Note: Currently this is only being used when the bubble is persisted to disk.
+     */
+    Bubble(ShortcutInfo shortcutInfo) {
+        mShortcutInfo = shortcutInfo;
+        mKey = key(shortcutInfo);
+        mGroupId = groupId(shortcutInfo);
+        mFlags = 0;
+    }
+
     /** Used in tests when no UI is required. */
     @VisibleForTesting(visibility = PRIVATE)
     Bubble(NotificationEntry e,
             BubbleController.NotificationSuppressionChangedListener listener) {
         mEntry = e;
-        mKey = e.getKey();
+        mKey = key(e);
         mLastUpdated = e.getSbn().getPostTime();
         mGroupId = groupId(e);
         mSuppressionListener = listener;
+        mFlags = e.getSbn().getNotification().flags;
     }
 
     @Override
@@ -118,16 +171,26 @@
         return mKey;
     }
 
+    @Nullable
     public NotificationEntry getEntry() {
         return mEntry;
     }
 
+    @Nullable
+    public UserHandle getUser() {
+        if (mEntry != null) return mEntry.getSbn().getUser();
+        if (mShortcutInfo != null) return mShortcutInfo.getUserHandle();
+        return null;
+    }
+
     public String getGroupId() {
         return mGroupId;
     }
 
     public String getPackageName() {
-        return mEntry.getSbn().getPackageName();
+        return mEntry == null
+                ? mShortcutInfo == null ? null : mShortcutInfo.getPackage()
+                : mEntry.getSbn().getPackageName();
     }
 
     @Override
@@ -211,7 +274,8 @@
     void inflate(BubbleViewInfoTask.Callback callback,
             Context context,
             BubbleStackView stackView,
-            BubbleIconFactory iconFactory) {
+            BubbleIconFactory iconFactory,
+            boolean skipInflation) {
         if (isBubbleLoading()) {
             mInflationTask.cancel(true /* mayInterruptIfRunning */);
         }
@@ -219,6 +283,7 @@
                 context,
                 stackView,
                 iconFactory,
+                skipInflation,
                 callback);
         if (mInflateSynchronously) {
             mInflationTask.onPostExecute(mInflationTask.doInBackground());
@@ -338,6 +403,7 @@
      * Whether this notification should be shown in the shade.
      */
     boolean showInShade() {
+        if (mEntry == null) return false;
         return !shouldSuppressNotification() || !mEntry.isClearable();
     }
 
@@ -345,8 +411,8 @@
      * Sets whether this notification should be suppressed in the shade.
      */
     void setSuppressNotification(boolean suppressNotification) {
+        if (mEntry == null) return;
         boolean prevShowInShade = showInShade();
-
         Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
         int flags = data.getFlags();
         if (suppressNotification) {
@@ -377,6 +443,7 @@
      */
     @Override
     public boolean showDot() {
+        if (mEntry == null) return false;
         return mShowBubbleUpdateDot
                 && !mEntry.shouldSuppressNotificationDot()
                 && !shouldSuppressNotification();
@@ -386,6 +453,7 @@
      * Whether the flyout for the bubble should be shown.
      */
     boolean showFlyout() {
+        if (mEntry == null) return false;
         return !mSuppressFlyout && !mEntry.shouldSuppressPeek()
                 && !shouldSuppressNotification()
                 && !mEntry.shouldSuppressNotificationList();
@@ -409,11 +477,13 @@
      * is an ongoing bubble.
      */
     boolean isOngoing() {
+        if (mEntry == null) return false;
         int flags = mEntry.getSbn().getNotification().flags;
         return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
     }
 
     float getDesiredHeight(Context context) {
+        if (mEntry == null) return 0;
         Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
         boolean useRes = data.getDesiredHeightResId() != 0;
         if (useRes) {
@@ -427,6 +497,7 @@
     }
 
     String getDesiredHeightString() {
+        if (mEntry == null) return String.valueOf(0);
         Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
         boolean useRes = data.getDesiredHeightResId() != 0;
         if (useRes) {
@@ -443,11 +514,13 @@
      * To populate the icon use {@link LauncherApps#getShortcutIconDrawable(ShortcutInfo, int)}.
      */
     boolean usingShortcutInfo() {
-        return mEntry.getBubbleMetadata().getShortcutId() != null;
+        return mEntry != null && mEntry.getBubbleMetadata().getShortcutId() != null
+                || mShortcutInfo != null;
     }
 
     @Nullable
     PendingIntent getBubbleIntent() {
+        if (mEntry == null) return null;
         Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
         if (data != null) {
             return data.getIntent();
@@ -455,16 +528,32 @@
         return null;
     }
 
-    Intent getSettingsIntent() {
+    Intent getSettingsIntent(final Context context) {
         final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_BUBBLE_SETTINGS);
         intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
-        intent.putExtra(Settings.EXTRA_APP_UID, mEntry.getSbn().getUid());
+        final int uid = getUid(context);
+        if (uid != -1) {
+            intent.putExtra(Settings.EXTRA_APP_UID, uid);
+        }
         intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
         return intent;
     }
 
+    private int getUid(final Context context) {
+        if (mEntry != null) return mEntry.getSbn().getUid();
+        final PackageManager pm = context.getPackageManager();
+        if (pm == null) return -1;
+        try {
+            final ApplicationInfo info = pm.getApplicationInfo(mShortcutInfo.getPackage(), 0);
+            return info.uid;
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(TAG, "cannot find uid", e);
+        }
+        return -1;
+    }
+
     private int getDimenForPackageUser(Context context, int resId, String pkg, int userId) {
         PackageManager pm = context.getPackageManager();
         Resources r;
@@ -486,15 +575,30 @@
     }
 
     private boolean shouldSuppressNotification() {
+        if (mEntry == null) return false;
         return mEntry.getBubbleMetadata() != null
                 && mEntry.getBubbleMetadata().isNotificationSuppressed();
     }
 
     boolean shouldAutoExpand() {
+        if (mEntry == null) return false;
         Notification.BubbleMetadata metadata = mEntry.getBubbleMetadata();
         return metadata != null && metadata.getAutoExpandBubble();
     }
 
+    public boolean isBubble() {
+        if (mEntry == null) return (mFlags & FLAG_BUBBLE) != 0;
+        return (mEntry.getSbn().getNotification().flags & FLAG_BUBBLE) != 0;
+    }
+
+    public void enable(int option) {
+        mFlags |= option;
+    }
+
+    public void disable(int option) {
+        mFlags &= ~option;
+    }
+
     @Override
     public String toString() {
         return "Bubble{" + mKey + '}';
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 6a5e94c..8707d38 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -42,6 +42,7 @@
 import static java.lang.annotation.ElementType.PARAMETER;
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
+import android.annotation.NonNull;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.INotificationManager;
@@ -198,6 +199,11 @@
     /** Last known orientation, used to detect orientation changes in {@link #onConfigChanged}. */
     private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
 
+    /**
+     * Last known screen density, used to detect display size changes in {@link #onConfigChanged}.
+     */
+    private int mDensityDpi = Configuration.DENSITY_DPI_UNDEFINED;
+
     private boolean mInflateSynchronously;
 
     // TODO (b/145659174): allow for multiple callbacks to support the "shadow" new notif pipeline
@@ -237,7 +243,7 @@
          * This can happen when an app cancels a bubbled notification or when the user dismisses a
          * bubble.
          */
-        void removeNotification(NotificationEntry entry, int reason);
+        void removeNotification(@NonNull NotificationEntry entry, int reason);
 
         /**
          * Called when a bubbled notification has changed whether it should be
@@ -253,7 +259,7 @@
          * removes all remnants of the group's summary from the notification pipeline.
          * TODO: (b/145659174) Only old pipeline needs this - delete post-migration.
          */
-        void maybeCancelSummary(NotificationEntry entry);
+        void maybeCancelSummary(@NonNull NotificationEntry entry);
     }
 
     /**
@@ -476,7 +482,7 @@
 
         addNotifCallback(new NotifCallback() {
             @Override
-            public void removeNotification(NotificationEntry entry, int reason) {
+            public void removeNotification(@NonNull final NotificationEntry entry, int reason) {
                 mNotificationEntryManager.performRemoveNotification(entry.getSbn(),
                         reason);
             }
@@ -487,7 +493,7 @@
             }
 
             @Override
-            public void maybeCancelSummary(NotificationEntry entry) {
+            public void maybeCancelSummary(@NonNull final NotificationEntry entry) {
                 // Check if removed bubble has an associated suppressed group summary that needs
                 // to be removed now.
                 final String groupKey = entry.getSbn().getGroupKey();
@@ -696,18 +702,27 @@
         mBubbleIconFactory = new BubbleIconFactory(mContext);
         // Reload each bubble
         for (Bubble b: mBubbleData.getBubbles()) {
-            b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory);
+            b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory,
+                    false /* skipInflation */);
         }
         for (Bubble b: mBubbleData.getOverflowBubbles()) {
-            b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory);
+            b.inflate(null /* callback */, mContext, mStackView, mBubbleIconFactory,
+                    false /* skipInflation */);
         }
     }
 
     @Override
     public void onConfigChanged(Configuration newConfig) {
-        if (mStackView != null && newConfig != null && newConfig.orientation != mOrientation) {
-            mOrientation = newConfig.orientation;
-            mStackView.onOrientationChanged(newConfig.orientation);
+        if (mStackView != null && newConfig != null) {
+            if (newConfig.orientation != mOrientation) {
+                mOrientation = newConfig.orientation;
+                mStackView.onOrientationChanged(newConfig.orientation);
+            }
+            if (newConfig.densityDpi != mDensityDpi) {
+                mDensityDpi = newConfig.densityDpi;
+                mBubbleIconFactory = new BubbleIconFactory(mContext);
+                mStackView.onDisplaySizeChanged();
+            }
         }
     }
 
@@ -791,7 +806,7 @@
             if (bubble != null) {
                 mBubbleData.promoteBubbleFromOverflow(bubble, mStackView, mBubbleIconFactory);
             }
-        } else if (bubble.getEntry().isBubble()){
+        } else if (bubble.isBubble()) {
             mBubbleData.setSelectedBubble(bubble);
         }
         mBubbleData.setExpanded(true);
@@ -820,10 +835,33 @@
         updateBubble(notif, suppressFlyout, true /* showInShade */);
     }
 
+    /**
+     * Fills the overflow bubbles by loading them from disk.
+     */
+    void loadOverflowBubblesFromDisk() {
+        if (!mBubbleData.getOverflowBubbles().isEmpty()) {
+            // we don't need to load overflow bubbles from disk if it is already in memory
+            return;
+        }
+        mDataRepository.loadBubbles((bubbles) -> {
+            bubbles.forEach(bubble -> {
+                if (mBubbleData.getBubbles().contains(bubble)) {
+                    // if the bubble is already active, there's no need to push it to overflow
+                    return;
+                }
+                bubble.inflate((b) -> mBubbleData.overflowBubble(DISMISS_AGED, bubble),
+                        mContext, mStackView, mBubbleIconFactory, true /* skipInflation */);
+            });
+            return null;
+        });
+    }
+
     void updateBubble(NotificationEntry notif, boolean suppressFlyout, boolean showInShade) {
         if (mStackView == null) {
             // Lazy init stack view when a bubble is created
             ensureStackViewCreated();
+            // Lazy load overflow bubbles from disk
+            loadOverflowBubblesFromDisk();
         }
         // If this is an interruptive notif, mark that it's interrupted
         if (notif.getImportance() >= NotificationManager.IMPORTANCE_HIGH) {
@@ -843,11 +881,11 @@
                             return;
                         }
                         mHandler.post(
-                                () -> removeBubble(bubble.getEntry(),
+                                () -> removeBubble(bubble.getKey(),
                                         BubbleController.DISMISS_INVALID_INTENT));
                     });
                 },
-                mContext, mStackView, mBubbleIconFactory);
+                mContext, mStackView, mBubbleIconFactory, false /* skipInflation */);
     }
 
     /**
@@ -859,7 +897,10 @@
      * @param entry the notification to change bubble state for.
      * @param shouldBubble whether the notification should show as a bubble or not.
      */
-    public void onUserChangedBubble(NotificationEntry entry, boolean shouldBubble) {
+    public void onUserChangedBubble(@Nullable final NotificationEntry entry, boolean shouldBubble) {
+        if (entry == null) {
+            return;
+        }
         NotificationChannel channel = entry.getChannel();
         final String appPkg = entry.getSbn().getPackageName();
         final int appUid = entry.getSbn().getUid();
@@ -870,6 +911,7 @@
         // Update the state in NotificationManagerService
         try {
             int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
+            flags |= Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE;
             mBarService.onNotificationBubbleChanged(entry.getKey(), shouldBubble, flags);
         } catch (RemoteException e) {
         }
@@ -897,14 +939,14 @@
     }
 
     /**
-     * Removes the bubble with the given NotificationEntry.
+     * Removes the bubble with the given key.
      * <p>
      * Must be called from the main thread.
      */
     @MainThread
-    void removeBubble(NotificationEntry entry, int reason) {
-        if (mBubbleData.hasAnyBubbleWithKey(entry.getKey())) {
-            mBubbleData.notificationEntryRemoved(entry, reason);
+    void removeBubble(String key, int reason) {
+        if (mBubbleData.hasAnyBubbleWithKey(key)) {
+            mBubbleData.notificationEntryRemoved(key, reason);
         }
     }
 
@@ -920,7 +962,7 @@
                 && canLaunchInActivityView(mContext, entry);
         if (!shouldBubble && mBubbleData.hasAnyBubbleWithKey(entry.getKey())) {
             // It was previously a bubble but no longer a bubble -- lets remove it
-            removeBubble(entry, DISMISS_NO_LONGER_BUBBLE);
+            removeBubble(entry.getKey(), DISMISS_NO_LONGER_BUBBLE);
         } else if (shouldBubble) {
             updateBubble(entry);
         }
@@ -934,10 +976,10 @@
             // Remove any associated bubble children with the summary
             final List<Bubble> bubbleChildren = mBubbleData.getBubblesInGroup(groupKey);
             for (int i = 0; i < bubbleChildren.size(); i++) {
-                removeBubble(bubbleChildren.get(i).getEntry(), DISMISS_GROUP_CANCELLED);
+                removeBubble(bubbleChildren.get(i).getKey(), DISMISS_GROUP_CANCELLED);
             }
         } else {
-            removeBubble(entry, DISMISS_NOTIF_CANCEL);
+            removeBubble(entry.getKey(), DISMISS_NOTIF_CANCEL);
         }
     }
 
@@ -959,7 +1001,8 @@
             rankingMap.getRanking(key, mTmpRanking);
             boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key);
             if (isActiveBubble && !mTmpRanking.canBubble()) {
-                mBubbleData.notificationEntryRemoved(entry, BubbleController.DISMISS_BLOCKED);
+                mBubbleData.notificationEntryRemoved(entry.getKey(),
+                        BubbleController.DISMISS_BLOCKED);
             } else if (entry != null && mTmpRanking.isBubble() && !isActiveBubble) {
                 entry.setFlagBubble(true);
                 onEntryUpdated(entry);
@@ -969,9 +1012,15 @@
 
     private void setIsBubble(Bubble b, boolean isBubble) {
         if (isBubble) {
-            b.getEntry().getSbn().getNotification().flags |= FLAG_BUBBLE;
+            if (b.getEntry() != null) {
+                b.getEntry().getSbn().getNotification().flags |= FLAG_BUBBLE;
+            }
+            b.enable(FLAG_BUBBLE);
         } else {
-            b.getEntry().getSbn().getNotification().flags &= ~FLAG_BUBBLE;
+            if (b.getEntry() != null) {
+                b.getEntry().getSbn().getNotification().flags &= ~FLAG_BUBBLE;
+            }
+            b.disable(FLAG_BUBBLE);
         }
         try {
             mBarService.onNotificationBubbleChanged(b.getKey(), isBubble, 0);
@@ -1019,23 +1068,27 @@
                         // The bubble is now gone & the notification is hidden from the shade, so
                         // time to actually remove it
                         for (NotifCallback cb : mCallbacks) {
-                            cb.removeNotification(bubble.getEntry(), REASON_CANCEL);
+                            if (bubble.getEntry() != null) {
+                                cb.removeNotification(bubble.getEntry(), REASON_CANCEL);
+                            }
                         }
                     } else {
-                        if (bubble.getEntry().isBubble() && bubble.showInShade()) {
+                        if (bubble.isBubble() && bubble.showInShade()) {
                             setIsBubble(bubble, /* isBubble */ false);
                         }
-                        if (bubble.getEntry().getRow() != null) {
+                        if (bubble.getEntry() != null && bubble.getEntry().getRow() != null) {
                             bubble.getEntry().getRow().updateBubbleButton();
                         }
                     }
 
                 }
-                final String groupKey = bubble.getEntry().getSbn().getGroupKey();
-                if (mBubbleData.getBubblesInGroup(groupKey).isEmpty()) {
-                    // Time to potentially remove the summary
-                    for (NotifCallback cb : mCallbacks) {
-                        cb.maybeCancelSummary(bubble.getEntry());
+                if (bubble.getEntry() != null) {
+                    final String groupKey = bubble.getEntry().getSbn().getGroupKey();
+                    if (mBubbleData.getBubblesInGroup(groupKey).isEmpty()) {
+                        // Time to potentially remove the summary
+                        for (NotifCallback cb : mCallbacks) {
+                            cb.maybeCancelSummary(bubble.getEntry());
+                        }
                     }
                 }
             }
@@ -1060,7 +1113,7 @@
 
             if (update.selectionChanged) {
                 mStackView.setSelectedBubble(update.selectedBubble);
-                if (update.selectedBubble != null) {
+                if (update.selectedBubble != null && update.selectedBubble.getEntry() != null) {
                     mNotificationGroupManager.updateSuppression(
                             update.selectedBubble.getEntry());
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 65d5beb..7b323ce 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -23,6 +23,7 @@
 
 import static java.util.stream.Collectors.toList;
 
+import android.annotation.NonNull;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -223,7 +224,7 @@
                             false, /* showInShade */ true);
                     setSelectedBubble(bubble);
                 },
-                mContext, stack, factory);
+                mContext, stack, factory, false /* skipInflation */);
         dispatchPendingChanges();
     }
 
@@ -278,7 +279,8 @@
         }
         mPendingBubbles.remove(bubble); // No longer pending once we're here
         Bubble prevBubble = getBubbleInStackWithKey(bubble.getKey());
-        suppressFlyout |= !bubble.getEntry().getRanking().visuallyInterruptive();
+        suppressFlyout |= bubble.getEntry() == null
+                || !bubble.getEntry().getRanking().visuallyInterruptive();
 
         if (prevBubble == null) {
             // Create a new bubble
@@ -307,11 +309,14 @@
         dispatchPendingChanges();
     }
 
-    public void notificationEntryRemoved(NotificationEntry entry, @DismissReason int reason) {
+    /**
+     * Called when a notification associated with a bubble is removed.
+     */
+    public void notificationEntryRemoved(String key, @DismissReason int reason) {
         if (DEBUG_BUBBLE_DATA) {
-            Log.d(TAG, "notificationEntryRemoved: entry=" + entry + " reason=" + reason);
+            Log.d(TAG, "notificationEntryRemoved: key=" + key + " reason=" + reason);
         }
-        doRemove(entry.getKey(), reason);
+        doRemove(key, reason);
         dispatchPendingChanges();
     }
 
@@ -359,7 +364,7 @@
             return bubbleChildren;
         }
         for (Bubble b : mBubbles) {
-            if (groupKey.equals(b.getEntry().getSbn().getGroupKey())) {
+            if (b.getEntry() != null && groupKey.equals(b.getEntry().getSbn().getGroupKey())) {
                 bubbleChildren.add(b);
             }
         }
@@ -470,7 +475,9 @@
             Bubble newSelected = mBubbles.get(newIndex);
             setSelectedBubbleInternal(newSelected);
         }
-        maybeSendDeleteIntent(reason, bubbleToRemove.getEntry());
+        if (bubbleToRemove.getEntry() != null) {
+            maybeSendDeleteIntent(reason, bubbleToRemove.getEntry());
+        }
     }
 
     void overflowBubble(@DismissReason int reason, Bubble bubble) {
@@ -744,7 +751,8 @@
         return true;
     }
 
-    private void maybeSendDeleteIntent(@DismissReason int reason, NotificationEntry entry) {
+    private void maybeSendDeleteIntent(@DismissReason int reason,
+            @NonNull final NotificationEntry entry) {
         if (reason == BubbleController.DISMISS_USER_GESTURE) {
             Notification.BubbleMetadata bubbleMetadata = entry.getBubbleMetadata();
             PendingIntent deleteIntent = bubbleMetadata != null
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt
index b9825e1..6df3132 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDataRepository.kt
@@ -15,24 +15,32 @@
  */
 package com.android.systemui.bubbles
 
+import android.annotation.SuppressLint
 import android.annotation.UserIdInt
+import android.content.pm.LauncherApps
+import android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC
+import android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER
+import android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED
+import android.os.UserHandle
 import android.util.Log
+import com.android.systemui.bubbles.storage.BubbleEntity
 import com.android.systemui.bubbles.storage.BubblePersistentRepository
 import com.android.systemui.bubbles.storage.BubbleVolatileRepository
-import com.android.systemui.bubbles.storage.BubbleXmlEntity
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.cancelAndJoin
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.yield
+
 import javax.inject.Inject
 import javax.inject.Singleton
 
 @Singleton
 internal class BubbleDataRepository @Inject constructor(
     private val volatileRepository: BubbleVolatileRepository,
-    private val persistentRepository: BubblePersistentRepository
+    private val persistentRepository: BubblePersistentRepository,
+    private val launcherApps: LauncherApps
 ) {
 
     private val ioScope = CoroutineScope(Dispatchers.IO)
@@ -64,10 +72,13 @@
         if (entities.isNotEmpty()) persistToDisk()
     }
 
-    private fun transform(userId: Int, bubbles: List<Bubble>): List<BubbleXmlEntity> {
+    private fun transform(userId: Int, bubbles: List<Bubble>): List<BubbleEntity> {
         return bubbles.mapNotNull { b ->
-            val shortcutId = b.shortcutInfo?.id ?: return@mapNotNull null
-            BubbleXmlEntity(userId, b.packageName, shortcutId)
+            var shortcutId = b.shortcutInfo?.id
+            if (shortcutId == null) shortcutId = b.entry?.bubbleMetadata?.shortcutId
+            if (shortcutId == null) shortcutId = b.entry?.ranking?.shortcutInfo?.id
+            if (shortcutId == null) return@mapNotNull null
+            BubbleEntity(userId, b.packageName, shortcutId)
         }
     }
 
@@ -100,15 +111,59 @@
     /**
      * Load bubbles from disk.
      */
+    @SuppressLint("WrongConstant")
     fun loadBubbles(cb: (List<Bubble>) -> Unit) = ioScope.launch {
-        val bubbleXmlEntities = persistentRepository.readFromDisk()
-        volatileRepository.addBubbles(bubbleXmlEntities)
-        uiScope.launch {
-            // TODO: transform bubbleXmlEntities into bubbles
-            // cb(bubbles)
-        }
+        /**
+         * Load BubbleEntity from disk.
+         * e.g.
+         * [
+         *     BubbleEntity(0, "com.example.messenger", "id-2"),
+         *     BubbleEntity(10, "com.example.chat", "my-id1")
+         *     BubbleEntity(0, "com.example.messenger", "id-1")
+         * ]
+         */
+        val entities = persistentRepository.readFromDisk()
+        volatileRepository.addBubbles(entities)
+        /**
+         * Extract userId/packageName from these entities.
+         * e.g.
+         * [
+         *     ShortcutKey(0, "com.example.messenger"), ShortcutKey(0, "com.example.chat")
+         * ]
+         */
+        val shortcutKeys = entities.map { ShortcutKey(it.userId, it.packageName) }.toSet()
+        /**
+         * Retrieve shortcuts with given userId/packageName combination, then construct a mapping
+         * between BubbleEntity and ShortcutInfo.
+         * e.g.
+         * {
+         *     BubbleEntity(0, "com.example.messenger", "id-0") ->
+         *         ShortcutInfo(userId=0, pkg="com.example.messenger", id="id-0"),
+         *     BubbleEntity(0, "com.example.messenger", "id-2") ->
+         *         ShortcutInfo(userId=0, pkg="com.example.messenger", id="id-2"),
+         *     BubbleEntity(10, "com.example.chat", "id-1") ->
+         *         ShortcutInfo(userId=10, pkg="com.example.chat", id="id-1"),
+         *     BubbleEntity(10, "com.example.chat", "id-3") ->
+         *         ShortcutInfo(userId=10, pkg="com.example.chat", id="id-3")
+         * }
+         */
+        val shortcutMap = shortcutKeys.flatMap { key ->
+            launcherApps.getShortcuts(
+                    LauncherApps.ShortcutQuery()
+                            .setPackage(key.pkg)
+                            .setQueryFlags(SHORTCUT_QUERY_FLAG), UserHandle.of(key.userId))
+                    ?.map { BubbleEntity(key.userId, key.pkg, it.id) to it } ?: emptyList()
+        }.toMap()
+        // For each entity loaded from xml, find the corresponding ShortcutInfo then convert them
+        // into Bubble.
+        val bubbles = entities.mapNotNull { entity -> shortcutMap[entity]?.let { Bubble(it) } }
+        uiScope.launch { cb(bubbles) }
     }
+
+    private data class ShortcutKey(val userId: Int, val pkg: String)
 }
 
 private const val TAG = "BubbleDataRepository"
 private const val DEBUG = false
+private const val SHORTCUT_QUERY_FLAG =
+        FLAG_MATCH_DYNAMIC or FLAG_MATCH_PINNED_BY_ANY_LAUNCHER or FLAG_MATCH_CACHED
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index baf92dc..0a1a0f7 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -65,7 +65,6 @@
 import com.android.systemui.R;
 import com.android.systemui.recents.TriangleShape;
 import com.android.systemui.statusbar.AlphaOptimizedButton;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 
 /**
  * Container for the expanded bubble view, handles rendering the caret and settings icon.
@@ -161,7 +160,7 @@
                             // the bubble again so we'll just remove it.
                             Log.w(TAG, "Exception while displaying bubble: " + getBubbleKey()
                                     + ", " + e.getMessage() + "; removing bubble");
-                            mBubbleController.removeBubble(getBubbleEntry(),
+                            mBubbleController.removeBubble(getBubbleKey(),
                                     BubbleController.DISMISS_INVALID_INTENT);
                         }
                     });
@@ -205,7 +204,7 @@
             }
             if (mBubble != null) {
                 // Must post because this is called from a binder thread.
-                post(() -> mBubbleController.removeBubble(mBubble.getEntry(),
+                post(() -> mBubbleController.removeBubble(mBubble.getKey(),
                         BubbleController.DISMISS_TASK_FINISHED));
             }
         }
@@ -292,10 +291,6 @@
         return mBubble != null ? mBubble.getKey() : "null";
     }
 
-    private NotificationEntry getBubbleEntry() {
-        return mBubble != null ? mBubble.getEntry() : null;
-    }
-
     void setManageClickListener(OnClickListener manageClickListener) {
         findViewById(R.id.settings_button).setOnClickListener(manageClickListener);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
index e96bef3..f4eb580 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflow.java
@@ -58,12 +58,13 @@
     public BubbleOverflow(Context context) {
         mContext = context;
         mInflater = LayoutInflater.from(context);
-        mBitmapSize = mContext.getResources().getDimensionPixelSize(R.dimen.bubble_bitmap_size);
-        mIconBitmapSize = mContext.getResources().getDimensionPixelSize(
-                R.dimen.bubble_overflow_icon_bitmap_size);
     }
 
     void setUpOverflow(ViewGroup parentViewGroup, BubbleStackView stackView) {
+        mBitmapSize = mContext.getResources().getDimensionPixelSize(R.dimen.bubble_bitmap_size);
+        mIconBitmapSize = mContext.getResources().getDimensionPixelSize(
+                R.dimen.bubble_overflow_icon_bitmap_size);
+
         mExpandedView = (BubbleExpandedView) mInflater.inflate(
                 R.layout.bubble_expanded_view, parentViewGroup /* root */,
                 false /* attachToRoot */);
@@ -74,6 +75,7 @@
     }
 
     void updateIcon(Context context, ViewGroup parentViewGroup) {
+        mContext = context;
         mInflater = LayoutInflater.from(context);
         mOverflowBtn = (BadgedImageView) mInflater.inflate(R.layout.bubble_overflow_button,
                 parentViewGroup /* root */,
@@ -87,7 +89,7 @@
         ta.recycle();
 
         TypedValue typedValue = new TypedValue();
-        context.getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
+        mContext.getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
         int colorAccent = mContext.getColor(typedValue.resourceId);
         mOverflowBtn.getDrawable().setTint(colorAccent);
         mDotColor = colorAccent;
@@ -97,7 +99,7 @@
                 mBitmapSize - mIconBitmapSize /* inset */);
         AdaptiveIconDrawable adaptiveIconDrawable = new AdaptiveIconDrawable(bg, fg);
 
-        BubbleIconFactory iconFactory = new BubbleIconFactory(context);
+        BubbleIconFactory iconFactory = new BubbleIconFactory(mContext);
         mIcon = iconFactory.createBadgedIconBitmap(adaptiveIconDrawable,
                 null /* user */,
                 true /* shrinkNonAdaptiveIcons */).icon;
@@ -106,7 +108,7 @@
                 null /* outBounds */, null /* path */, null /* outMaskShape */);
         float radius = DEFAULT_PATH_SIZE / 2f;
         mPath = PathParser.createPathFromPathData(
-                context.getResources().getString(com.android.internal.R.string.config_icon_mask));
+                mContext.getResources().getString(com.android.internal.R.string.config_icon_mask));
         Matrix matrix = new Matrix();
         matrix.setScale(scale /* x scale */, scale /* y scale */, radius /* pivot x */,
                 radius /* pivot y */);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
index 0074249..08ec789 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleOverflowActivity.java
@@ -41,6 +41,7 @@
 import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 
+import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.R;
 
 import java.util.ArrayList;
@@ -214,6 +215,8 @@
     @Override
     public BubbleOverflowAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
             int viewType) {
+
+        // Set layout for overflow bubble view.
         LinearLayout overflowView = (LinearLayout) LayoutInflater.from(parent.getContext())
                 .inflate(R.layout.bubble_overflow_view, parent, false);
         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
@@ -222,6 +225,18 @@
         params.width = mWidth;
         params.height = mHeight;
         overflowView.setLayoutParams(params);
+
+        // Ensure name has enough contrast.
+        final TypedArray ta = mContext.obtainStyledAttributes(
+                new int[]{android.R.attr.colorBackgroundFloating, android.R.attr.textColorPrimary});
+        final int bgColor = ta.getColor(0, Color.WHITE);
+        int textColor = ta.getColor(1, Color.BLACK);
+        textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, true);
+        ta.recycle();
+
+        TextView viewName = overflowView.findViewById(R.id.bubble_view_name);
+        viewName.setTextColor(textColor);
+
         return new ViewHolder(overflowView);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 2cb097f..e35b203 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -49,7 +49,6 @@
 import android.graphics.Region;
 import android.os.Bundle;
 import android.os.Vibrator;
-import android.service.notification.StatusBarNotification;
 import android.util.Log;
 import android.view.Choreographer;
 import android.view.DisplayCutout;
@@ -445,6 +444,10 @@
             final boolean clickedBubbleIsCurrentlyExpandedBubble =
                     clickedBubble.getKey().equals(mExpandedBubble.getKey());
 
+            if (isExpanded()) {
+                mExpandedAnimationController.onGestureFinished();
+            }
+
             if (isExpanded() && !clickedBubbleIsCurrentlyExpandedBubble) {
                 if (clickedBubble != mBubbleData.getSelectedBubble()) {
                     // Select the clicked bubble.
@@ -464,7 +467,6 @@
                     mBubbleData.setExpanded(!mBubbleData.isExpanded());
                 }
             }
-            mExpandedAnimationController.onGestureFinished();
         }
     };
 
@@ -787,8 +789,8 @@
 
         mOrientationChangedListener =
                 (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
-                    mExpandedAnimationController.updateOrientation(mOrientation, mDisplaySize);
-                    mStackAnimationController.updateOrientation(mOrientation);
+                    mExpandedAnimationController.updateResources(mOrientation, mDisplaySize);
+                    mStackAnimationController.updateResources(mOrientation);
 
                     // Reposition & adjust the height for new orientation
                     if (mIsExpanded) {
@@ -916,10 +918,10 @@
                     showManageMenu(false /* show */);
                     final Bubble bubble = mBubbleData.getSelectedBubble();
                     if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
-                        final Intent intent = bubble.getSettingsIntent();
+                        final Intent intent = bubble.getSettingsIntent(mContext);
                         collapseStack(() -> {
-                            mContext.startActivityAsUser(
-                                    intent, bubble.getEntry().getSbn().getUser());
+
+                            mContext.startActivityAsUser(intent, bubble.getUser());
                             logBubbleClickEvent(
                                     bubble,
                                     SysUiStatsLog.BUBBLE_UICHANGED__ACTION__HEADER_GO_TO_SETTINGS);
@@ -1004,7 +1006,7 @@
             mBubbleOverflow.setUpOverflow(mBubbleContainer, this);
         } else {
             mBubbleContainer.removeView(mBubbleOverflow.getBtn());
-            mBubbleOverflow.updateIcon(mContext, this);
+            mBubbleOverflow.updateIcon(mContext,this);
             overflowBtnIndex = mBubbleContainer.getChildCount();
         }
         mBubbleContainer.addView(mBubbleOverflow.getBtn(), overflowBtnIndex,
@@ -1051,10 +1053,33 @@
         mShowingManage = false;
     }
 
+    /** Respond to the display size change by recalculating view size and location. */
+    public void onDisplaySizeChanged() {
+        setUpOverflow();
+
+        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
+        wm.getDefaultDisplay().getRealSize(mDisplaySize);
+        Resources res = getContext().getResources();
+        mStatusBarHeight = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_height);
+        mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
+        mBubbleSize = getResources().getDimensionPixelSize(R.dimen.individual_bubble_size);
+        for (Bubble b : mBubbleData.getBubbles()) {
+            if (b.getIconView() == null) {
+                Log.d(TAG, "Display size changed. Icon null: " + b);
+                continue;
+            }
+            b.getIconView().setLayoutParams(new LayoutParams(mBubbleSize, mBubbleSize));
+        }
+        mExpandedAnimationController.updateResources(mOrientation, mDisplaySize);
+        mStackAnimationController.updateResources(mOrientation);
+    }
+
     @Override
     public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
         inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
 
+        mTempRect.setEmpty();
         getTouchableRegion(mTempRect);
         inoutInfo.touchableRegion.set(mTempRect);
     }
@@ -1153,13 +1178,19 @@
         for (int i = 0; i < mBubbleData.getBubbles().size(); i++) {
             final Bubble bubble = mBubbleData.getBubbles().get(i);
             final String appName = bubble.getAppName();
-            final Notification notification = bubble.getEntry().getSbn().getNotification();
-            final CharSequence titleCharSeq =
-                    notification.extras.getCharSequence(Notification.EXTRA_TITLE);
 
-            String titleStr = getResources().getString(R.string.notification_bubble_title);
+            final CharSequence titleCharSeq;
+            if (bubble.getEntry() == null) {
+                titleCharSeq = null;
+            } else {
+                titleCharSeq = bubble.getEntry().getSbn().getNotification().extras.getCharSequence(
+                        Notification.EXTRA_TITLE);
+            }
+            final String titleStr;
             if (titleCharSeq != null) {
                 titleStr = titleCharSeq.toString();
+            } else {
+                titleStr = getResources().getString(R.string.notification_bubble_title);
             }
 
             if (bubble.getIconView() != null) {
@@ -1290,7 +1321,7 @@
         Log.d(TAG, "was asked to remove Bubble, but didn't find the view! " + bubble);
     }
 
-    private void updateOverflowBtnVisibility(boolean apply) {
+    private void updateOverflowBtnVisibility() {
         if (!BubbleExperimentConfig.allowBubbleOverflow(mContext)) {
             return;
         }
@@ -1299,11 +1330,6 @@
                 Log.d(TAG, "Show overflow button.");
             }
             mBubbleOverflow.setBtnVisible(VISIBLE);
-            if (apply) {
-                mExpandedAnimationController.expandFromStack(() -> {
-                    updatePointerPosition();
-                } /* after */);
-            }
         } else {
             if (DEBUG_BUBBLE_STACK_VIEW) {
                 Log.d(TAG, "Collapsed. Hide overflow button.");
@@ -1563,7 +1589,7 @@
             Log.d(TAG, BubbleDebugConfig.formatBubblesString(getBubblesOnScreen(),
                     mExpandedBubble));
         }
-        updateOverflowBtnVisibility(/* apply */ false);
+        updateOverflowBtnVisibility();
         mBubbleContainer.cancelAllAnimations();
         mExpandedAnimationController.collapseBackToStack(
                 mStackAnimationController.getStackPositionAlongNearestHorizontalEdge()
@@ -1587,7 +1613,7 @@
         beforeExpandedViewAnimation();
 
         mBubbleContainer.setActiveController(mExpandedAnimationController);
-        updateOverflowBtnVisibility(/* apply */ false);
+        updateOverflowBtnVisibility();
         mExpandedAnimationController.expandFromStack(() -> {
             updatePointerPosition();
             afterExpandedViewAnimation();
@@ -1777,7 +1803,7 @@
     private void dismissBubbleIfExists(@Nullable Bubble bubble) {
         if (bubble != null && mBubbleData.hasBubbleInStackWithKey(bubble.getKey())) {
             mBubbleData.notificationEntryRemoved(
-                    bubble.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                    bubble.getKey(), BubbleController.DISMISS_USER_GESTURE);
         }
     }
 
@@ -2275,18 +2301,12 @@
      * @param action the user interaction enum.
      */
     private void logBubbleClickEvent(Bubble bubble, int action) {
-        StatusBarNotification notification = bubble.getEntry().getSbn();
-        SysUiStatsLog.write(SysUiStatsLog.BUBBLE_UI_CHANGED,
-                notification.getPackageName(),
-                notification.getNotification().getChannelId(),
-                notification.getId(),
-                getBubbleIndex(getExpandedBubble()),
+        bubble.logUIEvent(
                 getBubbleCount(),
                 action,
                 getNormalizedXPosition(),
                 getNormalizedYPosition(),
-                bubble.showInShade(),
-                bubble.isOngoing(),
-                false /* isAppForeground (unused) */);
+                getBubbleIndex(getExpandedBubble())
+        );
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
index 8a57a73..525d5b5 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleViewInfoTask.java
@@ -37,6 +37,7 @@
 import android.graphics.drawable.Icon;
 import android.os.AsyncTask;
 import android.os.Parcelable;
+import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
 import android.util.Log;
@@ -74,6 +75,7 @@
     private WeakReference<Context> mContext;
     private WeakReference<BubbleStackView> mStackView;
     private BubbleIconFactory mIconFactory;
+    private boolean mSkipInflation;
     private Callback mCallback;
 
     /**
@@ -84,17 +86,20 @@
             Context context,
             BubbleStackView stackView,
             BubbleIconFactory factory,
+            boolean skipInflation,
             Callback c) {
         mBubble = b;
         mContext = new WeakReference<>(context);
         mStackView = new WeakReference<>(stackView);
         mIconFactory = factory;
+        mSkipInflation = skipInflation;
         mCallback = c;
     }
 
     @Override
     protected BubbleViewInfo doInBackground(Void... voids) {
-        return BubbleViewInfo.populate(mContext.get(), mStackView.get(), mIconFactory, mBubble);
+        return BubbleViewInfo.populate(mContext.get(), mStackView.get(), mIconFactory, mBubble,
+                mSkipInflation);
     }
 
     @Override
@@ -123,11 +128,36 @@
 
         @Nullable
         static BubbleViewInfo populate(Context c, BubbleStackView stackView,
-                BubbleIconFactory iconFactory, Bubble b) {
+                BubbleIconFactory iconFactory, Bubble b, boolean skipInflation) {
+            final NotificationEntry entry = b.getEntry();
+            if (entry == null) {
+                // populate from ShortcutInfo when NotificationEntry is not available
+                final ShortcutInfo s = b.getShortcutInfo();
+                return populate(c, stackView, iconFactory, skipInflation || b.isInflated(),
+                        s.getPackage(), s.getUserHandle(), s, null);
+            }
+            final StatusBarNotification sbn = entry.getSbn();
+            final String bubbleShortcutId =  entry.getBubbleMetadata().getShortcutId();
+            final ShortcutInfo si = bubbleShortcutId == null
+                    ? null : entry.getRanking().getShortcutInfo();
+            return populate(
+                    c, stackView, iconFactory, skipInflation || b.isInflated(),
+                    sbn.getPackageName(), sbn.getUser(), si, entry);
+        }
+
+        private static BubbleViewInfo populate(
+                @NonNull final Context c,
+                @NonNull final BubbleStackView stackView,
+                @NonNull final BubbleIconFactory iconFactory,
+                final boolean isInflated,
+                @NonNull final String packageName,
+                @NonNull final UserHandle user,
+                @Nullable final ShortcutInfo shortcutInfo,
+                @Nullable final NotificationEntry entry) {
             BubbleViewInfo info = new BubbleViewInfo();
 
             // View inflation: only should do this once per bubble
-            if (!b.isInflated()) {
+            if (!isInflated) {
                 LayoutInflater inflater = LayoutInflater.from(c);
                 info.imageView = (BadgedImageView) inflater.inflate(
                         R.layout.bubble_view, stackView, false /* attachToRoot */);
@@ -137,12 +167,8 @@
                 info.expandedView.setStackView(stackView);
             }
 
-            StatusBarNotification sbn = b.getEntry().getSbn();
-            String packageName = sbn.getPackageName();
-
-            String bubbleShortcutId =  b.getEntry().getBubbleMetadata().getShortcutId();
-            if (bubbleShortcutId != null) {
-                info.shortcutInfo = b.getEntry().getRanking().getShortcutInfo();
+            if (shortcutInfo != null) {
+                info.shortcutInfo = shortcutInfo;
             }
 
             // App name & app icon
@@ -161,7 +187,7 @@
                     info.appName = String.valueOf(pm.getApplicationLabel(appInfo));
                 }
                 appIcon = pm.getApplicationIcon(packageName);
-                badgedIcon = pm.getUserBadgedIcon(appIcon, sbn.getUser());
+                badgedIcon = pm.getUserBadgedIcon(appIcon, user);
             } catch (PackageManager.NameNotFoundException exception) {
                 // If we can't find package... don't think we should show the bubble.
                 Log.w(TAG, "Unable to find package: " + packageName);
@@ -170,7 +196,7 @@
 
             // Badged bubble image
             Drawable bubbleDrawable = iconFactory.getBubbleDrawable(c, info.shortcutInfo,
-                    b.getEntry().getBubbleMetadata());
+                    entry == null ? null : entry.getBubbleMetadata());
             if (bubbleDrawable == null) {
                 // Default to app icon
                 bubbleDrawable = appIcon;
@@ -196,7 +222,9 @@
                     Color.WHITE, WHITE_SCRIM_ALPHA);
 
             // Flyout
-            info.flyoutMessage = extractFlyoutMessage(c, b.getEntry());
+            if (entry != null) {
+                info.flyoutMessage = extractFlyoutMessage(c, entry);
+            }
             return info;
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
index 35406c7..f57cf42 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -118,7 +118,7 @@
 
     public ExpandedAnimationController(Point displaySize, int expandedViewPadding,
             int orientation) {
-        updateOrientation(orientation, displaySize);
+        updateResources(orientation, displaySize);
         mExpandedViewPadding = expandedViewPadding;
     }
 
@@ -168,7 +168,7 @@
      * @param orientation Landscape or portrait.
      * @param displaySize Updated display size.
      */
-    public void updateOrientation(int orientation, Point displaySize) {
+    public void updateResources(int orientation, Point displaySize) {
         mScreenOrientation = orientation;
         mDisplaySize = displaySize;
         if (mLayout != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
index 5f3a2bd..2cfe1dd 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
@@ -809,7 +809,7 @@
      * Update effective screen width based on current orientation.
      * @param orientation Landscape or portrait.
      */
-    public void updateOrientation(int orientation) {
+    public void updateResources(int orientation) {
         if (mLayout != null) {
             Resources res = mLayout.getContext().getResources();
             mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlEntity.kt b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlEntity.kt
rename to packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
index d0f7607..4690a8e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlEntity.kt
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleEntity.kt
@@ -17,7 +17,7 @@
 
 import android.annotation.UserIdInt
 
-data class BubbleXmlEntity(
+data class BubbleEntity(
     @UserIdInt val userId: Int,
     val packageName: String,
     val shortcutId: String
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubblePersistentRepository.kt b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubblePersistentRepository.kt
index 149e2c4..7c3271e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubblePersistentRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubblePersistentRepository.kt
@@ -32,7 +32,7 @@
     private val bubbleFile: AtomicFile = AtomicFile(File(context.filesDir,
             "overflow_bubbles.xml"), "overflow-bubbles")
 
-    fun persistsToDisk(bubbles: List<BubbleXmlEntity>): Boolean {
+    fun persistsToDisk(bubbles: List<BubbleEntity>): Boolean {
         if (DEBUG) Log.d(TAG, "persisting ${bubbles.size} bubbles")
         synchronized(bubbleFile) {
             val stream: FileOutputStream = try { bubbleFile.startWrite() } catch (e: IOException) {
@@ -52,7 +52,7 @@
         return false
     }
 
-    fun readFromDisk(): List<BubbleXmlEntity> {
+    fun readFromDisk(): List<BubbleEntity> {
         synchronized(bubbleFile) {
             try { return bubbleFile.openRead().use(::readXml) } catch (e: Throwable) {
                 Log.e(TAG, "Failed to open bubble file", e)
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt
index e1f675b..d1eee2f6 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleVolatileRepository.kt
@@ -29,12 +29,12 @@
     /**
      * An ordered set of bubbles based on their natural ordering.
      */
-    private val entities = mutableSetOf<BubbleXmlEntity>()
+    private val entities = mutableSetOf<BubbleEntity>()
 
     /**
      * Returns a snapshot of all the bubbles.
      */
-    val bubbles: List<BubbleXmlEntity>
+    val bubbles: List<BubbleEntity>
         @Synchronized
         get() = entities.toList()
 
@@ -43,7 +43,7 @@
      * it will be moved to the last.
      */
     @Synchronized
-    fun addBubbles(bubbles: List<BubbleXmlEntity>) {
+    fun addBubbles(bubbles: List<BubbleEntity>) {
         if (bubbles.isEmpty()) return
         bubbles.forEach { entities.remove(it) }
         if (entities.size + bubbles.size >= CAPACITY) {
@@ -53,7 +53,7 @@
     }
 
     @Synchronized
-    fun removeBubbles(bubbles: List<BubbleXmlEntity>) {
+    fun removeBubbles(bubbles: List<BubbleEntity>) {
         bubbles.forEach { entities.remove(it) }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt
index 1e91653..821b64c 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlHelper.kt
@@ -35,7 +35,7 @@
  * Writes the bubbles in xml format into given output stream.
  */
 @Throws(IOException::class)
-fun writeXml(stream: OutputStream, bubbles: List<BubbleXmlEntity>) {
+fun writeXml(stream: OutputStream, bubbles: List<BubbleEntity>) {
     val serializer: XmlSerializer = FastXmlSerializer()
     serializer.setOutput(stream, StandardCharsets.UTF_8.name())
     serializer.startDocument(null, true)
@@ -51,7 +51,7 @@
  * <bb uid="0" pkg="com.example.messenger" sid="my-shortcut" />
  * ```
  */
-private fun writeXmlEntry(serializer: XmlSerializer, bubble: BubbleXmlEntity) {
+private fun writeXmlEntry(serializer: XmlSerializer, bubble: BubbleEntity) {
     try {
         serializer.startTag(null, TAG_BUBBLE)
         serializer.attribute(null, ATTR_USER_ID, bubble.userId.toString())
@@ -66,8 +66,8 @@
 /**
  * Reads the bubbles from xml file.
  */
-fun readXml(stream: InputStream): List<BubbleXmlEntity> {
-    val bubbles = mutableListOf<BubbleXmlEntity>()
+fun readXml(stream: InputStream): List<BubbleEntity> {
+    val bubbles = mutableListOf<BubbleEntity>()
     val parser: XmlPullParser = Xml.newPullParser()
     parser.setInput(stream, StandardCharsets.UTF_8.name())
     XmlUtils.beginDocument(parser, TAG_BUBBLES)
@@ -78,9 +78,9 @@
     return bubbles
 }
 
-private fun readXmlEntry(parser: XmlPullParser): BubbleXmlEntity? {
+private fun readXmlEntry(parser: XmlPullParser): BubbleEntity? {
     while (parser.eventType != XmlPullParser.START_TAG) { parser.next() }
-    return BubbleXmlEntity(
+    return BubbleEntity(
             parser.getAttributeWithName(ATTR_USER_ID)?.toInt() ?: return null,
             parser.getAttributeWithName(ATTR_PACKAGE) ?: return null,
             parser.getAttributeWithName(ATTR_SHORTCUT_ID) ?: return null
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 79dd9ed..4b283d6 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -23,9 +23,14 @@
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.view.accessibility.AccessibilityNodeInfo
 import android.widget.CheckBox
 import android.widget.ImageView
+import android.widget.Switch
 import android.widget.TextView
+import androidx.core.view.AccessibilityDelegateCompat
+import androidx.core.view.ViewCompat
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.RecyclerView
 import com.android.systemui.R
@@ -72,7 +77,8 @@
                         elevation = this@ControlAdapter.elevation
                         background = parent.context.getDrawable(
                                 R.drawable.control_background_ripple)
-                    }
+                    },
+                    model is FavoritesModel // Indicates that position information is needed
                 ) { id, favorite ->
                     model?.changeFavoriteStatus(id, favorite)
                 }
@@ -175,8 +181,14 @@
  */
 internal class ControlHolder(
     view: View,
+    val withPosition: Boolean,
     val favoriteCallback: ModelFavoriteChanger
 ) : Holder(view) {
+    private val favoriteStateDescription =
+        itemView.context.getString(R.string.accessibility_control_favorite)
+    private val notFavoriteStateDescription =
+        itemView.context.getString(R.string.accessibility_control_not_favorite)
+
     private val icon: ImageView = itemView.requireViewById(R.id.icon)
     private val title: TextView = itemView.requireViewById(R.id.title)
     private val subtitle: TextView = itemView.requireViewById(R.id.subtitle)
@@ -185,15 +197,38 @@
         visibility = View.VISIBLE
     }
 
+    private val accessibilityDelegate = ControlHolderAccessibilityDelegate(this::stateDescription)
+
+    init {
+        ViewCompat.setAccessibilityDelegate(itemView, accessibilityDelegate)
+    }
+
+    // Determine the stateDescription based on favorite state and maybe position
+    private fun stateDescription(favorite: Boolean): CharSequence? {
+        if (!favorite) {
+            return notFavoriteStateDescription
+        } else if (!withPosition) {
+            return favoriteStateDescription
+        } else {
+            val position = layoutPosition + 1
+            return itemView.context.getString(
+                R.string.accessibility_control_favorite_position, position)
+        }
+    }
+
     override fun bindData(wrapper: ElementWrapper) {
         wrapper as ControlInterface
         val renderInfo = getRenderInfo(wrapper.component, wrapper.deviceType)
         title.text = wrapper.title
         subtitle.text = wrapper.subtitle
-        favorite.isChecked = wrapper.favorite
-        removed.text = if (wrapper.removed) "Removed" else ""
+        updateFavorite(wrapper.favorite)
+        removed.text = if (wrapper.removed) {
+            itemView.context.getText(R.string.controls_removed)
+        } else {
+            ""
+        }
         itemView.setOnClickListener {
-            favorite.isChecked = !favorite.isChecked
+            updateFavorite(!favorite.isChecked)
             favoriteCallback(wrapper.controlId, favorite.isChecked)
         }
         applyRenderInfo(renderInfo)
@@ -201,6 +236,8 @@
 
     override fun updateFavorite(favorite: Boolean) {
         this.favorite.isChecked = favorite
+        accessibilityDelegate.isFavorite = favorite
+        itemView.stateDescription = stateDescription(favorite)
     }
 
     private fun getRenderInfo(
@@ -219,6 +256,36 @@
     }
 }
 
+private class ControlHolderAccessibilityDelegate(
+    val stateRetriever: (Boolean) -> CharSequence?
+) : AccessibilityDelegateCompat() {
+
+    var isFavorite = false
+
+    override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) {
+        super.onInitializeAccessibilityNodeInfo(host, info)
+
+        // Change the text for the double-tap action
+        val clickActionString = if (isFavorite) {
+            host.context.getString(R.string.accessibility_control_change_unfavorite)
+        } else {
+            host.context.getString(R.string.accessibility_control_change_favorite)
+        }
+        val click = AccessibilityNodeInfoCompat.AccessibilityActionCompat(
+            AccessibilityNodeInfo.ACTION_CLICK,
+            // “favorite/unfavorite”
+            clickActionString)
+        info.addAction(click)
+
+        // Determine the stateDescription based on the holder information
+        info.stateDescription = stateRetriever(isFavorite)
+        // Remove the information at the end indicating row and column.
+        info.setCollectionItemInfo(null)
+
+        info.className = Switch::class.java.name
+    }
+}
+
 class MarginItemDecorator(
     private val topMargin: Int,
     private val sideMargins: Int
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
index 4e9c550..ff40a8a 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
@@ -130,6 +130,7 @@
             inflate()
         }
         requireViewById<TextView>(R.id.title).text = structure
+        setTitle(structure)
         subtitle = requireViewById<TextView>(R.id.subtitle).apply {
             setText(SUBTITLE_ID)
         }
@@ -191,7 +192,18 @@
 
         recyclerView.apply {
             this.adapter = adapter
-            layoutManager = GridLayoutManager(recyclerView.context, 2).apply {
+            layoutManager = object : GridLayoutManager(recyclerView.context, 2) {
+
+                // This will remove from the announcement the row corresponding to the divider,
+                // as it's not something that should be announced.
+                override fun getRowCountForAccessibility(
+                    recycler: RecyclerView.Recycler,
+                    state: RecyclerView.State
+                ): Int {
+                    val initial = super.getRowCountForAccessibility(recycler, state)
+                    return if (initial > 0) initial - 1 else initial
+                }
+            }.apply {
                 spanSizeLookup = adapter.spanSizeLookup
             }
             addItemDecoration(itemDecorator)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
index eb15262..496b21b6 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
@@ -208,7 +208,7 @@
                     val name = listOfStructures[position].structureName
                     val title = if (!TextUtils.isEmpty(name)) name else appName
                     titleView.text = title
-                    setTitle(title)
+                    titleView.requestFocus()
                 }
 
                 override fun onPageScrolled(
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
index 48f191d..a2adcf9 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
@@ -106,9 +106,15 @@
 
     override fun changeUser(newUser: UserHandle) {
         backgroundExecutor.execute {
-            callbacks.clear()
-            availableServices = emptyList()
             serviceListing.setListening(false)
+
+            // Notify all callbacks in order to clear their existing state prior to attaching
+            // a new listener
+            availableServices = emptyList()
+            callbacks.forEach {
+                it.onServicesUpdated(emptyList())
+            }
+
             currentUserId = newUser.identifier
             val contextForUser = context.createContextAsUser(newUser, 0)
             serviceListing = serviceListingBuilder(contextForUser)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
index 275c778..842c39b 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
@@ -30,6 +30,9 @@
 
     /**
      * Will be invoked on every update provided to the Control
+     *
+     * @param cws ControlWithState, as loaded from favorites and/or the application
+     * @param colorOffset An additional flag to control rendering color. See [RenderInfo]
      */
-    fun bind(cws: ControlWithState)
+    fun bind(cws: ControlWithState, colorOffset: Int = 0)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
index 1f07e37..6c28d11 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
@@ -50,7 +50,8 @@
     fun createPinDialog(
         cvh: ControlViewHolder,
         useAlphaNumeric: Boolean,
-        useRetryStrings: Boolean
+        useRetryStrings: Boolean,
+        onCancel: () -> Unit
     ): Dialog? {
         val lastAction = cvh.lastAction
         if (lastAction == null) {
@@ -86,7 +87,10 @@
             })
             setNegativeButton(
                 android.R.string.cancel,
-                DialogInterface.OnClickListener { dialog, _ -> dialog.cancel() }
+                DialogInterface.OnClickListener { dialog, _ ->
+                    onCancel.invoke()
+                    dialog.cancel()
+                }
             )
         }
         return builder.create().apply {
@@ -111,7 +115,7 @@
     /**
      * AlertDialogs to handle [ControlAction#RESPONSE_CHALLENGE_ACK] response type.
      */
-    fun createConfirmationDialog(cvh: ControlViewHolder): Dialog? {
+    fun createConfirmationDialog(cvh: ControlViewHolder, onCancel: () -> Unit): Dialog? {
         val lastAction = cvh.lastAction
         if (lastAction == null) {
             Log.e(ControlsUiController.TAG,
@@ -120,7 +124,7 @@
         }
         val builder = AlertDialog.Builder(cvh.context, STYLE).apply {
             val res = cvh.context.resources
-            setMessage(res.getString(
+            setTitle(res.getString(
                 R.string.controls_confirmation_message, cvh.title.getText()))
             setPositiveButton(
                 android.R.string.ok,
@@ -130,7 +134,10 @@
             })
             setNegativeButton(
                 android.R.string.cancel,
-                DialogInterface.OnClickListener { dialog, _ -> dialog.cancel() }
+                DialogInterface.OnClickListener { dialog, _ ->
+                    onCancel.invoke()
+                    dialog.cancel()
+                }
             )
         }
         return builder.create().apply {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
index 2653ce0..17e4234 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
@@ -28,6 +28,7 @@
 import android.service.controls.DeviceTypes
 import android.service.controls.actions.ControlAction
 import android.service.controls.templates.ControlTemplate
+import android.service.controls.templates.RangeTemplate
 import android.service.controls.templates.StatelessTemplate
 import android.service.controls.templates.TemperatureControlTemplate
 import android.service.controls.templates.ToggleRangeTemplate
@@ -69,6 +70,25 @@
 
         const val MIN_LEVEL = 0
         const val MAX_LEVEL = 10000
+
+        fun findBehaviorClass(
+            status: Int,
+            template: ControlTemplate,
+            deviceType: Int
+        ): KClass<out Behavior> {
+            return when {
+                status == Control.STATUS_UNKNOWN -> StatusBehavior::class
+                status == Control.STATUS_ERROR -> StatusBehavior::class
+                status == Control.STATUS_NOT_FOUND -> StatusBehavior::class
+                deviceType == DeviceTypes.TYPE_CAMERA -> TouchBehavior::class
+                template is ToggleTemplate -> ToggleBehavior::class
+                template is StatelessTemplate -> TouchBehavior::class
+                template is ToggleRangeTemplate -> ToggleRangeBehavior::class
+                template is RangeTemplate -> ToggleRangeBehavior::class
+                template is TemperatureControlTemplate -> TemperatureControlBehavior::class
+                else -> DefaultBehavior::class
+            }
+        }
     }
 
     private val toggleBackgroundIntensity: Float = layout.context.resources
@@ -86,6 +106,7 @@
     var behavior: Behavior? = null
     var lastAction: ControlAction? = null
     private var lastChallengeDialog: Dialog? = null
+    private val onDialogCancel: () -> Unit = { lastChallengeDialog = null }
 
     val deviceType: Int
         get() = cws.control?.let { it.getDeviceType() } ?: cws.ci.deviceType
@@ -123,20 +144,8 @@
             })
         }
 
-        val clazz = findBehavior(controlStatus, template, deviceType)
-        if (behavior == null || behavior!!::class != clazz) {
-            // Behavior changes can signal a change in template from the app or
-            // first time setup
-            behavior = clazz.java.newInstance()
-            behavior?.initialize(this)
-
-            // let behaviors define their own, if necessary, and clear any existing ones
-            layout.setAccessibilityDelegate(null)
-        }
-
-        behavior?.bind(cws)
-
-        layout.setContentDescription("${title.text} ${subtitle.text} ${status.text}")
+        behavior = bindBehavior(behavior, findBehaviorClass(controlStatus, template, deviceType))
+        updateContentDescription()
     }
 
     fun actionResponse(@ControlAction.ResponseResult response: Int) {
@@ -154,15 +163,18 @@
                 setTransientStatus(context.resources.getString(R.string.controls_error_failed))
             }
             ControlAction.RESPONSE_CHALLENGE_PIN -> {
-                lastChallengeDialog = ChallengeDialogs.createPinDialog(this, false, failedAttempt)
+                lastChallengeDialog = ChallengeDialogs.createPinDialog(
+                    this, false, failedAttempt, onDialogCancel)
                 lastChallengeDialog?.show()
             }
             ControlAction.RESPONSE_CHALLENGE_PASSPHRASE -> {
-                lastChallengeDialog = ChallengeDialogs.createPinDialog(this, true, failedAttempt)
+                lastChallengeDialog = ChallengeDialogs.createPinDialog(
+                    this, false, failedAttempt, onDialogCancel)
                 lastChallengeDialog?.show()
             }
             ControlAction.RESPONSE_CHALLENGE_ACK -> {
-                lastChallengeDialog = ChallengeDialogs.createConfirmationDialog(this)
+                lastChallengeDialog = ChallengeDialogs.createConfirmationDialog(
+                    this, onDialogCancel)
                 lastChallengeDialog?.show()
             }
         }
@@ -178,11 +190,16 @@
 
         cancelUpdate = uiExecutor.executeDelayed({
                 status.setText(previousText)
+                updateContentDescription()
             }, UPDATE_DELAY_IN_MILLIS)
 
         status.setText(tempStatus)
+        updateContentDescription()
     }
 
+    private fun updateContentDescription() =
+        layout.setContentDescription("${title.text} ${subtitle.text} ${status.text}")
+
     fun action(action: ControlAction) {
         lastAction = action
         controlsController.action(cws.componentName, cws.ci, action)
@@ -190,25 +207,30 @@
 
     fun usePanel(): Boolean = deviceType in ControlViewHolder.FORCE_PANEL_DEVICES
 
-    private fun findBehavior(
-        status: Int,
-        template: ControlTemplate,
-        deviceType: Int
-    ): KClass<out Behavior> {
-        return when {
-            status == Control.STATUS_UNKNOWN -> StatusBehavior::class
-            status == Control.STATUS_ERROR -> StatusBehavior::class
-            status == Control.STATUS_NOT_FOUND -> StatusBehavior::class
-            deviceType == DeviceTypes.TYPE_CAMERA -> TouchBehavior::class
-            template is ToggleTemplate -> ToggleBehavior::class
-            template is StatelessTemplate -> TouchBehavior::class
-            template is ToggleRangeTemplate -> ToggleRangeBehavior::class
-            template is TemperatureControlTemplate -> TemperatureControlBehavior::class
-            else -> DefaultBehavior::class
+    fun bindBehavior(
+        existingBehavior: Behavior?,
+        clazz: KClass<out Behavior>,
+        offset: Int = 0
+    ): Behavior {
+        val behavior = if (existingBehavior == null || existingBehavior!!::class != clazz) {
+            // Behavior changes can signal a change in template from the app or
+            // first time setup
+            val newBehavior = clazz.java.newInstance()
+            newBehavior.initialize(this)
+
+            // let behaviors define their own, if necessary, and clear any existing ones
+            layout.setAccessibilityDelegate(null)
+            newBehavior
+        } else {
+            existingBehavior
+        }
+
+        return behavior.also {
+            it.bind(cws, offset)
         }
     }
 
-    internal fun applyRenderInfo(enabled: Boolean, offset: Int = 0, animated: Boolean = true) {
+    internal fun applyRenderInfo(enabled: Boolean, offset: Int, animated: Boolean = true) {
         setEnabled(enabled)
 
         val ri = RenderInfo.lookup(context, cws.componentName, deviceType, enabled, offset)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DefaultBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DefaultBehavior.kt
index e850a6a..722ade9 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DefaultBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DefaultBehavior.kt
@@ -23,8 +23,8 @@
         this.cvh = cvh
     }
 
-    override fun bind(cws: ControlWithState) {
+    override fun bind(cws: ControlWithState, colorOffset: Int) {
         cvh.status.setText(cws.control?.getStatusText() ?: "")
-        cvh.applyRenderInfo(false)
+        cvh.applyRenderInfo(false, colorOffset)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
index 49c4408..d8dceba 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
@@ -27,7 +27,7 @@
         this.cvh = cvh
     }
 
-    override fun bind(cws: ControlWithState) {
+    override fun bind(cws: ControlWithState, colorOffset: Int) {
         val status = cws.control?.status ?: Control.STATUS_UNKNOWN
         val msg = when (status) {
             Control.STATUS_ERROR -> R.string.controls_error_generic
@@ -35,6 +35,6 @@
             else -> com.android.internal.R.string.loading
         }
         cvh.status.setText(cvh.context.getString(msg))
-        cvh.applyRenderInfo(false)
+        cvh.applyRenderInfo(false, colorOffset)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
index b4d0e63..2795c7a 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
@@ -19,6 +19,7 @@
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.LayerDrawable
 import android.service.controls.Control
+import android.service.controls.templates.ControlTemplate
 import android.service.controls.templates.TemperatureControlTemplate
 
 import com.android.systemui.R
@@ -29,17 +30,13 @@
     lateinit var clipLayer: Drawable
     lateinit var control: Control
     lateinit var cvh: ControlViewHolder
-    lateinit var template: TemperatureControlTemplate
+    var subBehavior: Behavior? = null
 
     override fun initialize(cvh: ControlViewHolder) {
         this.cvh = cvh
-
-        cvh.layout.setOnClickListener { _ ->
-            cvh.controlActionCoordinator.touch(cvh, template.getTemplateId(), control)
-        }
     }
 
-    override fun bind(cws: ControlWithState) {
+    override fun bind(cws: ControlWithState, colorOffset: Int) {
         this.control = cws.control!!
 
         cvh.status.setText(control.getStatusText())
@@ -47,11 +44,32 @@
         val ld = cvh.layout.getBackground() as LayerDrawable
         clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
 
-        template = control.getControlTemplate() as TemperatureControlTemplate
-
+        val template = control.getControlTemplate() as TemperatureControlTemplate
         val activeMode = template.getCurrentActiveMode()
-        val enabled = activeMode != 0 && activeMode != TemperatureControlTemplate.MODE_OFF
-        clipLayer.setLevel(if (enabled) MAX_LEVEL else MIN_LEVEL)
-        cvh.applyRenderInfo(enabled, activeMode)
+        val subTemplate = template.getTemplate()
+        if (subTemplate == ControlTemplate.getNoTemplateObject() ||
+            subTemplate == ControlTemplate.getErrorTemplate()) {
+            // No sub template is specified, apply a default look with basic touch interaction.
+            // Treat an error as no template.
+            val enabled = activeMode != 0 && activeMode != TemperatureControlTemplate.MODE_OFF
+            clipLayer.setLevel(if (enabled) MAX_LEVEL else MIN_LEVEL)
+            cvh.applyRenderInfo(enabled, activeMode)
+
+            cvh.layout.setOnClickListener { _ ->
+                cvh.controlActionCoordinator.touch(cvh, template.getTemplateId(), control)
+            }
+        } else {
+            // A sub template has been specified, use this as the default behavior for user
+            // interactions (touch, range)
+            subBehavior = cvh.bindBehavior(
+                subBehavior,
+                ControlViewHolder.findBehaviorClass(
+                    control.status,
+                    subTemplate,
+                    control.deviceType
+                ),
+                activeMode
+            )
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
index 3e16698..c432c09 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
@@ -19,7 +19,9 @@
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.LayerDrawable
 import android.service.controls.Control
+import android.service.controls.templates.TemperatureControlTemplate
 import android.service.controls.templates.ToggleTemplate
+import android.util.Log
 import android.view.View
 import com.android.systemui.R
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MAX_LEVEL
@@ -39,17 +41,25 @@
         })
     }
 
-    override fun bind(cws: ControlWithState) {
+    override fun bind(cws: ControlWithState, colorOffset: Int) {
         this.control = cws.control!!
 
         cvh.status.setText(control.getStatusText())
-        template = control.getControlTemplate() as ToggleTemplate
+        val controlTemplate = control.getControlTemplate()
+        template = when (controlTemplate) {
+            is ToggleTemplate -> controlTemplate
+            is TemperatureControlTemplate -> controlTemplate.getTemplate() as ToggleTemplate
+            else -> {
+                Log.e(ControlsUiController.TAG, "Unsupported template type: $controlTemplate")
+                return
+            }
+        }
 
         val ld = cvh.layout.getBackground() as LayerDrawable
         clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
         clipLayer.level = MAX_LEVEL
 
         val checked = template.isChecked()
-        cvh.applyRenderInfo(checked)
+        cvh.applyRenderInfo(checked, colorOffset)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
index 3dc0ff3..a09ed09 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
@@ -25,7 +25,9 @@
 import android.os.Bundle
 import android.service.controls.Control
 import android.service.controls.actions.FloatAction
+import android.service.controls.templates.ControlTemplate
 import android.service.controls.templates.RangeTemplate
+import android.service.controls.templates.TemperatureControlTemplate
 import android.service.controls.templates.ToggleRangeTemplate
 import android.util.Log
 import android.util.MathUtils
@@ -44,10 +46,14 @@
 import com.android.systemui.controls.ui.ControlViewHolder.Companion.MIN_LEVEL
 import java.util.IllegalFormatException
 
+/**
+ * Supports [ToggleRangeTemplate] and [RangeTemplate], as well as when one of those templates is
+ * defined as the subtemplate in [TemperatureControlTemplate].
+ */
 class ToggleRangeBehavior : Behavior {
     private var rangeAnimator: ValueAnimator? = null
     lateinit var clipLayer: Drawable
-    lateinit var template: ToggleRangeTemplate
+    lateinit var templateId: String
     lateinit var control: Control
     lateinit var cvh: ControlViewHolder
     lateinit var rangeTemplate: RangeTemplate
@@ -55,6 +61,9 @@
     lateinit var context: Context
     var currentStatusText: CharSequence = ""
     var currentRangeValue: String = ""
+    var isChecked: Boolean = false
+    var isToggleable: Boolean = false
+    var colorOffset: Int = 0
 
     companion object {
         private const val DEFAULT_FORMAT = "%.1f"
@@ -65,7 +74,7 @@
         status = cvh.status
         context = status.getContext()
 
-        cvh.applyRenderInfo(false /* enabled */, 0 /* offset */, false /* animated */)
+        cvh.applyRenderInfo(false /* enabled */, colorOffset, false /* animated */)
 
         val gestureListener = ToggleRangeGestureListener(cvh.layout)
         val gestureDetector = GestureDetector(context, gestureListener)
@@ -86,8 +95,40 @@
         }
     }
 
-    override fun bind(cws: ControlWithState) {
+    private fun setup(template: ToggleRangeTemplate) {
+        rangeTemplate = template.getRange()
+        isToggleable = true
+        isChecked = template.isChecked()
+    }
+
+    private fun setup(template: RangeTemplate) {
+        rangeTemplate = template
+
+        // only show disabled state when value is at the minimum
+        isChecked = rangeTemplate.currentValue != rangeTemplate.minValue
+    }
+
+    private fun setupTemplate(template: ControlTemplate): Boolean {
+        return when (template) {
+            is ToggleRangeTemplate -> {
+                setup(template)
+                true
+            }
+            is RangeTemplate -> {
+                setup(template)
+                true
+            }
+            is TemperatureControlTemplate -> setupTemplate(template.getTemplate())
+            else -> {
+                Log.e(ControlsUiController.TAG, "Unsupported template type: $template")
+                false
+            }
+        }
+    }
+
+    override fun bind(cws: ControlWithState, colorOffset: Int) {
         this.control = cws.control!!
+        this.colorOffset = colorOffset
 
         currentStatusText = control.getStatusText()
         status.setText(currentStatusText)
@@ -99,13 +140,14 @@
         val ld = cvh.layout.getBackground() as LayerDrawable
         clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
 
-        template = control.getControlTemplate() as ToggleRangeTemplate
-        rangeTemplate = template.getRange()
+        val template = control.getControlTemplate()
+        if (!setupTemplate(template)) return
+        templateId = template.getTemplateId()
 
-        val checked = template.isChecked()
-        updateRange(rangeToLevelValue(rangeTemplate.currentValue), checked, /* isDragging */ false)
+        updateRange(rangeToLevelValue(rangeTemplate.currentValue), isChecked,
+            /* isDragging */ false)
 
-        cvh.applyRenderInfo(checked)
+        cvh.applyRenderInfo(isChecked, colorOffset)
 
         /*
          * This is custom widget behavior, so add a new accessibility delegate to
@@ -141,9 +183,12 @@
             ): Boolean {
                 val handled = when (action) {
                     AccessibilityNodeInfo.ACTION_CLICK -> {
-                        cvh.controlActionCoordinator.toggle(cvh, template.getTemplateId(),
-                            template.isChecked())
-                        true
+                        if (!isToggleable) {
+                            false
+                        } else {
+                            cvh.controlActionCoordinator.toggle(cvh, templateId, isChecked)
+                            true
+                        }
                     }
                     AccessibilityNodeInfo.ACTION_LONG_CLICK -> {
                         cvh.controlActionCoordinator.longPress(cvh)
@@ -157,7 +202,7 @@
                             val value = arguments.getFloat(
                                 AccessibilityNodeInfo.ACTION_ARGUMENT_PROGRESS_VALUE)
                             val level = rangeToLevelValue(value)
-                            updateRange(level, template.isChecked(), /* isDragging */ true)
+                            updateRange(level, isChecked, /* isDragging */ true)
                             endUpdateRange()
                             true
                         }
@@ -182,7 +227,14 @@
     }
 
     fun updateRange(level: Int, checked: Boolean, isDragging: Boolean) {
-        val newLevel = if (checked) Math.max(MIN_LEVEL, Math.min(MAX_LEVEL, level)) else MIN_LEVEL
+        val newLevel = Math.max(MIN_LEVEL, Math.min(MAX_LEVEL, level))
+
+        // If the current level is at the minimum and the user is dragging, set the control to
+        // the enabled state to indicate their intention to enable the device. This will update
+        // control colors to support dragging.
+        if (clipLayer.level == MIN_LEVEL && newLevel > MIN_LEVEL) {
+            cvh.applyRenderInfo(checked, colorOffset, false /* animated */)
+        }
 
         rangeAnimator?.cancel()
         if (isDragging) {
@@ -282,7 +334,7 @@
             if (isDragging) {
                 return
             }
-            cvh.controlActionCoordinator.longPress(this@ToggleRangeBehavior.cvh)
+            cvh.controlActionCoordinator.longPress(cvh)
         }
 
         override fun onScroll(
@@ -291,26 +343,21 @@
             xDiff: Float,
             yDiff: Float
         ): Boolean {
-            if (!template.isChecked) {
-                return false
-            }
             if (!isDragging) {
                 v.getParent().requestDisallowInterceptTouchEvent(true)
-                this@ToggleRangeBehavior.beginUpdateRange()
+                beginUpdateRange()
                 isDragging = true
             }
 
             val ratioDiff = -xDiff / v.width
             val changeAmount = ((MAX_LEVEL - MIN_LEVEL) * ratioDiff).toInt()
-            this@ToggleRangeBehavior.updateRange(clipLayer.level + changeAmount,
-                    checked = true, isDragging = true)
+            updateRange(clipLayer.level + changeAmount, checked = true, isDragging = true)
             return true
         }
 
         override fun onSingleTapUp(e: MotionEvent): Boolean {
-            val th = this@ToggleRangeBehavior
-            cvh.controlActionCoordinator.toggle(th.cvh, th.template.getTemplateId(),
-                    th.template.isChecked())
+            if (!isToggleable) return false
+            cvh.controlActionCoordinator.toggle(cvh, templateId, isChecked)
             return true
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
index 7ae3df7..8ce2e61 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
@@ -44,7 +44,7 @@
         })
     }
 
-    override fun bind(cws: ControlWithState) {
+    override fun bind(cws: ControlWithState, colorOffset: Int) {
         this.control = cws.control!!
         cvh.status.setText(control.getStatusText())
         template = control.getControlTemplate()
@@ -53,6 +53,6 @@
         clipLayer = ld.findDrawableByLayerId(R.id.clip_layer)
         clipLayer.setLevel(MIN_LEVEL)
 
-        cvh.applyRenderInfo(false)
+        cvh.applyRenderInfo(false, colorOffset)
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyBinder.java
index 82ccb17..e2a6d6c 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyBinder.java
@@ -21,7 +21,6 @@
 import com.android.systemui.appops.AppOpsControllerImpl;
 import com.android.systemui.classifier.FalsingManagerProxy;
 import com.android.systemui.controls.dagger.ControlsModule;
-import com.android.systemui.doze.DozeHost;
 import com.android.systemui.globalactions.GlobalActionsComponent;
 import com.android.systemui.globalactions.GlobalActionsImpl;
 import com.android.systemui.plugins.ActivityStarter;
@@ -38,7 +37,6 @@
 import com.android.systemui.statusbar.StatusBarStateControllerImpl;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
-import com.android.systemui.statusbar.phone.DozeServiceHost;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -259,11 +257,6 @@
     /**
      */
     @Binds
-    public abstract DozeHost provideDozeHost(DozeServiceHost dozeServiceHost);
-
-    /**
-     */
-    @Binds
     public abstract VolumeComponent provideVolumeComponent(
             VolumeDialogComponent volumeDialogComponent);
 
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 6d1bf72..3bb953a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -31,6 +31,7 @@
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManagerImpl;
+import com.android.systemui.doze.DozeHost;
 import com.android.systemui.plugins.qs.QSFactory;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.EnhancedEstimates;
@@ -43,6 +44,7 @@
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.phone.DozeServiceHost;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
@@ -148,4 +150,7 @@
     @Binds
     abstract KeyguardViewController bindKeyguardViewController(
             StatusBarKeyguardViewManager statusBarKeyguardViewManager);
+
+    @Binds
+    abstract DozeHost provideDozeHost(DozeServiceHost dozeServiceHost);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 8117bbb..5e36704 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -33,7 +33,6 @@
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.DozeParameters;
-import com.android.systemui.statusbar.phone.DozeServiceHost;
 import com.android.systemui.statusbar.policy.BatteryController;
 import com.android.systemui.util.sensors.AsyncSensorManager;
 import com.android.systemui.util.sensors.ProximitySensor;
@@ -59,7 +58,7 @@
     private final Handler mHandler;
     private final BiometricUnlockController mBiometricUnlockController;
     private final BroadcastDispatcher mBroadcastDispatcher;
-    private final DozeServiceHost mDozeServiceHost;
+    private final DozeHost mDozeHost;
 
     @Inject
     public DozeFactory(FalsingManager falsingManager, DozeLog dozeLog,
@@ -70,7 +69,7 @@
             ProximitySensor proximitySensor,
             DelayedWakeLock.Builder delayedWakeLockBuilder, Handler handler,
             BiometricUnlockController biometricUnlockController,
-            BroadcastDispatcher broadcastDispatcher, DozeServiceHost dozeServiceHost) {
+            BroadcastDispatcher broadcastDispatcher, DozeHost dozeHost) {
         mFalsingManager = falsingManager;
         mDozeLog = dozeLog;
         mDozeParameters = dozeParameters;
@@ -86,7 +85,7 @@
         mHandler = handler;
         mBiometricUnlockController = biometricUnlockController;
         mBroadcastDispatcher = broadcastDispatcher;
-        mDozeServiceHost = dozeServiceHost;
+        mDozeHost = dozeHost;
     }
 
     /** Creates a DozeMachine with its parts for {@code dozeService}. */
@@ -95,7 +94,7 @@
         WakeLock wakeLock = mDelayedWakeLockBuilder.setHandler(mHandler).setTag("Doze").build();
 
         DozeMachine.Service wrappedService = dozeService;
-        wrappedService = new DozeBrightnessHostForwarder(wrappedService, mDozeServiceHost);
+        wrappedService = new DozeBrightnessHostForwarder(wrappedService, mDozeHost);
         wrappedService = DozeScreenStatePreventingAdapter.wrapIfNeeded(
                 wrappedService, mDozeParameters);
         wrappedService = DozeSuspendScreenStatePreventingAdapter.wrapIfNeeded(
@@ -103,19 +102,19 @@
 
         DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock,
                 mWakefulnessLifecycle, mBatteryController, mDozeLog, mDockManager,
-                mDozeServiceHost);
+                mDozeHost);
         machine.setParts(new DozeMachine.Part[]{
                 new DozePauser(mHandler, machine, mAlarmManager, mDozeParameters.getPolicy()),
                 new DozeFalsingManagerAdapter(mFalsingManager),
-                createDozeTriggers(dozeService, mAsyncSensorManager, mDozeServiceHost,
+                createDozeTriggers(dozeService, mAsyncSensorManager, mDozeHost,
                         mAlarmManager, config, mDozeParameters, mHandler, wakeLock, machine,
                         mDockManager, mDozeLog),
-                createDozeUi(dozeService, mDozeServiceHost, wakeLock, machine, mHandler,
+                createDozeUi(dozeService, mDozeHost, wakeLock, machine, mHandler,
                         mAlarmManager, mDozeParameters, mDozeLog),
-                new DozeScreenState(wrappedService, mHandler, mDozeServiceHost, mDozeParameters,
+                new DozeScreenState(wrappedService, mHandler, mDozeHost, mDozeParameters,
                         wakeLock),
                 createDozeScreenBrightness(dozeService, wrappedService, mAsyncSensorManager,
-                        mDozeServiceHost, mDozeParameters, mHandler),
+                        mDozeHost, mDozeParameters, mHandler),
                 new DozeWallpaperState(mWallpaperManager, mBiometricUnlockController,
                         mDozeParameters),
                 new DozeDockHandler(config, machine, mDockManager),
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index e02b1ec..8e1854a 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -69,6 +69,9 @@
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
+import android.transition.AutoTransition;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
 import android.util.ArraySet;
 import android.util.FeatureFlagUtils;
 import android.util.Log;
@@ -206,7 +209,8 @@
     @VisibleForTesting
     protected final ArrayList<Action> mOverflowItems = new ArrayList<>();
 
-    private ActionsDialog mDialog;
+    @VisibleForTesting
+    protected ActionsDialog mDialog;
 
     private Action mSilentModeAction;
     private ToggleAction mAirplaneModeOn;
@@ -246,6 +250,9 @@
         @UiEvent(doc = "The global actions / power menu surface became visible on the screen.")
         GA_POWER_MENU_OPEN(337),
 
+        @UiEvent(doc = "The global actions / power menu surface was dismissed.")
+        GA_POWER_MENU_CLOSE(471),
+
         @UiEvent(doc = "The global actions bugreport button was pressed.")
         GA_BUGREPORT_PRESS(344),
 
@@ -360,10 +367,9 @@
             @Override
             public void onUnlockedChanged() {
                 if (mDialog != null) {
-                    boolean unlocked = keyguardStateController.isUnlocked()
-                            || keyguardStateController.canDismissLockScreen();
                     if (mDialog.mPanelController != null) {
-                        mDialog.mPanelController.onDeviceLockStateChanged(unlocked);
+                        mDialog.mPanelController.onDeviceLockStateChanged(
+                                !mKeyguardStateController.isUnlocked());
                     }
                     if (!mDialog.isShowingControls() && shouldShowControls()) {
                         mDialog.showControls(mControlsUiController);
@@ -1168,6 +1174,7 @@
         if (mDialog == dialog) {
             mDialog = null;
         }
+        mUiEventLogger.log(GlobalActionsEvent.GA_POWER_MENU_CLOSE);
         mWindowManagerFuncs.onGlobalActionsHidden();
         mLifecycle.setCurrentState(Lifecycle.State.DESTROYED);
     }
@@ -2022,7 +2029,22 @@
                         new FrameLayout.LayoutParams(
                                 FrameLayout.LayoutParams.MATCH_PARENT,
                                 FrameLayout.LayoutParams.MATCH_PARENT);
-                panelContainer.addView(mPanelController.getPanelContent(), panelParams);
+                View walletView = mPanelController.getPanelContent();
+                panelContainer.addView(walletView, panelParams);
+                // Smooth transitions when wallet is resized, which can happen when a card is added
+                ViewGroup root = findViewById(com.android.systemui.R.id.global_actions_grid_root);
+                if (root != null) {
+                    walletView.addOnLayoutChangeListener((v, l, t, r, b, ol, ot, or, ob) -> {
+                        int oldHeight = ob - ot;
+                        int newHeight = b - t;
+                        if (oldHeight > 0 && oldHeight != newHeight) {
+                            TransitionSet transition = new AutoTransition()
+                                    .setDuration(250)
+                                    .setOrdering(TransitionSet.ORDERING_TOGETHER);
+                            TransitionManager.beginDelayedTransition(root, transition);
+                        }
+                    });
+                }
             }
         }
 
@@ -2340,6 +2362,14 @@
         }
 
         public void refreshDialog() {
+            // ensure dropdown menus are dismissed before re-initializing the dialog
+            dismissPanel();
+            dismissOverflow(true);
+            if (mControlsUiController != null) {
+                mControlsUiController.hide();
+            }
+
+            // re-create dialog
             initializeLayout();
             mGlobalActionsLayout.updateList();
             if (mControlsUiController != null) {
@@ -2378,11 +2408,10 @@
 
     @VisibleForTesting
     protected boolean shouldShowControls() {
-        boolean isUnlocked = mKeyguardStateController.isUnlocked()
-                || mKeyguardStateController.canDismissLockScreen();
-        return (isUnlocked || mShowLockScreenCardsAndControls)
+        return (mKeyguardStateController.isUnlocked() || mShowLockScreenCardsAndControls)
                 && mControlsUiController.getAvailable()
-                && !mControlsServiceInfos.isEmpty();
+                && !mControlsServiceInfos.isEmpty()
+                && mDeviceProvisioned;
     }
     // TODO: Remove legacy layout XML and classes.
     protected boolean shouldUseControlsLayout() {
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
index fa45ea1..1a53c28 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
@@ -134,7 +134,7 @@
     private void setupTexture(Bitmap bitmap) {
         final int[] tids = new int[1];
 
-        if (bitmap == null) {
+        if (bitmap == null || bitmap.isRecycled()) {
             Log.w(TAG, "setupTexture: invalid bitmap");
             return;
         }
@@ -146,16 +146,20 @@
             return;
         }
 
-        // Bind a named texture to a target.
-        glBindTexture(GL_TEXTURE_2D, tids[0]);
-        // Load the bitmap data and copy it over into the texture object that is currently bound.
-        GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
-        // Use bilinear texture filtering when minification.
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-        // Use bilinear texture filtering when magnification.
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-        mTextureId = tids[0];
+        try {
+            // Bind a named texture to a target.
+            glBindTexture(GL_TEXTURE_2D, tids[0]);
+            // Load the bitmap data and copy it over into the texture object
+            // that is currently bound.
+            GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
+            // Use bilinear texture filtering when minification.
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+            // Use bilinear texture filtering when magnification.
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+            mTextureId = tids[0];
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "Failed uploading texture: " + e.getLocalizedMessage());
+        }
     }
 
     void useTexture() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 60c2ed2..e08d7a5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -26,6 +26,7 @@
 import android.content.res.ColorStateList;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
@@ -37,9 +38,7 @@
 import android.media.session.PlaybackState;
 import android.service.media.MediaBrowserService;
 import android.util.Log;
-import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.widget.ImageButton;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
@@ -90,24 +89,21 @@
     };
 
     private final SeekBarViewModel mSeekBarViewModel;
-    private final SeekBarObserver mSeekBarObserver;
+    private SeekBarObserver mSeekBarObserver;
     private final Executor mForegroundExecutor;
     protected final Executor mBackgroundExecutor;
     private final ActivityStarter mActivityStarter;
-    private final LayoutAnimationHelper mLayoutAnimationHelper;
+    private LayoutAnimationHelper mLayoutAnimationHelper;
 
     private Context mContext;
-    private MotionLayout mMediaNotifView;
-    private final View mBackground;
-    private View mSeamless;
+    private PlayerViewHolder mViewHolder;
     private MediaSession.Token mToken;
     private MediaController mController;
-    private int mForegroundColor;
     private int mBackgroundColor;
     private MediaDevice mDevice;
     protected ComponentName mServiceComponent;
     private boolean mIsRegistered = false;
-    private final List<KeyFrames> mKeyFrames;
+    private List<KeyFrames> mKeyFrames;
     private String mKey;
     private int mAlbumArtSize;
     private int mAlbumArtRadius;
@@ -166,37 +162,27 @@
     /**
      * Initialize a new control panel
      * @param context
-     * @param parent
      * @param routeManager Manager used to listen for device change events.
      * @param foregroundExecutor foreground executor
      * @param backgroundExecutor background executor, used for processing artwork
      * @param activityStarter activity starter
      */
-    public MediaControlPanel(Context context, ViewGroup parent,
-            @Nullable LocalMediaManager routeManager, Executor foregroundExecutor,
-            DelayableExecutor backgroundExecutor, ActivityStarter activityStarter) {
+    public MediaControlPanel(Context context, @Nullable LocalMediaManager routeManager,
+            Executor foregroundExecutor, DelayableExecutor backgroundExecutor,
+            ActivityStarter activityStarter) {
         mContext = context;
-        LayoutInflater inflater = LayoutInflater.from(mContext);
-        mMediaNotifView = (MotionLayout) inflater.inflate(R.layout.qs_media_panel, parent, false);
-        mBackground = mMediaNotifView.findViewById(R.id.media_background);
-        mLayoutAnimationHelper = new LayoutAnimationHelper(mMediaNotifView);
-        GoneChildrenHideHelper.clipGoneChildrenOnLayout(mMediaNotifView);
-        mKeyFrames = mMediaNotifView.getDefinedTransitions().get(0).getKeyFrameList();
         mLocalMediaManager = routeManager;
         mForegroundExecutor = foregroundExecutor;
         mBackgroundExecutor = backgroundExecutor;
         mActivityStarter = activityStarter;
         mSeekBarViewModel = new SeekBarViewModel(backgroundExecutor);
-        mSeekBarObserver = new SeekBarObserver(getView());
-        mSeekBarViewModel.getProgress().observeForever(mSeekBarObserver);
-        SeekBar bar = getView().findViewById(R.id.media_progress_bar);
-        bar.setOnSeekBarChangeListener(mSeekBarViewModel.getSeekBarListener());
-        bar.setOnTouchListener(mSeekBarViewModel.getSeekBarTouchListener());
         loadDimens();
     }
 
     public void onDestroy() {
-        mSeekBarViewModel.getProgress().removeObserver(mSeekBarObserver);
+        if (mSeekBarObserver != null) {
+            mSeekBarViewModel.getProgress().removeObserver(mSeekBarObserver);
+        }
         makeInactive();
     }
 
@@ -207,11 +193,12 @@
     }
 
     /**
-     * Get the view used to display media controls
-     * @return the view
+     * Get the view holder used to display media controls
+     * @return the view holder
      */
-    public MotionLayout getView() {
-        return mMediaNotifView;
+    @Nullable
+    public PlayerViewHolder getView() {
+        return mViewHolder;
     }
 
     /**
@@ -234,12 +221,28 @@
         return mContext;
     }
 
+    /** Attaches the player to the view holder. */
+    public void attach(PlayerViewHolder vh) {
+        mViewHolder = vh;
+        MotionLayout motionView = vh.getPlayer();
+        mLayoutAnimationHelper = new LayoutAnimationHelper(motionView);
+        GoneChildrenHideHelper.clipGoneChildrenOnLayout(motionView);
+        mKeyFrames = motionView.getDefinedTransitions().get(0).getKeyFrameList();
+        mSeekBarObserver = new SeekBarObserver(motionView);
+        mSeekBarViewModel.getProgress().observeForever(mSeekBarObserver);
+        SeekBar bar = vh.getSeekBar();
+        bar.setOnSeekBarChangeListener(mSeekBarViewModel.getSeekBarListener());
+        bar.setOnTouchListener(mSeekBarViewModel.getSeekBarTouchListener());
+    }
+
     /**
      * Bind this view based on the data given
      */
     public void bind(@NotNull MediaData data) {
+        if (mViewHolder == null) {
+            return;
+        }
         MediaSession.Token token = data.getToken();
-        mForegroundColor = data.getForegroundColor();
         mBackgroundColor = data.getBackgroundColor();
         if (mToken == null || !mToken.equals(token)) {
             if (mQSMediaBrowser != null) {
@@ -254,8 +257,8 @@
 
         mController = new MediaController(mContext, mToken);
 
-        ConstraintSet expandedSet = mMediaNotifView.getConstraintSet(R.id.expanded);
-        ConstraintSet collapsedSet = mMediaNotifView.getConstraintSet(R.id.collapsed);
+        ConstraintSet expandedSet = mViewHolder.getPlayer().getConstraintSet(R.id.expanded);
+        ConstraintSet collapsedSet = mViewHolder.getPlayer().getConstraintSet(R.id.collapsed);
 
         // Try to find a browser service component for this app
         // TODO also check for a media button receiver intended for restarting (b/154127084)
@@ -281,64 +284,60 @@
 
         mController.registerCallback(mSessionCallback);
 
-        mMediaNotifView.requireViewById(R.id.media_background).setBackgroundTintList(
+        mViewHolder.getBackground().setBackgroundTintList(
                 ColorStateList.valueOf(mBackgroundColor));
 
         // Click action
         PendingIntent clickIntent = data.getClickIntent();
         if (clickIntent != null) {
-            mMediaNotifView.setOnClickListener(v -> {
+            mViewHolder.getPlayer().setOnClickListener(v -> {
                 mActivityStarter.postStartActivityDismissingKeyguard(clickIntent);
             });
         }
 
-        ImageView albumView = mMediaNotifView.findViewById(R.id.album_art);
+        ImageView albumView = mViewHolder.getAlbumView();
         // TODO: migrate this to a view with rounded corners instead of baking the rounding
         // into the bitmap
         Drawable artwork = createRoundedBitmap(data.getArtwork());
         albumView.setImageDrawable(artwork);
 
         // App icon
-        ImageView appIcon = mMediaNotifView.requireViewById(R.id.icon);
-        Drawable iconDrawable = data.getAppIcon().mutate();
-        iconDrawable.setTint(mForegroundColor);
-        appIcon.setImageDrawable(iconDrawable);
+        ImageView appIcon = mViewHolder.getAppIcon();
+        appIcon.setImageDrawable(data.getAppIcon());
 
         // Song name
-        TextView titleText = mMediaNotifView.requireViewById(R.id.header_title);
+        TextView titleText = mViewHolder.getTitleText();
         titleText.setText(data.getSong());
-        titleText.setTextColor(data.getForegroundColor());
 
         // App title
-        TextView appName = mMediaNotifView.requireViewById(R.id.app_name);
+        TextView appName = mViewHolder.getAppName();
         appName.setText(data.getApp());
-        appName.setTextColor(mForegroundColor);
 
         // Artist name
-        TextView artistText = mMediaNotifView.requireViewById(R.id.header_artist);
+        TextView artistText = mViewHolder.getArtistText();
         artistText.setText(data.getArtist());
-        artistText.setTextColor(mForegroundColor);
 
         // Transfer chip
-        mSeamless = mMediaNotifView.findViewById(R.id.media_seamless);
-        if (mSeamless != null) {
-            if (mLocalMediaManager != null) {
-                mSeamless.setVisibility(View.VISIBLE);
-                setVisibleAndAlpha(collapsedSet, R.id.media_seamless, true /*visible */);
-                setVisibleAndAlpha(expandedSet, R.id.media_seamless, true /*visible */);
-                updateDevice(mLocalMediaManager.getCurrentConnectedDevice());
-                mSeamless.setOnClickListener(v -> {
-                    final Intent intent = new Intent()
-                            .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
-                            .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
-                                    mController.getPackageName())
-                            .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken);
-                    mActivityStarter.startActivity(intent, false, true /* dismissShade */,
-                            Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-                });
-            } else {
-                Log.d(TAG, "LocalMediaManager is null. Not binding output chip for pkg=" + pkgName);
+        if (mLocalMediaManager != null) {
+            mViewHolder.getSeamless().setVisibility(View.VISIBLE);
+            setVisibleAndAlpha(collapsedSet, R.id.media_seamless, true /*visible */);
+            setVisibleAndAlpha(expandedSet, R.id.media_seamless, true /*visible */);
+            updateDevice(mLocalMediaManager.getCurrentConnectedDevice());
+            if (mViewHolder.getBackground().getBackground() instanceof IlluminationDrawable) {
+                    ((IlluminationDrawable) mViewHolder.getBackground().getBackground())
+                            .setupTouch(mViewHolder.getSeamless(), mViewHolder.getPlayer());
             }
+            mViewHolder.getSeamless().setOnClickListener(v -> {
+                final Intent intent = new Intent()
+                        .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
+                        .putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
+                                mController.getPackageName())
+                        .putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN, mToken);
+                mActivityStarter.startActivity(intent, false, true /* dismissShade */,
+                        Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+            });
+        } else {
+            Log.d(TAG, "LocalMediaManager is null. Not binding output chip for pkg=" + pkgName);
         }
         PlaybackInfo playbackInfo = mController.getPlaybackInfo();
         if (playbackInfo != null) {
@@ -353,16 +352,15 @@
         List<MediaAction> actionIcons = data.getActions();
         for (; i < actionIcons.size() && i < ACTION_IDS.length; i++) {
             int actionId = ACTION_IDS[i];
-            final ImageButton button = mMediaNotifView.findViewById(actionId);
+            final ImageButton button = mViewHolder.getAction(actionId);
             MediaAction mediaAction = actionIcons.get(i);
             button.setImageDrawable(mediaAction.getDrawable());
             button.setContentDescription(mediaAction.getContentDescription());
-            button.setImageTintList(ColorStateList.valueOf(mForegroundColor));
             PendingIntent actionIntent = mediaAction.getIntent();
 
-            if (mBackground.getBackground() instanceof IlluminationDrawable) {
-                ((IlluminationDrawable) mBackground.getBackground())
-                        .setupTouch(button, mMediaNotifView);
+            if (mViewHolder.getBackground().getBackground() instanceof IlluminationDrawable) {
+                ((IlluminationDrawable) mViewHolder.getBackground().getBackground())
+                        .setupTouch(button, mViewHolder.getPlayer());
             }
 
             button.setOnClickListener(v -> {
@@ -388,8 +386,7 @@
 
         // Seek Bar
         final MediaController controller = getController();
-        mBackgroundExecutor.execute(
-                () -> mSeekBarViewModel.updateController(controller, data.getForegroundColor()));
+        mBackgroundExecutor.execute(() -> mSeekBarViewModel.updateController(controller));
 
         // Set up long press menu
         // TODO: b/156036025 bring back media guts
@@ -397,8 +394,8 @@
         makeActive();
 
         // Update both constraint sets to regenerate the animation.
-        mMediaNotifView.updateState(R.id.collapsed, collapsedSet);
-        mMediaNotifView.updateState(R.id.expanded, expandedSet);
+        mViewHolder.getPlayer().updateState(R.id.collapsed, collapsedSet);
+        mViewHolder.getPlayer().updateState(R.id.expanded, expandedSet);
     }
 
     @UiThread
@@ -441,6 +438,9 @@
      * @param visible is the view visible
      */
     private void updateKeyFrameVisibility(int actionId, boolean visible) {
+        if (mKeyFrames == null) {
+            return;
+        }
         for (int i = 0; i < mKeyFrames.size(); i++) {
             KeyFrames keyframe = mKeyFrames.get(i);
             ArrayList<Key> viewKeyFrames = keyframe.getKeyFramesForView(actionId);
@@ -528,41 +528,36 @@
      * @param device device information to display
      */
     private void updateDevice(MediaDevice device) {
-        if (mSeamless == null) {
-            return;
-        }
         mForegroundExecutor.execute(() -> {
             updateChipInternal(device);
         });
     }
 
     private void updateChipInternal(MediaDevice device) {
-        ColorStateList fgTintList = ColorStateList.valueOf(mForegroundColor);
+        if (mViewHolder == null) {
+            return;
+        }
+        ImageView iconView = mViewHolder.getSeamlessIcon();
+        TextView deviceName = mViewHolder.getSeamlessText();
 
         // Update the outline color
-        LinearLayout viewLayout = (LinearLayout) mSeamless;
+        LinearLayout viewLayout = (LinearLayout) mViewHolder.getSeamless();
         RippleDrawable bkgDrawable = (RippleDrawable) viewLayout.getBackground();
         GradientDrawable rect = (GradientDrawable) bkgDrawable.getDrawable(0);
-        rect.setStroke(2, mForegroundColor);
-        rect.setColor(mBackgroundColor);
-
-        ImageView iconView = mSeamless.findViewById(R.id.media_seamless_image);
-        TextView deviceName = mSeamless.findViewById(R.id.media_seamless_text);
-        deviceName.setTextColor(fgTintList);
+        rect.setStroke(2, deviceName.getCurrentTextColor());
+        rect.setColor(Color.TRANSPARENT);
 
         if (mIsRemotePlayback) {
-            mSeamless.setEnabled(false);
-            mSeamless.setAlpha(0.38f);
+            mViewHolder.getSeamless().setEnabled(false);
+            mViewHolder.getSeamless().setAlpha(0.38f);
             iconView.setImageResource(R.drawable.ic_hardware_speaker);
             iconView.setVisibility(View.VISIBLE);
-            iconView.setImageTintList(fgTintList);
             deviceName.setText(R.string.media_seamless_remote_device);
         } else if (device != null) {
-            mSeamless.setEnabled(true);
-            mSeamless.setAlpha(1f);
+            mViewHolder.getSeamless().setEnabled(true);
+            mViewHolder.getSeamless().setAlpha(1f);
             Drawable icon = device.getIcon();
             iconView.setVisibility(View.VISIBLE);
-            iconView.setImageTintList(fgTintList);
 
             if (icon instanceof AdaptiveIcon) {
                 AdaptiveIcon aIcon = (AdaptiveIcon) icon;
@@ -575,8 +570,8 @@
         } else {
             // Reset to default
             Log.d(TAG, "device is null. Not binding output chip.");
-            mSeamless.setEnabled(true);
-            mSeamless.setAlpha(1f);
+            mViewHolder.getSeamless().setEnabled(true);
+            mViewHolder.getSeamless().setAlpha(1f);
             iconView.setVisibility(View.GONE);
             deviceName.setText(com.android.internal.R.string.ext_media_seamless_action);
         }
@@ -601,17 +596,20 @@
      * Hide the media buttons and show only a restart button
      */
     protected void resetButtons() {
+        if (mViewHolder == null) {
+            return;
+        }
         // Hide all the old buttons
 
-        ConstraintSet expandedSet = mMediaNotifView.getConstraintSet(R.id.expanded);
-        ConstraintSet collapsedSet = mMediaNotifView.getConstraintSet(R.id.collapsed);
+        ConstraintSet expandedSet = mViewHolder.getPlayer().getConstraintSet(R.id.expanded);
+        ConstraintSet collapsedSet = mViewHolder.getPlayer().getConstraintSet(R.id.collapsed);
         for (int i = 1; i < ACTION_IDS.length; i++) {
             setVisibleAndAlpha(expandedSet, ACTION_IDS[i], false /*visible */);
             setVisibleAndAlpha(collapsedSet, ACTION_IDS[i], false /*visible */);
         }
 
         // Add a restart button
-        ImageButton btn = mMediaNotifView.findViewById(ACTION_IDS[0]);
+        ImageButton btn = mViewHolder.getAction0();
         btn.setOnClickListener(v -> {
             Log.d(TAG, "Attempting to restart session");
             if (mQSMediaBrowser != null) {
@@ -632,16 +630,15 @@
             mQSMediaBrowser.restart();
         });
         btn.setImageDrawable(mContext.getResources().getDrawable(R.drawable.lb_ic_play));
-        btn.setImageTintList(ColorStateList.valueOf(mForegroundColor));
         setVisibleAndAlpha(expandedSet, ACTION_IDS[0], true /*visible */);
         setVisibleAndAlpha(collapsedSet, ACTION_IDS[0], true /*visible */);
 
         mSeekBarViewModel.clearController();
         // TODO: fix guts
         //        View guts = mMediaNotifView.findViewById(R.id.media_guts);
-        View options = mMediaNotifView.findViewById(R.id.qs_media_controls_options);
+        View options = mViewHolder.getOptions();
 
-        mMediaNotifView.setOnLongClickListener(v -> {
+        mViewHolder.getPlayer().setOnLongClickListener(v -> {
             // Replace player view with close/cancel view
 //            guts.setVisibility(View.GONE);
             options.setVisibility(View.VISIBLE);
@@ -748,20 +745,28 @@
     protected void removePlayer() { }
 
     public void measure(@Nullable MediaMeasurementInput input) {
+        if (mViewHolder == null) {
+            return;
+        }
         if (input != null) {
             int width = input.getWidth();
             setPlayerWidth(width);
-            mMediaNotifView.measure(input.getWidthMeasureSpec(), input.getHeightMeasureSpec());
+            mViewHolder.getPlayer().measure(input.getWidthMeasureSpec(),
+                    input.getHeightMeasureSpec());
         }
     }
 
     public void setPlayerWidth(int width) {
-        ConstraintSet expandedSet = mMediaNotifView.getConstraintSet(R.id.expanded);
-        ConstraintSet collapsedSet = mMediaNotifView.getConstraintSet(R.id.collapsed);
+        if (mViewHolder == null) {
+            return;
+        }
+        MotionLayout view = mViewHolder.getPlayer();
+        ConstraintSet expandedSet = view.getConstraintSet(R.id.expanded);
+        ConstraintSet collapsedSet = view.getConstraintSet(R.id.collapsed);
         collapsedSet.setGuidelineBegin(R.id.view_width, width);
         expandedSet.setGuidelineBegin(R.id.view_width, width);
-        mMediaNotifView.updateState(R.id.collapsed, collapsedSet);
-        mMediaNotifView.updateState(R.id.expanded, expandedSet);
+        view.updateState(R.id.collapsed, collapsedSet);
+        view.updateState(R.id.expanded, expandedSet);
     }
 
     public void animatePendingSizeChange(long duration, long startDelay) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
index 6a26461..85965d0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaData.kt
@@ -24,7 +24,6 @@
 /** State of a media view. */
 data class MediaData(
     val initialized: Boolean = false,
-    val foregroundColor: Int,
     val backgroundColor: Int,
     val app: String?,
     val appIcon: Drawable?,
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 8da864c..07ce9e4 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -21,6 +21,7 @@
 import android.content.Context
 import android.graphics.Bitmap
 import android.graphics.Canvas
+import android.graphics.Color
 import android.graphics.ImageDecoder
 import android.graphics.drawable.Drawable
 import android.graphics.drawable.Icon
@@ -30,7 +31,7 @@
 import android.service.notification.StatusBarNotification
 import android.text.TextUtils
 import android.util.Log
-import com.android.internal.util.ContrastColorUtil
+import com.android.internal.graphics.ColorUtils
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.statusbar.notification.MediaNotificationProcessor
@@ -40,7 +41,6 @@
 import java.util.concurrent.Executor
 import javax.inject.Inject
 import javax.inject.Singleton
-import kotlin.collections.LinkedHashMap
 
 // URI fields to try loading album art from
 private val ART_URIS = arrayOf(
@@ -50,8 +50,11 @@
 )
 
 private const val TAG = "MediaDataManager"
+private const val DEFAULT_LUMINOSITY = 0.25f
+private const val LUMINOSITY_THRESHOLD = 0.05f
+private const val SATURATION_MULTIPLIER = 0.8f
 
-private val LOADING = MediaData(false, 0, 0, null, null, null, null, null,
+private val LOADING = MediaData(false,  0, null, null, null, null, null,
         emptyList(), emptyList(), null, null, null)
 
 /**
@@ -107,8 +110,7 @@
 
         // Foreground and Background colors computed from album art
         val notif: Notification = sbn.notification
-        var fgColor = notif.color
-        var bgColor = -1
+        var bgColor = Color.WHITE
         var artworkBitmap = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART)
         if (artworkBitmap == null) {
             artworkBitmap = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART)
@@ -142,13 +144,22 @@
                     .generate()
             val swatch = MediaNotificationProcessor.findBackgroundSwatch(p)
             bgColor = swatch.rgb
-            fgColor = MediaNotificationProcessor.selectForegroundColor(bgColor, p)
         }
-        // Make sure colors will be legible
-        val isDark = !ContrastColorUtil.isColorLight(bgColor)
-        fgColor = ContrastColorUtil.resolveContrastColor(context, fgColor, bgColor,
-                isDark)
-        fgColor = ContrastColorUtil.ensureTextContrast(fgColor, bgColor, isDark)
+        // Adapt background color, so it's always subdued and text is legible
+        val tmpHsl = floatArrayOf(0f, 0f, 0f)
+        ColorUtils.colorToHSL(bgColor, tmpHsl)
+
+        val l = tmpHsl[2]
+        // Colors with very low luminosity can have any saturation. This means that changing the
+        // luminosity can make a black become red. Let's remove the saturation of very light or
+        // very dark colors to avoid this issue.
+        if (l < LUMINOSITY_THRESHOLD || l > 1f - LUMINOSITY_THRESHOLD) {
+            tmpHsl[1] = 0f
+        }
+        tmpHsl[1] *= SATURATION_MULTIPLIER
+        tmpHsl[2] = DEFAULT_LUMINOSITY
+
+        bgColor = ColorUtils.HSLToColor(tmpHsl)
 
         // App name
         val builder = Notification.Builder.recoverBuilder(context, notif)
@@ -189,8 +200,8 @@
         }
 
         foregroundExcecutor.execute {
-            onMediaDataLoaded(key, MediaData(true, fgColor, bgColor, app, smallIconDrawable, artist,
-                    song, artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token,
+            onMediaDataLoaded(key, MediaData(true, bgColor, app, smallIconDrawable, artist, song,
+                    artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token,
                     notif.contentIntent))
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt
index 49d2d88..8db9dcc 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewManager.kt
@@ -42,10 +42,10 @@
     val mediaCarousel: HorizontalScrollView
     private val mediaContent: ViewGroup
     private val mediaPlayers: MutableMap<String, MediaControlPanel> = mutableMapOf()
-    private val visualStabilityCallback = ::reorderAllPlayers
+    private val visualStabilityCallback : VisualStabilityManager.Callback
     private var activeMediaIndex: Int = 0
+    private var needsReordering: Boolean = false
     private var scrollIntoCurrentMedia: Int = 0
-
     private var currentlyExpanded = true
         set(value) {
             if (field != value) {
@@ -56,8 +56,13 @@
             }
         }
     private val scrollChangedListener = object : View.OnScrollChangeListener {
-        override fun onScrollChange(v: View?, scrollX: Int, scrollY: Int, oldScrollX: Int,
-                                    oldScrollY: Int) {
+        override fun onScrollChange(
+            v: View?,
+            scrollX: Int,
+            scrollY: Int,
+            oldScrollX: Int,
+            oldScrollY: Int
+        ) {
             if (playerWidthPlusPadding == 0) {
                 return
             }
@@ -70,6 +75,16 @@
         mediaCarousel = inflateMediaCarousel()
         mediaCarousel.setOnScrollChangeListener(scrollChangedListener)
         mediaContent = mediaCarousel.requireViewById(R.id.media_carousel)
+        visualStabilityCallback = VisualStabilityManager.Callback {
+            if (needsReordering) {
+                needsReordering = false
+                reorderAllPlayers()
+            }
+            // Let's reset our scroll position
+            mediaCarousel.scrollX = 0
+        }
+        visualStabilityManager.addReorderingAllowedCallback(visualStabilityCallback,
+                true /* persistent */)
         mediaManager.addListener(object : MediaDataManager.Listener {
             override fun onMediaDataLoaded(key: String, data: MediaData) {
                 updateView(key, data)
@@ -79,16 +94,17 @@
             override fun onMediaDataRemoved(key: String) {
                 val removed = mediaPlayers.remove(key)
                 removed?.apply {
-                    val beforeActive = mediaContent.indexOfChild(removed.view) <= activeMediaIndex
-                    mediaContent.removeView(removed.view)
+                    val beforeActive = mediaContent.indexOfChild(removed.view?.player) <=
+                            activeMediaIndex
+                    mediaContent.removeView(removed.view?.player)
                     removed.onDestroy()
                     updateMediaPaddings()
                     if (beforeActive) {
                         // also update the index here since the scroll below might not always lead
                         // to a scrolling changed
                         activeMediaIndex = Math.max(0, activeMediaIndex - 1)
-                        mediaCarousel.scrollX = Math.max(mediaCarousel.scrollX
-                                - playerWidthPlusPadding, 0)
+                        mediaCarousel.scrollX = Math.max(mediaCarousel.scrollX -
+                                playerWidthPlusPadding, 0)
                     }
                     updatePlayerVisibilities()
                 }
@@ -103,7 +119,7 @@
 
     private fun reorderAllPlayers() {
         for (mediaPlayer in mediaPlayers.values) {
-            val view = mediaPlayer.view
+            val view = mediaPlayer.view?.player
             if (mediaPlayer.isPlaying && mediaContent.indexOfChild(view) != 0) {
                 mediaContent.removeView(view)
                 mediaContent.addView(view, 0)
@@ -142,32 +158,34 @@
             val routeManager = LocalMediaManager(context, localBluetoothManager,
                     imm, data.packageName)
 
-            existingPlayer = MediaControlPanel(context, mediaContent, routeManager,
-                    foregroundExecutor, backgroundExecutor, activityStarter)
+            existingPlayer = MediaControlPanel(context, routeManager, foregroundExecutor,
+                    backgroundExecutor, activityStarter)
+            existingPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context),
+                    mediaContent))
             mediaPlayers[key] = existingPlayer
             val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                     ViewGroup.LayoutParams.WRAP_CONTENT)
-            existingPlayer.view.setLayoutParams(lp)
+            existingPlayer.view?.player?.setLayoutParams(lp)
             existingPlayer.setListening(currentlyExpanded)
             if (existingPlayer.isPlaying) {
-                mediaContent.addView(existingPlayer.view, 0)
+                mediaContent.addView(existingPlayer.view?.player, 0)
             } else {
-                mediaContent.addView(existingPlayer.view)
+                mediaContent.addView(existingPlayer.view?.player)
             }
             updatePlayerToCurrentState(existingPlayer)
         } else if (existingPlayer.isPlaying &&
-                    mediaContent.indexOfChild(existingPlayer.view) != 0) {
+                    mediaContent.indexOfChild(existingPlayer.view?.player) != 0) {
             if (visualStabilityManager.isReorderingAllowed) {
-                mediaContent.removeView(existingPlayer.view)
-                mediaContent.addView(existingPlayer.view, 0)
+                mediaContent.removeView(existingPlayer.view?.player)
+                mediaContent.addView(existingPlayer.view?.player, 0)
             } else {
-                visualStabilityManager.addReorderingAllowedCallback(visualStabilityCallback)
+                needsReordering = true
             }
         }
         existingPlayer.bind(data)
         // Resetting the progress to make sure it's taken into account for the latest
         // motion model
-        existingPlayer.view.progress = currentState?.expansion ?: 0.0f
+        existingPlayer.view?.player?.progress = currentState?.expansion ?: 0.0f
         updateMediaPaddings()
     }
 
@@ -190,7 +208,6 @@
                 mediaView.layoutParams = layoutParams
             }
         }
-
     }
 
     /**
@@ -201,8 +218,8 @@
         currentState = state
         currentlyExpanded = state.expansion > 0
         for (mediaPlayer in mediaPlayers.values) {
-            val view = mediaPlayer.view
-            view.progress = state.expansion
+            val view = mediaPlayer.view?.player
+            view?.progress = state.expansion
         }
     }
 
@@ -215,8 +232,12 @@
      * @param desiredState the target state we're transitioning to
      * @param animate should this be animated
      */
-    fun onDesiredLocationChanged(desiredState: MediaState?, animate: Boolean, duration: Long,
-                                 startDelay: Long) {
+    fun onDesiredLocationChanged(
+        desiredState: MediaState?,
+        animate: Boolean,
+        duration: Long,
+        startDelay: Long
+    ) {
         if (desiredState is MediaHost.MediaHostState) {
             // This is a hosting view, let's remeasure our players
             this.desiredState = desiredState
@@ -224,7 +245,7 @@
             if (playerWidth != width) {
                 setPlayerWidth(width)
                 for (mediaPlayer in mediaPlayers.values) {
-                    if (animate && mediaPlayer.view.visibility == View.VISIBLE) {
+                    if (animate && mediaPlayer.view?.player?.visibility == View.VISIBLE) {
                         mediaPlayer.animatePendingSizeChange(duration, startDelay)
                     }
                 }
@@ -266,24 +287,25 @@
      * Get a measurement for the given input state. This measures the first player and returns
      * its bounds as if it were measured with the given measurement dimensions
      */
-    fun obtainMeasurement(input: MediaMeasurementInput) : MeasurementOutput? {
+    fun obtainMeasurement(input: MediaMeasurementInput): MeasurementOutput? {
         val firstPlayer = mediaPlayers.values.firstOrNull() ?: return null
-        // Let's measure the size of the first player and return its height
-        val previousProgress = firstPlayer.view.progress
-        val previousRight = firstPlayer.view.right
-        val previousBottom = firstPlayer.view.bottom
-        firstPlayer.view.progress = input.expansion
-        firstPlayer.measure(input)
-        // Relayouting is necessary in motionlayout to obtain its size properly ....
-        firstPlayer.view.layout(0, 0, firstPlayer.view.measuredWidth,
-                firstPlayer.view.measuredHeight)
-        val result = MeasurementOutput(firstPlayer.view.measuredWidth,
-                firstPlayer.view.measuredHeight)
-        firstPlayer.view.progress = previousProgress
-        if (desiredState != null) {
-            // remeasure it to the old size again!
-            firstPlayer.measure(desiredState!!.measurementInput)
-            firstPlayer.view.layout(0, 0, previousRight, previousBottom)
+        var result: MeasurementOutput? = null
+        firstPlayer.view?.player?.let {
+            // Let's measure the size of the first player and return its height
+            val previousProgress = it.progress
+            val previousRight = it.right
+            val previousBottom = it.bottom
+            it.progress = input.expansion
+            firstPlayer.measure(input)
+            // Relayouting is necessary in motionlayout to obtain its size properly ....
+            it.layout(0, 0, it.measuredWidth, it.measuredHeight)
+            result = MeasurementOutput(it.measuredWidth, it.measuredHeight)
+            it.progress = previousProgress
+            if (desiredState != null) {
+                // remeasure it to the old size again!
+                firstPlayer.measure(desiredState!!.measurementInput)
+                it.layout(0, 0, previousRight, previousBottom)
+            }
         }
         return result
     }
@@ -295,8 +317,8 @@
             val widthSpec = desiredState!!.measurementInput?.widthMeasureSpec ?: 0
             val heightSpec = desiredState!!.measurementInput?.heightMeasureSpec ?: 0
             for (mediaPlayer in mediaPlayers.values) {
-                mediaPlayer.view.measure(widthSpec, heightSpec)
+                mediaPlayer.view?.player?.measure(widthSpec, heightSpec)
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
new file mode 100644
index 0000000..571e18d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/PlayerViewHolder.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.systemui.media
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.SeekBar
+import android.widget.TextView
+
+import androidx.constraintlayout.motion.widget.MotionLayout
+
+import com.android.systemui.R
+
+/**
+ * ViewHolder for a media player.
+ */
+class PlayerViewHolder private constructor(itemView: View) {
+
+    val player = itemView as MotionLayout
+    val background = itemView.requireViewById<View>(R.id.media_background)
+
+    // Player information
+    val appIcon = itemView.requireViewById<ImageView>(R.id.icon)
+    val appName = itemView.requireViewById<TextView>(R.id.app_name)
+    val albumView = itemView.requireViewById<ImageView>(R.id.album_art)
+    val titleText = itemView.requireViewById<TextView>(R.id.header_title)
+    val artistText = itemView.requireViewById<TextView>(R.id.header_artist)
+
+    // Output switcher
+    val seamless = itemView.findViewById<ViewGroup>(R.id.media_seamless)
+    val seamlessIcon = itemView.requireViewById<ImageView>(R.id.media_seamless_image)
+    val seamlessText = itemView.requireViewById<TextView>(R.id.media_seamless_text)
+
+    // Seek bar
+    val seekBar = itemView.requireViewById<SeekBar>(R.id.media_progress_bar)
+    val elapsedTimeView = itemView.requireViewById<TextView>(R.id.media_elapsed_time)
+    val totalTimeView = itemView.requireViewById<TextView>(R.id.media_total_time)
+
+    // Action Buttons
+    val action0 = itemView.requireViewById<ImageButton>(R.id.action0)
+    val action1 = itemView.requireViewById<ImageButton>(R.id.action1)
+    val action2 = itemView.requireViewById<ImageButton>(R.id.action2)
+    val action3 = itemView.requireViewById<ImageButton>(R.id.action3)
+    val action4 = itemView.requireViewById<ImageButton>(R.id.action4)
+
+    fun getAction(id: Int): ImageButton {
+        return when (id) {
+            R.id.action0 -> action0
+            R.id.action1 -> action1
+            R.id.action2 -> action2
+            R.id.action3 -> action3
+            R.id.action4 -> action4
+            else -> {
+                throw IllegalArgumentException()
+            }
+        }
+    }
+
+    // Settings screen
+    val options = itemView.requireViewById<View>(R.id.qs_media_controls_options)
+
+    companion object {
+        /**
+         * Creates a PlayerViewHolder.
+         *
+         * @param inflater LayoutInflater to use to inflate the layout.
+         * @param parent Parent of inflated view.
+         */
+        @JvmStatic fun create(inflater: LayoutInflater, parent: ViewGroup): PlayerViewHolder {
+            val v = inflater.inflate(R.layout.qs_media_panel, parent, false)
+            return PlayerViewHolder(v)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
index 51c157a..110b08c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.media
 
 import android.content.res.ColorStateList
+import android.graphics.Color
 import android.text.format.DateUtils
 import android.view.View
 import android.widget.SeekBar
@@ -46,18 +47,6 @@
     /** Updates seek bar views when the data model changes. */
     @UiThread
     override fun onChanged(data: SeekBarViewModel.Progress) {
-
-        data.color?.let {
-            var tintList = ColorStateList.valueOf(it)
-            seekBarView.setThumbTintList(tintList)
-            tintList = tintList.withAlpha(192) // 75%
-            seekBarView.setProgressTintList(tintList)
-            tintList = tintList.withAlpha(128) // 50%
-            seekBarView.setProgressBackgroundTintList(tintList)
-            elapsedTimeView.setTextColor(it)
-            totalTimeView.setTextColor(it)
-        }
-
         if (!data.enabled) {
             seekBarView.setEnabled(false)
             seekBarView.getThumb().setAlpha(0)
diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
index f72a74b..b08124b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
@@ -67,7 +67,7 @@
 /** ViewModel for seek bar in QS media player. */
 class SeekBarViewModel(val bgExecutor: DelayableExecutor) {
 
-    private var _data = Progress(false, false, null, null, null)
+    private var _data = Progress(false, false, null, null)
         set(value) {
             field = value
             _progress.postValue(value)
@@ -100,10 +100,9 @@
     /**
      * Updates media information.
      * @param mediaController controller for media session
-     * @param color foreground color for UI elements
      */
     @WorkerThread
-    fun updateController(mediaController: MediaController?, color: Int) {
+    fun updateController(mediaController: MediaController?) {
         controller = mediaController
         playbackState = controller?.playbackState
         val mediaMetadata = controller?.metadata
@@ -113,7 +112,7 @@
         val enabled = if (playbackState == null ||
                 playbackState?.getState() == PlaybackState.STATE_NONE ||
                 (duration != null && duration <= 0)) false else true
-        _data = Progress(enabled, seekAvailable, position, duration, color)
+        _data = Progress(enabled, seekAvailable, position, duration)
         if (shouldPollPlaybackPosition()) {
             checkPlaybackPosition()
         }
@@ -191,7 +190,6 @@
         val enabled: Boolean,
         val seekAvailable: Boolean,
         val elapsedTime: Int?,
-        val duration: Int?,
-        val color: Int?
+        val duration: Int?
     )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
index f72de11..13516a9 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java
@@ -65,6 +65,10 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface TransitionDirection {}
 
+    public static boolean isInPipDirection(@TransitionDirection int direction) {
+        return direction == TRANSITION_DIRECTION_TO_PIP;
+    }
+
     public static boolean isOutPipDirection(@TransitionDirection int direction) {
         return direction == TRANSITION_DIRECTION_TO_FULLSCREEN
                 || direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN;
@@ -104,6 +108,12 @@
         if (mCurrentAnimator == null) {
             mCurrentAnimator = setupPipTransitionAnimator(
                     PipTransitionAnimator.ofBounds(leash, startBounds, endBounds));
+        } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA
+                && mCurrentAnimator.isRunning()) {
+            // If we are still animating the fade into pip, then just move the surface and ensure
+            // we update with the new destination bounds, but don't interrupt the existing animation
+            // with a new bounds
+            mCurrentAnimator.setDestinationBounds(endBounds);
         } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_BOUNDS
                 && mCurrentAnimator.isRunning()) {
             mCurrentAnimator.setDestinationBounds(endBounds);
@@ -265,8 +275,7 @@
 
         boolean inScaleTransition() {
             if (mAnimationType != ANIM_TYPE_BOUNDS) return false;
-            final int direction = getTransitionDirection();
-            return !isOutPipDirection(direction) && direction != TRANSITION_DIRECTION_TO_PIP;
+            return !isInPipDirection(getTransitionDirection());
         }
 
         /**
@@ -354,7 +363,11 @@
                             getCastedFractionValue(start.bottom, end.bottom, fraction));
                     setCurrentValue(mTmpRect);
                     if (inScaleTransition()) {
-                        getSurfaceTransactionHelper().scale(tx, leash, start, mTmpRect);
+                        if (isOutPipDirection(getTransitionDirection())) {
+                            getSurfaceTransactionHelper().scale(tx, leash, end, mTmpRect);
+                        } else {
+                            getSurfaceTransactionHelper().scale(tx, leash, start, mTmpRect);
+                        }
                     } else {
                         getSurfaceTransactionHelper().crop(tx, leash, mTmpRect);
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index 3eeadc3..394f997 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -209,6 +209,10 @@
         return new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
     }
 
+    public int getDisplayRotation() {
+        return mDisplayInfo.rotation;
+    }
+
     /**
      * Responds to IPinnedStackListener on {@link DisplayInfo} change.
      * It will normally follow up with a
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
index 7e2efc0..78d2d98 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.pip;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
 import static com.android.systemui.pip.PipAnimationController.ANIM_TYPE_ALPHA;
@@ -25,25 +28,30 @@
 import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_FULLSCREEN;
 import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
 import static com.android.systemui.pip.PipAnimationController.TRANSITION_DIRECTION_TO_SPLIT_SCREEN;
+import static com.android.systemui.pip.PipAnimationController.isInPipDirection;
 import static com.android.systemui.pip.PipAnimationController.isOutPipDirection;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
 import android.app.PictureInPictureParams;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
+import android.os.RemoteException;
 import android.util.Log;
 import android.util.Size;
 import android.view.SurfaceControl;
 import android.window.TaskOrganizer;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
+import android.window.WindowContainerTransactionCallback;
 import android.window.WindowOrganizer;
 
 import com.android.internal.os.SomeArgs;
@@ -51,6 +59,7 @@
 import com.android.systemui.pip.phone.PipUpdateThread;
 import com.android.systemui.stackdivider.Divider;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -90,7 +99,7 @@
     private final Rect mLastReportedBounds = new Rect();
     private final int mEnterExitAnimationDuration;
     private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
-    private final Map<IBinder, Rect> mBoundsToRestore = new HashMap<>();
+    private final Map<IBinder, Configuration> mInitialState = new HashMap<>();
     private final Divider mSplitDivider;
 
     // These callbacks are called on the update thread
@@ -110,7 +119,8 @@
         @Override
         public void onPipAnimationEnd(SurfaceControl.Transaction tx,
                 PipAnimationController.PipTransitionAnimator animator) {
-            finishResize(tx, animator.getDestinationBounds(), animator.getTransitionDirection());
+            finishResize(tx, animator.getDestinationBounds(), animator.getTransitionDirection(),
+                    animator.getAnimationType());
             mMainHandler.post(() -> {
                 for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
                     final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
@@ -170,7 +180,7 @@
             case MSG_FINISH_RESIZE: {
                 SurfaceControl.Transaction tx = (SurfaceControl.Transaction) args.arg2;
                 Rect toBounds = (Rect) args.arg3;
-                finishResize(tx, toBounds, args.argi1 /* direction */);
+                finishResize(tx, toBounds, args.argi1 /* direction */, -1);
                 if (updateBoundsCallback != null) {
                     updateBoundsCallback.accept(toBounds);
                 }
@@ -240,28 +250,76 @@
     }
 
     /**
-     * Dismiss PiP, this is done in two phases using {@link WindowContainerTransaction}
-     * - setActivityWindowingMode to undefined at beginning of the transaction. without changing
-     *   the windowing mode of the Task itself. This makes sure the activity render it's final
-     *   configuration while the Task is still in PiP.
+     * Expands PiP to the previous bounds, this is done in two phases using
+     * {@link WindowContainerTransaction}
+     * - setActivityWindowingMode to either fullscreen or split-secondary at beginning of the
+     *   transaction. without changing the windowing mode of the Task itself. This makes sure the
+     *   activity render it's final configuration while the Task is still in PiP.
      * - setWindowingMode to undefined at the end of transition
      * @param animationDurationMs duration in millisecond for the exiting PiP transition
      */
-    public void dismissPip(int animationDurationMs) {
+    public void exitPip(int animationDurationMs) {
         if (!mInPip || mToken == null) {
-            Log.wtf(TAG, "Not allowed to dismissPip in current state"
+            Log.wtf(TAG, "Not allowed to exitPip in current state"
                     + " mInPip=" + mInPip + " mToken=" + mToken);
             return;
         }
+
+        final Configuration initialConfig = mInitialState.remove(mToken.asBinder());
+        final boolean orientationDiffers = initialConfig.windowConfiguration.getRotation()
+                != mPipBoundsHandler.getDisplayRotation();
         final WindowContainerTransaction wct = new WindowContainerTransaction();
-        wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
-        WindowOrganizer.applyTransaction(wct);
-        final Rect destinationBounds = mBoundsToRestore.remove(mToken.asBinder());
-        final int direction = syncWithSplitScreenBounds(destinationBounds)
-                ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN : TRANSITION_DIRECTION_TO_FULLSCREEN;
-        scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
-                direction, animationDurationMs, null /* updateBoundsCallback */);
-        mInPip = false;
+        if (orientationDiffers) {
+            // Don't bother doing an animation if the display rotation differs or if it's in
+            // a non-supported windowing mode
+            wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+            wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+            WindowOrganizer.applyTransaction(wct);
+            mInPip = false;
+        } else {
+            final Rect destinationBounds = initialConfig.windowConfiguration.getBounds();
+            final int direction = syncWithSplitScreenBounds(destinationBounds)
+                    ? TRANSITION_DIRECTION_TO_SPLIT_SCREEN
+                    : TRANSITION_DIRECTION_TO_FULLSCREEN;
+            final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
+            mSurfaceTransactionHelper.scale(tx, mLeash, destinationBounds,
+                    mLastReportedBounds);
+            tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height());
+            wct.setActivityWindowingMode(mToken, direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN
+                    ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
+                    : WINDOWING_MODE_FULLSCREEN);
+            wct.setBounds(mToken, destinationBounds);
+            wct.setBoundsChangeTransaction(mToken, tx);
+            applySyncTransaction(wct, new WindowContainerTransactionCallback() {
+                @Override
+                public void onTransactionReady(int id, SurfaceControl.Transaction t) {
+                    t.apply();
+                    scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
+                            direction, animationDurationMs, null /* updateBoundsCallback */);
+                    mInPip = false;
+                }
+            });
+        }
+    }
+
+    /**
+     * Removes PiP immediately.
+     */
+    public void removePip() {
+        if (!mInPip || mToken == null) {
+            Log.wtf(TAG, "Not allowed to removePip in current state"
+                    + " mInPip=" + mInPip + " mToken=" + mToken);
+            return;
+        }
+        getUpdateHandler().post(() -> {
+            try {
+                ActivityTaskManager.getService().removeStacksInWindowingModes(
+                        new int[]{ WINDOWING_MODE_PINNED });
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to remove PiP", e);
+            }
+        });
+        mInitialState.remove(mToken.asBinder());
     }
 
     @Override
@@ -277,19 +335,37 @@
         mInPip = true;
         mLeash = leash;
 
+        // TODO: Skip enter animation when entering pip from another orientation
         final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
-        mBoundsToRestore.put(mToken.asBinder(), currentBounds);
+        mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
+
         if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
             scheduleAnimateResizePip(currentBounds, destinationBounds,
                     TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration,
                     null /* updateBoundsCallback */);
         } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
-            mUpdateHandler.post(() -> mPipAnimationController
-                    .getAnimator(mLeash, destinationBounds, 0f, 1f)
-                    .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
-                    .setPipAnimationCallback(mPipAnimationCallback)
-                    .setDuration(mEnterExitAnimationDuration)
-                    .start());
+            // If we are fading the PIP in, then we should move the pip to the final location as
+            // soon as possible, but set the alpha immediately since the transaction can take a
+            // while to process
+            final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
+            tx.setAlpha(mLeash, 0f);
+            tx.apply();
+            final WindowContainerTransaction wct = new WindowContainerTransaction();
+            wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+            wct.setBounds(mToken, destinationBounds);
+            wct.scheduleFinishEnterPip(mToken, destinationBounds);
+            applySyncTransaction(wct, new WindowContainerTransactionCallback() {
+                @Override
+                public void onTransactionReady(int id, SurfaceControl.Transaction t) {
+                    t.apply();
+                    mUpdateHandler.post(() -> mPipAnimationController
+                            .getAnimator(mLeash, destinationBounds, 0f, 1f)
+                            .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
+                            .setPipAnimationCallback(mPipAnimationCallback)
+                            .setDuration(mEnterExitAnimationDuration)
+                            .start());
+                }
+            });
             mOneShotAnimationType = ANIM_TYPE_BOUNDS;
         } else {
             throw new RuntimeException("Unrecognized animation type: " + mOneShotAnimationType);
@@ -297,7 +373,7 @@
     }
 
     /**
-     * Note that dismissing PiP is now originated from SystemUI, see {@link #dismissPip(int)}.
+     * Note that dismissing PiP is now originated from SystemUI, see {@link #exitPip(int)}.
      * Meanwhile this callback is invoked whenever the task is removed. For instance:
      *   - as a result of removeStacksInWindowingModes from WM
      *   - activity itself is died
@@ -411,6 +487,7 @@
             // can be initiated in other component, ignore if we are no longer in PIP
             return;
         }
+
         SomeArgs args = SomeArgs.obtain();
         args.arg1 = updateBoundsCallback;
         args.arg2 = currentBounds;
@@ -449,12 +526,21 @@
      * {@link #scheduleResizePip}.
      */
     public void scheduleFinishResizePip(Rect destinationBounds) {
+        scheduleFinishResizePip(destinationBounds, null);
+    }
+
+    /**
+     * Same as {@link #scheduleFinishResizePip} but with a callback.
+     */
+    public void scheduleFinishResizePip(Rect destinationBounds,
+            Consumer<Rect> updateBoundsCallback) {
         final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
         mSurfaceTransactionHelper
                 .crop(tx, mLeash, destinationBounds)
                 .resetScale(tx, mLeash, destinationBounds)
                 .round(tx, mLeash, mInPip);
-        scheduleFinishResizePip(tx, destinationBounds, TRANSITION_DIRECTION_NONE, null);
+        scheduleFinishResizePip(tx, destinationBounds, TRANSITION_DIRECTION_NONE,
+                updateBoundsCallback);
     }
 
     private void scheduleFinishResizePip(SurfaceControl.Transaction tx,
@@ -509,7 +595,7 @@
             throw new RuntimeException("Callers should call scheduleResizePip() instead of this "
                     + "directly");
         }
-        // Could happen when dismissPip
+        // Could happen when exitPip
         if (mToken == null || mLeash == null) {
             Log.w(TAG, "Abort animation, invalid leash");
             return;
@@ -526,7 +612,7 @@
             throw new RuntimeException("Callers should call scheduleUserResizePip() instead of "
                     + "this directly");
         }
-        // Could happen when dismissPip
+        // Could happen when exitPip
         if (mToken == null || mLeash == null) {
             Log.w(TAG, "Abort animation, invalid leash");
             return;
@@ -537,32 +623,43 @@
     }
 
     private void finishResize(SurfaceControl.Transaction tx, Rect destinationBounds,
-            @PipAnimationController.TransitionDirection int direction) {
+            @PipAnimationController.TransitionDirection int direction,
+            @PipAnimationController.AnimationType int type) {
         if (Looper.myLooper() != mUpdateHandler.getLooper()) {
             throw new RuntimeException("Callers should call scheduleResizePip() instead of this "
                     + "directly");
         }
         mLastReportedBounds.set(destinationBounds);
+        if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) {
+            return;
+        }
+
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         final Rect taskBounds;
-        if (isOutPipDirection(direction)) {
+        if (isInPipDirection(direction)) {
+            // If we are animating from fullscreen using a bounds animation, then reset the
+            // activity windowing mode set by WM, and set the task bounds to the final bounds
+            taskBounds = destinationBounds;
+            wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+            wct.scheduleFinishEnterPip(mToken, destinationBounds);
+        } else if (isOutPipDirection(direction)) {
             // If we are animating to fullscreen, then we need to reset the override bounds
             // on the task to ensure that the task "matches" the parent's bounds.
             taskBounds = (direction == TRANSITION_DIRECTION_TO_FULLSCREEN)
                     ? null : destinationBounds;
-            // As for the final windowing mode, simply reset it to undefined.
+            // As for the final windowing mode, simply reset it to undefined and reset the activity
+            // mode set prior to the animation running
             wct.setWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+            wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
             if (mSplitDivider != null && direction == TRANSITION_DIRECTION_TO_SPLIT_SCREEN) {
                 wct.reparent(mToken, mSplitDivider.getSecondaryRoot(), true /* onTop */);
             }
         } else {
+            // Just a resize in PIP
             taskBounds = destinationBounds;
         }
-        if (direction == TRANSITION_DIRECTION_TO_PIP) {
-            wct.scheduleFinishEnterPip(mToken, taskBounds);
-        } else {
-            wct.setBounds(mToken, taskBounds);
-        }
+
+        wct.setBounds(mToken, taskBounds);
         wct.setBoundsChangeTransaction(mToken, tx);
         WindowOrganizer.applyTransaction(wct);
     }
@@ -573,17 +670,17 @@
             throw new RuntimeException("Callers should call scheduleAnimateResizePip() instead of "
                     + "this directly");
         }
-        // Could happen when dismissPip
+        // Could happen when exitPip
         if (mToken == null || mLeash == null) {
             Log.w(TAG, "Abort animation, invalid leash");
             return;
         }
-        mUpdateHandler.post(() -> mPipAnimationController
+        mPipAnimationController
                 .getAnimator(mLeash, currentBounds, destinationBounds)
                 .setTransitionDirection(direction)
                 .setPipAnimationCallback(mPipAnimationCallback)
                 .setDuration(durationMs)
-                .start());
+                .start();
     }
 
     private Size getMinimalSize(ActivityInfo activityInfo) {
@@ -612,7 +709,7 @@
      * @return {@code true} if destinationBounds is altered for split screen
      */
     private boolean syncWithSplitScreenBounds(Rect destinationBoundsOut) {
-        if (mSplitDivider == null || !mSplitDivider.inSplitMode()) {
+        if (mSplitDivider == null || !mSplitDivider.isDividerVisible()) {
             // bail early if system is not in split screen mode
             return false;
         }
@@ -624,6 +721,27 @@
     }
 
     /**
+     * Dumps internal states.
+     */
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mTaskInfo=" + mTaskInfo);
+        pw.println(innerPrefix + "mToken=" + mToken
+                + " binder=" + (mToken != null ? mToken.asBinder() : null));
+        pw.println(innerPrefix + "mLeash=" + mLeash);
+        pw.println(innerPrefix + "mInPip=" + mInPip);
+        pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType);
+        pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams);
+        pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds);
+        pw.println(innerPrefix + "mInitialState:");
+        for (Map.Entry<IBinder, Configuration> e : mInitialState.entrySet()) {
+            pw.println(innerPrefix + "  binder=" + e.getKey()
+                    + " winConfig=" + e.getValue().windowConfiguration);
+        }
+    }
+
+    /**
      * Callback interface for PiP transitions (both from and to PiP mode)
      */
     public interface PipTransitionCallback {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
index 84f7e89..f1eef43 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipAccessibilityInteractionConnection.java
@@ -101,7 +101,7 @@
                     result = true;
                     break;
                 case AccessibilityNodeInfo.ACTION_EXPAND:
-                    mMotionHelper.expandPip();
+                    mMotionHelper.expandPipToFullscreen();
                     result = true;
                     break;
                 default:
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 0841bb7..30d6cd9 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -25,7 +25,6 @@
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.IActivityManager;
-import android.app.IActivityTaskManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ParceledListSlice;
@@ -140,7 +139,7 @@
                     != WINDOWING_MODE_PINNED) {
                 return;
             }
-            mTouchHandler.getMotionHelper().expandPip(clearedTask /* skipAnimation */);
+            mTouchHandler.getMotionHelper().expandPipToFullscreen(clearedTask /* skipAnimation */);
         }
     };
 
@@ -214,7 +213,6 @@
         }
         ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
 
-        final IActivityTaskManager activityTaskManager = ActivityTaskManager.getService();
         mPipBoundsHandler = pipBoundsHandler;
         mPipTaskOrganizer = pipTaskOrganizer;
         mPipTaskOrganizer.registerPipTransitionCallback(this);
@@ -222,7 +220,7 @@
         mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher);
         mMenuController = new PipMenuActivityController(context, mMediaController,
                 mInputConsumerController);
-        mTouchHandler = new PipTouchHandler(context, mActivityManager, activityTaskManager,
+        mTouchHandler = new PipTouchHandler(context, mActivityManager,
                 mMenuController, mInputConsumerController, mPipBoundsHandler, mPipTaskOrganizer,
                 floatingContentCoordinator, deviceConfig, pipSnapAlgorithm);
         mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
@@ -237,7 +235,7 @@
 
         try {
             mPipTaskOrganizer.registerOrganizer(WINDOWING_MODE_PINNED);
-            ActivityManager.StackInfo stackInfo = activityTaskManager.getStackInfo(
+            ActivityManager.StackInfo stackInfo = ActivityTaskManager.getService().getStackInfo(
                     WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
             if (stackInfo != null) {
                 // If SystemUI restart, and it already existed a pinned stack,
@@ -261,7 +259,7 @@
      */
     @Override
     public void expandPip() {
-        mTouchHandler.getMotionHelper().expandPip(false /* skipAnimation */);
+        mTouchHandler.getMotionHelper().expandPipToFullscreen(false /* skipAnimation */);
     }
 
     /**
@@ -378,5 +376,6 @@
         mMenuController.dump(pw, innerPrefix);
         mTouchHandler.dump(pw, innerPrefix);
         mPipBoundsHandler.dump(pw, innerPrefix);
+        mPipTaskOrganizer.dump(pw, innerPrefix);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 08d4222..d099597 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -16,16 +16,12 @@
 
 package com.android.systemui.pip.phone;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.IActivityTaskManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Debug;
-import android.os.RemoteException;
 import android.util.Log;
 
 import androidx.dynamicanimation.animation.SpringForce;
@@ -33,7 +29,6 @@
 import com.android.systemui.pip.PipSnapAlgorithm;
 import com.android.systemui.pip.PipTaskOrganizer;
 import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.util.FloatingContentCoordinator;
 import com.android.systemui.util.animation.FloatProperties;
 import com.android.systemui.util.animation.PhysicsAnimator;
@@ -60,12 +55,10 @@
     private static final float DEFAULT_FRICTION = 2f;
 
     private final Context mContext;
-    private final IActivityTaskManager mActivityTaskManager;
     private final PipTaskOrganizer mPipTaskOrganizer;
 
     private PipMenuActivityController mMenuController;
     private PipSnapAlgorithm mSnapAlgorithm;
-    private FlingAnimationUtils mFlingAnimationUtils;
 
     private final Rect mStableInsets = new Rect();
 
@@ -147,16 +140,13 @@
         public void onPipTransitionCanceled(ComponentName activity, int direction) {}
     };
 
-    public PipMotionHelper(Context context, IActivityTaskManager activityTaskManager,
-            PipTaskOrganizer pipTaskOrganizer, PipMenuActivityController menuController,
-            PipSnapAlgorithm snapAlgorithm, FlingAnimationUtils flingAnimationUtils,
+    public PipMotionHelper(Context context, PipTaskOrganizer pipTaskOrganizer,
+            PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm,
             FloatingContentCoordinator floatingContentCoordinator) {
         mContext = context;
-        mActivityTaskManager = activityTaskManager;
         mPipTaskOrganizer = pipTaskOrganizer;
         mMenuController = menuController;
         mSnapAlgorithm = snapAlgorithm;
-        mFlingAnimationUtils = flingAnimationUtils;
         mFloatingContentCoordinator = floatingContentCoordinator;
         onConfigurationChanged();
         mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback);
@@ -267,22 +257,24 @@
     /**
      * Resizes the pinned stack back to fullscreen.
      */
-    void expandPip() {
-        expandPip(false /* skipAnimation */);
+    void expandPipToFullscreen() {
+        expandPipToFullscreen(false /* skipAnimation */);
     }
 
     /**
      * Resizes the pinned stack back to fullscreen.
      */
-    void expandPip(boolean skipAnimation) {
+    void expandPipToFullscreen(boolean skipAnimation) {
         if (DEBUG) {
-            Log.d(TAG, "expandPip: skipAnimation=" + skipAnimation
+            Log.d(TAG, "exitPip: skipAnimation=" + skipAnimation
                     + " callers=\n" + Debug.getCallers(5, "    "));
         }
         cancelAnimations();
         mMenuController.hideMenuWithoutResize();
         mPipTaskOrganizer.getUpdateHandler().post(() -> {
-            mPipTaskOrganizer.dismissPip(skipAnimation ? 0 : EXPAND_STACK_TO_FULLSCREEN_DURATION);
+            mPipTaskOrganizer.exitPip(skipAnimation
+                    ? 0
+                    : EXPAND_STACK_TO_FULLSCREEN_DURATION);
         });
     }
 
@@ -292,18 +284,11 @@
     @Override
     public void dismissPip() {
         if (DEBUG) {
-            Log.d(TAG, "dismissPip: callers=\n" + Debug.getCallers(5, "    "));
+            Log.d(TAG, "removePip: callers=\n" + Debug.getCallers(5, "    "));
         }
         cancelAnimations();
         mMenuController.hideMenuWithoutResize();
-        mPipTaskOrganizer.getUpdateHandler().post(() -> {
-            try {
-                mActivityTaskManager.removeStacksInWindowingModes(
-                        new int[]{ WINDOWING_MODE_PINNED });
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to remove PiP", e);
-            }
-        });
+        mPipTaskOrganizer.removePip();
     }
 
     /** Sets the movement bounds to use to constrain PIP position animations. */
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
index d80f18a..5f0bf56 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
@@ -29,6 +29,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.input.InputManager;
+import android.os.Handler;
 import android.os.Looper;
 import android.provider.DeviceConfig;
 import android.util.DisplayMetrics;
@@ -45,6 +46,7 @@
 import com.android.systemui.util.DeviceConfigProxy;
 
 import java.util.concurrent.Executor;
+import java.util.function.Supplier;
 
 /**
  * Helper on top of PipTouchHandler that handles inputs OUTSIDE of the PIP window, which is used to
@@ -66,8 +68,15 @@
     private final Point mMinSize = new Point();
     private final Rect mLastResizeBounds = new Rect();
     private final Rect mLastDownBounds = new Rect();
-    private final Rect mTmpBounds = new Rect();
+    private final Rect mDragCornerSize = new Rect();
+    private final Rect mTmpTopLeftCorner = new Rect();
+    private final Rect mTmpTopRightCorner = new Rect();
+    private final Rect mTmpBottomLeftCorner = new Rect();
+    private final Rect mTmpBottomRightCorner = new Rect();
+    private final Rect mDisplayBounds = new Rect();
     private final int mDelta;
+    private final Supplier<Rect> mMovementBoundsSupplier;
+    private final Runnable mUpdateMovementBoundsRunnable;
 
     private boolean mAllowGesture;
     private boolean mIsAttached;
@@ -82,7 +91,8 @@
 
     public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler,
             PipMotionHelper motionHelper, DeviceConfigProxy deviceConfig,
-            PipTaskOrganizer pipTaskOrganizer) {
+            PipTaskOrganizer pipTaskOrganizer, Supplier<Rect> movementBoundsSupplier,
+            Runnable updateMovementBoundsRunnable) {
         final Resources res = context.getResources();
         context.getDisplay().getMetrics(mDisplayMetrics);
         mDisplayId = context.getDisplayId();
@@ -90,6 +100,8 @@
         mPipBoundsHandler = pipBoundsHandler;
         mMotionHelper = motionHelper;
         mPipTaskOrganizer = pipTaskOrganizer;
+        mMovementBoundsSupplier = movementBoundsSupplier;
+        mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
 
         context.getDisplay().getRealSize(mMaxSize);
         mDelta = res.getDimensionPixelSize(R.dimen.pip_resize_edge_size);
@@ -110,6 +122,14 @@
                 });
     }
 
+    private void resetDragCorners() {
+        mDragCornerSize.set(0, 0, mDelta, mDelta);
+        mTmpTopLeftCorner.set(mDragCornerSize);
+        mTmpTopRightCorner.set(mDragCornerSize);
+        mTmpBottomLeftCorner.set(mDragCornerSize);
+        mTmpBottomRightCorner.set(mDragCornerSize);
+    }
+
     private void disposeInputChannel() {
         if (mInputEventReceiver != null) {
             mInputEventReceiver.dispose();
@@ -154,34 +174,75 @@
         }
     }
 
-    private boolean isWithinTouchRegion(int x, int y) {
+    /**
+     * Check whether the current x,y coordinate is within the region in which drag-resize should
+     * start.
+     * This consists of 4 small squares on the 4 corners of the PIP window, a quarter of which
+     * overlaps with the PIP window while the rest goes outside of the PIP window.
+     *  _ _           _ _
+     * |_|_|_________|_|_|
+     * |_|_|         |_|_|
+     *   |     PIP     |
+     *   |   WINDOW    |
+     *  _|_           _|_
+     * |_|_|_________|_|_|
+     * |_|_|         |_|_|
+     */
+    public boolean isWithinTouchRegion(int x, int y) {
         final Rect currentPipBounds = mMotionHelper.getBounds();
         if (currentPipBounds == null) {
             return false;
         }
+        resetDragCorners();
+        mTmpTopLeftCorner.offset(currentPipBounds.left - mDelta / 2,
+                currentPipBounds.top - mDelta /  2);
+        mTmpTopRightCorner.offset(currentPipBounds.right - mDelta / 2,
+                currentPipBounds.top - mDelta /  2);
+        mTmpBottomLeftCorner.offset(currentPipBounds.left - mDelta / 2,
+                currentPipBounds.bottom - mDelta /  2);
+        mTmpBottomRightCorner.offset(currentPipBounds.right - mDelta / 2,
+                currentPipBounds.bottom - mDelta /  2);
 
-        mTmpBounds.set(currentPipBounds);
-        mTmpBounds.inset(-mDelta, -mDelta);
+        mTmpRegion.setEmpty();
+        mTmpRegion.op(mTmpTopLeftCorner, Region.Op.UNION);
+        mTmpRegion.op(mTmpTopRightCorner, Region.Op.UNION);
+        mTmpRegion.op(mTmpBottomLeftCorner, Region.Op.UNION);
+        mTmpRegion.op(mTmpBottomRightCorner, Region.Op.UNION);
 
-        mTmpRegion.set(mTmpBounds);
-        mTmpRegion.op(currentPipBounds, Region.Op.DIFFERENCE);
+        return mTmpRegion.contains(x, y);
+    }
 
-        if (mTmpRegion.contains(x, y)) {
-            if (x < currentPipBounds.left) {
-                mCtrlType |= CTRL_LEFT;
-            }
-            if (x > currentPipBounds.right) {
-                mCtrlType |= CTRL_RIGHT;
-            }
-            if (y < currentPipBounds.top) {
-                mCtrlType |= CTRL_TOP;
-            }
-            if (y > currentPipBounds.bottom) {
-                mCtrlType |= CTRL_BOTTOM;
-            }
-            return true;
+    private void setCtrlType(int x, int y) {
+        final Rect currentPipBounds = mMotionHelper.getBounds();
+
+        Rect movementBounds = mMovementBoundsSupplier.get();
+        mDisplayBounds.set(movementBounds.left,
+                movementBounds.top,
+                movementBounds.right + currentPipBounds.width(),
+                movementBounds.bottom + currentPipBounds.height());
+
+        if (mTmpTopLeftCorner.contains(x, y) && currentPipBounds.top != mDisplayBounds.top
+                && currentPipBounds.left != mDisplayBounds.left) {
+            mCtrlType |= CTRL_LEFT;
+            mCtrlType |= CTRL_TOP;
         }
-        return false;
+        if (mTmpTopRightCorner.contains(x, y) && currentPipBounds.top != mDisplayBounds.top
+                && currentPipBounds.right != mDisplayBounds.right) {
+            mCtrlType |= CTRL_RIGHT;
+            mCtrlType |= CTRL_TOP;
+        }
+        if (mTmpBottomRightCorner.contains(x, y)
+                && currentPipBounds.bottom != mDisplayBounds.bottom
+                && currentPipBounds.right != mDisplayBounds.right) {
+            mCtrlType |= CTRL_RIGHT;
+            mCtrlType |= CTRL_BOTTOM;
+        }
+        if (mTmpBottomLeftCorner.contains(x, y)
+                && currentPipBounds.bottom != mDisplayBounds.bottom
+                && currentPipBounds.left != mDisplayBounds.left) {
+            mCtrlType |= CTRL_LEFT;
+            mCtrlType |= CTRL_BOTTOM;
+        }
     }
 
     private void onMotionEvent(MotionEvent ev) {
@@ -190,6 +251,7 @@
             mLastResizeBounds.setEmpty();
             mAllowGesture = isWithinTouchRegion((int) ev.getX(), (int) ev.getY());
             if (mAllowGesture) {
+                setCtrlType((int) ev.getX(), (int) ev.getY());
                 mDownPoint.set(ev.getX(), ev.getY());
                 mLastDownBounds.set(mMotionHelper.getBounds());
             }
@@ -214,10 +276,14 @@
                     break;
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL:
-                    mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds);
-                    mMotionHelper.synchronizePinnedStackBounds();
-                    mCtrlType = CTRL_NONE;
-                    mAllowGesture = false;
+                    mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds, (Rect bounds) -> {
+                        new Handler(Looper.getMainLooper()).post(() -> {
+                            mMotionHelper.synchronizePinnedStackBounds();
+                            mUpdateMovementBoundsRunnable.run();
+                            mCtrlType = CTRL_NONE;
+                            mAllowGesture = false;
+                        });
+                    });
                     break;
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index b70fb3f..59c962d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -23,7 +23,6 @@
 
 import android.annotation.SuppressLint;
 import android.app.IActivityManager;
-import android.app.IActivityTaskManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Resources;
@@ -188,7 +187,7 @@
 
         @Override
         public void onPipExpand() {
-            mMotionHelper.expandPip();
+            mMotionHelper.expandPipToFullscreen();
         }
 
         @Override
@@ -210,7 +209,7 @@
 
     @SuppressLint("InflateParams")
     public PipTouchHandler(Context context, IActivityManager activityManager,
-            IActivityTaskManager activityTaskManager, PipMenuActivityController menuController,
+            PipMenuActivityController menuController,
             InputConsumerController inputConsumerController,
             PipBoundsHandler pipBoundsHandler,
             PipTaskOrganizer pipTaskOrganizer,
@@ -228,11 +227,12 @@
         mFlingAnimationUtils = new FlingAnimationUtils(context.getResources().getDisplayMetrics(),
                 2.5f);
         mGesture = new DefaultPipTouchGesture();
-        mMotionHelper = new PipMotionHelper(mContext, activityTaskManager, pipTaskOrganizer,
-                mMenuController, mSnapAlgorithm, mFlingAnimationUtils, floatingContentCoordinator);
+        mMotionHelper = new PipMotionHelper(mContext, pipTaskOrganizer, mMenuController,
+                mSnapAlgorithm, floatingContentCoordinator);
         mPipResizeGestureHandler =
                 new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper,
-                        deviceConfig, pipTaskOrganizer);
+                        deviceConfig, pipTaskOrganizer, this::getMovementBounds,
+                        this::updateMovementBounds);
         mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler,
                 () -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(),
                         true /* allowMenuTimeout */, willResizeMenu()));
@@ -572,6 +572,11 @@
 
         MotionEvent ev = (MotionEvent) inputEvent;
 
+
+        if (mPipResizeGestureHandler.isWithinTouchRegion((int) ev.getX(), (int) ev.getY())) {
+            return true;
+        }
+
         if (mMagnetizedPip.maybeConsumeMotionEvent(ev)) {
             // If the first touch event occurs within the magnetic field, pass the ACTION_DOWN event
             // to the touch state. Touch state needs a DOWN event in order to later process MOVE
@@ -809,6 +814,7 @@
     private class DefaultPipTouchGesture extends PipTouchGesture {
         private final Point mStartPosition = new Point();
         private final PointF mDelta = new PointF();
+        private boolean mShouldHideMenuAfterFling;
 
         @Override
         public void onDown(PipTouchState touchState) {
@@ -886,26 +892,22 @@
             final float velocity = PointF.length(vel.x, vel.y);
 
             if (touchState.isDragging()) {
-                Runnable endAction = null;
                 if (mMenuState != MENU_STATE_NONE) {
                     // If the menu is still visible, then just poke the menu so that
                     // it will timeout after the user stops touching it
                     mMenuController.showMenu(mMenuState, mMotionHelper.getBounds(),
                             true /* allowMenuTimeout */, willResizeMenu());
-                } else {
-                    // If the menu is not visible, then we can still be showing the activity for the
-                    // dismiss overlay, so just finish it after the animation completes
-                    endAction = mMenuController::hideMenu;
                 }
+                mShouldHideMenuAfterFling = mMenuState == MENU_STATE_NONE;
 
                 mMotionHelper.flingToSnapTarget(vel.x, vel.y,
                         PipTouchHandler.this::updateDismissFraction /* updateAction */,
-                        endAction /* endAction */);
+                        this::flingEndAction /* endAction */);
             } else if (mTouchState.isDoubleTap()) {
                 // Expand to fullscreen if this is a double tap
                 // the PiP should be frozen until the transition ends
                 setTouchEnabled(false);
-                mMotionHelper.expandPip();
+                mMotionHelper.expandPipToFullscreen();
             } else if (mMenuState != MENU_STATE_FULL) {
                 if (!mTouchState.isWaitingForDoubleTap()) {
                     // User has stalled long enough for this not to be a drag or a double tap, just
@@ -921,6 +923,15 @@
             }
             return true;
         }
+
+        private void flingEndAction() {
+            mTouchState.setAllowTouches(true);
+            if (mShouldHideMenuAfterFling) {
+                // If the menu is not visible, then we can still be showing the activity for the
+                // dismiss overlay, so just finish it after the animation completes
+                mMenuController.hideMenu();
+            }
+        }
     };
 
     /**
@@ -937,6 +948,10 @@
                 isMenuExpanded  && willResizeMenu() ? mExpandedShortestEdgeSize : 0);
     }
 
+    private Rect getMovementBounds() {
+        return mMovementBounds;
+    }
+
     /**
      * @return whether the menu will resize as a part of showing the full menu.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index f49732d..6282236 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -468,7 +468,7 @@
             mPipTaskOrganizer.scheduleAnimateResizePip(mCurrentPipBounds, mResizeAnimationDuration,
                     null);
         } else {
-            mPipTaskOrganizer.dismissPip(mResizeAnimationDuration);
+            mPipTaskOrganizer.exitPip(mResizeAnimationDuration);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index c8cf02a..10b04c0 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -302,13 +302,15 @@
     }
 
     private void showAutoSaverSuggestionNotification() {
+        final CharSequence message = mContext.getString(R.string.auto_saver_text);
         final Notification.Builder nb =
                 new Notification.Builder(mContext, NotificationChannels.HINTS)
                         .setSmallIcon(R.drawable.ic_power_saver)
                         .setWhen(0)
                         .setShowWhen(false)
                         .setContentTitle(mContext.getString(R.string.auto_saver_title))
-                        .setContentText(mContext.getString(R.string.auto_saver_text));
+                        .setStyle(new Notification.BigTextStyle().bigText(message))
+                        .setContentText(message);
         nb.setContentIntent(pendingBroadcast(ACTION_ENABLE_AUTO_SAVER));
         nb.setDeleteIntent(pendingBroadcast(ACTION_DISMISS_AUTO_SAVER_SUGGESTION));
         nb.addAction(0,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index b157f4b..aaff9ac 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -152,15 +152,33 @@
     }
 
     @Override
+    public void fakeDragBy(float xOffset) {
+        try {
+            super.fakeDragBy(xOffset);
+            // Keep on drawing until the animation has finished.
+            postInvalidateOnAnimation();
+        } catch (NullPointerException e) {
+            Log.e(TAG, "FakeDragBy called before begin", e);
+            // If we were trying to fake drag, it means we just added a new tile to the last
+            // page, so animate there.
+            final int lastPageNumber = mPages.size() - 1;
+            post(() -> {
+                setCurrentItem(lastPageNumber, true);
+                if (mBounceAnimatorSet != null) {
+                    mBounceAnimatorSet.start();
+                }
+                setOffscreenPageLimit(1);
+            });
+        }
+    }
+
+    @Override
     public void computeScroll() {
         if (!mScroller.isFinished() && mScroller.computeScrollOffset()) {
             if (!isFakeDragging()) {
                 beginFakeDrag();
             }
             fakeDragBy(getScrollX() - mScroller.getCurrX());
-            // Keep on drawing until the animation has finished.
-            postInvalidateOnAnimation();
-            return;
         } else if (isFakeDragging()) {
             endFakeDrag();
             mBounceAnimatorSet.start();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 80e5071..5e3e438 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -21,7 +21,6 @@
 import static com.android.systemui.util.Utils.useQsMediaPlayer;
 
 import android.annotation.Nullable;
-import android.app.Notification;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -30,8 +29,6 @@
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
 import android.media.MediaDescription;
 import android.metrics.LogMaker;
 import android.os.Bundle;
@@ -50,7 +47,6 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.statusbar.NotificationVisibility;
 import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
@@ -60,7 +56,6 @@
 import com.android.systemui.media.MediaControlPanel;
 import com.android.systemui.media.MediaHierarchyManager;
 import com.android.systemui.media.MediaHost;
-import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.DetailAdapter;
 import com.android.systemui.plugins.qs.QSTile;
 import com.android.systemui.plugins.qs.QSTileView;
@@ -70,7 +65,6 @@
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.settings.BrightnessController;
 import com.android.systemui.settings.ToggleSliderView;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController;
 import com.android.systemui.statusbar.policy.BrightnessMirrorController.BrightnessMirrorListener;
 import com.android.systemui.tuner.TunerService;
@@ -545,6 +539,7 @@
 
     public void setListening(boolean listening) {
         if (mListening == listening) return;
+        mListening = listening;
         if (mTileLayout != null) {
             mQSLogger.logAllTilesChangeListening(listening, getDumpableTag(), mCachedSpecs);
             mTileLayout.setListening(listening);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index 54a928d..4008918 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -339,13 +339,18 @@
         changeTileSpecs(tileSpecs-> !tileSpecs.contains(spec) && tileSpecs.add(spec));
     }
 
+    private void saveTilesToSettings(List<String> tileSpecs) {
+        Settings.Secure.putStringForUser(mContext.getContentResolver(), TILES_SETTING,
+                TextUtils.join(",", tileSpecs), null /* tag */,
+                false /* default */, mCurrentUser, true /* overrideable by restore */);
+    }
+
     private void changeTileSpecs(Predicate<List<String>> changeFunction) {
         final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
-            TILES_SETTING, ActivityManager.getCurrentUser());
+                TILES_SETTING, mCurrentUser);
         final List<String> tileSpecs = loadTileSpecs(mContext, setting);
         if (changeFunction.test(tileSpecs)) {
-            Settings.Secure.putStringForUser(mContext.getContentResolver(), TILES_SETTING,
-                TextUtils.join(",", tileSpecs), ActivityManager.getCurrentUser());
+            saveTilesToSettings(tileSpecs);
         }
     }
 
@@ -375,7 +380,7 @@
                 Intent intent = new Intent().setComponent(component);
                 TileLifecycleManager lifecycleManager = new TileLifecycleManager(new Handler(),
                         mContext, mServices, new Tile(), intent,
-                        new UserHandle(ActivityManager.getCurrentUser()),
+                        new UserHandle(mCurrentUser),
                         mBroadcastDispatcher);
                 lifecycleManager.onStopListening();
                 lifecycleManager.onTileRemoved();
@@ -384,8 +389,7 @@
             }
         }
         if (DEBUG) Log.d(TAG, "saveCurrentTiles " + newTiles);
-        Secure.putStringForUser(getContext().getContentResolver(), QSTileHost.TILES_SETTING,
-                TextUtils.join(",", newTiles), ActivityManager.getCurrentUser());
+        saveTilesToSettings(newTiles);
     }
 
     public QSTile createTile(String tileSpec) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index dfd385d..2f06c4b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -32,7 +32,6 @@
 import com.android.systemui.R;
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.dump.DumpManager;
-import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.media.MediaHierarchyManager;
 import com.android.systemui.media.MediaHost;
 import com.android.systemui.plugins.qs.QSTile;
@@ -228,6 +227,11 @@
     }
 
     @Override
+    protected boolean shouldShowDetail() {
+        return !mExpanded;
+    }
+
+    @Override
     protected void drawTile(TileRecord r, State state) {
         if (state instanceof SignalState) {
             SignalState copy = new SignalState();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index f821b19..9e2bb98 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -36,7 +36,6 @@
 import android.util.Log;
 import android.util.PathParser;
 import android.view.Gravity;
-import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
@@ -44,7 +43,6 @@
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.Switch;
-import android.widget.TextView;
 
 import com.android.settingslib.Utils;
 import com.android.systemui.R;
@@ -70,7 +68,6 @@
     private float mStrokeWidthInactive;
 
     private final ImageView mBg;
-    private final TextView mDetailText;
     private final int mColorActive;
     private final int mColorInactive;
     private final int mColorDisabled;
@@ -112,12 +109,6 @@
                 ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT,
                 Gravity.CENTER);
         mIconFrame.addView(mIcon, params);
-
-        // "..." afforadance below icon
-        mDetailText = (TextView) LayoutInflater.from(context).inflate(R.layout.qs_tile_detail_text,
-                mIconFrame, false);
-        mIconFrame.addView(mDetailText);
-
         mIconFrame.setClipChildren(false);
         mIconFrame.setClipToPadding(false);
 
@@ -173,10 +164,6 @@
             tile.longClick();
             return true;
         });
-
-        if (tile.supportsDetailView()) {
-            mDetailText.setVisibility(View.VISIBLE);
-        }
     }
 
     public void init(OnClickListener click, OnClickListener secondaryClick,
@@ -254,8 +241,6 @@
             mCircleColor = circleColor;
         }
 
-        mDetailText.setTextColor(QSTileImpl.getColorForState(getContext(), state.state));
-
         mShowRippleEffect = state.showRippleEffect;
         setClickable(state.state != Tile.STATE_UNAVAILABLE);
         setLongClickable(state.handlesLongClick);
@@ -400,4 +385,4 @@
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 7e5f2e19..87faacc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -68,8 +68,6 @@
 import com.android.systemui.qs.QSHost;
 import com.android.systemui.qs.QuickStatusBarHeader;
 import com.android.systemui.qs.logging.QSLogger;
-import com.android.systemui.qs.tiles.QSSettingsControllerKt;
-import com.android.systemui.qs.tiles.QSSettingsPanel;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -152,19 +150,12 @@
      */
     abstract public int getMetricsCategory();
 
-    /**
-     * Experimental option on whether to use settings panels. Only loaded on creation, so the tile
-     * needs to be removed and added for this to take effect.
-     */
-    protected final QSSettingsPanel mQSSettingsPanelOption;
-
     protected QSTileImpl(QSHost host) {
         mHost = host;
         mContext = host.getContext();
         mInstanceId = host.getNewInstanceId();
         mState = newTileState();
         mTmpState = newTileState();
-        mQSSettingsPanelOption = QSSettingsControllerKt.getQSSettingsPanelOption();
         mQSLogger = host.getQSLogger();
         mUiEventLogger = host.getUiEventLogger();
     }
@@ -366,10 +357,6 @@
      * {@link QSTileImpl#getLongClickIntent}
      */
     protected void handleLongClick() {
-        if (mQSSettingsPanelOption == QSSettingsPanel.USE_DETAIL) {
-            showDetail(true);
-            return;
-        }
         Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(
                 getLongClickIntent(), 0);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QSSettingsController.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/QSSettingsController.kt
deleted file mode 100644
index c7ef0be..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QSSettingsController.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.qs.tiles
-
-import android.provider.DeviceConfig
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
-
-enum class QSSettingsPanel {
-    DEFAULT,
-    OPEN_LONG_PRESS,
-    OPEN_CLICK,
-    USE_DETAIL
-}
-
-fun getQSSettingsPanelOption(): QSSettingsPanel =
-        when (DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.QS_USE_SETTINGS_PANELS, 0)) {
-            1 -> QSSettingsPanel.OPEN_LONG_PRESS
-            2 -> QSSettingsPanel.OPEN_CLICK
-            3 -> QSSettingsPanel.USE_DETAIL
-            else -> QSSettingsPanel.DEFAULT
-        }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index da78903..d7dd6f2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -79,19 +79,15 @@
         state.value = isRecording || isStarting;
         state.state = (isRecording || isStarting) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.label = mContext.getString(R.string.quick_settings_screen_record_label);
+        state.icon = ResourceIcon.get(R.drawable.ic_screenrecord);
 
         if (isRecording) {
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_screenrecord);
             state.secondaryLabel = mContext.getString(R.string.quick_settings_screen_record_stop);
         } else if (isStarting) {
             // round, since the timer isn't exact
             int countdown = (int) Math.floorDiv(mMillisUntilFinished + 500, 1000);
-            // TODO update icon
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_screenrecord);
             state.secondaryLabel = String.format("%d...", countdown);
         } else {
-            // TODO update icon
-            state.icon = ResourceIcon.get(R.drawable.ic_qs_screenrecord);
             state.secondaryLabel = mContext.getString(R.string.quick_settings_screen_record_start);
         }
         state.contentDescription = TextUtils.isEmpty(state.secondaryLabel)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index f169501..1279d42 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -56,7 +56,6 @@
 /** Quick settings tile: Wifi **/
 public class WifiTile extends QSTileImpl<SignalState> {
     private static final Intent WIFI_SETTINGS = new Intent(Settings.ACTION_WIFI_SETTINGS);
-    private static final Intent WIFI_PANEL = new Intent(Settings.Panel.ACTION_WIFI);
 
     protected final NetworkController mController;
     private final AccessPointController mWifiController;
@@ -109,21 +108,11 @@
 
     @Override
     public Intent getLongClickIntent() {
-        if (mQSSettingsPanelOption == QSSettingsPanel.OPEN_LONG_PRESS) return WIFI_PANEL;
-        else return WIFI_SETTINGS;
-    }
-
-    @Override
-    public boolean supportsDetailView() {
-        return getDetailAdapter() != null && mQSSettingsPanelOption == QSSettingsPanel.OPEN_CLICK;
+        return WIFI_SETTINGS;
     }
 
     @Override
     protected void handleClick() {
-        if (mQSSettingsPanelOption == QSSettingsPanel.OPEN_CLICK) {
-            mActivityStarter.postStartActivityDismissingKeyguard(WIFI_PANEL, 0);
-            return;
-        }
         // Secondary clicks are header clicks, just toggle.
         mState.copyTo(mStateBeforeClick);
         boolean wifiEnabled = mState.value;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 4148289..9cfb1b2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.screenshot;
 
+import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
+import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
@@ -61,16 +63,19 @@
 import android.view.Display;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewOutlineProvider;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityManager;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.widget.FrameLayout;
+import android.widget.HorizontalScrollView;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.Toast;
@@ -169,7 +174,7 @@
     private static final long SCREENSHOT_DISMISS_ALPHA_OFFSET_MS = 50; // delay before starting fade
     private static final float SCREENSHOT_ACTIONS_START_SCALE_X = .7f;
     private static final float ROUNDED_CORNER_RADIUS = .05f;
-    private static final long SCREENSHOT_CORNER_TIMEOUT_MILLIS = 6000;
+    private static final int SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS = 6000;
     private static final int MESSAGE_CORNER_TIMEOUT = 2;
 
     private final Interpolator mAccelerateInterpolator = new AccelerateInterpolator();
@@ -183,24 +188,25 @@
     private final Display mDisplay;
     private final DisplayMetrics mDisplayMetrics;
 
-    private final View mScreenshotLayout;
-    private final ScreenshotSelectorView mScreenshotSelectorView;
-    private final ImageView mScreenshotAnimatedView;
-    private final ImageView mScreenshotPreview;
-    private final ImageView mScreenshotFlash;
-    private final ImageView mActionsContainerBackground;
-    private final FrameLayout mActionsContainer;
-    private final LinearLayout mActionsView;
-    private final ImageView mBackgroundProtection;
-    private final FrameLayout mDismissButton;
-    private final ImageView mDismissImage;
+    private View mScreenshotLayout;
+    private ScreenshotSelectorView mScreenshotSelectorView;
+    private ImageView mScreenshotAnimatedView;
+    private ImageView mScreenshotPreview;
+    private ImageView mScreenshotFlash;
+    private ImageView mActionsContainerBackground;
+    private HorizontalScrollView mActionsContainer;
+    private LinearLayout mActionsView;
+    private ImageView mBackgroundProtection;
+    private FrameLayout mDismissButton;
 
     private Bitmap mScreenBitmap;
     private SaveImageInBackgroundTask mSaveInBgTask;
     private Animator mScreenshotAnimation;
     private Runnable mOnCompleteRunnable;
-    private boolean mInDarkMode = false;
     private Animator mDismissAnimation;
+    private boolean mInDarkMode = false;
+    private boolean mDirectionLTR = true;
+    private boolean mOrientationPortrait = true;
 
     private float mScreenshotOffsetXPx;
     private float mScreenshotOffsetYPx;
@@ -232,57 +238,18 @@
      */
     @Inject
     public GlobalScreenshot(
-            Context context, @Main Resources resources, LayoutInflater layoutInflater,
+            Context context, @Main Resources resources,
             ScreenshotNotificationsController screenshotNotificationsController,
             UiEventLogger uiEventLogger) {
         mContext = context;
         mNotificationsController = screenshotNotificationsController;
         mUiEventLogger = uiEventLogger;
 
-        // Inflate the screenshot layout
-        mScreenshotLayout = layoutInflater.inflate(R.layout.global_screenshot, null);
-        mScreenshotAnimatedView =
-                mScreenshotLayout.findViewById(R.id.global_screenshot_animated_view);
-        mScreenshotAnimatedView.setClipToOutline(true);
-        mScreenshotAnimatedView.setOutlineProvider(new ViewOutlineProvider() {
-            @Override
-            public void getOutline(View view, Outline outline) {
-                outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
-                        ROUNDED_CORNER_RADIUS * view.getWidth());
-            }
-        });
-        mScreenshotPreview = mScreenshotLayout.findViewById(R.id.global_screenshot_preview);
-        mScreenshotPreview.setClipToOutline(true);
-        mScreenshotPreview.setOutlineProvider(new ViewOutlineProvider() {
-            @Override
-            public void getOutline(View view, Outline outline) {
-                outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
-                        ROUNDED_CORNER_RADIUS * view.getWidth());
-            }
-        });
-
-        mActionsContainerBackground = mScreenshotLayout.findViewById(
-                R.id.global_screenshot_actions_container_background);
-        mActionsContainer = mScreenshotLayout.findViewById(
-                R.id.global_screenshot_actions_container);
-        mActionsView = mScreenshotLayout.findViewById(R.id.global_screenshot_actions);
-        mBackgroundProtection = mScreenshotLayout.findViewById(
-                R.id.global_screenshot_actions_background);
-        mDismissButton = mScreenshotLayout.findViewById(R.id.global_screenshot_dismiss_button);
-        mDismissButton.setOnClickListener(view -> {
-            mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL);
-            dismissScreenshot("dismiss_button", false);
-            mOnCompleteRunnable.run();
-        });
-        mDismissImage = mDismissButton.findViewById(R.id.global_screenshot_dismiss_image);
-
-        mScreenshotFlash = mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
-        mScreenshotSelectorView = mScreenshotLayout.findViewById(R.id.global_screenshot_selector);
-        mScreenshotLayout.setFocusable(true);
-        mScreenshotSelectorView.setFocusable(true);
-        mScreenshotSelectorView.setFocusableInTouchMode(true);
-        mScreenshotAnimatedView.setPivotX(0);
-        mScreenshotAnimatedView.setPivotY(0);
+        reloadAssets();
+        Configuration config = mContext.getResources().getConfiguration();
+        mInDarkMode = config.isNightModeActive();
+        mDirectionLTR = config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
+        mOrientationPortrait = config.orientation == ORIENTATION_PORTRAIT;
 
         // Setup the window that we are going to use
         mWindowLayoutParams = new WindowManager.LayoutParams(
@@ -333,6 +300,121 @@
         inoutInfo.touchableRegion.set(touchRegion);
     }
 
+    private void onConfigChanged(Configuration newConfig) {
+        boolean needsUpdate = false;
+        // dark mode
+        if (newConfig.isNightModeActive()) {
+            // Night mode is active, we're using dark theme
+            if (!mInDarkMode) {
+                mInDarkMode = true;
+                needsUpdate = true;
+            }
+        } else {
+            // Night mode is not active, we're using the light theme
+            if (mInDarkMode) {
+                mInDarkMode = false;
+                needsUpdate = true;
+            }
+        }
+
+        // RTL configuration
+        switch (newConfig.getLayoutDirection()) {
+            case View.LAYOUT_DIRECTION_LTR:
+                if (!mDirectionLTR) {
+                    mDirectionLTR = true;
+                    needsUpdate = true;
+                }
+                break;
+            case View.LAYOUT_DIRECTION_RTL:
+                if (mDirectionLTR) {
+                    mDirectionLTR = false;
+                    needsUpdate = true;
+                }
+                break;
+        }
+
+        // portrait/landscape orientation
+        switch (newConfig.orientation) {
+            case ORIENTATION_PORTRAIT:
+                if (!mOrientationPortrait) {
+                    mOrientationPortrait = true;
+                    needsUpdate = true;
+                }
+                break;
+            case ORIENTATION_LANDSCAPE:
+                if (mOrientationPortrait) {
+                    mOrientationPortrait = false;
+                    needsUpdate = true;
+                }
+                break;
+        }
+
+        if (needsUpdate) {
+            reloadAssets();
+        }
+    }
+
+    /**
+     * Update assets (called when the dark theme status changes). We only need to update the dismiss
+     * button and the actions container background, since the buttons are re-inflated on demand.
+     */
+    private void reloadAssets() {
+        boolean wasAttached = mScreenshotLayout != null && mScreenshotLayout.isAttachedToWindow();
+        if (wasAttached) {
+            mWindowManager.removeView(mScreenshotLayout);
+        }
+
+        // Inflate the screenshot layout
+        mScreenshotLayout = LayoutInflater.from(mContext).inflate(R.layout.global_screenshot, null);
+        mScreenshotAnimatedView =
+                mScreenshotLayout.findViewById(R.id.global_screenshot_animated_view);
+        mScreenshotAnimatedView.setClipToOutline(true);
+        mScreenshotAnimatedView.setOutlineProvider(new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
+                        ROUNDED_CORNER_RADIUS * view.getWidth());
+            }
+        });
+        mScreenshotPreview = mScreenshotLayout.findViewById(R.id.global_screenshot_preview);
+        mScreenshotPreview.setClipToOutline(true);
+        mScreenshotPreview.setOutlineProvider(new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                outline.setRoundRect(new Rect(0, 0, view.getWidth(), view.getHeight()),
+                        ROUNDED_CORNER_RADIUS * view.getWidth());
+            }
+        });
+
+        mActionsContainerBackground = mScreenshotLayout.findViewById(
+                R.id.global_screenshot_actions_container_background);
+        mActionsContainer = mScreenshotLayout.findViewById(
+                R.id.global_screenshot_actions_container);
+        mActionsView = mScreenshotLayout.findViewById(R.id.global_screenshot_actions);
+        mBackgroundProtection = mScreenshotLayout.findViewById(
+                R.id.global_screenshot_actions_background);
+        mDismissButton = mScreenshotLayout.findViewById(R.id.global_screenshot_dismiss_button);
+        mDismissButton.setOnClickListener(view -> {
+            mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_EXPLICIT_DISMISSAL);
+            dismissScreenshot("dismiss_button", false);
+            mOnCompleteRunnable.run();
+        });
+
+        mScreenshotFlash = mScreenshotLayout.findViewById(R.id.global_screenshot_flash);
+        mScreenshotSelectorView = mScreenshotLayout.findViewById(R.id.global_screenshot_selector);
+        mScreenshotLayout.setFocusable(true);
+        mScreenshotSelectorView.setFocusable(true);
+        mScreenshotSelectorView.setFocusableInTouchMode(true);
+        mScreenshotAnimatedView.setPivotX(0);
+        mScreenshotAnimatedView.setPivotY(0);
+        mActionsContainer.setScrollX(0);
+
+        if (wasAttached) {
+            mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
+        }
+    }
+
+
     /**
      * Creates a new worker thread and saves the screenshot to the media store.
      */
@@ -382,10 +464,8 @@
         mScreenBitmap.setHasAlpha(false);
         mScreenBitmap.prepareToDraw();
 
-        updateDarkTheme();
+        onConfigChanged(mContext.getResources().getConfiguration());
 
-        mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
-        mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
 
         if (mDismissAnimation != null && mDismissAnimation.isRunning()) {
             mDismissAnimation.cancel();
@@ -395,7 +475,6 @@
     }
 
     void takeScreenshot(Consumer<Uri> finisher, Runnable onComplete) {
-        dismissScreenshot("new screenshot requested", true);
         mOnCompleteRunnable = onComplete;
 
         mDisplay.getRealMetrics(mDisplayMetrics);
@@ -407,7 +486,6 @@
     void handleImageAsScreenshot(Bitmap screenshot, Rect screenshotScreenBounds,
             Insets visibleInsets, int taskId, Consumer<Uri> finisher, Runnable onComplete) {
         // TODO use taskId and visibleInsets
-        dismissScreenshot("new screenshot requested", true);
         mOnCompleteRunnable = onComplete;
         takeScreenshot(screenshot, finisher, screenshotScreenBounds);
     }
@@ -513,41 +591,6 @@
     }
 
     /**
-     * Update assets (called when the dark theme status changes). We only need to update the
-     * dismiss
-     * button and the actions container background, since the buttons are re-inflated on demand.
-     */
-    private void reloadAssets() {
-        mDismissImage.setImageDrawable(mContext.getDrawable(R.drawable.screenshot_cancel));
-        mActionsContainerBackground.setBackground(
-                mContext.getDrawable(R.drawable.action_chip_container_background));
-    }
-
-    /**
-     * Checks the current dark theme status and updates if it has changed.
-     */
-    private void updateDarkTheme() {
-        int currentNightMode = mContext.getResources().getConfiguration().uiMode
-                & Configuration.UI_MODE_NIGHT_MASK;
-        switch (currentNightMode) {
-            case Configuration.UI_MODE_NIGHT_NO:
-                // Night mode is not active, we're using the light theme
-                if (mInDarkMode) {
-                    mInDarkMode = false;
-                    reloadAssets();
-                }
-                break;
-            case Configuration.UI_MODE_NIGHT_YES:
-                // Night mode is active, we're using dark theme
-                if (!mInDarkMode) {
-                    mInDarkMode = true;
-                    reloadAssets();
-                }
-                break;
-        }
-    }
-
-    /**
      * Starts the animation after taking the screenshot
      */
     private void startAnimation(final Consumer<Uri> finisher, int w, int h,
@@ -588,26 +631,48 @@
                         } else {
                             createScreenshotActionsShadeAnimation(imageData).start();
                         }
+                        AccessibilityManager accessibilityManager = (AccessibilityManager)
+                                mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
+                        long timeoutMs = accessibilityManager.getRecommendedTimeoutMillis(
+                                SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS,
+                                AccessibilityManager.FLAG_CONTENT_CONTROLS);
+
                         mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
                         mScreenshotHandler.sendMessageDelayed(
                                 mScreenshotHandler.obtainMessage(MESSAGE_CORNER_TIMEOUT),
-                                SCREENSHOT_CORNER_TIMEOUT_MILLIS);
+                                timeoutMs);
                     });
                 }
             }
         });
         mScreenshotHandler.post(() -> {
-            // Play the shutter sound to notify that we've taken a screenshot
-            mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
+            if (!mScreenshotLayout.isAttachedToWindow()) {
+                mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);
+            }
+            mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);
 
-            mScreenshotPreview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-            mScreenshotPreview.buildLayer();
-            mScreenshotAnimation.start();
+            mScreenshotHandler.post(() -> {
+
+                // Play the shutter sound to notify that we've taken a screenshot
+                mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
+
+                mScreenshotPreview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                mScreenshotPreview.buildLayer();
+                mScreenshotAnimation.start();
+            });
+
         });
+
     }
 
     private AnimatorSet createScreenshotDropInAnimation(int width, int height, Rect bounds) {
-        float cornerScale = mCornerSizeX / (float) width;
+        int rotation = mContext.getDisplay().getRotation();
+        float cornerScale;
+        if (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) {
+            cornerScale = (mCornerSizeX / (float) height);
+        } else {
+            cornerScale = (mCornerSizeX / (float) width);
+        }
 
         mScreenshotAnimatedView.setScaleX(1);
         mScreenshotAnimatedView.setScaleY(1);
@@ -632,8 +697,7 @@
 
         final PointF startPos = new PointF(bounds.centerX(), bounds.centerY());
         float finalX;
-        if (mContext.getResources().getConfiguration().getLayoutDirection()
-                == View.LAYOUT_DIRECTION_LTR) {
+        if (mDirectionLTR) {
             finalX = mScreenshotOffsetXPx + width * cornerScale / 2f;
         } else {
             finalX = width - mScreenshotOffsetXPx - width * cornerScale / 2f;
@@ -713,7 +777,6 @@
     private ValueAnimator createScreenshotActionsShadeAnimation(SavedImageData imageData) {
         LayoutInflater inflater = LayoutInflater.from(mContext);
         mActionsView.removeAllViews();
-        mActionsContainer.setScrollX(0);
         mScreenshotLayout.invalidate();
         mScreenshotLayout.requestLayout();
         mScreenshotLayout.getViewTreeObserver().dispatchOnGlobalLayout();
@@ -803,14 +866,11 @@
         animator.setDuration(SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS);
         float alphaFraction = (float) SCREENSHOT_ACTIONS_ALPHA_DURATION_MS
                 / SCREENSHOT_ACTIONS_EXPANSION_DURATION_MS;
-        mActionsContainer.setVisibility(View.VISIBLE);
         mActionsContainer.setAlpha(0f);
         mActionsContainerBackground.setAlpha(0f);
+        mActionsContainer.setVisibility(View.VISIBLE);
         mActionsContainerBackground.setVisibility(View.VISIBLE);
 
-        mActionsContainer.setPivotX(0);
-        mActionsContainerBackground.setPivotX(0);
-
         animator.addUpdateListener(animation -> {
             float t = animation.getAnimatedFraction();
             mBackgroundProtection.setAlpha(t);
@@ -825,6 +885,10 @@
                 chip.setAlpha(t);
                 chip.setScaleX(1 / containerScale); // invert to keep size of children constant
             }
+            mActionsContainer.setScrollX(mDirectionLTR ? 0 : mActionsContainer.getWidth());
+            mActionsContainer.setPivotX(mDirectionLTR ? 0 : mActionsContainer.getWidth());
+            mActionsContainerBackground.setPivotX(
+                    mDirectionLTR ? 0 : mActionsContainerBackground.getWidth());
         });
         return animator;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
index 4f20492..f7f1223 100644
--- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java
@@ -92,7 +92,7 @@
     }
 
     private void handleDockKey(long shortcutCode) {
-        if (mDivider == null || !mDivider.inSplitMode()) {
+        if (mDivider == null || !mDivider.isDividerVisible()) {
             // Split the screen
             mRecents.splitPrimaryTask((shortcutCode == SC_DOCK_LEFT)
                     ? SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 02a7aca..cdd1280 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.stackdivider;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
 import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
 import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
@@ -123,14 +124,17 @@
                 SplitDisplayLayout sdl = new SplitDisplayLayout(mContext, displayLayout, mSplits);
                 sdl.rotateTo(toRotation);
                 mRotateSplitLayout = sdl;
-                int position = mMinimized ? mView.mSnapTargetBeforeMinimized.position
-                        : mView.getCurrentPosition();
+                final int position = isDividerVisible()
+                        ? (mMinimized ? mView.mSnapTargetBeforeMinimized.position
+                                : mView.getCurrentPosition())
+                        // snap resets to middle target when not in split-mode
+                        : sdl.getSnapAlgorithm().getMiddleTarget().position;
                 DividerSnapAlgorithm snap = sdl.getSnapAlgorithm();
                 final DividerSnapAlgorithm.SnapTarget target =
                         snap.calculateNonDismissingSnapTarget(position);
                 sdl.resizeSplits(target.position, t);
 
-                if (inSplitMode()) {
+                if (isSplitActive()) {
                     WindowManagerProxy.applyHomeTasksMinimized(sdl, mSplits.mSecondary.token, t);
                 }
             };
@@ -199,7 +203,7 @@
         @Override
         public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
                 boolean imeShouldShow, SurfaceControl.Transaction t) {
-            if (!inSplitMode()) {
+            if (!isDividerVisible()) {
                 return;
             }
             final boolean splitIsVisible = !mView.isHidden();
@@ -298,7 +302,7 @@
         @Override
         public void onImePositionChanged(int displayId, int imeTop,
                 SurfaceControl.Transaction t) {
-            if (mAnimation != null || !inSplitMode() || mPaused) {
+            if (mAnimation != null || !isDividerVisible() || mPaused) {
                 // Not synchronized with IME anymore, so return.
                 return;
             }
@@ -310,7 +314,7 @@
         @Override
         public void onImeEndPositioning(int displayId, boolean cancelled,
                 SurfaceControl.Transaction t) {
-            if (mAnimation != null || !inSplitMode() || mPaused) {
+            if (mAnimation != null || !isDividerVisible() || mPaused) {
                 // Not synchronized with IME anymore, so return.
                 return;
             }
@@ -479,7 +483,7 @@
 
             @Override
             public void onKeyguardShowingChanged() {
-                if (!inSplitMode() || mView == null) {
+                if (!isDividerVisible() || mView == null) {
                     return;
                 }
                 mView.setHidden(mKeyguardStateController.isShowing());
@@ -559,10 +563,20 @@
     }
 
     /** {@code true} if this is visible */
-    public boolean inSplitMode() {
+    public boolean isDividerVisible() {
         return mView != null && mView.getVisibility() == View.VISIBLE;
     }
 
+    /**
+     * This indicates that at-least one of the splits has content. This differs from
+     * isDividerVisible because the divider is only visible once *everything* is in split mode
+     * while this only cares if some things are (eg. while entering/exiting as well).
+     */
+    private boolean isSplitActive() {
+        return mSplits.mPrimary.topActivityType != ACTIVITY_TYPE_UNDEFINED
+                || mSplits.mSecondary.topActivityType != ACTIVITY_TYPE_UNDEFINED;
+    }
+
     private void addDivider(Configuration configuration) {
         Context dctx = mDisplayController.getDisplayContext(mContext.getDisplayId());
         mView = (DividerView)
@@ -592,13 +606,11 @@
         removeDivider();
         addDivider(configuration);
 
-        if (mView != null) {
-            if (mMinimized) {
-                mView.setMinimizedDockStack(true, mHomeStackResizable);
-                updateTouchable();
-            }
-            mView.setHidden(isDividerHidden);
+        if (mMinimized) {
+            mView.setMinimizedDockStack(true, mHomeStackResizable);
+            updateTouchable();
         }
+        mView.setHidden(isDividerHidden);
     }
 
     void onTaskVanished() {
@@ -610,7 +622,7 @@
                 mContext.getDisplayId()).getResources().getConfiguration()));
     }
 
-    void updateVisibility(final boolean visible) {
+    private void updateVisibility(final boolean visible) {
         if (DEBUG) Slog.d(TAG, "Updating visibility " + mVisible + "->" + visible);
         if (mVisible != visible) {
             mVisible = visible;
@@ -637,8 +649,9 @@
     }
 
     void onSplitDismissed() {
-        mMinimized = false;
         updateVisibility(false /* visible */);
+        mMinimized = false;
+        removeDivider();
     }
 
     /** Switch to minimized state if appropriate */
@@ -656,7 +669,8 @@
     private void setHomeMinimized(final boolean minimized, boolean homeStackResizable) {
         if (DEBUG) {
             Slog.d(TAG, "setHomeMinimized  min:" + mMinimized + "->" + minimized + " hrsz:"
-                    + mHomeStackResizable + "->" + homeStackResizable + " split:" + inSplitMode());
+                    + mHomeStackResizable + "->" + homeStackResizable
+                    + " split:" + isDividerVisible());
         }
         WindowContainerTransaction wct = new WindowContainerTransaction();
         final boolean minimizedChanged = mMinimized != minimized;
@@ -671,7 +685,7 @@
         final boolean homeResizableChanged = mHomeStackResizable != homeStackResizable;
         if (homeResizableChanged) {
             mHomeStackResizable = homeStackResizable;
-            if (inSplitMode()) {
+            if (isDividerVisible()) {
                 WindowManagerProxy.applyHomeTasksMinimized(
                         mSplitLayout, mSplits.mSecondary.token, wct);
             }
@@ -781,20 +795,22 @@
 
     /** Register a listener that gets called whenever the existence of the divider changes */
     public void registerInSplitScreenListener(Consumer<Boolean> listener) {
-        listener.accept(inSplitMode());
+        listener.accept(isDividerVisible());
         synchronized (mDockedStackExistsListeners) {
             mDockedStackExistsListeners.add(new WeakReference<>(listener));
         }
     }
 
     void startEnterSplit() {
+        update(mDisplayController.getDisplayContext(
+                mContext.getDisplayId()).getResources().getConfiguration());
         // Set resizable directly here because applyEnterSplit already resizes home stack.
         mHomeStackResizable = WindowManagerProxy.applyEnterSplit(mSplits, mSplitLayout);
     }
 
     void ensureMinimizedSplit() {
         setHomeMinimized(true /* minimized */, mSplits.mSecondary.isResizable());
-        if (!inSplitMode()) {
+        if (!isDividerVisible()) {
             // Wasn't in split-mode yet, so enter now.
             if (DEBUG) {
                 Slog.d(TAG, " entering split mode with minimized=true");
@@ -805,7 +821,7 @@
 
     void ensureNormalSplit() {
         setHomeMinimized(false /* minimized */, mHomeStackResizable);
-        if (!inSplitMode()) {
+        if (!isDividerVisible()) {
             // Wasn't in split-mode, so enter now.
             if (DEBUG) {
                 Slog.d(TAG, " enter split mode unminimized ");
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 060760a..db89cea 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -28,12 +28,14 @@
 import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.Region.Op;
 import android.hardware.display.DisplayManager;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.RemoteException;
 import android.util.AttributeSet;
 import android.util.Slog;
 import android.view.Display;
@@ -164,6 +166,9 @@
     int mDividerPositionX;
     int mDividerPositionY;
 
+    private final Matrix mTmpMatrix = new Matrix();
+    private final float[] mTmpValues = new float[9];
+
     // The view is removed or in the process of been removed from the system.
     private boolean mRemoved;
 
@@ -249,6 +254,22 @@
         }
     };
 
+    private Runnable mUpdateEmbeddedMatrix = () -> {
+        if (getViewRootImpl() == null) {
+            return;
+        }
+        if (isHorizontalDivision()) {
+            mTmpMatrix.setTranslate(0, mDividerPositionY - mDividerInsets);
+        } else {
+            mTmpMatrix.setTranslate(mDividerPositionX - mDividerInsets, 0);
+        }
+        mTmpMatrix.getValues(mTmpValues);
+        try {
+            getViewRootImpl().getAccessibilityEmbeddedConnection().setScreenMatrix(mTmpValues);
+        } catch (RemoteException e) {
+        }
+    };
+
     public DividerView(Context context) {
         this(context, null);
     }
@@ -1084,6 +1105,10 @@
                 t.setPosition(dividerCtrl, mDividerPositionX - mDividerInsets, 0);
             }
         }
+        if (getViewRootImpl() != null) {
+            mHandler.removeCallbacks(mUpdateEmbeddedMatrix);
+            mHandler.post(mUpdateEmbeddedMatrix);
+        }
     }
 
     void setResizeDimLayer(Transaction t, boolean primary, float alpha) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
index 2862c83..c496d22 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/SplitScreenTaskOrganizer.java
@@ -193,7 +193,7 @@
                 Log.d(TAG, " at-least one split empty " + mPrimary.topActivityType
                         + "  " + mSecondary.topActivityType);
             }
-            if (mDivider.inSplitMode()) {
+            if (mDivider.isDividerVisible()) {
                 // Was in split-mode, which means we are leaving split, so continue that.
                 // This happens when the stack in the primary-split is dismissed.
                 if (DEBUG) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 2647c04..2baab61 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -19,8 +19,8 @@
 import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
 
 import static com.android.systemui.DejankUtils.whitelistIpcs;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_MEDIA_CONTROLS;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_MEDIA_CONTROLS;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT;
 
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index e7f2618..765f85a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -195,13 +195,15 @@
                 boolean wasChildInGroup = ent.isChildInGroup();
                 if (isChildInGroup && !wasChildInGroup) {
                     isChildInGroup = wasChildInGroup;
-                    mVisualStabilityManager.addGroupChangesAllowedCallback(mEntryManager);
+                    mVisualStabilityManager.addGroupChangesAllowedCallback(mEntryManager,
+                            false /* persistent */);
                 } else if (!isChildInGroup && wasChildInGroup) {
                     // We allow grouping changes if the group was collapsed
                     if (mGroupManager.isLogicalGroupExpanded(ent.getSbn())) {
                         isChildInGroup = wasChildInGroup;
                         parent = ent.getRow().getNotificationParent().getEntry();
-                        mVisualStabilityManager.addGroupChangesAllowedCallback(mEntryManager);
+                        mVisualStabilityManager.addGroupChangesAllowedCallback(mEntryManager,
+                                false /* persistent */);
                     }
                 }
             }
@@ -286,7 +288,8 @@
                 if (mVisualStabilityManager.canReorderNotification(targetChild)) {
                     mListContainer.changeViewPosition(targetChild, i);
                 } else {
-                    mVisualStabilityManager.addReorderingAllowedCallback(mEntryManager);
+                    mVisualStabilityManager.addReorderingAllowedCallback(mEntryManager,
+                            false  /* persistent */);
                 }
             }
             j++;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index 02c98ae..88f148b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -121,14 +121,14 @@
     }
 
     override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
-        return canHandleMotionEvent() && startExpansion(event)
+        return maybeStartExpansion(event)
     }
 
-    private fun canHandleMotionEvent(): Boolean {
-        return !wakeUpCoordinator.canShowPulsingHuns || qsExpanded || bouncerShowing
-    }
-
-    private fun startExpansion(event: MotionEvent): Boolean {
+    private fun maybeStartExpansion(event: MotionEvent): Boolean {
+        if (!wakeUpCoordinator.canShowPulsingHuns || qsExpanded ||
+                bouncerShowing) {
+            return false
+        }
         if (velocityTracker == null) {
             velocityTracker = VelocityTracker.obtain()
         }
@@ -177,14 +177,9 @@
     }
 
     override fun onTouchEvent(event: MotionEvent): Boolean {
-        if (!canHandleMotionEvent()) {
-            return false
+        if (!isExpanding) {
+            return maybeStartExpansion(event)
         }
-
-        if (!isExpanding || event.actionMasked == MotionEvent.ACTION_DOWN) {
-            return startExpansion(event)
-        }
-
         velocityTracker!!.addMovement(event)
         val y = event.y
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java
index 44ef6b4..006b219 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ScreenRecordDrawable.java
@@ -39,10 +39,13 @@
  */
 public class ScreenRecordDrawable extends DrawableWrapper {
     private Drawable mFillDrawable;
+    private Drawable mIconDrawable;
     private int mHorizontalPadding;
     private int mLevel;
     private float mTextSize;
-    private float mIconRadius;
+    private int mIconRadius;
+    private int mWidthPx;
+    private int mHeightPx;
     private Paint mPaint;
 
     /** No-arg constructor used by drawable inflation. */
@@ -57,6 +60,7 @@
         super.inflate(r, parser, attrs, theme);
         setDrawable(r.getDrawable(R.drawable.ic_screen_record_background, theme).mutate());
         mFillDrawable = r.getDrawable(R.drawable.ic_screen_record_background, theme).mutate();
+        mIconDrawable = r.getDrawable(R.drawable.ic_screenrecord, theme).mutate();
         mHorizontalPadding = r.getDimensionPixelSize(R.dimen.status_bar_horizontal_padding);
 
         mTextSize = r.getDimensionPixelSize(R.dimen.screenrecord_status_text_size);
@@ -68,6 +72,19 @@
         mPaint.setColor(Color.WHITE);
         mPaint.setTextSize(mTextSize);
         mPaint.setFakeBoldText(true);
+
+        mWidthPx = r.getDimensionPixelSize(R.dimen.screenrecord_status_icon_width);
+        mHeightPx = r.getDimensionPixelSize(R.dimen.screenrecord_status_icon_height);
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mWidthPx;
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mHeightPx;
     }
 
     @Override
@@ -103,10 +120,14 @@
             String val = String.valueOf(mLevel);
             Rect textBounds = new Rect();
             mPaint.getTextBounds(val, 0, val.length(), textBounds);
-            float yOffset = textBounds.height() / 4; // half, and half again since it's centered
-            canvas.drawText(val, b.centerX(), b.centerY() + yOffset, mPaint);
+            canvas.drawText(val, b.centerX(), b.centerY() + textBounds.height() / 2, mPaint);
         } else {
-            canvas.drawCircle(b.centerX(), b.centerY() - mIconRadius / 2, mIconRadius, mPaint);
+            Rect iconBounds = new Rect(b.centerX() - mIconRadius,
+                    b.centerY() - mIconRadius,
+                    b.centerX() + mIconRadius,
+                    b.centerY() + mIconRadius);
+            mIconDrawable.setBounds(iconBounds);
+            mIconDrawable.draw(canvas);
         }
     }
 
@@ -114,9 +135,6 @@
     public boolean getPadding(Rect padding) {
         padding.left += mHorizontalPadding;
         padding.right += mHorizontalPadding;
-        padding.top = 0;
-        padding.bottom = 0;
-        android.util.Log.d("ScreenRecordDrawable", "set zero top/bottom pad");
         return true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
index e2b01ff..ce6013f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
@@ -21,11 +21,12 @@
 
 import com.android.internal.annotations.VisibleForTesting
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_HEADS_UP
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_MEDIA_CONTROLS
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
+import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
+import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
+import com.android.systemui.statusbar.notification.stack.BUCKET_HEADS_UP
+import com.android.systemui.statusbar.notification.stack.BUCKET_MEDIA_CONTROLS
+import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
+import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
 import com.android.systemui.util.DeviceConfigProxy
 import com.android.systemui.util.Utils
 
@@ -52,12 +53,14 @@
     fun getNotificationBuckets(): IntArray {
         return when {
             isFilteringEnabled() && isMediaControlsEnabled() ->
-                intArrayOf(BUCKET_HEADS_UP, BUCKET_MEDIA_CONTROLS, BUCKET_PEOPLE, BUCKET_ALERTING,
-                    BUCKET_SILENT)
+                intArrayOf(BUCKET_HEADS_UP, BUCKET_FOREGROUND_SERVICE, BUCKET_MEDIA_CONTROLS,
+                        BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT)
             !isFilteringEnabled() && isMediaControlsEnabled() ->
-                intArrayOf(BUCKET_HEADS_UP, BUCKET_MEDIA_CONTROLS, BUCKET_ALERTING, BUCKET_SILENT)
+                intArrayOf(BUCKET_HEADS_UP, BUCKET_FOREGROUND_SERVICE, BUCKET_MEDIA_CONTROLS,
+                        BUCKET_ALERTING, BUCKET_SILENT)
             isFilteringEnabled() && !isMediaControlsEnabled() ->
-                intArrayOf(BUCKET_HEADS_UP, BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT)
+                intArrayOf(BUCKET_HEADS_UP, BUCKET_FOREGROUND_SERVICE, BUCKET_PEOPLE,
+                        BUCKET_ALERTING, BUCKET_SILENT)
             NotificationUtils.useNewInterruptionModel(context) ->
                 intArrayOf(BUCKET_ALERTING, BUCKET_SILENT)
             else ->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
index 7ac5995..8341c02 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
@@ -43,7 +43,9 @@
     private static final long TEMPORARY_REORDERING_ALLOWED_DURATION = 1000;
 
     private final ArrayList<Callback> mReorderingAllowedCallbacks = new ArrayList<>();
+    private final ArraySet<Callback> mPersistentReorderingCallbacks = new ArraySet<>();
     private final ArrayList<Callback> mGroupChangesAllowedCallbacks = new ArrayList<>();
+    private final ArraySet<Callback> mPersistentGroupCallbacks = new ArraySet<>();
     private final Handler mHandler;
 
     private boolean mPanelExpanded;
@@ -85,8 +87,15 @@
 
     /**
      * Add a callback to invoke when reordering is allowed again.
+     *
+     * @param callback the callback to add
+     * @param persistent {@code true} if this callback should this callback be persisted, otherwise
+     *                               it will be removed after a single invocation
      */
-    public void addReorderingAllowedCallback(Callback callback) {
+    public void addReorderingAllowedCallback(Callback callback, boolean persistent) {
+        if (persistent) {
+            mPersistentReorderingCallbacks.add(callback);
+        }
         if (mReorderingAllowedCallbacks.contains(callback)) {
             return;
         }
@@ -95,8 +104,15 @@
 
     /**
      * Add a callback to invoke when group changes are allowed again.
+     *
+     * @param callback the callback to add
+     * @param persistent {@code true} if this callback should this callback be persisted, otherwise
+     *                               it will be removed after a single invocation
      */
-    public void addGroupChangesAllowedCallback(Callback callback) {
+    public void addGroupChangesAllowedCallback(Callback callback, boolean persistent) {
+        if (persistent) {
+            mPersistentGroupCallbacks.add(callback);
+        }
         if (mGroupChangesAllowedCallbacks.contains(callback)) {
             return;
         }
@@ -136,21 +152,26 @@
         boolean changedToTrue = reorderingAllowed && !mReorderingAllowed;
         mReorderingAllowed = reorderingAllowed;
         if (changedToTrue) {
-            notifyChangeAllowed(mReorderingAllowedCallbacks);
+            notifyChangeAllowed(mReorderingAllowedCallbacks, mPersistentReorderingCallbacks);
         }
         boolean groupChangesAllowed = (!mScreenOn || !mPanelExpanded) && !mPulsing;
         changedToTrue = groupChangesAllowed && !mGroupChangedAllowed;
         mGroupChangedAllowed = groupChangesAllowed;
         if (changedToTrue) {
-            notifyChangeAllowed(mGroupChangesAllowedCallbacks);
+            notifyChangeAllowed(mGroupChangesAllowedCallbacks, mPersistentGroupCallbacks);
         }
     }
 
-    private void notifyChangeAllowed(ArrayList<Callback> callbacks) {
+    private void notifyChangeAllowed(ArrayList<Callback> callbacks,
+            ArraySet<Callback> persistentCallbacks) {
         for (int i = 0; i < callbacks.size(); i++) {
-            callbacks.get(i).onChangeAllowed();
+            Callback callback = callbacks.get(i);
+            callback.onChangeAllowed();
+            if (!persistentCallbacks.contains(callback)) {
+                callbacks.remove(callback);
+                i--;
+            }
         }
-        callbacks.clear();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 634872d..22ac1a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -31,7 +31,7 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
 
 import static com.android.systemui.statusbar.notification.collection.NotifCollection.REASON_NOT_CANCELED;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_ALERTING;
 
 import static java.util.Objects.requireNonNull;
 
@@ -68,7 +68,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController;
 import com.android.systemui.statusbar.notification.row.NotificationGuts;
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
+import com.android.systemui.statusbar.notification.stack.PriorityBucket;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -409,12 +409,12 @@
         return wasBubble != isBubble();
     }
 
-    @NotificationSectionsManager.PriorityBucket
+    @PriorityBucket
     public int getBucket() {
         return mBucket;
     }
 
-    public void setBucket(@NotificationSectionsManager.PriorityBucket int bucket) {
+    public void setBucket(@PriorityBucket int bucket) {
         mBucket = bucket;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
index c78370e..cbf680c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManager.kt
@@ -28,11 +28,11 @@
 import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_HEADS_UP
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.PriorityBucket
+import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
+import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
+import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
+import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
+import com.android.systemui.statusbar.notification.stack.PriorityBucket
 import com.android.systemui.statusbar.phone.NotificationGroupManager
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import dagger.Lazy
@@ -137,23 +137,8 @@
                 .filterNot(notifFilter::shouldFilterOut)
                 .sortedWith(rankingComparator)
                 .toList()
-        assignBuckets(filtered)
-        return filtered
-    }
-
-    private fun assignBuckets(entries: List<NotificationEntry>) {
         entries.forEach { it.bucket = getBucketForEntry(it) }
-        if (!usePeopleFiltering) {
-            // If we don't have a Conversation section, just assign buckets normally based on the
-            // content.
-            return
-        }
-        // If HUNs are not continuous with the top section, break out into a new Incoming section.
-        entries.asReversed().asSequence().zipWithNext().forEach { (next, entry) ->
-            if (entry.isRowHeadsUp && entry.bucket > next.bucket) {
-                entry.bucket = BUCKET_HEADS_UP
-            }
-        }
+        return filtered
     }
 
     @PriorityBucket
@@ -162,6 +147,8 @@
         val isMedia = isImportantMedia(entry)
         val isSystemMax = entry.isSystemMax()
         return when {
+            entry.sbn.notification.isForegroundService && entry.sbn.notification.isColorized ->
+                BUCKET_FOREGROUND_SERVICE
             usePeopleFiltering && entry.getPeopleNotificationType() != TYPE_NON_PERSON ->
                 BUCKET_PEOPLE
             isHeadsUp || isMedia || isSystemMax || entry.isHighPriority() ->
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
index 92426e5..57be1a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BubbleCoordinator.java
@@ -19,6 +19,8 @@
 import static android.service.notification.NotificationStats.DISMISSAL_OTHER;
 import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
 
+import android.annotation.NonNull;
+
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
@@ -121,7 +123,7 @@
     private final BubbleController.NotifCallback mNotifCallback =
             new BubbleController.NotifCallback() {
         @Override
-        public void removeNotification(NotificationEntry entry, int reason) {
+        public void removeNotification(@NonNull final NotificationEntry entry, int reason) {
             if (isInterceptingDismissal(entry)) {
                 mInterceptedDismissalEntries.remove(entry.getKey());
                 mOnEndDismissInterception.onEndDismissInterception(mDismissInterceptor, entry,
@@ -141,7 +143,7 @@
         }
 
         @Override
-        public void maybeCancelSummary(NotificationEntry entry) {
+        public void maybeCancelSummary(@NonNull final NotificationEntry entry) {
             // no-op
         }
     };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
index cc5de65..66c07bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PartialConversationInfo.java
@@ -135,10 +135,13 @@
     }
 
     private void bindActions() {
+        final OnClickListener settingsOnClickListener = getSettingsOnClickListener();
         final View settingsButton = findViewById(R.id.info);
-        settingsButton.setOnClickListener(getSettingsOnClickListener());
+        settingsButton.setOnClickListener(settingsOnClickListener);
         settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);
 
+        findViewById(R.id.settings_link).setOnClickListener(settingsOnClickListener);
+
         TextView msg = findViewById(R.id.non_configurable_text);
         msg.setText(getResources().getString(R.string.no_shortcut, mAppName));
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index c9b1318..99691b7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -463,7 +463,8 @@
                     mAttachedChildren.add(i, desiredChild);
                     result = true;
                 } else {
-                    visualStabilityManager.addReorderingAllowedCallback(callback);
+                    visualStabilityManager.addReorderingAllowedCallback(callback,
+                            false /* persistent */);
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
index 9d456ef..bad36bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
@@ -32,8 +32,8 @@
  * Represents the bounds of a section of the notification shade and handles animation when the
  * bounds change.
  */
-class NotificationSection {
-    private @NotificationSectionsManager.PriorityBucket int mBucket;
+public class NotificationSection {
+    private @PriorityBucket int mBucket;
     private View mOwningView;
     private Rect mBounds = new Rect();
     private Rect mCurrentBounds = new Rect(-1, -1, -1, -1);
@@ -44,7 +44,7 @@
     private ActivatableNotificationView mFirstVisibleChild;
     private ActivatableNotificationView mLastVisibleChild;
 
-    NotificationSection(View owningView, @NotificationSectionsManager.PriorityBucket int bucket) {
+    NotificationSection(View owningView, @PriorityBucket int bucket) {
         mOwningView = owningView;
         mBucket = bucket;
     }
@@ -74,7 +74,7 @@
         return mBottomAnimator != null || mTopAnimator != null;
     }
 
-    @NotificationSectionsManager.PriorityBucket
+    @PriorityBucket
     public int getBucket() {
         return mBucket;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt
index 9cf1f74..17b4143 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt
@@ -36,14 +36,52 @@
             { "Updating section boundaries: $reason" }
     )
 
-    fun logStr(str: String) = logBuffer.log(
+    fun logIncomingHeader(position: Int) = logPosition(position, "INCOMING HEADER")
+    fun logMediaControls(position: Int) = logPosition(position, "MEDIA CONTROLS")
+    fun logConversationsHeader(position: Int) = logPosition(position, "CONVERSATIONS HEADER")
+    fun logAlertingHeader(position: Int) = logPosition(position, "ALERTING HEADER")
+    fun logSilentHeader(position: Int) = logPosition(position, "SILENT HEADER")
+
+    fun logOther(position: Int, clazz: Class<*>) = logBuffer.log(
             TAG,
             LogLevel.DEBUG,
-            { str1 = str },
-            { str1 ?: "" }
+            {
+                int1 = position
+                str1 = clazz.name
+            },
+            { "$int1: other ($str1)" }
     )
 
-    fun logPosition(position: Int, label: String) = logBuffer.log(
+    fun logHeadsUp(position: Int, isHeadsUp: Boolean) =
+            logPosition(position, "Heads Up", isHeadsUp)
+    fun logConversation(position: Int, isHeadsUp: Boolean) =
+            logPosition(position, "Conversation", isHeadsUp)
+    fun logAlerting(position: Int, isHeadsUp: Boolean) =
+            logPosition(position, "Alerting", isHeadsUp)
+    fun logSilent(position: Int, isHeadsUp: Boolean) =
+            logPosition(position, "Silent", isHeadsUp)
+    fun logForegroundService(position: Int, isHeadsUp: Boolean) =
+            logPosition(position, "Foreground Service", isHeadsUp)
+
+    fun logStr(str: String) = logBuffer.log(TAG, LogLevel.DEBUG, { str1 = str }, { "$str1" })
+
+    private fun logPosition(position: Int, label: String, isHeadsUp: Boolean) {
+        val headsUpTag = if (isHeadsUp) " (HUN)" else ""
+        logBuffer.log(
+                TAG,
+                LogLevel.DEBUG,
+                {
+                    int1 = position
+                    str1 = label
+                    str2 = headsUpTag
+                },
+                {
+                    "$int1: $str1$str2"
+                }
+        )
+    }
+
+    private fun logPosition(position: Int, label: String) = logBuffer.log(
             TAG,
             LogLevel.DEBUG,
             {
@@ -52,4 +90,4 @@
             },
             { "$int1: $str1" }
     )
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
deleted file mode 100644
index dcf30ca..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.stack;
-
-import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_GENTLE;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.annotation.ColorInt;
-import android.annotation.IntDef;
-import android.annotation.LayoutRes;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Intent;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
-import com.android.systemui.media.KeyguardMediaController;
-import com.android.systemui.media.MediaHierarchyManager;
-import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
-import com.android.systemui.statusbar.notification.people.DataListener;
-import com.android.systemui.statusbar.notification.people.PeopleHubViewAdapter;
-import com.android.systemui.statusbar.notification.people.PeopleHubViewBoundary;
-import com.android.systemui.statusbar.notification.people.PersonViewModel;
-import com.android.systemui.statusbar.notification.people.Subscription;
-import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.ExpandableView;
-import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
-import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
-
-import java.lang.annotation.Retention;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import javax.inject.Inject;
-
-import kotlin.sequences.Sequence;
-
-/**
- * Manages the boundaries of the two notification sections (high priority and low priority). Also
- * shows/hides the headers for those sections where appropriate.
- *
- * TODO: Move remaining sections logic from NSSL into this class.
- */
-public class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvider {
-
-    private static final String TAG = "NotifSectionsManager";
-    private static final boolean DEBUG = false;
-    private static final boolean ENABLE_SNOOZED_CONVERSATION_HUB = false;
-
-    private final ActivityStarter mActivityStarter;
-    private final StatusBarStateController mStatusBarStateController;
-    private final ConfigurationController mConfigurationController;
-    private final PeopleHubViewAdapter mPeopleHubViewAdapter;
-    private final NotificationSectionsFeatureManager mSectionsFeatureManager;
-    private final KeyguardMediaController mKeyguardMediaController;
-    private final int mNumberOfSections;
-    private final NotificationSectionsLogger mLogger;
-    private final PeopleHubViewBoundary mPeopleHubViewBoundary = new PeopleHubViewBoundary() {
-        @Override
-        public void setVisible(boolean isVisible) {
-            if (mPeopleHubVisible != isVisible) {
-                mPeopleHubVisible = isVisible;
-                if (mInitialized) {
-                    updateSectionBoundaries("PeopleHub visibility changed");
-                }
-            }
-        }
-
-        @NonNull
-        @Override
-        public View getAssociatedViewForClickAnimation() {
-            return mPeopleHubView;
-        }
-
-        @NonNull
-        @Override
-        public Sequence<DataListener<PersonViewModel>> getPersonViewAdapters() {
-            return mPeopleHubView.getPersonViewAdapters();
-        }
-    };
-
-    private NotificationStackScrollLayout mParent;
-    private boolean mInitialized = false;
-
-    private SectionHeaderView mGentleHeader;
-    @Nullable private View.OnClickListener mOnClearGentleNotifsClickListener;
-
-    private SectionHeaderView mAlertingHeader;
-    private SectionHeaderView mIncomingHeader;
-
-    private PeopleHubView mPeopleHubView;
-    private boolean mPeopleHubVisible = false;
-    @Nullable private Subscription mPeopleHubSubscription;
-
-    private MediaHeaderView mMediaControlsView;
-
-    @Inject
-    NotificationSectionsManager(
-            ActivityStarter activityStarter,
-            StatusBarStateController statusBarStateController,
-            ConfigurationController configurationController,
-            PeopleHubViewAdapter peopleHubViewAdapter,
-            KeyguardMediaController keyguardMediaController,
-            NotificationSectionsFeatureManager sectionsFeatureManager,
-            NotificationSectionsLogger logger) {
-
-        mActivityStarter = activityStarter;
-        mStatusBarStateController = statusBarStateController;
-        mConfigurationController = configurationController;
-        mPeopleHubViewAdapter = peopleHubViewAdapter;
-        mSectionsFeatureManager = sectionsFeatureManager;
-        mNumberOfSections = mSectionsFeatureManager.getNumberOfBuckets();
-        mKeyguardMediaController = keyguardMediaController;
-        mLogger = logger;
-    }
-
-    NotificationSection[] createSectionsForBuckets() {
-        int[] buckets = mSectionsFeatureManager.getNotificationBuckets();
-        NotificationSection[] sections = new NotificationSection[buckets.length];
-        for (int i = 0; i < buckets.length; i++) {
-            sections[i] = new NotificationSection(mParent, buckets[i] /* bucket */);
-        }
-
-        return sections;
-    }
-
-    /** Must be called before use. */
-    void initialize(
-            NotificationStackScrollLayout parent, LayoutInflater layoutInflater) {
-        if (mInitialized) {
-            throw new IllegalStateException("NotificationSectionsManager already initialized");
-        }
-        mInitialized = true;
-        mParent = parent;
-        reinflateViews(layoutInflater);
-        mConfigurationController.addCallback(mConfigurationListener);
-    }
-
-    private <T extends ExpandableView> T reinflateView(
-            T view, LayoutInflater layoutInflater, @LayoutRes int layoutResId) {
-        int oldPos = -1;
-        if (view != null) {
-            if (view.getTransientContainer() != null) {
-                view.getTransientContainer().removeView(mGentleHeader);
-            } else if (view.getParent() != null) {
-                oldPos = mParent.indexOfChild(view);
-                mParent.removeView(view);
-            }
-        }
-
-        view = (T) layoutInflater.inflate(layoutResId, mParent, false);
-
-        if (oldPos != -1) {
-            mParent.addView(view, oldPos);
-        }
-
-        return view;
-    }
-
-    /**
-     * Reinflates the entire notification header, including all decoration views.
-     */
-    void reinflateViews(LayoutInflater layoutInflater) {
-        mGentleHeader = reinflateView(
-                mGentleHeader, layoutInflater, R.layout.status_bar_notification_section_header);
-        mGentleHeader.setHeaderText(R.string.notification_section_header_gentle);
-        mGentleHeader.setOnHeaderClickListener(this::onGentleHeaderClick);
-        mGentleHeader.setOnClearAllClickListener(this::onClearGentleNotifsClick);
-
-        mAlertingHeader = reinflateView(
-                mAlertingHeader, layoutInflater, R.layout.status_bar_notification_section_header);
-        mAlertingHeader.setHeaderText(R.string.notification_section_header_alerting);
-        mAlertingHeader.setOnHeaderClickListener(this::onGentleHeaderClick);
-
-        if (mPeopleHubSubscription != null) {
-            mPeopleHubSubscription.unsubscribe();
-        }
-        mPeopleHubView = reinflateView(mPeopleHubView, layoutInflater, R.layout.people_strip);
-        if (ENABLE_SNOOZED_CONVERSATION_HUB) {
-            mPeopleHubSubscription = mPeopleHubViewAdapter.bindView(mPeopleHubViewBoundary);
-        }
-
-        mIncomingHeader = reinflateView(
-                mIncomingHeader, layoutInflater, R.layout.status_bar_notification_section_header);
-        mIncomingHeader.setHeaderText(R.string.notification_section_header_incoming);
-        mIncomingHeader.setOnHeaderClickListener(this::onGentleHeaderClick);
-
-        mMediaControlsView = reinflateView(mMediaControlsView, layoutInflater,
-                R.layout.keyguard_media_header);
-        mKeyguardMediaController.attach(mMediaControlsView);
-    }
-
-    /** Listener for when the "clear all" button is clicked on the gentle notification header. */
-    void setOnClearGentleNotifsClickListener(View.OnClickListener listener) {
-        mOnClearGentleNotifsClickListener = listener;
-    }
-
-    @Override
-    public boolean beginsSection(@NonNull View view, @Nullable View previous) {
-        return view == mGentleHeader
-                || view == mMediaControlsView
-                || view == mPeopleHubView
-                || view == mAlertingHeader
-                || view == mIncomingHeader
-                || !Objects.equals(getBucket(view), getBucket(previous));
-    }
-
-    private boolean isUsingMultipleSections() {
-        return mNumberOfSections > 1;
-    }
-
-    @Nullable
-    private Integer getBucket(View view) {
-        if (view == mGentleHeader) {
-            return BUCKET_SILENT;
-        } else if (view == mIncomingHeader) {
-            return BUCKET_HEADS_UP;
-        } else if (view == mMediaControlsView) {
-            return BUCKET_MEDIA_CONTROLS;
-        } else if (view == mPeopleHubView) {
-            return BUCKET_PEOPLE;
-        } else if (view == mAlertingHeader) {
-            return BUCKET_ALERTING;
-        } else if (view instanceof ExpandableNotificationRow) {
-            return ((ExpandableNotificationRow) view).getEntry().getBucket();
-        }
-        return null;
-    }
-
-    private void logShadeContents() {
-        final int childCount = mParent.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = mParent.getChildAt(i);
-            if (child == mIncomingHeader) {
-                mLogger.logPosition(i, "INCOMING HEADER");
-                continue;
-            }
-            if (child == mMediaControlsView) {
-                mLogger.logPosition(i, "MEDIA CONTROLS");
-                continue;
-            }
-            if (child == mPeopleHubView) {
-                mLogger.logPosition(i, "CONVERSATIONS HEADER");
-                continue;
-            }
-            if (child == mAlertingHeader) {
-                mLogger.logPosition(i, "ALERTING HEADER");
-                continue;
-            }
-            if (child == mGentleHeader) {
-                mLogger.logPosition(i, "SILENT HEADER");
-                continue;
-            }
-
-            if (!(child instanceof ExpandableNotificationRow)) {
-                mLogger.logPosition(i, "other:" + child.getClass().getName());
-                continue;
-            }
-            ExpandableNotificationRow row = (ExpandableNotificationRow) child;
-            // Once we enter a new section, calculate the target position for the header.
-            switch (row.getEntry().getBucket()) {
-                case BUCKET_HEADS_UP:
-                    mLogger.logPosition(i, "Heads Up");
-                    break;
-                case BUCKET_PEOPLE:
-                    mLogger.logPosition(i, "Conversation");
-                    break;
-                case BUCKET_ALERTING:
-                    mLogger.logPosition(i, "Alerting");
-                    break;
-                case BUCKET_SILENT:
-                    mLogger.logPosition(i, "Silent");
-                    break;
-            }
-        }
-    }
-
-    @VisibleForTesting
-    void updateSectionBoundaries() {
-        updateSectionBoundaries("test");
-    }
-
-    /**
-     * Should be called whenever notifs are added, removed, or updated. Updates section boundary
-     * bookkeeping and adds/moves/removes section headers if appropriate.
-     */
-    void updateSectionBoundaries(String reason) {
-        if (!isUsingMultipleSections()) {
-            return;
-        }
-
-        mLogger.logStartSectionUpdate(reason);
-
-        // The overall strategy here is to iterate over the current children of mParent, looking
-        // for where the sections headers are currently positioned, and where each section begins.
-        // Then, once we find the start of a new section, we track that position as the "target" for
-        // the section header, adjusted for the case where existing headers are in front of that
-        // target, but won't be once they are moved / removed after the pass has completed.
-
-        final boolean showHeaders = mStatusBarStateController.getState() != StatusBarState.KEYGUARD;
-        final boolean usingPeopleFiltering = mSectionsFeatureManager.isFilteringEnabled();
-        final boolean usingMediaControls = mSectionsFeatureManager.isMediaControlsEnabled();
-
-        boolean peopleNotifsPresent = false;
-
-        int currentMediaControlsIdx = -1;
-        // Currently, just putting media controls in the front and incrementing the position based
-        // on the number of heads-up notifs.
-        int mediaControlsTarget = usingMediaControls ? 0 : -1;
-        int currentIncomingHeaderIdx = -1;
-        int incomingHeaderTarget = -1;
-        int currentPeopleHeaderIdx = -1;
-        int peopleHeaderTarget = -1;
-        int currentAlertingHeaderIdx = -1;
-        int alertingHeaderTarget = -1;
-        int currentGentleHeaderIdx = -1;
-        int gentleHeaderTarget = -1;
-
-        int lastNotifIndex = 0;
-
-        final int childCount = mParent.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View child = mParent.getChildAt(i);
-
-            // Track the existing positions of the headers
-            if (child == mIncomingHeader) {
-                mLogger.logPosition(i, "INCOMING HEADER");
-                currentIncomingHeaderIdx = i;
-                continue;
-            }
-            if (child == mMediaControlsView) {
-                mLogger.logPosition(i, "MEDIA CONTROLS");
-                currentMediaControlsIdx = i;
-                continue;
-            }
-            if (child == mPeopleHubView) {
-                mLogger.logPosition(i, "CONVERSATIONS HEADER");
-                currentPeopleHeaderIdx = i;
-                continue;
-            }
-            if (child == mAlertingHeader) {
-                mLogger.logPosition(i, "ALERTING HEADER");
-                currentAlertingHeaderIdx = i;
-                continue;
-            }
-            if (child == mGentleHeader) {
-                mLogger.logPosition(i, "SILENT HEADER");
-                currentGentleHeaderIdx = i;
-                continue;
-            }
-
-            if (!(child instanceof ExpandableNotificationRow)) {
-                mLogger.logPosition(i, "other");
-                continue;
-            }
-            lastNotifIndex = i;
-            ExpandableNotificationRow row = (ExpandableNotificationRow) child;
-            // Once we enter a new section, calculate the target position for the header.
-            switch (row.getEntry().getBucket()) {
-                case BUCKET_HEADS_UP:
-                    mLogger.logPosition(i, "Heads Up");
-                    if (showHeaders && incomingHeaderTarget == -1) {
-                        incomingHeaderTarget = i;
-                        // Offset the target if there are other headers before this that will be
-                        // moved.
-                        if (currentIncomingHeaderIdx != -1) {
-                            incomingHeaderTarget--;
-                        }
-                        if (currentMediaControlsIdx != -1) {
-                            incomingHeaderTarget--;
-                        }
-                        if (currentPeopleHeaderIdx != -1) {
-                            incomingHeaderTarget--;
-                        }
-                        if (currentAlertingHeaderIdx != -1) {
-                            incomingHeaderTarget--;
-                        }
-                        if (currentGentleHeaderIdx != -1) {
-                            incomingHeaderTarget--;
-                        }
-                    }
-                    if (mediaControlsTarget != -1) {
-                        mediaControlsTarget++;
-                    }
-                    break;
-                case BUCKET_PEOPLE:
-                    mLogger.logPosition(i, "Conversation");
-                    peopleNotifsPresent = true;
-                    if (showHeaders && peopleHeaderTarget == -1) {
-                        peopleHeaderTarget = i;
-                        // Offset the target if there are other headers before this that will be
-                        // moved.
-                        if (currentPeopleHeaderIdx != -1) {
-                            peopleHeaderTarget--;
-                        }
-                        if (currentAlertingHeaderIdx != -1) {
-                            peopleHeaderTarget--;
-                        }
-                        if (currentGentleHeaderIdx != -1) {
-                            peopleHeaderTarget--;
-                        }
-                    }
-                    break;
-                case BUCKET_ALERTING:
-                    mLogger.logPosition(i, "Alerting");
-                    if (showHeaders && usingPeopleFiltering && alertingHeaderTarget == -1) {
-                        alertingHeaderTarget = i;
-                        // Offset the target if there are other headers before this that will be
-                        // moved.
-                        if (currentAlertingHeaderIdx != -1) {
-                            alertingHeaderTarget--;
-                        }
-                        if (currentGentleHeaderIdx != -1) {
-                            alertingHeaderTarget--;
-                        }
-                    }
-                    break;
-                case BUCKET_SILENT:
-                    mLogger.logPosition(i, "Silent");
-                    if (showHeaders && gentleHeaderTarget == -1) {
-                        gentleHeaderTarget = i;
-                        // Offset the target if there are other headers before this that will be
-                        // moved.
-                        if (currentGentleHeaderIdx != -1) {
-                            gentleHeaderTarget--;
-                        }
-                    }
-                    break;
-                default:
-                    throw new IllegalStateException("Cannot find section bucket for view");
-            }
-        }
-        if (showHeaders && usingPeopleFiltering && mPeopleHubVisible && peopleHeaderTarget == -1) {
-            // Insert the people header even if there are no people visible, in order to show
-            // the hub. Put it directly above the next header.
-            if (alertingHeaderTarget != -1) {
-                peopleHeaderTarget = alertingHeaderTarget;
-            } else if (gentleHeaderTarget != -1) {
-                peopleHeaderTarget = gentleHeaderTarget;
-            } else {
-                // Put it at the end of the list.
-                peopleHeaderTarget = lastNotifIndex;
-            }
-            // Offset the target to account for the current position of the people header.
-            if (currentPeopleHeaderIdx != -1 && currentPeopleHeaderIdx < peopleHeaderTarget) {
-                peopleHeaderTarget--;
-            }
-        }
-
-        mLogger.logStr("New header target positions:");
-
-        mLogger.logPosition(incomingHeaderTarget, "INCOMING HEADER");
-        mLogger.logPosition(mediaControlsTarget, "MEDIA CONTROLS");
-        mLogger.logPosition(peopleHeaderTarget, "CONVERSATIONS HEADER");
-        mLogger.logPosition(alertingHeaderTarget, "ALERTING HEADER");
-        mLogger.logPosition(gentleHeaderTarget, "SILENT HEADER");
-
-        // Add headers in reverse order to preserve indices
-        adjustHeaderVisibilityAndPosition(
-                gentleHeaderTarget, mGentleHeader, currentGentleHeaderIdx);
-        adjustHeaderVisibilityAndPosition(
-                alertingHeaderTarget, mAlertingHeader, currentAlertingHeaderIdx);
-        adjustHeaderVisibilityAndPosition(
-                peopleHeaderTarget, mPeopleHubView, currentPeopleHeaderIdx);
-        adjustViewPosition(mediaControlsTarget, mMediaControlsView, currentMediaControlsIdx);
-        adjustViewPosition(incomingHeaderTarget, mIncomingHeader, currentIncomingHeaderIdx);
-
-
-        mLogger.logStr("Final order:");
-
-        logShadeContents();
-
-        mLogger.logStr("Section boundary update complete");
-
-        // Update headers to reflect state of section contents
-        mGentleHeader.setAreThereDismissableGentleNotifs(
-                mParent.hasActiveClearableNotifications(ROWS_GENTLE));
-        mPeopleHubView.setCanSwipe(showHeaders && mPeopleHubVisible && !peopleNotifsPresent);
-        if (peopleHeaderTarget != currentPeopleHeaderIdx) {
-            mPeopleHubView.resetTranslation();
-        }
-    }
-
-    private void adjustHeaderVisibilityAndPosition(
-            int targetPosition, StackScrollerDecorView header, int currentPosition) {
-        if (targetPosition == -1) {
-            if (currentPosition != -1) {
-                mParent.removeView(header);
-            }
-        } else {
-            if (currentPosition == -1) {
-                // If the header is animating away, it will still have a parent, so detach it first
-                // TODO: We should really cancel the active animations here. This will happen
-                // automatically when the view's intro animation starts, but it's a fragile link.
-                if (header.getTransientContainer() != null) {
-                    header.getTransientContainer().removeTransientView(header);
-                    header.setTransientContainer(null);
-                }
-                header.setContentVisible(true);
-                mParent.addView(header, targetPosition);
-            } else {
-                mParent.changeViewPosition(header, targetPosition);
-            }
-        }
-    }
-
-    private void adjustViewPosition(int targetPosition, ExpandableView header,
-            int currentPosition) {
-        if (targetPosition == -1) {
-            if (currentPosition != -1) {
-                mParent.removeView(header);
-            }
-        } else {
-            if (currentPosition == -1) {
-                // If the header is animating away, it will still have a parent, so detach it first
-                // TODO: We should really cancel the active animations here. This will happen
-                // automatically when the view's intro animation starts, but it's a fragile link.
-                if (header.getTransientContainer() != null) {
-                    header.getTransientContainer().removeTransientView(header);
-                    header.setTransientContainer(null);
-                }
-                mParent.addView(header, targetPosition);
-            } else {
-                mParent.changeViewPosition(header, targetPosition);
-            }
-        }
-    }
-
-    /**
-     * Updates the boundaries (as tracked by their first and last views) of the priority sections.
-     *
-     * @return {@code true} If the last view in the top section changed (so we need to animate).
-     */
-    boolean updateFirstAndLastViewsForAllSections(
-            NotificationSection[] sections,
-            List<ActivatableNotificationView> children) {
-
-        if (sections.length <= 0 || children.size() <= 0) {
-            for (NotificationSection s : sections) {
-                s.setFirstVisibleChild(null);
-                s.setLastVisibleChild(null);
-            }
-            return false;
-        }
-
-        boolean changed = false;
-        ArrayList<ActivatableNotificationView> viewsInBucket = new ArrayList<>();
-        for (NotificationSection s : sections) {
-            int filter = s.getBucket();
-            viewsInBucket.clear();
-
-            //TODO: do this in a single pass, and more better
-            for (ActivatableNotificationView v : children)  {
-                Integer bucket = getBucket(v);
-                if (bucket == null) {
-                    throw new IllegalArgumentException("Cannot find section bucket for view");
-                }
-
-                if (bucket == filter) {
-                    viewsInBucket.add(v);
-                }
-
-                if (viewsInBucket.size() >= 1) {
-                    changed |= s.setFirstVisibleChild(viewsInBucket.get(0));
-                    changed |= s.setLastVisibleChild(viewsInBucket.get(viewsInBucket.size() - 1));
-                } else {
-                    changed |= s.setFirstVisibleChild(null);
-                    changed |= s.setLastVisibleChild(null);
-                }
-            }
-        }
-
-        if (DEBUG) {
-            logSections(sections);
-        }
-
-        return changed;
-    }
-
-    private void logSections(NotificationSection[] sections) {
-        for (int i = 0; i < sections.length; i++) {
-            NotificationSection s = sections[i];
-            ActivatableNotificationView first = s.getFirstVisibleChild();
-            String fs = first == null ? "(null)"
-                    :  (first instanceof ExpandableNotificationRow)
-                            ? ((ExpandableNotificationRow) first).getEntry().getKey()
-                            : Integer.toHexString(System.identityHashCode(first));
-            ActivatableNotificationView last = s.getLastVisibleChild();
-            String ls = last == null ? "(null)"
-                    :  (last instanceof ExpandableNotificationRow)
-                            ? ((ExpandableNotificationRow) last).getEntry().getKey()
-                            : Integer.toHexString(System.identityHashCode(last));
-            android.util.Log.d(TAG, "updateSections: f=" + fs + " s=" + i);
-            android.util.Log.d(TAG, "updateSections: l=" + ls + " s=" + i);
-        }
-    }
-
-    @VisibleForTesting
-    ExpandableView getGentleHeaderView() {
-        return mGentleHeader;
-    }
-
-    @VisibleForTesting
-    ExpandableView getAlertingHeaderView() {
-        return mAlertingHeader;
-    }
-
-    @VisibleForTesting
-    ExpandableView getPeopleHeaderView() {
-        return mPeopleHubView;
-    }
-
-    @VisibleForTesting
-    ExpandableView getMediaControlsView() {
-        return mMediaControlsView;
-    }
-
-    @VisibleForTesting
-    void setPeopleHubVisible(boolean visible) {
-        mPeopleHubVisible = visible;
-    }
-
-    private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
-        @Override
-        public void onLocaleListChanged() {
-            reinflateViews(LayoutInflater.from(mParent.getContext()));
-        }
-    };
-
-    private void onGentleHeaderClick(View v) {
-        Intent intent = new Intent(Settings.ACTION_NOTIFICATION_SETTINGS);
-        mActivityStarter.startActivity(
-                intent,
-                true,
-                true,
-                Intent.FLAG_ACTIVITY_SINGLE_TOP);
-    }
-
-    private void onClearGentleNotifsClick(View v) {
-        if (mOnClearGentleNotifsClickListener != null) {
-            mOnClearGentleNotifsClickListener.onClick(v);
-        }
-    }
-
-    void hidePeopleRow() {
-        mPeopleHubVisible = false;
-        updateSectionBoundaries("PeopleHub dismissed");
-    }
-
-    void setHeaderForegroundColor(@ColorInt int color) {
-        mPeopleHubView.setTextColor(color);
-        mGentleHeader.setForegroundColor(color);
-        mAlertingHeader.setForegroundColor(color);
-    }
-
-    /**
-     * For now, declare the available notification buckets (sections) here so that other
-     * presentation code can decide what to do based on an entry's buckets
-     */
-    @Retention(SOURCE)
-    @IntDef(prefix = { "BUCKET_" }, value = {
-            BUCKET_HEADS_UP,
-            BUCKET_MEDIA_CONTROLS,
-            BUCKET_PEOPLE,
-            BUCKET_ALERTING,
-            BUCKET_SILENT
-    })
-    public @interface PriorityBucket {}
-    public static final int BUCKET_HEADS_UP = 0;
-    public static final int BUCKET_MEDIA_CONTROLS = 1;
-    public static final int BUCKET_PEOPLE = 2;
-    public static final int BUCKET_ALERTING = 3;
-    public static final int BUCKET_SILENT = 4;
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
new file mode 100644
index 0000000..65633a2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.stack
+
+import android.annotation.ColorInt
+import android.annotation.IntDef
+import android.annotation.LayoutRes
+import android.content.Intent
+import android.provider.Settings
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.R
+import com.android.systemui.media.KeyguardMediaController
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
+import com.android.systemui.statusbar.notification.people.DataListener
+import com.android.systemui.statusbar.notification.people.PeopleHubViewAdapter
+import com.android.systemui.statusbar.notification.people.PeopleHubViewBoundary
+import com.android.systemui.statusbar.notification.people.PersonViewModel
+import com.android.systemui.statusbar.notification.people.Subscription
+import com.android.systemui.statusbar.notification.row.ActivatableNotificationView
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.notification.row.StackScrollerDecorView
+import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
+import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.util.children
+import com.android.systemui.util.foldToSparseArray
+import javax.inject.Inject
+
+/**
+ * Manages the boundaries of the two notification sections (high priority and low priority). Also
+ * shows/hides the headers for those sections where appropriate.
+ *
+ * TODO: Move remaining sections logic from NSSL into this class.
+ */
+class NotificationSectionsManager @Inject internal constructor(
+    private val activityStarter: ActivityStarter,
+    private val statusBarStateController: StatusBarStateController,
+    private val configurationController: ConfigurationController,
+    private val peopleHubViewAdapter: PeopleHubViewAdapter,
+    private val keyguardMediaController: KeyguardMediaController,
+    private val sectionsFeatureManager: NotificationSectionsFeatureManager,
+    private val logger: NotificationSectionsLogger
+) : SectionProvider {
+
+    private val configurationListener = object : ConfigurationController.ConfigurationListener {
+        override fun onLocaleListChanged() {
+            reinflateViews(LayoutInflater.from(parent.context))
+        }
+    }
+
+    private val peopleHubViewBoundary: PeopleHubViewBoundary = object : PeopleHubViewBoundary {
+        override fun setVisible(isVisible: Boolean) {
+            if (peopleHubVisible != isVisible) {
+                peopleHubVisible = isVisible
+                if (initialized) {
+                    updateSectionBoundaries("PeopleHub visibility changed")
+                }
+            }
+        }
+
+        override val associatedViewForClickAnimation: View
+            get() = peopleHeaderView!!
+
+        override val personViewAdapters: Sequence<DataListener<PersonViewModel?>>
+            get() = peopleHeaderView!!.personViewAdapters
+    }
+
+    private lateinit var parent: NotificationStackScrollLayout
+    private var initialized = false
+    private var onClearSilentNotifsClickListener: View.OnClickListener? = null
+
+    @get:VisibleForTesting
+    var silentHeaderView: SectionHeaderView? = null
+        private set
+
+    @get:VisibleForTesting
+    var alertingHeaderView: SectionHeaderView? = null
+        private set
+
+    @get:VisibleForTesting
+    var incomingHeaderView: SectionHeaderView? = null
+        private set
+
+    @get:VisibleForTesting
+    var peopleHeaderView: PeopleHubView? = null
+        private set
+
+    @set:VisibleForTesting
+    var peopleHubVisible = false
+    private var peopleHubSubscription: Subscription? = null
+
+    @get:VisibleForTesting
+    var mediaControlsView: MediaHeaderView? = null
+        private set
+
+    /** Must be called before use.  */
+    fun initialize(parent: NotificationStackScrollLayout, layoutInflater: LayoutInflater) {
+        check(!initialized) { "NotificationSectionsManager already initialized" }
+        initialized = true
+        this.parent = parent
+        reinflateViews(layoutInflater)
+        configurationController.addCallback(configurationListener)
+    }
+
+    private fun <T : ExpandableView> reinflateView(
+        view: T?,
+        layoutInflater: LayoutInflater,
+        @LayoutRes layoutResId: Int
+    ): T {
+        var oldPos = -1
+        view?.let {
+            view.transientContainer?.removeView(view)
+            if (view.parent === parent) {
+                oldPos = parent.indexOfChild(view)
+                parent.removeView(view)
+            }
+        }
+        val inflated = layoutInflater.inflate(layoutResId, parent, false) as T
+        if (oldPos != -1) {
+            parent.addView(inflated, oldPos)
+        }
+        return inflated
+    }
+
+    fun createSectionsForBuckets(): Array<NotificationSection> =
+            sectionsFeatureManager.getNotificationBuckets()
+                    .map { NotificationSection(parent, it) }
+                    .toTypedArray()
+
+    /**
+     * Reinflates the entire notification header, including all decoration views.
+     */
+    fun reinflateViews(layoutInflater: LayoutInflater) {
+        silentHeaderView = reinflateView(
+                silentHeaderView, layoutInflater, R.layout.status_bar_notification_section_header
+        ).apply {
+            setHeaderText(R.string.notification_section_header_gentle)
+            setOnHeaderClickListener { onGentleHeaderClick() }
+            setOnClearAllClickListener { onClearGentleNotifsClick(it) }
+        }
+        alertingHeaderView = reinflateView(
+                alertingHeaderView, layoutInflater, R.layout.status_bar_notification_section_header
+        ).apply {
+            setHeaderText(R.string.notification_section_header_alerting)
+            setOnHeaderClickListener { onGentleHeaderClick() }
+        }
+        peopleHubSubscription?.unsubscribe()
+        peopleHubSubscription = null
+        peopleHeaderView = reinflateView(peopleHeaderView, layoutInflater, R.layout.people_strip)
+        if (ENABLE_SNOOZED_CONVERSATION_HUB) {
+            peopleHubSubscription = peopleHubViewAdapter.bindView(peopleHubViewBoundary)
+        }
+        incomingHeaderView = reinflateView(
+                incomingHeaderView, layoutInflater, R.layout.status_bar_notification_section_header
+        ).apply {
+            setHeaderText(R.string.notification_section_header_incoming)
+            setOnHeaderClickListener { onGentleHeaderClick() }
+        }
+        mediaControlsView =
+                reinflateView(mediaControlsView, layoutInflater, R.layout.keyguard_media_header)
+                        .also(keyguardMediaController::attach)
+    }
+
+    override fun beginsSection(view: View, previous: View?): Boolean =
+            view === silentHeaderView ||
+            view === mediaControlsView ||
+            view === peopleHeaderView ||
+            view === alertingHeaderView ||
+            view === incomingHeaderView ||
+            getBucket(view) != getBucket(previous)
+
+    private fun getBucket(view: View?): Int? = when {
+        view === silentHeaderView -> BUCKET_SILENT
+        view === incomingHeaderView -> BUCKET_HEADS_UP
+        view === mediaControlsView -> BUCKET_MEDIA_CONTROLS
+        view === peopleHeaderView -> BUCKET_PEOPLE
+        view === alertingHeaderView -> BUCKET_ALERTING
+        view is ExpandableNotificationRow -> view.entry.bucket
+        else -> null
+    }
+
+    private fun logShadeContents() = parent.children.forEachIndexed { i, child ->
+        when {
+            child === incomingHeaderView -> logger.logIncomingHeader(i)
+            child === mediaControlsView -> logger.logMediaControls(i)
+            child === peopleHeaderView -> logger.logConversationsHeader(i)
+            child === alertingHeaderView -> logger.logAlertingHeader(i)
+            child === silentHeaderView -> logger.logSilentHeader(i)
+            child !is ExpandableNotificationRow -> logger.logOther(i, child.javaClass)
+            else -> {
+                val isHeadsUp = child.isHeadsUp
+                when (child.entry.bucket) {
+                    BUCKET_HEADS_UP -> logger.logHeadsUp(i, isHeadsUp)
+                    BUCKET_PEOPLE -> logger.logConversation(i, isHeadsUp)
+                    BUCKET_ALERTING -> logger.logAlerting(i, isHeadsUp)
+                    BUCKET_SILENT -> logger.logSilent(i, isHeadsUp)
+                }
+            }
+        }
+    }
+
+    private val isUsingMultipleSections: Boolean
+        get() = sectionsFeatureManager.getNumberOfBuckets() > 1
+
+    @VisibleForTesting
+    fun updateSectionBoundaries() = updateSectionBoundaries("test")
+
+    /**
+     * Should be called whenever notifs are added, removed, or updated. Updates section boundary
+     * bookkeeping and adds/moves/removes section headers if appropriate.
+     */
+    fun updateSectionBoundaries(reason: String) {
+        if (!isUsingMultipleSections) {
+            return
+        }
+        logger.logStartSectionUpdate(reason)
+
+        // The overall strategy here is to iterate over the current children of mParent, looking
+        // for where the sections headers are currently positioned, and where each section begins.
+        // Then, once we find the start of a new section, we track that position as the "target" for
+        // the section header, adjusted for the case where existing headers are in front of that
+        // target, but won't be once they are moved / removed after the pass has completed.
+        val showHeaders = statusBarStateController.state != StatusBarState.KEYGUARD
+        val usingPeopleFiltering = sectionsFeatureManager.isFilteringEnabled()
+        val usingMediaControls = sectionsFeatureManager.isMediaControlsEnabled()
+
+        var peopleNotifsPresent = false
+        var currentMediaControlsIdx = -1
+        val mediaControlsTarget = if (usingMediaControls) 0 else -1
+        var currentIncomingHeaderIdx = -1
+        var incomingHeaderTarget = -1
+        var currentPeopleHeaderIdx = -1
+        var peopleHeaderTarget = -1
+        var currentAlertingHeaderIdx = -1
+        var alertingHeaderTarget = -1
+        var currentGentleHeaderIdx = -1
+        var gentleHeaderTarget = -1
+
+        var lastNotifIndex = 0
+        var lastIncomingIndex = -1
+        var prev: ExpandableNotificationRow? = null
+
+        for ((i, child) in parent.children.withIndex()) {
+            when {
+                // Track the existing positions of the headers
+                child === incomingHeaderView -> {
+                    logger.logIncomingHeader(i)
+                    currentIncomingHeaderIdx = i
+                }
+                child === mediaControlsView -> {
+                    logger.logMediaControls(i)
+                    currentMediaControlsIdx = i
+                }
+                child === peopleHeaderView -> {
+                    logger.logConversationsHeader(i)
+                    currentPeopleHeaderIdx = i
+                }
+                child === alertingHeaderView -> {
+                    logger.logAlertingHeader(i)
+                    currentAlertingHeaderIdx = i
+                }
+                child === silentHeaderView -> {
+                    logger.logSilentHeader(i)
+                    currentGentleHeaderIdx = i
+                }
+                child !is ExpandableNotificationRow -> logger.logOther(i, child.javaClass)
+                else -> {
+                    lastNotifIndex = i
+                    // Is there a section discontinuity? This usually occurs due to HUNs
+                    if (prev?.entry?.bucket?.let { it > child.entry.bucket } == true) {
+                        // Remove existing headers, and move the Incoming header if necessary
+                        if (alertingHeaderTarget != -1) {
+                            if (showHeaders && incomingHeaderTarget != -1) {
+                                incomingHeaderTarget = alertingHeaderTarget
+                            }
+                            alertingHeaderTarget = -1
+                        }
+                        if (peopleHeaderTarget != -1) {
+                            if (showHeaders && incomingHeaderTarget != -1) {
+                                incomingHeaderTarget = peopleHeaderTarget
+                            }
+                            peopleHeaderTarget = -1
+                        }
+                        if (showHeaders && incomingHeaderTarget == -1) {
+                            incomingHeaderTarget = 0
+                        }
+                        // Walk backwards changing all previous notifications to the Incoming
+                        // section
+                        for (j in i - 1 downTo lastIncomingIndex + 1) {
+                            val prevChild = parent.getChildAt(j)
+                            if (prevChild is ExpandableNotificationRow) {
+                                prevChild.entry.bucket = BUCKET_HEADS_UP
+                            }
+                        }
+                        // Track the new bottom of the Incoming section
+                        lastIncomingIndex = i - 1
+                    }
+                    val isHeadsUp = child.isHeadsUp
+                    when (child.entry.bucket) {
+                        BUCKET_FOREGROUND_SERVICE -> logger.logForegroundService(i, isHeadsUp)
+                        BUCKET_PEOPLE -> {
+                            logger.logConversation(i, isHeadsUp)
+                            peopleNotifsPresent = true
+                            if (showHeaders && peopleHeaderTarget == -1) {
+                                peopleHeaderTarget = i
+                                // Offset the target if there are other headers before this that
+                                // will be moved.
+                                if (currentPeopleHeaderIdx != -1) {
+                                    peopleHeaderTarget--
+                                }
+                                if (currentAlertingHeaderIdx != -1) {
+                                    peopleHeaderTarget--
+                                }
+                                if (currentGentleHeaderIdx != -1) {
+                                    peopleHeaderTarget--
+                                }
+                            }
+                        }
+                        BUCKET_ALERTING -> {
+                            logger.logAlerting(i, isHeadsUp)
+                            if (showHeaders && usingPeopleFiltering && alertingHeaderTarget == -1) {
+                                alertingHeaderTarget = i
+                                // Offset the target if there are other headers before this that
+                                // will be moved.
+                                if (currentAlertingHeaderIdx != -1) {
+                                    alertingHeaderTarget--
+                                }
+                                if (currentGentleHeaderIdx != -1) {
+                                    alertingHeaderTarget--
+                                }
+                            }
+                        }
+                        BUCKET_SILENT -> {
+                            logger.logSilent(i, isHeadsUp)
+                            if (showHeaders && gentleHeaderTarget == -1) {
+                                gentleHeaderTarget = i
+                                // Offset the target if there are other headers before this that
+                                // will be moved.
+                                if (currentGentleHeaderIdx != -1) {
+                                    gentleHeaderTarget--
+                                }
+                            }
+                        }
+                        else -> throw IllegalStateException("Cannot find section bucket for view")
+                    }
+
+                    prev = child
+                }
+            }
+        }
+
+        if (showHeaders && usingPeopleFiltering && peopleHubVisible && peopleHeaderTarget == -1) {
+            // Insert the people header even if there are no people visible, in order to show
+            // the hub. Put it directly above the next header.
+            peopleHeaderTarget = when {
+                alertingHeaderTarget != -1 -> alertingHeaderTarget
+                gentleHeaderTarget != -1 -> gentleHeaderTarget
+                else -> lastNotifIndex // Put it at the end of the list.
+            }
+            // Offset the target to account for the current position of the people header.
+            if (currentPeopleHeaderIdx != -1 && currentPeopleHeaderIdx < peopleHeaderTarget) {
+                peopleHeaderTarget--
+            }
+        }
+
+        logger.logStr("New header target positions:")
+        logger.logIncomingHeader(incomingHeaderTarget)
+        logger.logMediaControls(mediaControlsTarget)
+        logger.logConversationsHeader(peopleHeaderTarget)
+        logger.logAlertingHeader(alertingHeaderTarget)
+        logger.logSilentHeader(gentleHeaderTarget)
+
+        // Add headers in reverse order to preserve indices
+        silentHeaderView?.let {
+            adjustHeaderVisibilityAndPosition(gentleHeaderTarget, it, currentGentleHeaderIdx)
+        }
+        alertingHeaderView?.let {
+            adjustHeaderVisibilityAndPosition(alertingHeaderTarget, it, currentAlertingHeaderIdx)
+        }
+        peopleHeaderView?.let {
+            adjustHeaderVisibilityAndPosition(peopleHeaderTarget, it, currentPeopleHeaderIdx)
+        }
+        incomingHeaderView?.let {
+            adjustHeaderVisibilityAndPosition(incomingHeaderTarget, it, currentIncomingHeaderIdx)
+        }
+        mediaControlsView?.let {
+            adjustViewPosition(mediaControlsTarget, it, currentMediaControlsIdx)
+        }
+
+        logger.logStr("Final order:")
+        logShadeContents()
+        logger.logStr("Section boundary update complete")
+
+        // Update headers to reflect state of section contents
+        silentHeaderView?.setAreThereDismissableGentleNotifs(
+                parent.hasActiveClearableNotifications(NotificationStackScrollLayout.ROWS_GENTLE)
+        )
+        peopleHeaderView?.canSwipe = showHeaders && peopleHubVisible && !peopleNotifsPresent
+        if (peopleHeaderTarget != currentPeopleHeaderIdx) {
+            peopleHeaderView?.resetTranslation()
+        }
+    }
+
+    private fun adjustHeaderVisibilityAndPosition(
+        targetPosition: Int,
+        header: StackScrollerDecorView,
+        currentPosition: Int
+    ) {
+        adjustViewPosition(targetPosition, header, currentPosition)
+        if (targetPosition != -1 && currentPosition == -1) {
+            header.isContentVisible = true
+        }
+    }
+
+    private fun adjustViewPosition(
+        targetPosition: Int,
+        view: ExpandableView,
+        currentPosition: Int
+    ) {
+        if (targetPosition == -1) {
+            if (currentPosition != -1) {
+                parent.removeView(view)
+            }
+        } else {
+            if (currentPosition == -1) {
+                // If the header is animating away, it will still have a parent, so detach it first
+                // TODO: We should really cancel the active animations here. This will happen
+                // automatically when the view's intro animation starts, but it's a fragile link.
+                view.transientContainer?.removeTransientView(view)
+                view.transientContainer = null
+                parent.addView(view, targetPosition)
+            } else {
+                parent.changeViewPosition(view, targetPosition)
+            }
+        }
+    }
+
+    private sealed class SectionBounds {
+
+        data class Many(
+            val first: ActivatableNotificationView,
+            val last: ActivatableNotificationView
+        ) : SectionBounds()
+
+        data class One(val lone: ActivatableNotificationView) : SectionBounds()
+        object None : SectionBounds()
+
+        fun addNotif(notif: ActivatableNotificationView): SectionBounds = when (this) {
+            is None -> One(notif)
+            is One -> Many(lone, notif)
+            is Many -> copy(last = notif)
+        }
+
+        fun updateSection(section: NotificationSection): Boolean = when (this) {
+            is None -> section.setFirstAndLastVisibleChildren(null, null)
+            is One -> section.setFirstAndLastVisibleChildren(lone, lone)
+            is Many -> section.setFirstAndLastVisibleChildren(first, last)
+        }
+
+        private fun NotificationSection.setFirstAndLastVisibleChildren(
+            first: ActivatableNotificationView?,
+            last: ActivatableNotificationView?
+        ): Boolean {
+            val firstChanged = setFirstVisibleChild(first)
+            val lastChanged = setLastVisibleChild(last)
+            return firstChanged || lastChanged
+        }
+    }
+
+    /**
+     * Updates the boundaries (as tracked by their first and last views) of the priority sections.
+     *
+     * @return `true` If the last view in the top section changed (so we need to animate).
+     */
+    fun updateFirstAndLastViewsForAllSections(
+        sections: Array<NotificationSection>,
+        children: List<ActivatableNotificationView>
+    ): Boolean {
+        // Create mapping of bucket to section
+        val sectionBounds = children.asSequence()
+                // Group children by bucket
+                .groupingBy {
+                    getBucket(it)
+                            ?: throw IllegalArgumentException("Cannot find section bucket for view")
+                }
+                // Combine each bucket into a SectionBoundary
+                .foldToSparseArray(
+                        SectionBounds.None,
+                        size = sections.size,
+                        operation = SectionBounds::addNotif
+                )
+        // Update each section with the associated boundary, tracking if there was a change
+        val changed = sections.fold(false) { changed, section ->
+            val bounds = sectionBounds[section.bucket] ?: SectionBounds.None
+            bounds.updateSection(section) || changed
+        }
+        if (DEBUG) {
+            logSections(sections)
+        }
+        return changed
+    }
+
+    private fun logSections(sections: Array<NotificationSection>) {
+        for (i in sections.indices) {
+            val s = sections[i]
+            val fs = when (val first = s.firstVisibleChild) {
+                null -> "(null)"
+                is ExpandableNotificationRow -> first.entry.key
+                else -> Integer.toHexString(System.identityHashCode(first))
+            }
+            val ls = when (val last = s.lastVisibleChild) {
+                null -> "(null)"
+                is ExpandableNotificationRow -> last.entry.key
+                else -> Integer.toHexString(System.identityHashCode(last))
+            }
+            Log.d(TAG, "updateSections: f=$fs s=$i")
+            Log.d(TAG, "updateSections: l=$ls s=$i")
+        }
+    }
+
+    private fun onGentleHeaderClick() {
+        val intent = Intent(Settings.ACTION_NOTIFICATION_SETTINGS)
+        activityStarter.startActivity(
+                intent,
+                true,
+                true,
+                Intent.FLAG_ACTIVITY_SINGLE_TOP)
+    }
+
+    private fun onClearGentleNotifsClick(v: View) {
+        onClearSilentNotifsClickListener?.onClick(v)
+    }
+
+    /** Listener for when the "clear all" button is clicked on the gentle notification header. */
+    fun setOnClearSilentNotifsClickListener(listener: View.OnClickListener) {
+        onClearSilentNotifsClickListener = listener
+    }
+
+    fun hidePeopleRow() {
+        peopleHubVisible = false
+        updateSectionBoundaries("PeopleHub dismissed")
+    }
+
+    fun setHeaderForegroundColor(@ColorInt color: Int) {
+        peopleHeaderView?.setTextColor(color)
+        silentHeaderView?.setForegroundColor(color)
+        alertingHeaderView?.setForegroundColor(color)
+    }
+
+    companion object {
+        private const val TAG = "NotifSectionsManager"
+        private const val DEBUG = false
+        private const val ENABLE_SNOOZED_CONVERSATION_HUB = false
+    }
+}
+
+/**
+ * For now, declare the available notification buckets (sections) here so that other
+ * presentation code can decide what to do based on an entry's buckets
+ */
+@Retention(AnnotationRetention.SOURCE)
+@IntDef(
+        prefix = ["BUCKET_"],
+        value = [
+            BUCKET_UNKNOWN, BUCKET_MEDIA_CONTROLS, BUCKET_HEADS_UP, BUCKET_FOREGROUND_SERVICE,
+            BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT
+        ]
+)
+annotation class PriorityBucket
+
+const val BUCKET_UNKNOWN = 0
+const val BUCKET_MEDIA_CONTROLS = 1
+const val BUCKET_HEADS_UP = 2
+const val BUCKET_FOREGROUND_SERVICE = 3
+const val BUCKET_PEOPLE = 4
+const val BUCKET_ALERTING = 5
+const val BUCKET_SILENT = 6
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 1ccc2bd..3db4b6f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -21,7 +21,7 @@
 
 import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
 import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT;
 import static com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.ANCHOR_SCROLLING;
 import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_SWIPE;
 import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
@@ -577,7 +577,7 @@
 
         mSectionsManager = notificationSectionsManager;
         mSectionsManager.initialize(this, LayoutInflater.from(context));
-        mSectionsManager.setOnClearGentleNotifsClickListener(v -> {
+        mSectionsManager.setOnClearSilentNotifsClickListener(v -> {
             // Leave the shade open if there will be other notifs left over to clear
             final boolean closeShade = !hasActiveClearableNotifications(ROWS_HIGH_PRIORITY);
             clearNotifications(ROWS_GENTLE, closeShade);
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 6b0df95..3dcf7ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -439,7 +439,8 @@
                         // time out anyway
                         && !entry.showingPulsing()) {
                     mEntriesToRemoveWhenReorderingAllowed.add(entry);
-                    mVisualStabilityManager.addReorderingAllowedCallback(HeadsUpManagerPhone.this);
+                    mVisualStabilityManager.addReorderingAllowedCallback(HeadsUpManagerPhone.this,
+                            false  /* persistent */);
                 } else if (mTrackingHeadsUp) {
                     mEntriesToRemoveAfterExpand.add(entry);
                 } else if (mIsAutoHeadsUp && mStatusBarState == StatusBarState.KEYGUARD) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index 80785db..d0a872e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
@@ -454,7 +455,7 @@
      * If there is a {@link NotificationGroup} associated with the provided entry, this method
      * will update the suppression of that group.
      */
-    public void updateSuppression(NotificationEntry entry) {
+    public void updateSuppression(@NonNull final NotificationEntry entry) {
         NotificationGroup group = mGroupMap.get(getGroupKey(entry.getSbn()));
         if (group != null) {
             updateSuppression(group);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java
index 567ddb6..926c1bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java
@@ -279,7 +279,7 @@
         } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
             mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE;
             // Make sure to remove FLAG_ALT_FOCUSABLE_IM when keyguard needs input.
-            if (state.mKeyguardNeedsInput) {
+            if (state.mKeyguardNeedsInput && state.isKeyguardShowingAndNotOccluded()) {
                 mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
             } else {
                 mLpChanged.flags |= LayoutParams.FLAG_ALT_FOCUSABLE_IM;
@@ -321,8 +321,7 @@
                 || state.mPanelVisible || state.mKeyguardFadingAway || state.mBouncerShowing
                 || state.mHeadsUpShowing
                 || state.mScrimsVisibility != ScrimController.TRANSPARENT)
-                || state.mBackgroundBlurRadius > 0
-                || state.mLaunchingActivity;
+                || state.mBackgroundBlurRadius > 0;
     }
 
     private void applyFitsSystemWindows(State state) {
@@ -486,11 +485,6 @@
         apply(mCurrentState);
     }
 
-    void setLaunchingActivity(boolean launching) {
-        mCurrentState.mLaunchingActivity = launching;
-        apply(mCurrentState);
-    }
-
     public void setScrimsVisibility(int scrimsVisibility) {
         mCurrentState.mScrimsVisibility = scrimsVisibility;
         apply(mCurrentState);
@@ -651,7 +645,6 @@
         boolean mForceCollapsed;
         boolean mForceDozeBrightness;
         boolean mForceUserActivity;
-        boolean mLaunchingActivity;
         boolean mBackdropShowing;
         boolean mWallpaperSupportsAmbientMode;
         boolean mNotTouchable;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
index 0d25898..596a607 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewController.java
@@ -93,7 +93,6 @@
     private PhoneStatusBarView mStatusBarView;
     private PhoneStatusBarTransitions mBarTransitions;
     private StatusBar mService;
-    private NotificationShadeWindowController mNotificationShadeWindowController;
     private DragDownHelper mDragDownHelper;
     private boolean mDoubleTapEnabled;
     private boolean mSingleTapEnabled;
@@ -431,14 +430,10 @@
 
     public void setExpandAnimationPending(boolean pending) {
         mExpandAnimationPending = pending;
-        mNotificationShadeWindowController
-                .setLaunchingActivity(mExpandAnimationPending | mExpandAnimationRunning);
     }
 
     public void setExpandAnimationRunning(boolean running) {
         mExpandAnimationRunning = running;
-        mNotificationShadeWindowController
-                .setLaunchingActivity(mExpandAnimationPending | mExpandAnimationRunning);
     }
 
     public void cancelExpandHelper() {
@@ -461,9 +456,8 @@
         }
     }
 
-    public void setService(StatusBar statusBar, NotificationShadeWindowController controller) {
+    public void setService(StatusBar statusBar) {
         mService = statusBar;
-        mNotificationShadeWindowController = controller;
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index d4f4d3b..a065b74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -663,6 +663,7 @@
         if (DEBUG) Log.d(TAG, "screenrecord: countdown " + millisUntilFinished);
         int countdown = (int) Math.floorDiv(millisUntilFinished + 500, 1000);
         int resourceId = R.drawable.stat_sys_screen_record;
+        String description = Integer.toString(countdown);
         switch (countdown) {
             case 1:
                 resourceId = R.drawable.stat_sys_screen_record_1;
@@ -674,7 +675,7 @@
                 resourceId = R.drawable.stat_sys_screen_record_3;
                 break;
         }
-        mIconController.setIcon(mSlotScreenRecord, resourceId, null);
+        mIconController.setIcon(mSlotScreenRecord, resourceId, description);
         mIconController.setIconVisibility(mSlotScreenRecord, true);
     }
 
@@ -688,7 +689,8 @@
     public void onRecordingStart() {
         if (DEBUG) Log.d(TAG, "screenrecord: showing icon");
         mIconController.setIcon(mSlotScreenRecord,
-                R.drawable.stat_sys_screen_record, null);
+                R.drawable.stat_sys_screen_record,
+                mResources.getString(R.string.screenrecord_ongoing_screen_only));
         mIconController.setIconVisibility(mSlotScreenRecord, true);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index dd54a3d..3fa530a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1001,7 +1001,7 @@
         updateTheme();
 
         inflateStatusBarWindow();
-        mNotificationShadeWindowViewController.setService(this, mNotificationShadeWindowController);
+        mNotificationShadeWindowViewController.setService(this);
         mNotificationShadeWindowView.setOnTouchListener(getStatusBarWindowTouchListener());
 
         // TODO: Deal with the ugliness that comes from having some of the statusbar broken out
@@ -1488,7 +1488,7 @@
         if (mDividerOptional.isPresent()) {
             divider = mDividerOptional.get();
         }
-        if (divider == null || !divider.inSplitMode()) {
+        if (divider == null || !divider.isDividerVisible()) {
             final int navbarPos = WindowManagerWrapper.getInstance().getNavBarPosition(mDisplayId);
             if (navbarPos == NAV_BAR_POS_INVALID) {
                 return false;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 442c7ea..b6e72226 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -369,16 +369,24 @@
                     R.string.ext_media_new_notification_message, disk.getDescription());
 
             final PendingIntent initIntent = buildInitPendingIntent(vol);
-            return buildNotificationBuilder(vol, title, text)
-                    .addAction(new Action(R.drawable.ic_settings_24dp,
-                            mContext.getString(R.string.ext_media_init_action), initIntent))
-                    .addAction(new Action(R.drawable.ic_eject_24dp,
-                            mContext.getString(R.string.ext_media_unmount_action),
-                            buildUnmountPendingIntent(vol)))
-                    .setContentIntent(initIntent)
-                    .setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()))
-                    .build();
+            final PendingIntent unmountIntent = buildUnmountPendingIntent(vol);
 
+            if (isAutomotive()) {
+                return buildNotificationBuilder(vol, title, text)
+                        .setContentIntent(unmountIntent)
+                        .setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()))
+                        .build();
+            } else {
+                return buildNotificationBuilder(vol, title, text)
+                        .addAction(new Action(R.drawable.ic_settings_24dp,
+                                mContext.getString(R.string.ext_media_init_action), initIntent))
+                        .addAction(new Action(R.drawable.ic_eject_24dp,
+                                mContext.getString(R.string.ext_media_unmount_action),
+                                unmountIntent))
+                        .setContentIntent(initIntent)
+                        .setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()))
+                        .build();
+            }
         } else {
             final CharSequence title = disk.getDescription();
             final CharSequence text = mContext.getString(
@@ -427,9 +435,15 @@
                 R.string.ext_media_unmountable_notification_title, disk.getDescription());
         final CharSequence text = mContext.getString(
                 R.string.ext_media_unmountable_notification_message, disk.getDescription());
+        PendingIntent action;
+        if (isAutomotive()) {
+            action = buildUnmountPendingIntent(vol);
+        } else {
+            action = buildInitPendingIntent(vol);
+        }
 
         return buildNotificationBuilder(vol, title, text)
-                .setContentIntent(buildInitPendingIntent(vol))
+                .setContentIntent(action)
                 .setCategory(Notification.CATEGORY_ERROR)
                 .build();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
index 367d4d2..2973e0a 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -23,15 +23,12 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.ServiceManager;
-import android.util.EventLog;
 import android.util.Log;
 import android.view.LayoutInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.CheckBox;
-import android.widget.Toast;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
@@ -79,25 +76,6 @@
         window.setCloseOnTouchOutside(false);
 
         setupAlert();
-
-        // adding touch listener on affirmative button - checks if window is obscured
-        // if obscured, do not let user give permissions (could be tapjacking involved)
-        final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {
-            // Filter obscured touches by consuming them.
-            if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)
-                    || ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
-                if (event.getAction() == MotionEvent.ACTION_UP) {
-                    EventLog.writeEvent(0x534e4554, "62187985"); // safety net logging
-                    Toast.makeText(v.getContext(),
-                            R.string.touch_filtered_warning,
-                            Toast.LENGTH_SHORT).show();
-                }
-                return true;
-            }
-            return false;
-        };
-        mAlert.getButton(BUTTON_POSITIVE).setOnTouchListener(filterTouchListener);
-
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlEntity.kt b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
similarity index 70%
copy from packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlEntity.kt
copy to packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
index d0f7607..c91033e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/storage/BubbleXmlEntity.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
@@ -13,12 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.bubbles.storage
 
-import android.annotation.UserIdInt
+package com.android.systemui.util
 
-data class BubbleXmlEntity(
-    @UserIdInt val userId: Int,
-    val packageName: String,
-    val shortcutId: String
-)
+import android.view.ViewGroup
+
+/** [Sequence] that yields all of the direct children of this [ViewGroup] */
+val ViewGroup.children
+    get() = sequence {
+        for (i in 0 until childCount) yield(getChildAt(i))
+    }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt b/packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt
new file mode 100644
index 0000000..accb81e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt
@@ -0,0 +1,136 @@
+/*
+ * 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.systemui.util
+
+import android.util.SparseArray
+
+/**
+ * Transforms an [Array] into a [SparseArray], by applying each element to [keySelector] in order to
+ * generate the index at which it will be placed. If two elements produce the same index, the latter
+ * replaces the former in the final result.
+ *
+ * See [Array.associateBy].
+ */
+inline fun <T> Array<T>.associateByToSparseArray(
+    crossinline keySelector: (T) -> Int
+): SparseArray<T> {
+    val sparseArray = SparseArray<T>(size)
+    for (value in this) {
+        sparseArray.put(keySelector(value), value)
+    }
+    return sparseArray
+}
+
+/**
+ * Folds a [Grouping] into a [SparseArray]. See [Grouping.fold].
+ */
+inline fun <T, R> Grouping<T, Int>.foldToSparseArray(
+    initial: R,
+    size: Int = -1,
+    crossinline operation: (R, T) -> R
+): SparseArray<R> {
+    val sparseArray = when {
+        size < 0 -> SparseArray<R>()
+        else -> SparseArray<R>(size)
+    }
+    sourceIterator().forEach { elem ->
+        val key = keyOf(elem)
+        val acc = sparseArray.get(key) ?: initial
+        sparseArray.put(key, operation(acc, elem))
+    }
+    return sparseArray
+}
+
+/**
+ * Wraps this [SparseArray] into an immutable [Map], the methods of which forward to this
+ * [SparseArray].
+ */
+fun <T> SparseArray<T>.asMap(): Map<Int, T> = SparseArrayMapWrapper(this)
+
+private class SparseArrayMapWrapper<T>(
+    private val sparseArray: SparseArray<T>
+) : Map<Int, T> {
+
+    private data class Entry<T>(override val key: Int, override val value: T) : Map.Entry<Int, T>
+
+    private val entrySequence = sequence {
+        val size = sparseArray.size()
+        for (i in 0 until size) {
+            val key = sparseArray.keyAt(i)
+            val value = sparseArray.get(key)
+            yield(Entry(key, value))
+        }
+    }
+
+    override val entries: Set<Map.Entry<Int, T>>
+        get() = object : Set<Map.Entry<Int, T>> {
+            override val size: Int
+                get() = this@SparseArrayMapWrapper.size
+
+            override fun contains(element: Map.Entry<Int, T>): Boolean =
+                    sparseArray[element.key]?.let { it == element.value } == true
+
+            override fun containsAll(elements: Collection<Map.Entry<Int, T>>): Boolean =
+                    elements.all { contains(it) }
+
+            override fun isEmpty(): Boolean = size == 0
+
+            override fun iterator(): Iterator<Map.Entry<Int, T>> = entrySequence.iterator()
+        }
+
+    override val keys: Set<Int> = object : Set<Int> {
+        private val keySequence = entrySequence.map { it.key }
+
+        override val size: Int
+            get() = this@SparseArrayMapWrapper.size
+
+        override fun contains(element: Int): Boolean = containsKey(element)
+
+        override fun containsAll(elements: Collection<Int>): Boolean =
+                elements.all { contains(it) }
+
+        override fun isEmpty(): Boolean = size == 0
+
+        override fun iterator(): Iterator<Int> = keySequence.iterator()
+    }
+    override val size: Int
+        get() = sparseArray.size()
+    override val values: Collection<T>
+        get() = object : Collection<T> {
+            private val valueSequence = entrySequence.map { it.value }
+
+            override val size: Int
+                get() = this@SparseArrayMapWrapper.size
+
+            override fun contains(element: T): Boolean = containsValue(element)
+
+            override fun containsAll(elements: Collection<T>): Boolean =
+                    elements.all { contains(it) }
+
+            override fun isEmpty(): Boolean = this@SparseArrayMapWrapper.isEmpty()
+
+            override fun iterator(): Iterator<T> = valueSequence.iterator()
+        }
+
+    override fun containsKey(key: Int): Boolean = sparseArray.contains(key)
+
+    override fun containsValue(value: T): Boolean = sparseArray.indexOfValue(value) >= 0
+
+    override fun get(key: Int): T? = sparseArray.get(key)
+
+    override fun isEmpty(): Boolean = sparseArray.size() == 0
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
index 93f45c5..21f67ae 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/SystemWindows.java
@@ -125,7 +125,7 @@
      */
     public void removeView(View view) {
         SurfaceControlViewHost root = mViewRoots.remove(view);
-        root.die();
+        root.release();
     }
 
     /**
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
index 870010a..aa4122f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java
@@ -134,6 +134,7 @@
         mDependency.injectMockDependency(WakefulnessLifecycle.class);
         mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
                 new Handler(mTestableLooper.getLooper()));
+        mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
         mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
 
         doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
@@ -150,6 +151,7 @@
         // This should not start listening on any of the real dependencies but will test that
         // callbacks in mKeyguardUpdateMonitor are done in the mTestableLooper thread
         mCarrierTextController.setListening(mCarrierTextCallback);
+        mTestableLooper.processAllMessages();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index b5609dd..7bc453a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -38,6 +38,7 @@
 
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
+import android.app.trust.IStrongAuthTracker;
 import android.app.trust.TrustManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -72,6 +73,8 @@
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.widget.ILockSettings;
+import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor.BiometricAuthenticated;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -120,6 +123,10 @@
     @Mock
     private TrustManager mTrustManager;
     @Mock
+    private LockPatternUtils mLockPatternUtils;
+    @Mock
+    private ILockSettings mLockSettings;
+    @Mock
     private FingerprintManager mFingerprintManager;
     @Mock
     private FaceManager mFaceManager;
@@ -169,12 +176,13 @@
         when(mFaceManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
         when(mUserManager.isUserUnlocked(anyInt())).thenReturn(true);
         when(mUserManager.isPrimaryUser()).thenReturn(true);
+        when(mStrongAuthTracker.getStub()).thenReturn(mock(IStrongAuthTracker.Stub.class));
         when(mStrongAuthTracker
                 .isUnlockingWithBiometricAllowed(anyBoolean() /* isStrongBiometric */))
                 .thenReturn(true);
-
         when(mTelephonyManager.getServiceStateForSubscriber(anyInt()))
                 .thenReturn(new ServiceState());
+        when(mLockPatternUtils.getLockSettings()).thenReturn(mLockSettings);
         mSpiedContext.addMockSystemService(TrustManager.class, mTrustManager);
         mSpiedContext.addMockSystemService(FingerprintManager.class, mFingerprintManager);
         mSpiedContext.addMockSystemService(BiometricManager.class, mBiometricManager);
@@ -729,8 +737,9 @@
             super(context,
                     TestableLooper.get(KeyguardUpdateMonitorTest.this).getLooper(),
                     mBroadcastDispatcher, mDumpManager,
-                    mRingerModeTracker, mBackgroundExecutor, mStatusBarStateController);
-            mStrongAuthTracker = KeyguardUpdateMonitorTest.this.mStrongAuthTracker;
+                    mRingerModeTracker, mBackgroundExecutor,
+                    mStatusBarStateController, mLockPatternUtils);
+            setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
         }
 
         public boolean hasSimStateJustChanged() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 96e868d..52923ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -317,7 +317,7 @@
         verify(mNotificationEntryManager).updateNotifications(any());
 
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
         assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
         verify(mNotificationEntryManager, times(2)).updateNotifications(anyString());
 
@@ -329,7 +329,7 @@
         mBubbleController.updateBubble(mRow2.getEntry());
         mBubbleController.updateBubble(mRow.getEntry());
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
 
         Bubble b = mBubbleData.getOverflowBubbleWithKey(mRow.getEntry().getKey());
         assertThat(mBubbleData.getOverflowBubbles()).isEqualTo(ImmutableList.of(b));
@@ -350,9 +350,10 @@
         mBubbleController.updateBubble(mRow.getEntry(), /* suppressFlyout */
                 false, /* showInShade */ true);
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
 
-        mBubbleController.removeBubble(mRow.getEntry(), BubbleController.DISMISS_NOTIF_CANCEL);
+        mBubbleController.removeBubble(
+                mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
         verify(mNotificationEntryManager, times(1)).performRemoveNotification(
                 eq(mRow.getEntry().getSbn()), anyInt());
         assertThat(mBubbleData.getOverflowBubbles()).isEmpty();
@@ -365,7 +366,7 @@
         assertTrue(mBubbleController.hasBubbles());
 
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_USER_CHANGED);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_CHANGED);
         verify(mNotificationEntryManager, never()).performRemoveNotification(
                 eq(mRow.getEntry().getSbn()), anyInt());
         assertFalse(mBubbleController.hasBubbles());
@@ -563,7 +564,8 @@
 
         // Dismiss currently expanded
         mBubbleController.removeBubble(
-                mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey()).getEntry(),
+                mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey())
+                        .getEntry().getKey(),
                 BubbleController.DISMISS_USER_GESTURE);
         verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().getKey());
 
@@ -574,7 +576,8 @@
 
         // Dismiss that one
         mBubbleController.removeBubble(
-                mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey()).getEntry(),
+                mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey())
+                        .getEntry().getKey(),
                 BubbleController.DISMISS_USER_GESTURE);
 
         // Make sure state changes and collapse happens
@@ -700,7 +703,7 @@
     @Test
     public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException {
         mBubbleController.updateBubble(mRow.getEntry());
-        mBubbleController.removeBubble(mRow.getEntry(), BubbleController.DISMISS_AGED);
+        mBubbleController.removeBubble(mRow.getEntry().getKey(), BubbleController.DISMISS_AGED);
         verify(mDeleteIntent, never()).send();
     }
 
@@ -708,7 +711,7 @@
     public void testDeleteIntent_removeBubble_user() throws PendingIntent.CanceledException {
         mBubbleController.updateBubble(mRow.getEntry());
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
         verify(mDeleteIntent, times(1)).send();
     }
 
@@ -808,7 +811,7 @@
 
         // Dismiss the bubble into overflow.
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
         assertFalse(mBubbleController.hasBubbles());
 
         boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
@@ -829,7 +832,7 @@
                 mRow.getEntry()));
 
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_NO_LONGER_BUBBLE);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_NO_LONGER_BUBBLE);
         assertFalse(mBubbleController.hasBubbles());
 
         boolean intercepted = mRemoveInterceptor.onNotificationRemoveRequested(
@@ -851,12 +854,12 @@
 
         mBubbleData.setMaxOverflowBubbles(1);
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
         assertEquals(mBubbleData.getBubbles().size(), 2);
         assertEquals(mBubbleData.getOverflowBubbles().size(), 1);
 
         mBubbleController.removeBubble(
-                mRow2.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                mRow2.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
         // Overflow max of 1 is reached; mRow is oldest, so it gets removed
         verify(mNotificationEntryManager, times(1)).performRemoveNotification(
                 mRow.getEntry().getSbn(), REASON_CANCEL);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
index 66f119a..882504b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
@@ -20,11 +20,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
@@ -180,7 +177,8 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
 
         // Verify
         verifyUpdateReceived();
@@ -297,12 +295,14 @@
         mBubbleData.setListener(mListener);
 
         mBubbleData.setMaxOverflowBubbles(1);
-        mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
         verifyUpdateReceived();
         assertOverflowChangedTo(ImmutableList.of(mBubbleA1));
 
         // Overflow max of 1 is reached; A1 is oldest, so it gets removed
-        mBubbleData.notificationEntryRemoved(mEntryA2, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA2.getKey(), BubbleController.DISMISS_USER_GESTURE);
         verifyUpdateReceived();
         assertOverflowChangedTo(ImmutableList.of(mBubbleA2));
     }
@@ -449,7 +449,8 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryA2, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA2.getKey(), BubbleController.DISMISS_USER_GESTURE);
         verifyUpdateReceived();
         assertOrderChangedTo(mBubbleB2, mBubbleB1, mBubbleA1);
     }
@@ -469,7 +470,8 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryB1, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryB1.getKey(), BubbleController.DISMISS_USER_GESTURE);
         verifyUpdateReceived();
         assertOrderNotChanged();
     }
@@ -489,7 +491,8 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_NOTIF_CANCEL);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA1.getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
         verifyUpdateReceived();
         assertOrderChangedTo(mBubbleB2, mBubbleB1, mBubbleA2);
     }
@@ -510,12 +513,14 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_NOTIF_CANCEL);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA1.getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
         verifyUpdateReceived();
         assertOverflowChangedTo(ImmutableList.of(mBubbleA2));
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryA2, BubbleController.DISMISS_GROUP_CANCELLED);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA2.getKey(), BubbleController.DISMISS_GROUP_CANCELLED);
         verifyUpdateReceived();
         assertOverflowChangedTo(ImmutableList.of());
     }
@@ -534,7 +539,8 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryA2, BubbleController.DISMISS_NOTIF_CANCEL);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA2.getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
         verifyUpdateReceived();
         assertSelectionChangedTo(mBubbleB2);
     }
@@ -625,7 +631,8 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
 
         // Verify the selection was cleared.
         verifyUpdateReceived();
@@ -779,7 +786,8 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryB2, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryB2.getKey(), BubbleController.DISMISS_USER_GESTURE);
         verifyUpdateReceived();
         assertOrderChangedTo(mBubbleB1, mBubbleA2, mBubbleA1);
     }
@@ -804,11 +812,13 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryA2, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA2.getKey(), BubbleController.DISMISS_USER_GESTURE);
         verifyUpdateReceived();
         assertSelectionChangedTo(mBubbleA1);
 
-        mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
         verifyUpdateReceived();
         assertSelectionChangedTo(mBubbleB1);
     }
@@ -923,7 +933,8 @@
         mBubbleData.setListener(mListener);
 
         // Test
-        mBubbleData.notificationEntryRemoved(mEntryA1, BubbleController.DISMISS_USER_GESTURE);
+        mBubbleData.notificationEntryRemoved(
+                mEntryA1.getKey(), BubbleController.DISMISS_USER_GESTURE);
         verifyUpdateReceived();
         assertExpandedChangedTo(false);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
index 73b8760..c16801c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java
@@ -285,7 +285,8 @@
         assertTrue(mBubbleController.hasBubbles());
         verify(mNotifCallback, times(1)).invalidateNotifications(anyString());
 
-        mBubbleController.removeBubble(mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+        mBubbleController.removeBubble(
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
         assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
         verify(mNotifCallback, times(2)).invalidateNotifications(anyString());
     }
@@ -302,7 +303,8 @@
         mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).setSuppressNotification(true);
 
         // Now remove the bubble
-        mBubbleController.removeBubble(mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+        mBubbleController.removeBubble(
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
         assertTrue(mBubbleData.hasOverflowBubbleWithKey(mRow.getEntry().getKey()));
 
         // We don't remove the notification since the bubble is still in overflow.
@@ -322,7 +324,8 @@
         mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).setSuppressNotification(true);
 
         // Now remove the bubble
-        mBubbleController.removeBubble(mRow.getEntry(), BubbleController.DISMISS_NOTIF_CANCEL);
+        mBubbleController.removeBubble(
+                mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
         assertFalse(mBubbleData.hasOverflowBubbleWithKey(mRow.getEntry().getKey()));
 
         // Since the notif is dismissed and not in overflow, once the bubble is removed,
@@ -502,7 +505,8 @@
 
         // Dismiss currently expanded
         mBubbleController.removeBubble(
-                mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey()).getEntry(),
+                mBubbleData.getBubbleInStackWithKey(
+                        stackView.getExpandedBubble().getKey()).getEntry().getKey(),
                 BubbleController.DISMISS_USER_GESTURE);
         verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow2.getEntry().getKey());
 
@@ -513,7 +517,8 @@
 
         // Dismiss that one
         mBubbleController.removeBubble(
-                mBubbleData.getBubbleInStackWithKey(stackView.getExpandedBubble().getKey()).getEntry(),
+                mBubbleData.getBubbleInStackWithKey(
+                        stackView.getExpandedBubble().getKey()).getEntry().getKey(),
                 BubbleController.DISMISS_USER_GESTURE);
 
         // Make sure state changes and collapse happens
@@ -613,7 +618,7 @@
     @Test
     public void testDeleteIntent_removeBubble_aged() throws PendingIntent.CanceledException {
         mBubbleController.updateBubble(mRow.getEntry());
-        mBubbleController.removeBubble(mRow.getEntry(), BubbleController.DISMISS_AGED);
+        mBubbleController.removeBubble(mRow.getEntry().getKey(), BubbleController.DISMISS_AGED);
         verify(mDeleteIntent, never()).send();
     }
 
@@ -621,7 +626,7 @@
     public void testDeleteIntent_removeBubble_user() throws PendingIntent.CanceledException {
         mBubbleController.updateBubble(mRow.getEntry());
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
         verify(mDeleteIntent, times(1)).send();
     }
 
@@ -686,7 +691,7 @@
 
         // Dismiss the bubble
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_USER_GESTURE);
         assertFalse(mBubbleController.hasBubbles());
 
         // Dismiss the notification
@@ -707,7 +712,7 @@
 
         // Dismiss the bubble
         mBubbleController.removeBubble(
-                mRow.getEntry(), BubbleController.DISMISS_NOTIF_CANCEL);
+                mRow.getEntry().getKey(), BubbleController.DISMISS_NOTIF_CANCEL);
         assertFalse(mBubbleController.hasBubbles());
 
         // Dismiss the notification
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubblePersistentRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubblePersistentRepositoryTest.kt
new file mode 100644
index 0000000..d49d021
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubblePersistentRepositoryTest.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.systemui.bubbles.storage
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import junit.framework.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class BubblePersistentRepositoryTest : SysuiTestCase() {
+
+    private val bubbles = listOf(
+            BubbleEntity(0, "com.example.messenger", "shortcut-1"),
+            BubbleEntity(10, "com.example.chat", "alice and bob"),
+            BubbleEntity(0, "com.example.messenger", "shortcut-2")
+    )
+    private lateinit var repository: BubblePersistentRepository
+
+    @Before
+    fun setup() {
+        repository = BubblePersistentRepository(mContext)
+    }
+
+    @Test
+    fun testReadWriteOperation() {
+        repository.persistsToDisk(bubbles)
+        assertEquals(bubbles, repository.readFromDisk())
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt
new file mode 100644
index 0000000..7acc937
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleVolatileRepositoryTest.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.systemui.bubbles.storage
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import junit.framework.Assert.assertEquals
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class BubbleVolatileRepositoryTest : SysuiTestCase() {
+
+    private val bubble1 = BubbleEntity(0, "com.example.messenger", "shortcut-1")
+    private val bubble2 = BubbleEntity(10, "com.example.chat", "alice and bob")
+    private val bubble3 = BubbleEntity(0, "com.example.messenger", "shortcut-2")
+    private val bubbles = listOf(bubble1, bubble2, bubble3)
+
+    private lateinit var repository: BubbleVolatileRepository
+
+    @Before
+    fun setup() {
+        repository = BubbleVolatileRepository()
+    }
+
+    @Test
+    fun testAddAndRemoveBubbles() {
+        repository.addBubbles(bubbles)
+        assertEquals(bubbles, repository.bubbles)
+        repository.addBubbles(listOf(bubble1))
+        assertEquals(listOf(bubble2, bubble3, bubble1), repository.bubbles)
+        repository.removeBubbles(listOf(bubble3))
+        assertEquals(listOf(bubble2, bubble1), repository.bubbles)
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt
new file mode 100644
index 0000000..ef4580c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/storage/BubbleXmlHelperTest.kt
@@ -0,0 +1,67 @@
+/*
+ * 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.systemui.bubbles.storage
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import junit.framework.Assert.assertEquals
+import junit.framework.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class BubbleXmlHelperTest : SysuiTestCase() {
+
+    private val bubbles = listOf(
+        BubbleEntity(0, "com.example.messenger", "shortcut-1"),
+        BubbleEntity(10, "com.example.chat", "alice and bob"),
+        BubbleEntity(0, "com.example.messenger", "shortcut-2")
+    )
+
+    @Test
+    fun testWriteXml() {
+        val expectedEntries = """
+            <bb uid="0" pkg="com.example.messenger" sid="shortcut-1" />
+            <bb uid="10" pkg="com.example.chat" sid="alice and bob" />
+            <bb uid="0" pkg="com.example.messenger" sid="shortcut-2" />
+        """.trimIndent()
+        ByteArrayOutputStream().use {
+            writeXml(it, bubbles)
+            val actual = it.toString()
+            assertTrue("cannot find expected entry in \n$actual",
+                    actual.contains(expectedEntries))
+        }
+    }
+
+    @Test
+    fun testReadXml() {
+        val src = """
+            <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
+            <bs>
+            <bb uid="0" pkg="com.example.messenger" sid="shortcut-1" />
+            <bb uid="10" pkg="com.example.chat" sid="alice and bob" />
+            <bb uid="0" pkg="com.example.messenger" sid="shortcut-2" />
+            </bs>
+        """.trimIndent()
+        val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8)))
+        assertEquals("failed parsing bubbles from xml\n$src", bubbles, actual)
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
index 9b40c5e..128a7e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
@@ -177,4 +177,31 @@
         inOrder.verify(mockSL).setListening(true)
         inOrder.verify(mockSL).reload()
     }
-}
\ No newline at end of file
+
+    @Test
+    fun testChangeUserResetsExistingCallbackServices() {
+        val list = listOf(serviceInfo)
+        controller.addCallback(mockCallback)
+
+        @Suppress("unchecked_cast")
+        val captor: ArgumentCaptor<List<ControlsServiceInfo>> =
+                ArgumentCaptor.forClass(List::class.java)
+                        as ArgumentCaptor<List<ControlsServiceInfo>>
+        executor.runAllReady()
+        reset(mockCallback)
+
+        serviceListingCallbackCaptor.value.onServicesReloaded(list)
+
+        executor.runAllReady()
+        verify(mockCallback).onServicesUpdated(capture(captor))
+        assertEquals(1, captor.value.size)
+
+        reset(mockCallback)
+        controller.changeUser(UserHandle.of(otherUser))
+        executor.runAllReady()
+        assertEquals(otherUser, controller.currentUserId)
+
+        verify(mockCallback).onServicesUpdated(capture(captor))
+        assertEquals(0, captor.value.size)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
index 64acdcc..ee7733a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogTest.java
@@ -156,13 +156,20 @@
     }
 
     @Test
-    public void testShouldLogVisibility() {
+    public void testShouldLogShow() {
         mGlobalActionsDialog.onShow(null);
         mTestableLooper.processAllMessages();
         verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_POWER_MENU_OPEN);
     }
 
     @Test
+    public void testShouldLogDismiss() {
+        mGlobalActionsDialog.onDismiss(mGlobalActionsDialog.mDialog);
+        mTestableLooper.processAllMessages();
+        verifyLogPosted(GlobalActionsDialog.GlobalActionsEvent.GA_POWER_MENU_CLOSE);
+    }
+
+    @Test
     public void testShouldLogBugreportPress() throws InterruptedException {
         GlobalActionsDialog.BugReportAction bugReportAction =
                 mGlobalActionsDialog.makeBugReportActionForTesting();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
index d407b8a..58ee79e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
@@ -16,19 +16,15 @@
 
 package com.android.systemui.media
 
-import android.graphics.Color
-import android.content.res.ColorStateList
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import android.view.View
 import android.widget.SeekBar
 import android.widget.TextView
 import androidx.test.filters.SmallTest
-
 import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.google.common.truth.Truth.assertThat
-
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -65,7 +61,7 @@
     fun seekBarGone() {
         // WHEN seek bar is disabled
         val isEnabled = false
-        val data = SeekBarViewModel.Progress(isEnabled, false, null, null, null)
+        val data = SeekBarViewModel.Progress(isEnabled, false, null, null)
         observer.onChanged(data)
         // THEN seek bar shows just a line with no text
         assertThat(seekBarView.isEnabled()).isFalse()
@@ -78,7 +74,7 @@
     fun seekBarVisible() {
         // WHEN seek bar is enabled
         val isEnabled = true
-        val data = SeekBarViewModel.Progress(isEnabled, true, 3000, 12000, -1)
+        val data = SeekBarViewModel.Progress(isEnabled, true, 3000, 12000)
         observer.onChanged(data)
         // THEN seek bar is visible
         assertThat(seekBarView.getVisibility()).isEqualTo(View.VISIBLE)
@@ -89,7 +85,7 @@
     @Test
     fun seekBarProgress() {
         // WHEN seek bar progress is about half
-        val data = SeekBarViewModel.Progress(true, true, 3000, 120000, -1)
+        val data = SeekBarViewModel.Progress(true, true, 3000, 120000)
         observer.onChanged(data)
         // THEN seek bar is visible
         assertThat(seekBarView.progress).isEqualTo(100)
@@ -102,7 +98,7 @@
     fun seekBarDisabledWhenSeekNotAvailable() {
         // WHEN seek is not available
         val isSeekAvailable = false
-        val data = SeekBarViewModel.Progress(true, isSeekAvailable, 3000, 120000, -1)
+        val data = SeekBarViewModel.Progress(true, isSeekAvailable, 3000, 120000)
         observer.onChanged(data)
         // THEN seek bar is not enabled
         assertThat(seekBarView.isEnabled()).isFalse()
@@ -112,20 +108,9 @@
     fun seekBarEnabledWhenSeekNotAvailable() {
         // WHEN seek is available
         val isSeekAvailable = true
-        val data = SeekBarViewModel.Progress(true, isSeekAvailable, 3000, 120000, -1)
+        val data = SeekBarViewModel.Progress(true, isSeekAvailable, 3000, 120000)
         observer.onChanged(data)
         // THEN seek bar is not enabled
         assertThat(seekBarView.isEnabled()).isTrue()
     }
-
-    @Test
-    fun seekBarColor() {
-        // WHEN data included color
-        val data = SeekBarViewModel.Progress(true, true, 3000, 120000, Color.RED)
-        observer.onChanged(data)
-        // THEN seek bar is colored
-        val red = ColorStateList.valueOf(Color.RED)
-        assertThat(elapsedTimeView.getTextColors()).isEqualTo(red)
-        assertThat(totalTimeView.getTextColors()).isEqualTo(red)
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
index cde575d..1bbf24f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
@@ -16,7 +16,6 @@
 
 package com.android.systemui.media
 
-import android.graphics.Color
 import android.media.MediaMetadata
 import android.media.session.MediaController
 import android.media.session.PlaybackState
@@ -80,12 +79,6 @@
     }
 
     @Test
-    fun updateColor() {
-        viewModel.updateController(mockController, Color.RED)
-        assertThat(viewModel.progress.value!!.color).isEqualTo(Color.RED)
-    }
-
-    @Test
     fun updateDurationWithPlayback() {
         // GIVEN that the duration is contained within the metadata
         val duration = 12000L
@@ -101,7 +94,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN the controller is updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN the duration is extracted
         assertThat(viewModel.progress.value!!.duration).isEqualTo(duration)
         assertThat(viewModel.progress.value!!.enabled).isTrue()
@@ -117,7 +110,7 @@
         }
         whenever(mockController.getMetadata()).thenReturn(metadata)
         // WHEN the controller is updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN the duration is extracted
         assertThat(viewModel.progress.value!!.duration).isEqualTo(duration)
         assertThat(viewModel.progress.value!!.enabled).isFalse()
@@ -139,7 +132,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN the controller is updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN the seek bar is disabled
         assertThat(viewModel.progress.value!!.enabled).isFalse()
     }
@@ -160,7 +153,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN the controller is updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN the seek bar is disabled
         assertThat(viewModel.progress.value!!.enabled).isFalse()
     }
@@ -175,7 +168,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN the controller is updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN elapsed time is captured
         assertThat(viewModel.progress.value!!.elapsedTime).isEqualTo(200.toInt())
     }
@@ -189,7 +182,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN the controller is updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN seek is available
         assertThat(viewModel.progress.value!!.seekAvailable).isTrue()
     }
@@ -203,7 +196,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN the controller is updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN seek is not available
         assertThat(viewModel.progress.value!!.seekAvailable).isFalse()
     }
@@ -211,7 +204,7 @@
     @Test
     fun handleSeek() {
         whenever(mockController.getTransportControls()).thenReturn(mockTransport)
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // WHEN user input is dispatched
         val pos = 42L
         viewModel.onSeek(pos)
@@ -223,7 +216,7 @@
     @Test
     fun handleProgressChangedUser() {
         whenever(mockController.getTransportControls()).thenReturn(mockTransport)
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // WHEN user starts dragging the seek bar
         val pos = 42
         viewModel.seekBarListener.onProgressChanged(SeekBar(context), pos, true)
@@ -235,7 +228,7 @@
     @Test
     fun handleProgressChangedOther() {
         whenever(mockController.getTransportControls()).thenReturn(mockTransport)
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // WHEN user starts dragging the seek bar
         val pos = 42
         viewModel.seekBarListener.onProgressChanged(SeekBar(context), pos, false)
@@ -247,7 +240,7 @@
     @Test
     fun handleStartTrackingTouch() {
         whenever(mockController.getTransportControls()).thenReturn(mockTransport)
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // WHEN user starts dragging the seek bar
         val pos = 42
         val bar = SeekBar(context).apply {
@@ -262,7 +255,7 @@
     @Test
     fun handleStopTrackingTouch() {
         whenever(mockController.getTransportControls()).thenReturn(mockTransport)
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // WHEN user ends drag
         val pos = 42
         val bar = SeekBar(context).apply {
@@ -283,7 +276,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN the controller is updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN a task is queued
         assertThat(fakeExecutor.numPending()).isEqualTo(1)
     }
@@ -297,7 +290,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN an update task is not queued
         assertThat(fakeExecutor.numPending()).isEqualTo(0)
     }
@@ -317,7 +310,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN an update task is queued
         assertThat(fakeExecutor.numPending()).isEqualTo(1)
     }
@@ -337,7 +330,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // WHEN updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // THEN an update task is not queued
         assertThat(fakeExecutor.numPending()).isEqualTo(0)
     }
@@ -350,7 +343,7 @@
             build()
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // WHEN the next task runs
         with(fakeExecutor) {
             advanceClockToNext()
@@ -361,25 +354,6 @@
     }
 
     @Test
-    fun taskUpdatesProgress() {
-        // GIVEN that the PlaybackState contins the initial position
-        val initialPosition = 0L
-        val state = PlaybackState.Builder().run {
-            setState(PlaybackState.STATE_PLAYING, initialPosition, 1f)
-            build()
-        }
-        whenever(mockController.getPlaybackState()).thenReturn(state)
-        viewModel.updateController(mockController, Color.RED)
-        // WHEN the task runs
-        with(fakeExecutor) {
-            advanceClockToNext()
-            runAllReady()
-        }
-        // THEN elapsed time has increased
-        assertThat(viewModel.progress.value!!.elapsedTime).isGreaterThan(initialPosition.toInt())
-    }
-
-    @Test
     fun startListeningQueuesPollTask() {
         // GIVEN not listening
         viewModel.listening = false
@@ -393,7 +367,7 @@
             build()
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // WHEN start listening
         viewModel.listening = true
         // THEN an update task is queued
@@ -415,7 +389,7 @@
         }
         whenever(mockController.getPlaybackState()).thenReturn(state)
         // AND the controller has been updated
-        viewModel.updateController(mockController, Color.RED)
+        viewModel.updateController(mockController)
         // WHEN the controller is cleared on the event when the session is destroyed
         viewModel.clearController()
         with(fakeExecutor) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
index 7211254..601fad6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java
@@ -65,9 +65,6 @@
     private IActivityManager mActivityManager;
 
     @Mock
-    private IActivityTaskManager mIActivityTaskManager;
-
-    @Mock
     private PipMenuActivityController mPipMenuActivityController;
 
     @Mock
@@ -101,7 +98,7 @@
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         mPipSnapAlgorithm = new PipSnapAlgorithm(mContext);
-        mPipTouchHandler = new PipTouchHandler(mContext, mActivityManager, mIActivityTaskManager,
+        mPipTouchHandler = new PipTouchHandler(mContext, mActivityManager,
                 mPipMenuActivityController, mInputConsumerController, mPipBoundsHandler,
                 mPipTaskOrganizer, mFloatingContentCoordinator, mDeviceConfigProxy,
                 mPipSnapAlgorithm);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
index 6c543c7..05b31c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.java
@@ -161,6 +161,9 @@
 
         mQsPanel.setListening(true);
         verify(mQSLogger).logAllTilesChangeListening(true, mQsPanel.getDumpableTag(), "dnd");
+
+        mQsPanel.setListening(false);
+        verify(mQSLogger).logAllTilesChangeListening(false, mQsPanel.getDumpableTag(), "dnd");
     }
 
 /*    @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index d124bad..a24fa84 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -20,9 +20,9 @@
 import static android.content.Intent.ACTION_USER_SWITCHED;
 import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL;
 
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_MEDIA_CONTROLS;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_MEDIA_CONTROLS;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_PEOPLE;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT;
 
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
index ca7a5db..8948fd0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
@@ -74,7 +74,7 @@
                 DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_USE_PEOPLE_FILTERING, "true", false)
 
         assertTrue("People filtering should be enabled", manager!!.isFilteringEnabled())
-        assertTrue("Expecting 4 buckets when people filtering is enabled",
-                manager!!.getNumberOfBuckets() == 4)
+        assertTrue("Expecting 5 buckets when people filtering is enabled",
+                manager!!.getNumberOfBuckets() == 5)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
index 3d06c57..ea1b498 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -108,7 +109,7 @@
     public void testCallBackCalledScreenOn() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false  /* persistent */);
         mVisualStabilityManager.setScreenOn(false);
         verify(mCallback).onChangeAllowed();
     }
@@ -117,7 +118,7 @@
     public void testCallBackCalledPanelExpanded() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false  /* persistent */);
         mVisualStabilityManager.setPanelExpanded(false);
         verify(mCallback).onChangeAllowed();
     }
@@ -126,7 +127,7 @@
     public void testCallBackExactlyOnce() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
-        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false  /* persistent */);
         mVisualStabilityManager.setScreenOn(false);
         mVisualStabilityManager.setScreenOn(true);
         mVisualStabilityManager.setScreenOn(false);
@@ -134,6 +135,17 @@
     }
 
     @Test
+    public void testCallBackCalledContinuouslyWhenRequested() {
+        mVisualStabilityManager.setPanelExpanded(true);
+        mVisualStabilityManager.setScreenOn(true);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback, true  /* persistent */);
+        mVisualStabilityManager.setScreenOn(false);
+        mVisualStabilityManager.setScreenOn(true);
+        mVisualStabilityManager.setScreenOn(false);
+        verify(mCallback, times(2)).onChangeAllowed();
+    }
+
+    @Test
     public void testAddedCanReorder() {
         mVisualStabilityManager.setPanelExpanded(true);
         mVisualStabilityManager.setScreenOn(true);
@@ -188,7 +200,7 @@
     @Test
     public void testCallBackCalled_Pulsing() {
         mVisualStabilityManager.setPulsing(true);
-        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false  /* persistent */);
         mVisualStabilityManager.setPulsing(false);
         verify(mCallback).onChangeAllowed();
     }
@@ -198,7 +210,7 @@
         // GIVEN having the panel open (which would block reordering)
         mVisualStabilityManager.setScreenOn(true);
         mVisualStabilityManager.setPanelExpanded(true);
-        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false  /* persistent */);
 
         // WHEN we temprarily allow reordering
         mVisualStabilityManager.temporarilyAllowReordering();
@@ -212,7 +224,7 @@
     public void testTemporarilyAllowReorderingDoesntOverridePulsing() {
         // GIVEN we are in a pulsing state
         mVisualStabilityManager.setPulsing(true);
-        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false  /* persistent */);
 
         // WHEN we temprarily allow reordering
         mVisualStabilityManager.temporarilyAllowReordering();
@@ -227,7 +239,7 @@
         // GIVEN having the panel open (which would block reordering)
         mVisualStabilityManager.setScreenOn(true);
         mVisualStabilityManager.setPanelExpanded(true);
-        mVisualStabilityManager.addReorderingAllowedCallback(mCallback);
+        mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false  /* persistent */);
 
         // WHEN we temprarily allow reordering and then wait until the window expires
         mVisualStabilityManager.temporarilyAllowReordering();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
index b4cabfd..a83de13 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationRankingManagerTest.kt
@@ -36,8 +36,8 @@
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_PERSON
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
-import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
+import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
+import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
 import com.android.systemui.statusbar.phone.NotificationGroupManager
 import com.android.systemui.statusbar.policy.HeadsUpManager
 import dagger.Lazy
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
index d39b2c2..a3a46f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.notification.logging;
 
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_ALERTING;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
index 1bfebfb..f21b1a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/PartialConversationInfoTest.java
@@ -356,6 +356,30 @@
     }
 
     @Test
+    public void testBindNotification_SetsOnClickListenerForSettings_mainText() {
+        final CountDownLatch latch = new CountDownLatch(1);
+        mInfo.bindNotification(
+                mMockPackageManager,
+                mMockINotificationManager,
+                mChannelEditorDialogController,
+                TEST_PACKAGE_NAME,
+                mNotificationChannel,
+                mNotificationChannelSet,
+                mEntry,
+                (View v, NotificationChannel c, int appUid) -> {
+                    assertEquals(mNotificationChannel, c);
+                    latch.countDown();
+                },
+                true,
+                false);
+
+        final View settingsButton = mInfo.findViewById(R.id.settings_link);
+        settingsButton.performClick();
+        // Verify that listener was triggered.
+        assertEquals(0, latch.getCount());
+    }
+
+    @Test
     public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() {
         mInfo.bindNotification(
                 mMockPackageManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 0b86a78..3dc941a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -18,16 +18,20 @@
 
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_HEADS_UP;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE;
-import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_ALERTING;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_FOREGROUND_SERVICE;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_HEADS_UP;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_PEOPLE;
+import static com.android.systemui.statusbar.notification.stack.NotificationSectionsManagerKt.BUCKET_SILENT;
+
+import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -48,6 +52,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.people.PeopleHubViewAdapter;
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -62,6 +67,9 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -84,10 +92,23 @@
 
     @Before
     public void setUp() {
-        when(mSectionsFeatureManager.getNumberOfBuckets()).thenReturn(2);
-        when(mNotificationRowComponent.getActivatableNotificationViewController()).thenReturn(
-                mActivatableNotificationViewController
-        );
+        when(mSectionsFeatureManager.getNumberOfBuckets()).thenAnswer(
+                invocation -> {
+                    int count = 2;
+                    if (mSectionsFeatureManager.isFilteringEnabled()) {
+                        count = 5;
+                    }
+                    if (mSectionsFeatureManager.isMediaControlsEnabled()) {
+                        if (!mSectionsFeatureManager.isFilteringEnabled()) {
+                            count = 5;
+                        } else {
+                            count += 1;
+                        }
+                    }
+                    return count;
+                });
+        when(mNotificationRowComponent.getActivatableNotificationViewController())
+                .thenReturn(mActivatableNotificationViewController);
         mSectionsManager =
                 new NotificationSectionsManager(
                         mActivityStarterDelegate,
@@ -104,6 +125,7 @@
         mSectionsManager.initialize(mNssl, LayoutInflater.from(mContext));
         when(mNssl.indexOfChild(any(View.class))).thenReturn(-1);
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
+
     }
 
     @Test(expected =  IllegalStateException.class)
@@ -114,140 +136,152 @@
     @Test
     public void testInsertHeader() {
         // GIVEN a stack with HI and LO rows but no section headers
-        setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.ALERTING, ChildType.GENTLE);
+        setStackState(
+                ALERTING,
+                ALERTING,
+                ALERTING,
+                GENTLE);
 
         // WHEN we update the section headers
         mSectionsManager.updateSectionBoundaries();
 
         // THEN a LO section header is added
-        verify(mNssl).addView(mSectionsManager.getGentleHeaderView(), 3);
+        verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 3);
     }
 
     @Test
     public void testRemoveHeader() {
         // GIVEN a stack that originally had a header between the HI and LO sections
-        setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.GENTLE);
+        setStackState(
+                ALERTING,
+                ALERTING,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
         // WHEN the last LO row is replaced with a HI row
         setStackState(
-                ChildType.ALERTING,
-                ChildType.ALERTING,
-                ChildType.GENTLE_HEADER,
-                ChildType.ALERTING);
+                ALERTING,
+                ALERTING,
+                GENTLE_HEADER,
+                ALERTING);
         clearInvocations(mNssl);
         mSectionsManager.updateSectionBoundaries();
 
         // THEN the LO section header is removed
-        verify(mNssl).removeView(mSectionsManager.getGentleHeaderView());
+        verify(mNssl).removeView(mSectionsManager.getSilentHeaderView());
     }
 
     @Test
     public void testDoNothingIfHeaderAlreadyRemoved() {
         // GIVEN a stack with only HI rows
-        setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.ALERTING);
+        setStackState(
+                ALERTING,
+                ALERTING,
+                ALERTING);
 
         // WHEN we update the sections headers
         mSectionsManager.updateSectionBoundaries();
 
         // THEN we don't add any section headers
-        verify(mNssl, never()).addView(eq(mSectionsManager.getGentleHeaderView()), anyInt());
+        verify(mNssl, never()).addView(eq(mSectionsManager.getSilentHeaderView()), anyInt());
     }
 
     @Test
     public void testMoveHeaderForward() {
         // GIVEN a stack that originally had a header between the HI and LO sections
         setStackState(
-                ChildType.ALERTING,
-                ChildType.ALERTING,
-                ChildType.ALERTING,
-                ChildType.GENTLE);
+                ALERTING,
+                ALERTING,
+                ALERTING,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
         // WHEN the LO section moves forward
         setStackState(
-                ChildType.ALERTING,
-                ChildType.ALERTING,
-                ChildType.GENTLE,
-                ChildType.GENTLE_HEADER,
-                ChildType.GENTLE);
+                ALERTING,
+                ALERTING,
+                GENTLE,
+                GENTLE_HEADER,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
         // THEN the LO section header is also moved forward
-        verify(mNssl).changeViewPosition(mSectionsManager.getGentleHeaderView(), 2);
+        verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 2);
     }
 
     @Test
     public void testMoveHeaderBackward() {
         // GIVEN a stack that originally had a header between the HI and LO sections
         setStackState(
-                ChildType.ALERTING,
-                ChildType.GENTLE,
-                ChildType.GENTLE,
-                ChildType.GENTLE);
+                ALERTING,
+                GENTLE,
+                GENTLE,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
         // WHEN the LO section moves backward
         setStackState(
-                ChildType.ALERTING,
-                ChildType.GENTLE_HEADER,
-                ChildType.ALERTING,
-                ChildType.ALERTING,
-                ChildType.GENTLE);
+                ALERTING,
+                GENTLE_HEADER,
+                ALERTING,
+                ALERTING,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
         // THEN the LO section header is also moved backward (with appropriate index shifting)
-        verify(mNssl).changeViewPosition(mSectionsManager.getGentleHeaderView(), 3);
+        verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 3);
     }
 
     @Test
     public void testHeaderRemovedFromTransientParent() {
         // GIVEN a stack where the header is animating away
         setStackState(
-                ChildType.ALERTING,
-                ChildType.GENTLE,
-                ChildType.GENTLE,
-                ChildType.GENTLE);
-        mSectionsManager.updateSectionBoundaries();
-        setStackState(
-                ChildType.ALERTING,
-                ChildType.GENTLE_HEADER);
+                ALERTING,
+                GENTLE_HEADER);
         mSectionsManager.updateSectionBoundaries();
         clearInvocations(mNssl);
 
         ViewGroup transientParent = mock(ViewGroup.class);
-        mSectionsManager.getGentleHeaderView().setTransientContainer(transientParent);
+        mSectionsManager.getSilentHeaderView().setTransientContainer(transientParent);
 
         // WHEN the LO section reappears
         setStackState(
-                ChildType.ALERTING,
-                ChildType.GENTLE);
+                ALERTING,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
         // THEN the header is first removed from the transient parent before being added to the
         // NSSL.
-        verify(transientParent).removeTransientView(mSectionsManager.getGentleHeaderView());
-        verify(mNssl).addView(mSectionsManager.getGentleHeaderView(), 1);
+        verify(transientParent).removeTransientView(mSectionsManager.getSilentHeaderView());
+        verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 1);
     }
 
     @Test
     public void testHeaderNotShownOnLockscreen() {
         // GIVEN a stack of HI and LO notifs on the lockscreen
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
-        setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.ALERTING, ChildType.GENTLE);
+        setStackState(
+                ALERTING,
+                ALERTING,
+                ALERTING,
+                GENTLE);
 
         // WHEN we update the section headers
         mSectionsManager.updateSectionBoundaries();
 
         // Then the section header is not added
-        verify(mNssl, never()).addView(eq(mSectionsManager.getGentleHeaderView()), anyInt());
+        verify(mNssl, never()).addView(eq(mSectionsManager.getSilentHeaderView()), anyInt());
     }
 
     @Test
     public void testHeaderShownWhenEnterLockscreen() {
         // GIVEN a stack of HI and LO notifs on the lockscreen
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
-        setStackState(ChildType.ALERTING, ChildType.ALERTING, ChildType.ALERTING, ChildType.GENTLE);
+        setStackState(
+                ALERTING,
+                ALERTING,
+                ALERTING,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
         // WHEN we unlock
@@ -255,20 +289,23 @@
         mSectionsManager.updateSectionBoundaries();
 
         // Then the section header is added
-        verify(mNssl).addView(mSectionsManager.getGentleHeaderView(), 3);
+        verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 3);
     }
 
     @Test
     public void testHeaderHiddenWhenEnterLockscreen() {
         // GIVEN a stack of HI and LO notifs on the shade
-        setStackState(ChildType.ALERTING, ChildType.GENTLE_HEADER, ChildType.GENTLE);
+        setStackState(
+                ALERTING,
+                GENTLE_HEADER,
+                GENTLE);
 
         // WHEN we go back to the keyguard
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
         mSectionsManager.updateSectionBoundaries();
 
         // Then the section header is removed
-        verify(mNssl).removeView(mSectionsManager.getGentleHeaderView());
+        verify(mNssl).removeView(mSectionsManager.getSilentHeaderView());
     }
 
     @Test
@@ -276,13 +313,13 @@
         enablePeopleFiltering();
 
         setStackState(
-                ChildType.GENTLE_HEADER,
-                ChildType.PERSON,
-                ChildType.ALERTING,
-                ChildType.GENTLE);
+                GENTLE_HEADER,
+                PERSON,
+                ALERTING,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
-        verify(mNssl).changeViewPosition(mSectionsManager.getGentleHeaderView(), 2);
+        verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 2);
         verify(mNssl).addView(mSectionsManager.getAlertingHeaderView(), 1);
         verify(mNssl).addView(mSectionsManager.getPeopleHeaderView(), 0);
     }
@@ -292,12 +329,12 @@
         enablePeopleFiltering();
 
         setStackState(
-                ChildType.PERSON,
-                ChildType.ALERTING,
-                ChildType.GENTLE);
+                PERSON,
+                ALERTING,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
-        verify(mNssl).addView(mSectionsManager.getGentleHeaderView(), 2);
+        verify(mNssl).addView(mSectionsManager.getSilentHeaderView(), 2);
         verify(mNssl).addView(mSectionsManager.getAlertingHeaderView(), 1);
         verify(mNssl).addView(mSectionsManager.getPeopleHeaderView(), 0);
     }
@@ -307,15 +344,15 @@
         enablePeopleFiltering();
 
         setStackState(
-                ChildType.PEOPLE_HEADER,
-                ChildType.ALERTING_HEADER,
-                ChildType.GENTLE_HEADER,
-                ChildType.PERSON,
-                ChildType.ALERTING,
-                ChildType.GENTLE);
+                PEOPLE_HEADER,
+                ALERTING_HEADER,
+                GENTLE_HEADER,
+                PERSON,
+                ALERTING,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
-        verify(mNssl).changeViewPosition(mSectionsManager.getGentleHeaderView(), 4);
+        verify(mNssl).changeViewPosition(mSectionsManager.getSilentHeaderView(), 4);
         verify(mNssl).changeViewPosition(mSectionsManager.getAlertingHeaderView(), 2);
         verify(mNssl).changeViewPosition(mSectionsManager.getPeopleHeaderView(), 0);
     }
@@ -326,12 +363,11 @@
         enablePeopleFiltering();
 
         setStackState(
-                ChildType.PEOPLE_HEADER,
-                ChildType.ALERTING_HEADER,
-                ChildType.ALERTING,
-                ChildType.GENTLE_HEADER,
-                ChildType.GENTLE
-        );
+                PEOPLE_HEADER,
+                ALERTING_HEADER,
+                ALERTING,
+                GENTLE_HEADER,
+                GENTLE);
         mSectionsManager.updateSectionBoundaries();
 
         verify(mNssl, never()).removeView(mSectionsManager.getPeopleHeaderView());
@@ -339,11 +375,120 @@
     }
 
     @Test
+    public void testPeopleFiltering_AlertingHunWhilePeopleVisible() {
+        enablePeopleFiltering();
+
+        setupMockStack(
+                PEOPLE_HEADER,
+                ALERTING.headsUp(),
+                PERSON,
+                ALERTING_HEADER,
+                GENTLE_HEADER,
+                GENTLE
+        );
+        mSectionsManager.updateSectionBoundaries();
+
+        verifyMockStack(
+                ChildType.INCOMING_HEADER,
+                ChildType.HEADS_UP,
+                ChildType.PEOPLE_HEADER,
+                ChildType.PERSON,
+                ChildType.GENTLE_HEADER,
+                ChildType.GENTLE
+        );
+    }
+
+    @Test
+    public void testPeopleFiltering_PersonHunWhileAlertingHunVisible() {
+        enablePeopleFiltering();
+
+        setupMockStack(
+                PERSON.headsUp(),
+                INCOMING_HEADER,
+                ALERTING.headsUp(),
+                PEOPLE_HEADER,
+                PERSON
+        );
+        mSectionsManager.updateSectionBoundaries();
+
+        verifyMockStack(
+                ChildType.INCOMING_HEADER,
+                ChildType.HEADS_UP,
+                ChildType.HEADS_UP,
+                ChildType.PEOPLE_HEADER,
+                ChildType.PERSON
+        );
+    }
+
+    @Test
+    public void testPeopleFiltering_PersonHun() {
+        enablePeopleFiltering();
+
+        setupMockStack(
+                PERSON.headsUp(),
+                PEOPLE_HEADER,
+                PERSON
+        );
+        mSectionsManager.updateSectionBoundaries();
+
+        verifyMockStack(
+                ChildType.PEOPLE_HEADER,
+                ChildType.PERSON,
+                ChildType.PERSON
+        );
+    }
+
+    @Test
+    public void testPeopleFiltering_AlertingHunWhilePersonHunning() {
+        enablePeopleFiltering();
+
+        setupMockStack(
+                ALERTING.headsUp(),
+                PERSON.headsUp()
+        );
+        mSectionsManager.updateSectionBoundaries();
+        verifyMockStack(
+                ChildType.INCOMING_HEADER,
+                ChildType.HEADS_UP,
+                ChildType.PEOPLE_HEADER,
+                ChildType.PERSON
+        );
+    }
+
+    @Test
+    public void testPeopleFiltering_Fsn() {
+        enablePeopleFiltering();
+
+        setupMockStack(
+                INCOMING_HEADER,
+                ALERTING.headsUp(),
+                PEOPLE_HEADER,
+                FSN,
+                PERSON,
+                ALERTING,
+                GENTLE
+        );
+        mSectionsManager.updateSectionBoundaries();
+
+        verifyMockStack(
+                ChildType.INCOMING_HEADER,
+                ChildType.HEADS_UP,
+                ChildType.FSN,
+                ChildType.PEOPLE_HEADER,
+                ChildType.PERSON,
+                ChildType.ALERTING_HEADER,
+                ChildType.ALERTING,
+                ChildType.GENTLE_HEADER,
+                ChildType.GENTLE
+        );
+    }
+
+    @Test
     public void testMediaControls_AddWhenEnterKeyguard() {
         enableMediaControls();
 
         // GIVEN a stack that doesn't include media controls
-        setStackState(ChildType.ALERTING, ChildType.GENTLE_HEADER, ChildType.GENTLE);
+        setStackState(ALERTING, GENTLE_HEADER, GENTLE);
 
         // WHEN we go back to the keyguard
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
@@ -358,37 +503,45 @@
         enableMediaControls();
 
         // GIVEN a stack that doesn't include media controls but includes HEADS_UP
-        setStackState(ChildType.HEADS_UP, ChildType.ALERTING, ChildType.GENTLE_HEADER,
-                ChildType.GENTLE);
+        setupMockStack(
+                ALERTING.headsUp(),
+                ALERTING,
+                GENTLE_HEADER,
+                GENTLE);
 
         // WHEN we go back to the keyguard
         when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
         mSectionsManager.updateSectionBoundaries();
 
-        // Then the media controls are added after HEADS_UP
-        verify(mNssl).addView(mSectionsManager.getMediaControlsView(), 1);
+        verifyMockStack(
+                ChildType.MEDIA_CONTROLS,
+                ChildType.ALERTING,
+                ChildType.ALERTING,
+                ChildType.GENTLE);
     }
 
     private void enablePeopleFiltering() {
         when(mSectionsFeatureManager.isFilteringEnabled()).thenReturn(true);
-        when(mSectionsFeatureManager.getNumberOfBuckets()).thenReturn(4);
     }
 
     private void enableMediaControls() {
         when(mSectionsFeatureManager.isMediaControlsEnabled()).thenReturn(true);
-        when(mSectionsFeatureManager.getNumberOfBuckets()).thenReturn(4);
     }
 
     private enum ChildType {
-        MEDIA_CONTROLS, PEOPLE_HEADER, ALERTING_HEADER, GENTLE_HEADER, HEADS_UP, PERSON, ALERTING,
-            GENTLE, OTHER
+        INCOMING_HEADER, MEDIA_CONTROLS, PEOPLE_HEADER, ALERTING_HEADER, GENTLE_HEADER, HEADS_UP,
+        FSN, PERSON, ALERTING, GENTLE, OTHER
     }
 
-    private void setStackState(ChildType... children) {
+    private void setStackState(StackEntry... children) {
         when(mNssl.getChildCount()).thenReturn(children.length);
         for (int i = 0; i < children.length; i++) {
             View child;
-            switch (children[i]) {
+            StackEntry entry = children[i];
+            switch (entry.mChildType) {
+                case INCOMING_HEADER:
+                    child = mSectionsManager.getIncomingHeaderView();
+                    break;
                 case MEDIA_CONTROLS:
                     child = mSectionsManager.getMediaControlsView();
                     break;
@@ -399,19 +552,19 @@
                     child = mSectionsManager.getAlertingHeaderView();
                     break;
                 case GENTLE_HEADER:
-                    child = mSectionsManager.getGentleHeaderView();
+                    child = mSectionsManager.getSilentHeaderView();
                     break;
-                case HEADS_UP:
-                    child = mockNotification(BUCKET_HEADS_UP);
+                case FSN:
+                    child = mockNotification(BUCKET_FOREGROUND_SERVICE, entry.mIsHeadsUp);
                     break;
                 case PERSON:
-                    child = mockNotification(BUCKET_PEOPLE);
+                    child = mockNotification(BUCKET_PEOPLE, entry.mIsHeadsUp);
                     break;
                 case ALERTING:
-                    child = mockNotification(BUCKET_ALERTING);
+                    child = mockNotification(BUCKET_ALERTING, entry.mIsHeadsUp);
                     break;
                 case GENTLE:
-                    child = mockNotification(BUCKET_SILENT);
+                    child = mockNotification(BUCKET_SILENT, entry.mIsHeadsUp);
                     break;
                 case OTHER:
                     child = mock(View.class);
@@ -426,12 +579,183 @@
         }
     }
 
-    private View mockNotification(int bucket) {
-        ExpandableNotificationRow notifRow = mock(ExpandableNotificationRow.class,
-                RETURNS_DEEP_STUBS);
+    private View mockNotification(int bucket, boolean headsUp) {
+        ExpandableNotificationRow notifRow =
+                mock(ExpandableNotificationRow.class, RETURNS_DEEP_STUBS);
         when(notifRow.getVisibility()).thenReturn(View.VISIBLE);
-        when(notifRow.getEntry().getBucket()).thenReturn(bucket);
         when(notifRow.getParent()).thenReturn(mNssl);
+
+        NotificationEntry mockEntry = mock(NotificationEntry.class);
+        when(notifRow.getEntry()).thenReturn(mockEntry);
+
+        int[] bucketRef = new int[] { bucket };
+        when(mockEntry.getBucket()).thenAnswer(invocation -> bucketRef[0]);
+        doAnswer(invocation -> {
+            bucketRef[0] = invocation.getArgument(0);
+            return null;
+        }).when(mockEntry).setBucket(anyInt());
+
+        when(notifRow.isHeadsUp()).thenReturn(headsUp);
+        when(mockEntry.isRowHeadsUp()).thenReturn(headsUp);
         return notifRow;
     }
+
+    private void verifyMockStack(ChildType... expected) {
+        final List<ChildType> actual = new ArrayList<>();
+        int childCount = mNssl.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View child = mNssl.getChildAt(i);
+            if (child == mSectionsManager.getIncomingHeaderView()) {
+                actual.add(ChildType.INCOMING_HEADER);
+                continue;
+            }
+            if (child == mSectionsManager.getMediaControlsView()) {
+                actual.add(ChildType.MEDIA_CONTROLS);
+                continue;
+            }
+            if (child == mSectionsManager.getPeopleHeaderView()) {
+                actual.add(ChildType.PEOPLE_HEADER);
+                continue;
+            }
+            if (child == mSectionsManager.getAlertingHeaderView()) {
+                actual.add(ChildType.ALERTING_HEADER);
+                continue;
+            }
+            if (child == mSectionsManager.getSilentHeaderView()) {
+                actual.add(ChildType.GENTLE_HEADER);
+                continue;
+            }
+            if (child instanceof ExpandableNotificationRow) {
+                switch (((ExpandableNotificationRow) child).getEntry().getBucket()) {
+                    case BUCKET_HEADS_UP:
+                        actual.add(ChildType.HEADS_UP);
+                        break;
+                    case BUCKET_FOREGROUND_SERVICE:
+                        actual.add(ChildType.FSN);
+                        break;
+                    case BUCKET_PEOPLE:
+                        actual.add(ChildType.PERSON);
+                        break;
+                    case BUCKET_ALERTING:
+                        actual.add(ChildType.ALERTING);
+                        break;
+                    case BUCKET_SILENT:
+                        actual.add(ChildType.GENTLE);
+                        break;
+                    default:
+                        actual.add(ChildType.OTHER);
+                        break;
+                }
+                continue;
+            }
+            actual.add(ChildType.OTHER);
+        }
+        assertThat(actual).containsExactly((Object[]) expected).inOrder();
+    }
+
+    private void setupMockStack(StackEntry... entries) {
+        final List<View> children = new ArrayList<>();
+        when(mNssl.getChildCount()).thenAnswer(invocation -> children.size());
+        when(mNssl.getChildAt(anyInt()))
+                .thenAnswer(invocation -> children.get(invocation.getArgument(0)));
+        when(mNssl.indexOfChild(any()))
+                .thenAnswer(invocation -> children.indexOf(invocation.getArgument(0)));
+        doAnswer(invocation -> {
+            View child = invocation.getArgument(0);
+            int index = invocation.getArgument(1);
+            children.add(index, child);
+            return null;
+        }).when(mNssl).addView(any(), anyInt());
+        doAnswer(invocation -> {
+            View child = invocation.getArgument(0);
+            children.remove(child);
+            return null;
+        }).when(mNssl).removeView(any());
+        doAnswer(invocation -> {
+            View child = invocation.getArgument(0);
+            int newIndex = invocation.getArgument(1);
+            children.remove(child);
+            children.add(newIndex, child);
+            return null;
+        }).when(mNssl).changeViewPosition(any(), anyInt());
+        for (StackEntry entry : entries) {
+            View child;
+            switch (entry.mChildType) {
+                case INCOMING_HEADER:
+                    child = mSectionsManager.getIncomingHeaderView();
+                    break;
+                case MEDIA_CONTROLS:
+                    child = mSectionsManager.getMediaControlsView();
+                    break;
+                case PEOPLE_HEADER:
+                    child = mSectionsManager.getPeopleHeaderView();
+                    break;
+                case ALERTING_HEADER:
+                    child = mSectionsManager.getAlertingHeaderView();
+                    break;
+                case GENTLE_HEADER:
+                    child = mSectionsManager.getSilentHeaderView();
+                    break;
+                case FSN:
+                    child = mockNotification(BUCKET_FOREGROUND_SERVICE, entry.mIsHeadsUp);
+                    break;
+                case PERSON:
+                    child = mockNotification(BUCKET_PEOPLE, entry.mIsHeadsUp);
+                    break;
+                case ALERTING:
+                    child = mockNotification(BUCKET_ALERTING, entry.mIsHeadsUp);
+                    break;
+                case GENTLE:
+                    child = mockNotification(BUCKET_SILENT, entry.mIsHeadsUp);
+                    break;
+                case OTHER:
+                    child = mock(View.class);
+                    when(child.getVisibility()).thenReturn(View.VISIBLE);
+                    when(child.getParent()).thenReturn(mNssl);
+                    break;
+                default:
+                    throw new RuntimeException("Unknown ChildType: " + entry.mChildType);
+            }
+            children.add(child);
+        }
+    }
+
+    private static final StackEntry INCOMING_HEADER = new StackEntry(ChildType.INCOMING_HEADER);
+    private static final StackEntry MEDIA_CONTROLS = new StackEntry(ChildType.MEDIA_CONTROLS);
+    private static final StackEntry PEOPLE_HEADER = new StackEntry(ChildType.PEOPLE_HEADER);
+    private static final StackEntry ALERTING_HEADER = new StackEntry(ChildType.ALERTING_HEADER);
+    private static final StackEntry GENTLE_HEADER = new StackEntry(ChildType.GENTLE_HEADER);
+    private static final StackEntry FSN = new StackEntry(ChildType.FSN);
+    private static final StackEntry.Hunnable PERSON = new StackEntry.Hunnable(ChildType.PERSON);
+    private static final StackEntry.Hunnable ALERTING = new StackEntry.Hunnable(ChildType.ALERTING);
+    private static final StackEntry GENTLE = new StackEntry(ChildType.GENTLE);
+
+    private static class StackEntry {
+        final ChildType mChildType;
+        final boolean mIsHeadsUp;
+
+        StackEntry(ChildType childType) {
+            this(childType, false);
+        }
+
+        StackEntry(ChildType childType, boolean isHeadsUp) {
+            mChildType = childType;
+            mIsHeadsUp = isHeadsUp;
+        }
+
+        static class Hunnable extends StackEntry {
+
+            Hunnable(ChildType childType) {
+                super(childType, false);
+            }
+
+            Hunnable(ChildType childType, boolean isHeadsUp) {
+                super(childType, isHeadsUp);
+            }
+
+            public Hunnable headsUp() {
+                return new Hunnable(mChildType, true);
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java
index 5320ecd..ca6c16f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerTest.java
@@ -16,11 +16,15 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -44,6 +48,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -62,6 +67,7 @@
     @Mock private SysuiColorExtractor mColorExtractor;
     @Mock ColorExtractor.GradientColors mGradientColors;
     @Mock private DumpManager mDumpManager;
+    @Captor private ArgumentCaptor<WindowManager.LayoutParams> mLayoutParameters;
 
     private NotificationShadeWindowController mNotificationShadeWindowController;
 
@@ -121,4 +127,46 @@
         mNotificationShadeWindowController.setBackgroundBlurRadius(0);
         verify(mNotificationShadeWindowView).setVisibility(eq(View.INVISIBLE));
     }
+
+    @Test
+    public void setBouncerShowing_isFocusable_whenNeedsInput() {
+        mNotificationShadeWindowController.setKeyguardNeedsInput(true);
+        clearInvocations(mWindowManager);
+        mNotificationShadeWindowController.setBouncerShowing(true);
+
+        verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+        assertThat((mLayoutParameters.getValue().flags & FLAG_NOT_FOCUSABLE) == 0).isTrue();
+        assertThat((mLayoutParameters.getValue().flags & FLAG_ALT_FOCUSABLE_IM) == 0).isTrue();
+    }
+
+    @Test
+    public void setKeyguardShowing_focusable_notAltFocusable_whenNeedsInput() {
+        mNotificationShadeWindowController.setKeyguardShowing(true);
+        clearInvocations(mWindowManager);
+        mNotificationShadeWindowController.setKeyguardNeedsInput(true);
+
+        verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+        assertThat((mLayoutParameters.getValue().flags & FLAG_NOT_FOCUSABLE) == 0).isTrue();
+        assertThat((mLayoutParameters.getValue().flags & FLAG_ALT_FOCUSABLE_IM) == 0).isTrue();
+    }
+
+    @Test
+    public void setPanelExpanded_notFocusable_altFocusable_whenPanelIsOpen() {
+        mNotificationShadeWindowController.setPanelExpanded(true);
+        clearInvocations(mWindowManager);
+        mNotificationShadeWindowController.setNotificationShadeFocusable(true);
+
+        verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+        assertThat((mLayoutParameters.getValue().flags & FLAG_NOT_FOCUSABLE) == 0).isTrue();
+        assertThat((mLayoutParameters.getValue().flags & FLAG_ALT_FOCUSABLE_IM) != 0).isTrue();
+    }
+
+    @Test
+    public void setKeyguardShowing_notFocusable_byDefault() {
+        mNotificationShadeWindowController.setKeyguardShowing(false);
+
+        verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+        assertThat((mLayoutParameters.getValue().flags & FLAG_NOT_FOCUSABLE) != 0).isTrue();
+        assertThat((mLayoutParameters.getValue().flags & FLAG_ALT_FOCUSABLE_IM) == 0).isTrue();
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
index e04d25b..cc2d1c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowViewTest.java
@@ -83,7 +83,6 @@
     @Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
     @Mock private NotificationShadeDepthController mNotificationShadeDepthController;
     @Mock private SuperStatusBarViewFactory mStatusBarViewFactory;
-    @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
 
     @Before
     public void setUp() {
@@ -122,7 +121,7 @@
                 mNotificationPanelViewController,
                 mStatusBarViewFactory);
         mController.setupExpandedStatusBar();
-        mController.setService(mStatusBar, mNotificationShadeWindowController);
+        mController.setService(mStatusBar);
         mController.setDragDownHelper(mDragDownHelper);
 
     }
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index cbc5e14..1ee017b 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -51,6 +51,11 @@
 cc_library {
     name: "libtetherutilsjni",
     sdk_version: "current",
+    apex_available: [
+        "//apex_available:platform", // Used by InProcessTethering
+        "com.android.tethering",
+    ],
+    min_sdk_version: "current",
     srcs: [
         "jni/android_net_util_TetheringUtils.cpp",
     ],
@@ -110,6 +115,7 @@
     // InProcessTethering is a replacement for Tethering
     overrides: ["Tethering"],
     apex_available: ["com.android.tethering"],
+    min_sdk_version: "current",
 }
 
 // Updatable tethering packaged as an application
@@ -123,4 +129,5 @@
     // The permission configuration *must* be included to ensure security of the device
     required: ["NetworkPermissionConfig"],
     apex_available: ["com.android.tethering"],
+    min_sdk_version: "current",
 }
diff --git a/packages/Tethering/apex/Android.bp b/packages/Tethering/apex/Android.bp
index 20ccd2a..67097a7 100644
--- a/packages/Tethering/apex/Android.bp
+++ b/packages/Tethering/apex/Android.bp
@@ -17,7 +17,7 @@
 apex {
     name: "com.android.tethering",
     updatable: true,
-    min_sdk_version: "R",
+    min_sdk_version: "current",
     java_libs: ["framework-tethering"],
     apps: ["Tethering"],
     manifest: "manifest.json",
diff --git a/packages/Tethering/common/TetheringLib/Android.bp b/packages/Tethering/common/TetheringLib/Android.bp
index d029d2b..ae4bb3e 100644
--- a/packages/Tethering/common/TetheringLib/Android.bp
+++ b/packages/Tethering/common/TetheringLib/Android.bp
@@ -13,43 +13,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// AIDL interfaces between the core system and the tethering mainline module.
-aidl_interface {
-    name: "tethering-aidl-interfaces",
-    unstable: true,
-    local_include_dir: "src",
-    include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
-    srcs: [
-        // @JavaOnlyStableParcelable aidl declarations must not be listed here, as this would cause
-        // compilation to fail (b/148001843).
-        "src/android/net/IIntResultListener.aidl",
-        "src/android/net/ITetheringConnector.aidl",
-        "src/android/net/ITetheringEventCallback.aidl",
-        "src/android/net/TetheringCallbackStartedParcel.aidl",
-        "src/android/net/TetheringConfigurationParcel.aidl",
-        "src/android/net/TetheringRequestParcel.aidl",
-        "src/android/net/TetherStatesParcel.aidl",
-    ],
-    backend: {
-        ndk: {
-            enabled: false,
-        },
-        cpp: {
-            enabled: false,
-        },
-    },
-}
-
 java_library {
     name: "framework-tethering",
     sdk_version: "module_current",
     srcs: [
-        "src/android/net/TetheredClient.java",
-        "src/android/net/TetheringManager.java",
-        "src/android/net/TetheringConstants.java",
-    ],
-    static_libs: [
-        "tethering-aidl-interfaces-java",
+        ":framework-tethering-srcs",
     ],
     jarjar_rules: "jarjar-rules.txt",
     installable: true,
diff --git a/packages/Tethering/res/values/config.xml b/packages/Tethering/res/values/config.xml
index 9dda716..9269c6f 100644
--- a/packages/Tethering/res/values/config.xml
+++ b/packages/Tethering/res/values/config.xml
@@ -57,6 +57,12 @@
         <item>"bt-pan"</item>
     </string-array>
 
+    <!-- Use the BPF offload for tethering when the kernel has support. True by default.
+         If the device doesn't want to support tether BPF offload, this should be false.
+         Note that this setting could be overridden by device config.
+    -->
+    <bool translatable="false" name="config_tether_enable_bpf_offload">true</bool>
+
     <!-- Use the old dnsmasq DHCP server for tethering instead of the framework implementation. -->
     <bool translatable="false" name="config_tether_enable_legacy_dhcp_server">false</bool>
 
diff --git a/packages/Tethering/res/values/overlayable.xml b/packages/Tethering/res/values/overlayable.xml
index 4c78a74..4e2bb1e 100644
--- a/packages/Tethering/res/values/overlayable.xml
+++ b/packages/Tethering/res/values/overlayable.xml
@@ -23,6 +23,11 @@
             <item type="array" name="config_tether_wifi_p2p_regexs"/>
             <item type="array" name="config_tether_bluetooth_regexs"/>
             <item type="array" name="config_tether_dhcp_range"/>
+            <!-- Use the BPF offload for tethering when the kernel has support. True by default.
+                 If the device doesn't want to support tether BPF offload, this should be false.
+                 Note that this setting could be overridden by device config.
+            -->
+            <item type="bool" name="config_tether_enable_bpf_offload"/>
             <item type="bool" name="config_tether_enable_legacy_dhcp_server"/>
             <item type="integer" name="config_tether_offload_poll_interval"/>
             <item type="array" name="config_tether_upstream_types"/>
diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java
index 83727bc..d993306 100644
--- a/packages/Tethering/src/android/net/ip/IpServer.java
+++ b/packages/Tethering/src/android/net/ip/IpServer.java
@@ -227,6 +227,7 @@
     private final int mInterfaceType;
     private final LinkProperties mLinkProperties;
     private final boolean mUsingLegacyDhcp;
+    private final boolean mUsingBpfOffload;
 
     private final Dependencies mDeps;
 
@@ -302,9 +303,12 @@
 
     private final IpNeighborMonitor mIpNeighborMonitor;
 
+    // TODO: Add a dependency object to pass the data members or variables from the tethering
+    // object. It helps to reduce the arguments of the constructor.
     public IpServer(
             String ifaceName, Looper looper, int interfaceType, SharedLog log,
-            INetd netd, Callback callback, boolean usingLegacyDhcp, Dependencies deps) {
+            INetd netd, Callback callback, boolean usingLegacyDhcp, boolean usingBpfOffload,
+            Dependencies deps) {
         super(ifaceName, looper);
         mLog = log.forSubComponent(ifaceName);
         mNetd = netd;
@@ -314,6 +318,7 @@
         mInterfaceType = interfaceType;
         mLinkProperties = new LinkProperties();
         mUsingLegacyDhcp = usingLegacyDhcp;
+        mUsingBpfOffload = usingBpfOffload;
         mDeps = deps;
         resetLinkProperties();
         mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
@@ -321,7 +326,12 @@
 
         mIpNeighborMonitor = mDeps.getIpNeighborMonitor(getHandler(), mLog,
                 new MyNeighborEventConsumer());
-        if (!mIpNeighborMonitor.start()) {
+
+        // IP neighbor monitor monitors the neighbor events for adding/removing offload
+        // forwarding rules per client. If BPF offload is not supported, don't start listening
+        // for neighbor events. See updateIpv6ForwardingRules, addIpv6ForwardingRule,
+        // removeIpv6ForwardingRule.
+        if (mUsingBpfOffload && !mIpNeighborMonitor.start()) {
             mLog.e("Failed to create IpNeighborMonitor on " + mIfaceName);
         }
 
@@ -715,12 +725,12 @@
             final String upstreamIface = v6only.getInterfaceName();
 
             params = new RaParams();
-            // We advertise an mtu lower by 16, which is the closest multiple of 8 >= 14,
-            // the ethernet header size.  This makes kernel ebpf tethering offload happy.
-            // This hack should be reverted once we have the kernel fixed up.
+            // When BPF offload is enabled, we advertise an mtu lower by 16, which is the closest
+            // multiple of 8 >= 14, the ethernet header size. This makes kernel ebpf tethering
+            // offload happy. This hack should be reverted once we have the kernel fixed up.
             // Note: this will automatically clamp to at least 1280 (ipv6 minimum mtu)
             // see RouterAdvertisementDaemon.java putMtu()
-            params.mtu = v6only.getMtu() - 16;
+            params.mtu = mUsingBpfOffload ? v6only.getMtu() - 16 : v6only.getMtu();
             params.hasDefaultRoute = v6only.hasIpv6DefaultRoute();
 
             if (params.hasDefaultRoute) params.hopLimit = getHopLimit(upstreamIface);
@@ -844,6 +854,11 @@
     }
 
     private void addIpv6ForwardingRule(Ipv6ForwardingRule rule) {
+        // Theoretically, we don't need this check because IP neighbor monitor doesn't start if BPF
+        // offload is disabled. Add this check just in case.
+        // TODO: Perhaps remove this protection check.
+        if (!mUsingBpfOffload) return;
+
         try {
             mNetd.tetherOffloadRuleAdd(rule.toTetherOffloadRuleParcel());
             mIpv6ForwardingRules.put(rule.address, rule);
@@ -853,6 +868,11 @@
     }
 
     private void removeIpv6ForwardingRule(Ipv6ForwardingRule rule, boolean removeFromMap) {
+        // Theoretically, we don't need this check because IP neighbor monitor doesn't start if BPF
+        // offload is disabled. Add this check just in case.
+        // TODO: Perhaps remove this protection check.
+        if (!mUsingBpfOffload) return;
+
         try {
             mNetd.tetherOffloadRuleRemove(rule.toTetherOffloadRuleParcel());
             if (removeFromMap) {
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index 293f8ea..fe92204 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -66,6 +66,7 @@
 
     private final Handler mHandler;
     private final SharedLog mLog;
+    private final Dependencies mDeps;
     private IOffloadControl mOffloadControl;
     private TetheringOffloadCallback mTetheringOffloadCallback;
     private ControlCallback mControlCallback;
@@ -126,8 +127,76 @@
     }
 
     public OffloadHardwareInterface(Handler h, SharedLog log) {
+        this(h, log, new Dependencies(log));
+    }
+
+    OffloadHardwareInterface(Handler h, SharedLog log, Dependencies deps) {
         mHandler = h;
         mLog = log.forSubComponent(TAG);
+        mDeps = deps;
+    }
+
+    /** Capture OffloadHardwareInterface dependencies, for injection. */
+    static class Dependencies {
+        private final SharedLog mLog;
+
+        Dependencies(SharedLog log) {
+            mLog = log;
+        }
+
+        public IOffloadConfig getOffloadConfig() {
+            try {
+                return IOffloadConfig.getService(true /*retry*/);
+            } catch (RemoteException | NoSuchElementException e) {
+                mLog.e("getIOffloadConfig error " + e);
+                return null;
+            }
+        }
+
+        public IOffloadControl getOffloadControl() {
+            try {
+                return IOffloadControl.getService(true /*retry*/);
+            } catch (RemoteException | NoSuchElementException e) {
+                mLog.e("tethering offload control not supported: " + e);
+                return null;
+            }
+        }
+
+        public NativeHandle createConntrackSocket(final int groups) {
+            final FileDescriptor fd;
+            try {
+                fd = NetlinkSocket.forProto(OsConstants.NETLINK_NETFILTER);
+            } catch (ErrnoException e) {
+                mLog.e("Unable to create conntrack socket " + e);
+                return null;
+            }
+
+            final SocketAddress sockAddr = SocketUtils.makeNetlinkSocketAddress(0, groups);
+            try {
+                Os.bind(fd, sockAddr);
+            } catch (ErrnoException | SocketException e) {
+                mLog.e("Unable to bind conntrack socket for groups " + groups + " error: " + e);
+                try {
+                    SocketUtils.closeSocket(fd);
+                } catch (IOException ie) {
+                    // Nothing we can do here
+                }
+                return null;
+            }
+            try {
+                Os.connect(fd, sockAddr);
+            } catch (ErrnoException | SocketException e) {
+                mLog.e("connect to kernel fail for groups " + groups + " error: " + e);
+                try {
+                    SocketUtils.closeSocket(fd);
+                } catch (IOException ie) {
+                    // Nothing we can do here
+                }
+                return null;
+            }
+
+            return new NativeHandle(fd, true);
+        }
     }
 
     /** Get default value indicating whether offload is supported. */
@@ -141,13 +210,7 @@
      * share them with offload management process.
      */
     public boolean initOffloadConfig() {
-        IOffloadConfig offloadConfig;
-        try {
-            offloadConfig = IOffloadConfig.getService(true /*retry*/);
-        } catch (RemoteException | NoSuchElementException e) {
-            mLog.e("getIOffloadConfig error " + e);
-            return false;
-        }
+        final IOffloadConfig offloadConfig = mDeps.getOffloadConfig();
         if (offloadConfig == null) {
             mLog.e("Could not find IOffloadConfig service");
             return false;
@@ -159,11 +222,11 @@
         //
         // h2    provides a file descriptor bound to the following netlink groups
         //       (NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY).
-        final NativeHandle h1 = createConntrackSocket(
+        final NativeHandle h1 = mDeps.createConntrackSocket(
                 NF_NETLINK_CONNTRACK_NEW | NF_NETLINK_CONNTRACK_DESTROY);
         if (h1 == null) return false;
 
-        final NativeHandle h2 = createConntrackSocket(
+        final NativeHandle h2 = mDeps.createConntrackSocket(
                 NF_NETLINK_CONNTRACK_UPDATE | NF_NETLINK_CONNTRACK_DESTROY);
         if (h2 == null) {
             closeFdInNativeHandle(h1);
@@ -198,53 +261,12 @@
         }
     }
 
-    private NativeHandle createConntrackSocket(final int groups) {
-        FileDescriptor fd;
-        try {
-            fd = NetlinkSocket.forProto(OsConstants.NETLINK_NETFILTER);
-        } catch (ErrnoException e) {
-            mLog.e("Unable to create conntrack socket " + e);
-            return null;
-        }
-
-        final SocketAddress sockAddr = SocketUtils.makeNetlinkSocketAddress(0, groups);
-        try {
-            Os.bind(fd, sockAddr);
-        } catch (ErrnoException | SocketException e) {
-            mLog.e("Unable to bind conntrack socket for groups " + groups + " error: " + e);
-            try {
-                SocketUtils.closeSocket(fd);
-            } catch (IOException ie) {
-                // Nothing we can do here
-            }
-            return null;
-        }
-        try {
-            Os.connect(fd, sockAddr);
-        } catch (ErrnoException | SocketException e) {
-            mLog.e("connect to kernel fail for groups " + groups + " error: " + e);
-            try {
-                SocketUtils.closeSocket(fd);
-            } catch (IOException ie) {
-                // Nothing we can do here
-            }
-            return null;
-        }
-
-        return new NativeHandle(fd, true);
-    }
-
     /** Initialize the tethering offload HAL. */
     public boolean initOffloadControl(ControlCallback controlCb) {
         mControlCallback = controlCb;
 
         if (mOffloadControl == null) {
-            try {
-                mOffloadControl = IOffloadControl.getService(true /*retry*/);
-            } catch (RemoteException | NoSuchElementException e) {
-                mLog.e("tethering offload control not supported: " + e);
-                return false;
-            }
+            mOffloadControl = mDeps.getOffloadControl();
             if (mOffloadControl == null) {
                 mLog.e("tethering IOffloadControl.getService() returned null");
                 return false;
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index ae6119f2..04ad43f 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -109,8 +109,10 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ServiceSpecificException;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -228,6 +230,7 @@
     private final ConnectedClientsTracker mConnectedClientsTracker;
     private final TetheringThreadExecutor mExecutor;
     private final TetheringNotificationUpdater mNotificationUpdater;
+    private final UserManager mUserManager;
     private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
     // All the usage of mTetheringEventCallback should run in the same thread.
     private ITetheringEventCallback mTetheringEventCallback = null;
@@ -305,23 +308,24 @@
 
         mStateReceiver = new StateReceiver();
 
-        final UserManager userManager = (UserManager) mContext.getSystemService(
-                Context.USER_SERVICE);
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mTetheringRestriction = new UserRestrictionActionListener(
-                userManager, this, mNotificationUpdater);
+                mUserManager, this, mNotificationUpdater);
         mExecutor = new TetheringThreadExecutor(mHandler);
         mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
         mNetdCallback = new NetdCallback();
 
         // Load tethering configuration.
         updateConfiguration();
+
+        startStateMachineUpdaters();
     }
 
     /**
      * Start to register callbacks.
      * Call this function when tethering is ready to handle callback events.
      */
-    public void startStateMachineUpdaters() {
+    private void startStateMachineUpdaters() {
         try {
             mNetd.registerUnsolicitedEventListener(mNetdCallback);
         } catch (RemoteException e) {
@@ -779,7 +783,7 @@
 
     // TODO: Figure out how to update for local hotspot mode interfaces.
     private void sendTetherStateChangedBroadcast() {
-        if (!mDeps.isTetheringSupported()) return;
+        if (!isTetheringSupported()) return;
 
         final ArrayList<String> availableList = new ArrayList<>();
         final ArrayList<String> tetherList = new ArrayList<>();
@@ -1020,14 +1024,14 @@
 
     @VisibleForTesting
     protected static class UserRestrictionActionListener {
-        private final UserManager mUserManager;
+        private final UserManager mUserMgr;
         private final Tethering mWrapper;
         private final TetheringNotificationUpdater mNotificationUpdater;
         public boolean mDisallowTethering;
 
         public UserRestrictionActionListener(@NonNull UserManager um, @NonNull Tethering wrapper,
                 @NonNull TetheringNotificationUpdater updater) {
-            mUserManager = um;
+            mUserMgr = um;
             mWrapper = wrapper;
             mNotificationUpdater = updater;
             mDisallowTethering = false;
@@ -1037,7 +1041,7 @@
             // getUserRestrictions gets restriction for this process' user, which is the primary
             // user. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary
             // user. See UserManager.DISALLOW_CONFIG_TETHERING.
-            final Bundle restrictions = mUserManager.getUserRestrictions();
+            final Bundle restrictions = mUserMgr.getUserRestrictions();
             final boolean newlyDisallowed =
                     restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
             final boolean prevDisallowed = mDisallowTethering;
@@ -1988,7 +1992,7 @@
         mHandler.post(() -> {
             mTetheringEventCallbacks.register(callback, new CallbackCookie(hasListPermission));
             final TetheringCallbackStartedParcel parcel = new TetheringCallbackStartedParcel();
-            parcel.tetheringSupported = mDeps.isTetheringSupported();
+            parcel.tetheringSupported = isTetheringSupported();
             parcel.upstreamNetwork = mTetherUpstream;
             parcel.config = mConfig.toStableParcelable();
             parcel.states =
@@ -2111,6 +2115,20 @@
         }
     }
 
+    // if ro.tether.denied = true we default to no tethering
+    // gservices could set the secure setting to 1 though to enable it on a build where it
+    // had previously been turned off.
+    boolean isTetheringSupported() {
+        final int defaultVal =
+                SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
+        final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
+        final boolean tetherEnabledInSettings = tetherSupported
+                && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
+
+        return tetherEnabledInSettings && hasTetherableConfiguration();
+    }
+
     void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) {
         // Binder.java closes the resource for us.
         @SuppressWarnings("resource")
@@ -2296,7 +2314,7 @@
         final TetherState tetherState = new TetherState(
                 new IpServer(iface, mLooper, interfaceType, mLog, mNetd,
                              makeControlCallback(), mConfig.enableLegacyDhcpServer,
-                             mDeps.getIpServerDependencies()));
+                             mConfig.enableBpfOffload, mDeps.getIpServerDependencies()));
         mTetherStates.put(iface, tetherState);
         tetherState.ipServer.start();
     }
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index 9d4e747..48a600d 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -73,6 +73,12 @@
     private static final String[] DEFAULT_IPV4_DNS = {"8.8.4.4", "8.8.8.8"};
 
     /**
+     * Override enabling BPF offload configuration for tethering.
+     */
+    public static final String OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD =
+            "override_tether_enable_bpf_offload";
+
+    /**
      * Use the old dnsmasq DHCP server for tethering instead of the framework implementation.
      */
     public static final String TETHER_ENABLE_LEGACY_DHCP_SERVER =
@@ -95,6 +101,8 @@
     public final String[] legacyDhcpRanges;
     public final String[] defaultIPv4DNS;
     public final boolean enableLegacyDhcpServer;
+    // TODO: Add to TetheringConfigurationParcel if required.
+    public final boolean enableBpfOffload;
 
     public final String[] provisioningApp;
     public final String provisioningAppNoUi;
@@ -124,11 +132,12 @@
         isDunRequired = checkDunRequired(ctx);
 
         chooseUpstreamAutomatically = getResourceBoolean(
-                res, R.bool.config_tether_upstream_automatic);
+                res, R.bool.config_tether_upstream_automatic, false /** defaultValue */);
         preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired);
 
         legacyDhcpRanges = getLegacyDhcpRanges(res);
         defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
+        enableBpfOffload = getEnableBpfOffload(res);
         enableLegacyDhcpServer = getEnableLegacyDhcpServer(res);
 
         provisioningApp = getResourceStringArray(res, R.array.config_mobile_hotspot_provision_app);
@@ -208,6 +217,9 @@
         pw.print("provisioningAppNoUi: ");
         pw.println(provisioningAppNoUi);
 
+        pw.print("enableBpfOffload: ");
+        pw.println(enableBpfOffload);
+
         pw.print("enableLegacyDhcpServer: ");
         pw.println(enableLegacyDhcpServer);
     }
@@ -228,6 +240,7 @@
                 toIntArray(preferredUpstreamIfaceTypes)));
         sj.add(String.format("provisioningApp:%s", makeString(provisioningApp)));
         sj.add(String.format("provisioningAppNoUi:%s", provisioningAppNoUi));
+        sj.add(String.format("enableBpfOffload:%s", enableBpfOffload));
         sj.add(String.format("enableLegacyDhcpServer:%s", enableLegacyDhcpServer));
         return String.format("TetheringConfiguration{%s}", sj.toString());
     }
@@ -332,11 +345,11 @@
         }
     }
 
-    private static boolean getResourceBoolean(Resources res, int resId) {
+    private static boolean getResourceBoolean(Resources res, int resId, boolean defaultValue) {
         try {
             return res.getBoolean(resId);
         } catch (Resources.NotFoundException e404) {
-            return false;
+            return defaultValue;
         }
     }
 
@@ -357,14 +370,36 @@
         }
     }
 
+    private boolean getEnableBpfOffload(final Resources res) {
+        // Get BPF offload config
+        // Priority 1: Device config
+        // Priority 2: Resource config
+        // Priority 3: Default value
+        final boolean defaultValue = getResourceBoolean(
+                res, R.bool.config_tether_enable_bpf_offload, true /** default value */);
+
+        return getDeviceConfigBoolean(OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD, defaultValue);
+    }
+
     private boolean getEnableLegacyDhcpServer(final Resources res) {
-        return getResourceBoolean(res, R.bool.config_tether_enable_legacy_dhcp_server)
-                || getDeviceConfigBoolean(TETHER_ENABLE_LEGACY_DHCP_SERVER);
+        return getResourceBoolean(
+                res, R.bool.config_tether_enable_legacy_dhcp_server, false /** defaultValue */)
+                || getDeviceConfigBoolean(
+                TETHER_ENABLE_LEGACY_DHCP_SERVER, false /** defaultValue */);
+    }
+
+    private boolean getDeviceConfigBoolean(final String name, final boolean defaultValue) {
+        // Due to the limitation of static mock for testing, using #getDeviceConfigProperty instead
+        // of DeviceConfig#getBoolean. If using #getBoolean here, the test can't know that the
+        // returned boolean value comes from device config or default value (because of null
+        // property string). See the test case testBpfOffload{*} in TetheringConfigurationTest.java.
+        final String value = getDeviceConfigProperty(name);
+        return value != null ? Boolean.parseBoolean(value) : defaultValue;
     }
 
     @VisibleForTesting
-    protected boolean getDeviceConfigBoolean(final String name) {
-        return DeviceConfig.getBoolean(NAMESPACE_CONNECTIVITY, name, false /** defaultValue */);
+    protected String getDeviceConfigProperty(String name) {
+        return DeviceConfig.getProperty(NAMESPACE_CONNECTIVITY, name);
     }
 
     private Resources getResources(Context ctx, int subId) {
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
index d07c555f..bf7fb04 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringService.java
@@ -40,15 +40,12 @@
 import android.net.dhcp.DhcpServerCallbacks;
 import android.net.dhcp.DhcpServingParamsParcel;
 import android.net.ip.IpServer;
-import android.net.util.SharedLog;
 import android.os.Binder;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ResultReceiver;
-import android.os.SystemProperties;
-import android.os.UserManager;
 import android.provider.Settings;
 import android.util.Log;
 
@@ -68,21 +65,14 @@
 public class TetheringService extends Service {
     private static final String TAG = TetheringService.class.getSimpleName();
 
-    private final SharedLog mLog = new SharedLog(TAG);
     private TetheringConnector mConnector;
-    private Context mContext;
-    private TetheringDependencies mDeps;
-    private Tethering mTethering;
-    private UserManager mUserManager;
 
     @Override
     public void onCreate() {
-        mLog.mark("onCreate");
-        mDeps = getTetheringDependencies();
-        mContext = mDeps.getContext();
-        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        mTethering = makeTethering(mDeps);
-        mTethering.startStateMachineUpdaters();
+        final TetheringDependencies deps = makeTetheringDependencies();
+        // The Tethering object needs a fully functional context to start, so this can't be done
+        // in the constructor.
+        mConnector = new TetheringConnector(makeTethering(deps), TetheringService.this);
     }
 
     /**
@@ -94,21 +84,10 @@
         return new Tethering(deps);
     }
 
-    /**
-     * Create a binder connector for the system server to communicate with the tethering.
-     */
-    private synchronized IBinder makeConnector() {
-        if (mConnector == null) {
-            mConnector = new TetheringConnector(mTethering, TetheringService.this);
-        }
-        return mConnector;
-    }
-
     @NonNull
     @Override
     public IBinder onBind(Intent intent) {
-        mLog.mark("onBind");
-        return makeConnector();
+        return mConnector;
     }
 
     private static class TetheringConnector extends ITetheringConnector.Stub {
@@ -237,7 +216,7 @@
                     listener.onResult(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION);
                     return true;
                 }
-                if (!mService.isTetheringSupported()) {
+                if (!mTethering.isTetheringSupported()) {
                     listener.onResult(TETHER_ERROR_UNSUPPORTED);
                     return true;
                 }
@@ -253,7 +232,7 @@
                 receiver.send(TETHER_ERROR_NO_CHANGE_TETHERING_PERMISSION, null);
                 return true;
             }
-            if (!mService.isTetheringSupported()) {
+            if (!mTethering.isTetheringSupported()) {
                 receiver.send(TETHER_ERROR_UNSUPPORTED, null);
                 return true;
             }
@@ -287,105 +266,83 @@
         }
     }
 
-    // if ro.tether.denied = true we default to no tethering
-    // gservices could set the secure setting to 1 though to enable it on a build where it
-    // had previously been turned off.
-    private boolean isTetheringSupported() {
-        final int defaultVal =
-                SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1;
-        final boolean tetherSupported = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.TETHER_SUPPORTED, defaultVal) != 0;
-        final boolean tetherEnabledInSettings = tetherSupported
-                && !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
-
-        return tetherEnabledInSettings && mTethering.hasTetherableConfiguration();
-    }
-
     /**
      * An injection method for testing.
      */
     @VisibleForTesting
-    public TetheringDependencies getTetheringDependencies() {
-        if (mDeps == null) {
-            mDeps = new TetheringDependencies() {
-                @Override
-                public NetworkRequest getDefaultNetworkRequest() {
-                    // TODO: b/147280869, add a proper system API to replace this.
-                    final NetworkRequest trackDefaultRequest = new NetworkRequest.Builder()
-                            .clearCapabilities()
-                            .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                            .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
-                            .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-                            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                            .build();
-                    return trackDefaultRequest;
-                }
+    public TetheringDependencies makeTetheringDependencies() {
+        return new TetheringDependencies() {
+            @Override
+            public NetworkRequest getDefaultNetworkRequest() {
+                // TODO: b/147280869, add a proper system API to replace this.
+                final NetworkRequest trackDefaultRequest = new NetworkRequest.Builder()
+                        .clearCapabilities()
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                        .build();
+                return trackDefaultRequest;
+            }
 
-                @Override
-                public Looper getTetheringLooper() {
-                    final HandlerThread tetherThread = new HandlerThread("android.tethering");
-                    tetherThread.start();
-                    return tetherThread.getLooper();
-                }
+            @Override
+            public Looper getTetheringLooper() {
+                final HandlerThread tetherThread = new HandlerThread("android.tethering");
+                tetherThread.start();
+                return tetherThread.getLooper();
+            }
 
-                @Override
-                public boolean isTetheringSupported() {
-                    return TetheringService.this.isTetheringSupported();
-                }
+            @Override
+            public Context getContext() {
+                return TetheringService.this;
+            }
 
-                @Override
-                public Context getContext() {
-                    return TetheringService.this;
-                }
+            @Override
+            public IpServer.Dependencies getIpServerDependencies() {
+                return new IpServer.Dependencies() {
+                    @Override
+                    public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
+                            DhcpServerCallbacks cb) {
+                        try {
+                            final INetworkStackConnector service = getNetworkStackConnector();
+                            if (service == null) return;
 
-                @Override
-                public IpServer.Dependencies getIpServerDependencies() {
-                    return new IpServer.Dependencies() {
-                        @Override
-                        public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
-                                DhcpServerCallbacks cb) {
+                            service.makeDhcpServer(ifName, params, cb);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "Fail to make dhcp server");
                             try {
-                                final INetworkStackConnector service = getNetworkStackConnector();
-                                if (service == null) return;
-
-                                service.makeDhcpServer(ifName, params, cb);
-                            } catch (RemoteException e) {
-                                Log.e(TAG, "Fail to make dhcp server");
-                                try {
-                                    cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
-                                } catch (RemoteException re) { }
-                            }
+                                cb.onDhcpServerCreated(STATUS_UNKNOWN_ERROR, null);
+                            } catch (RemoteException re) { }
                         }
-                    };
-                }
-
-                // TODO: replace this by NetworkStackClient#getRemoteConnector after refactoring
-                // networkStackClient.
-                static final int NETWORKSTACK_TIMEOUT_MS = 60_000;
-                private INetworkStackConnector getNetworkStackConnector() {
-                    IBinder connector;
-                    try {
-                        final long before = System.currentTimeMillis();
-                        while ((connector = NetworkStack.getService()) == null) {
-                            if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
-                                Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector");
-                                return null;
-                            }
-                            Thread.sleep(200);
-                        }
-                    } catch (InterruptedException e) {
-                        Log.wtf(TAG, "Interrupted, fail to get INetworkStackConnector");
-                        return null;
                     }
-                    return INetworkStackConnector.Stub.asInterface(connector);
-                }
+                };
+            }
 
-                @Override
-                public BluetoothAdapter getBluetoothAdapter() {
-                    return BluetoothAdapter.getDefaultAdapter();
+            // TODO: replace this by NetworkStackClient#getRemoteConnector after refactoring
+            // networkStackClient.
+            static final int NETWORKSTACK_TIMEOUT_MS = 60_000;
+            private INetworkStackConnector getNetworkStackConnector() {
+                IBinder connector;
+                try {
+                    final long before = System.currentTimeMillis();
+                    while ((connector = NetworkStack.getService()) == null) {
+                        if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
+                            Log.wtf(TAG, "Timeout, fail to get INetworkStackConnector");
+                            return null;
+                        }
+                        Thread.sleep(200);
+                    }
+                } catch (InterruptedException e) {
+                    Log.wtf(TAG, "Interrupted, fail to get INetworkStackConnector");
+                    return null;
                 }
-            };
-        }
-        return mDeps;
+                return INetworkStackConnector.Stub.asInterface(connector);
+            }
+
+            @Override
+            public BluetoothAdapter getBluetoothAdapter() {
+                return BluetoothAdapter.getDefaultAdapter();
+            }
+        };
     }
 }
diff --git a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index f9be7b9..b9622da 100644
--- a/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/packages/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -106,6 +106,7 @@
     private static final String BLUETOOTH_IFACE_ADDR = "192.168.42.1";
     private static final int BLUETOOTH_DHCP_PREFIX_LENGTH = 24;
     private static final int DHCP_LEASE_TIME_SECS = 3600;
+    private static final boolean DEFAULT_USING_BPF_OFFLOAD = true;
 
     private static final InterfaceParams TEST_IFACE_PARAMS = new InterfaceParams(
             IFACE_NAME, 42 /* index */, MacAddress.ALL_ZEROS_ADDRESS, 1500 /* defaultMtu */);
@@ -130,10 +131,11 @@
     private NeighborEventConsumer mNeighborEventConsumer;
 
     private void initStateMachine(int interfaceType) throws Exception {
-        initStateMachine(interfaceType, false /* usingLegacyDhcp */);
+        initStateMachine(interfaceType, false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD);
     }
 
-    private void initStateMachine(int interfaceType, boolean usingLegacyDhcp) throws Exception {
+    private void initStateMachine(int interfaceType, boolean usingLegacyDhcp,
+            boolean usingBpfOffload) throws Exception {
         doAnswer(inv -> {
             final IDhcpServerCallbacks cb = inv.getArgument(2);
             new Thread(() -> {
@@ -165,7 +167,7 @@
 
         mIpServer = new IpServer(
                 IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, mNetd,
-                mCallback, usingLegacyDhcp, mDependencies);
+                mCallback, usingLegacyDhcp, usingBpfOffload, mDependencies);
         mIpServer.start();
         mNeighborEventConsumer = neighborCaptor.getValue();
 
@@ -179,12 +181,13 @@
 
     private void initTetheredStateMachine(int interfaceType, String upstreamIface)
             throws Exception {
-        initTetheredStateMachine(interfaceType, upstreamIface, false);
+        initTetheredStateMachine(interfaceType, upstreamIface, false,
+                DEFAULT_USING_BPF_OFFLOAD);
     }
 
     private void initTetheredStateMachine(int interfaceType, String upstreamIface,
-            boolean usingLegacyDhcp) throws Exception {
-        initStateMachine(interfaceType, usingLegacyDhcp);
+            boolean usingLegacyDhcp, boolean usingBpfOffload) throws Exception {
+        initStateMachine(interfaceType, usingLegacyDhcp, usingBpfOffload);
         dispatchCommand(IpServer.CMD_TETHER_REQUESTED, STATE_TETHERED);
         if (upstreamIface != null) {
             LinkProperties lp = new LinkProperties();
@@ -204,7 +207,8 @@
         when(mDependencies.getIpNeighborMonitor(any(), any(), any()))
                 .thenReturn(mIpNeighborMonitor);
         mIpServer = new IpServer(IFACE_NAME, mLooper.getLooper(), TETHERING_BLUETOOTH, mSharedLog,
-                mNetd, mCallback, false /* usingLegacyDhcp */, mDependencies);
+                mNetd, mCallback, false /* usingLegacyDhcp */, DEFAULT_USING_BPF_OFFLOAD,
+                mDependencies);
         mIpServer.start();
         mLooper.dispatchAll();
         verify(mCallback).updateInterfaceState(
@@ -494,7 +498,8 @@
 
     @Test
     public void doesNotStartDhcpServerIfDisabled() throws Exception {
-        initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, true /* usingLegacyDhcp */);
+        initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, true /* usingLegacyDhcp */,
+                DEFAULT_USING_BPF_OFFLOAD);
         dispatchTetherConnectionChanged(UPSTREAM_IFACE);
 
         verify(mDependencies, never()).makeDhcpServer(any(), any(), any());
@@ -577,7 +582,8 @@
 
     @Test
     public void addRemoveipv6ForwardingRules() throws Exception {
-        initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */);
+        initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
+                DEFAULT_USING_BPF_OFFLOAD);
 
         final int myIfindex = TEST_IFACE_PARAMS.index;
         final int notMyIfindex = myIfindex - 1;
@@ -678,6 +684,53 @@
         reset(mNetd);
     }
 
+    @Test
+    public void enableDisableUsingBpfOffload() throws Exception {
+        final int myIfindex = TEST_IFACE_PARAMS.index;
+        final InetAddress neigh = InetAddresses.parseNumericAddress("2001:db8::1");
+        final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a");
+        final MacAddress macNull = MacAddress.fromString("00:00:00:00:00:00");
+
+        reset(mNetd);
+
+        // Expect that rules can be only added/removed when the BPF offload config is enabled.
+        // Note that the usingBpfOffload false case is not a realistic test case. Because IP
+        // neighbor monitor doesn't start if BPF offload is disabled, there should have no
+        // neighbor event listening. This is used for testing the protection check just in case.
+        // TODO: Perhaps remove this test once we don't need this check anymore.
+        for (boolean usingBpfOffload : new boolean[]{true, false}) {
+            initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
+                    usingBpfOffload);
+
+            // A neighbor is added.
+            recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
+            if (usingBpfOffload) {
+                verify(mNetd).tetherOffloadRuleAdd(matches(UPSTREAM_IFINDEX, neigh, macA));
+            } else {
+                verify(mNetd, never()).tetherOffloadRuleAdd(any());
+            }
+            reset(mNetd);
+
+            // A neighbor is deleted.
+            recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
+            if (usingBpfOffload) {
+                verify(mNetd).tetherOffloadRuleRemove(matches(UPSTREAM_IFINDEX, neigh, macNull));
+            } else {
+                verify(mNetd, never()).tetherOffloadRuleRemove(any());
+            }
+            reset(mNetd);
+        }
+    }
+
+    @Test
+    public void doesNotStartIpNeighborMonitorIfBpfOffloadDisabled() throws Exception {
+        initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
+                false /* usingBpfOffload */);
+
+        // IP neighbor monitor doesn't start if BPF offload is disabled.
+        verify(mIpNeighborMonitor, never()).start();
+    }
+
     private void assertDhcpStarted(IpPrefix expectedPrefix) throws Exception {
         verify(mDependencies, times(1)).makeDhcpServer(eq(IFACE_NAME), any(), any());
         verify(mDhcpServer, timeout(MAKE_DHCPSERVER_TIMEOUT_MS).times(1)).startWithCallbacks(
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
index cdd0e24..72fa916 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/EntitlementManagerTest.java
@@ -147,9 +147,8 @@
         doReturn(false).when(
                 () -> SystemProperties.getBoolean(
                 eq(EntitlementManager.DISABLE_PROVISIONING_SYSPROP_KEY), anyBoolean()));
-        doReturn(false).when(
-                () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
-                eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+        doReturn(null).when(
+                () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY), anyString()));
 
         when(mResources.getStringArray(R.array.config_tether_dhcp_range))
                 .thenReturn(new String[0]);
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
new file mode 100644
index 0000000..f8ff1cb
--- /dev/null
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/OffloadHardwareInterfaceTest.java
@@ -0,0 +1,215 @@
+/*
+ * 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.networkstack.tethering;
+
+import static android.net.util.TetheringUtils.uint16;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
+import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
+import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
+import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
+import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
+import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
+import android.net.util.SharedLog;
+import android.os.Handler;
+import android.os.NativeHandle;
+import android.os.test.TestLooper;
+import android.system.OsConstants;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public final class OffloadHardwareInterfaceTest {
+    private static final String RMNET0 = "test_rmnet_data0";
+
+    private final TestLooper mTestLooper = new TestLooper();
+
+    private OffloadHardwareInterface mOffloadHw;
+    private ITetheringOffloadCallback mTetheringOffloadCallback;
+    private OffloadHardwareInterface.ControlCallback mControlCallback;
+
+    @Mock private IOffloadConfig mIOffloadConfig;
+    @Mock private IOffloadControl mIOffloadControl;
+    @Mock private NativeHandle mNativeHandle;
+
+    class MyDependencies extends OffloadHardwareInterface.Dependencies {
+        MyDependencies(SharedLog log) {
+            super(log);
+        }
+
+        @Override
+        public IOffloadConfig getOffloadConfig() {
+            return mIOffloadConfig;
+        }
+
+        @Override
+        public IOffloadControl getOffloadControl() {
+            return mIOffloadControl;
+        }
+
+        @Override
+        public NativeHandle createConntrackSocket(final int groups) {
+            return mNativeHandle;
+        }
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        final SharedLog log = new SharedLog("test");
+        mOffloadHw = new OffloadHardwareInterface(new Handler(mTestLooper.getLooper()), log,
+                new MyDependencies(log));
+        mControlCallback = spy(new OffloadHardwareInterface.ControlCallback());
+    }
+
+    private void startOffloadHardwareInterface() throws Exception {
+        mOffloadHw.initOffloadConfig();
+        mOffloadHw.initOffloadControl(mControlCallback);
+        final ArgumentCaptor<ITetheringOffloadCallback> mOffloadCallbackCaptor =
+                ArgumentCaptor.forClass(ITetheringOffloadCallback.class);
+        verify(mIOffloadControl).initOffload(mOffloadCallbackCaptor.capture(), any());
+        mTetheringOffloadCallback = mOffloadCallbackCaptor.getValue();
+    }
+
+    @Test
+    public void testGetForwardedStats() throws Exception {
+        startOffloadHardwareInterface();
+        final OffloadHardwareInterface.ForwardedStats stats = mOffloadHw.getForwardedStats(RMNET0);
+        verify(mIOffloadControl).getForwardedStats(eq(RMNET0), any());
+        assertNotNull(stats);
+    }
+
+    @Test
+    public void testSetLocalPrefixes() throws Exception {
+        startOffloadHardwareInterface();
+        final ArrayList<String> localPrefixes = new ArrayList<>();
+        localPrefixes.add("127.0.0.0/8");
+        localPrefixes.add("fe80::/64");
+        mOffloadHw.setLocalPrefixes(localPrefixes);
+        verify(mIOffloadControl).setLocalPrefixes(eq(localPrefixes), any());
+    }
+
+    @Test
+    public void testSetDataLimit() throws Exception {
+        startOffloadHardwareInterface();
+        final long limit = 12345;
+        mOffloadHw.setDataLimit(RMNET0, limit);
+        verify(mIOffloadControl).setDataLimit(eq(RMNET0), eq(limit), any());
+    }
+
+    @Test
+    public void testSetUpstreamParameters() throws Exception {
+        startOffloadHardwareInterface();
+        final String v4addr = "192.168.10.1";
+        final String v4gateway = "192.168.10.255";
+        final ArrayList<String> v6gws = new ArrayList<>(0);
+        v6gws.add("2001:db8::1");
+        mOffloadHw.setUpstreamParameters(RMNET0, v4addr, v4gateway, v6gws);
+        verify(mIOffloadControl).setUpstreamParameters(eq(RMNET0), eq(v4addr), eq(v4gateway),
+                eq(v6gws), any());
+
+        final ArgumentCaptor<ArrayList<String>> mArrayListCaptor =
+                ArgumentCaptor.forClass(ArrayList.class);
+        mOffloadHw.setUpstreamParameters(null, null, null, null);
+        verify(mIOffloadControl).setUpstreamParameters(eq(""), eq(""), eq(""),
+                mArrayListCaptor.capture(), any());
+        assertEquals(mArrayListCaptor.getValue().size(), 0);
+    }
+
+    @Test
+    public void testUpdateDownstreamPrefix() throws Exception {
+        startOffloadHardwareInterface();
+        final String ifName = "wlan1";
+        final String prefix = "192.168.43.0/24";
+        mOffloadHw.addDownstreamPrefix(ifName, prefix);
+        verify(mIOffloadControl).addDownstream(eq(ifName), eq(prefix), any());
+
+        mOffloadHw.removeDownstreamPrefix(ifName, prefix);
+        verify(mIOffloadControl).removeDownstream(eq(ifName), eq(prefix), any());
+    }
+
+    @Test
+    public void testTetheringOffloadCallback() throws Exception {
+        startOffloadHardwareInterface();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
+        mTestLooper.dispatchAll();
+        verify(mControlCallback).onStarted();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR);
+        mTestLooper.dispatchAll();
+        verify(mControlCallback).onStoppedError();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED);
+        mTestLooper.dispatchAll();
+        verify(mControlCallback).onStoppedUnsupported();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE);
+        mTestLooper.dispatchAll();
+        verify(mControlCallback).onSupportAvailable();
+
+        mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED);
+        mTestLooper.dispatchAll();
+        verify(mControlCallback).onStoppedLimitReached();
+
+        final NatTimeoutUpdate tcpParams = buildNatTimeoutUpdate(NetworkProtocol.TCP);
+        mTetheringOffloadCallback.updateTimeout(tcpParams);
+        mTestLooper.dispatchAll();
+        verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_TCP),
+                eq(tcpParams.src.addr),
+                eq(uint16(tcpParams.src.port)),
+                eq(tcpParams.dst.addr),
+                eq(uint16(tcpParams.dst.port)));
+
+        final NatTimeoutUpdate udpParams = buildNatTimeoutUpdate(NetworkProtocol.UDP);
+        mTetheringOffloadCallback.updateTimeout(udpParams);
+        mTestLooper.dispatchAll();
+        verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_UDP),
+                eq(udpParams.src.addr),
+                eq(uint16(udpParams.src.port)),
+                eq(udpParams.dst.addr),
+                eq(uint16(udpParams.dst.port)));
+    }
+
+    private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
+        final NatTimeoutUpdate params = new NatTimeoutUpdate();
+        params.proto = proto;
+        params.src.addr = "192.168.43.200";
+        params.src.port = 100;
+        params.dst.addr = "172.50.46.169";
+        params.dst.port = 150;
+        return params;
+    }
+}
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
index e8ba5b8..1999ad7 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringConfigurationTest.java
@@ -30,7 +30,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.when;
 
@@ -109,9 +108,9 @@
                 .mockStatic(DeviceConfig.class)
                 .strictness(Strictness.WARN)
                 .startMocking();
-        doReturn(false).when(
-                () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
-                eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+        doReturn(null).when(
+                () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+                eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
 
         when(mResources.getStringArray(R.array.config_tether_dhcp_range)).thenReturn(
                 new String[0]);
@@ -127,6 +126,8 @@
                 .thenReturn(new String[0]);
         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
                 false);
+        initializeBpfOffloadConfiguration(true, null /* unset */);
+
         mHasTelephonyManager = true;
         mMockContext = new MockContext(mContext);
         mEnableLegacyDhcpServer = false;
@@ -278,13 +279,57 @@
         assertFalse(upstreamIterator.hasNext());
     }
 
+    private void initializeBpfOffloadConfiguration(
+            final boolean fromRes, final String fromDevConfig) {
+        when(mResources.getBoolean(R.bool.config_tether_enable_bpf_offload)).thenReturn(fromRes);
+        doReturn(fromDevConfig).when(
+                () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+                eq(TetheringConfiguration.OVERRIDE_TETHER_ENABLE_BPF_OFFLOAD)));
+    }
+
+    @Test
+    public void testBpfOffloadEnabledByResource() {
+        initializeBpfOffloadConfiguration(true, null /* unset */);
+        final TetheringConfiguration enableByRes =
+                new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+        assertTrue(enableByRes.enableBpfOffload);
+    }
+
+    @Test
+    public void testBpfOffloadEnabledByDeviceConfigOverride() {
+        for (boolean res : new boolean[]{true, false}) {
+            initializeBpfOffloadConfiguration(res, "true");
+            final TetheringConfiguration enableByDevConOverride =
+                    new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+            assertTrue(enableByDevConOverride.enableBpfOffload);
+        }
+    }
+
+    @Test
+    public void testBpfOffloadDisabledByResource() {
+        initializeBpfOffloadConfiguration(false, null /* unset */);
+        final TetheringConfiguration disableByRes =
+                new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+        assertFalse(disableByRes.enableBpfOffload);
+    }
+
+    @Test
+    public void testBpfOffloadDisabledByDeviceConfigOverride() {
+        for (boolean res : new boolean[]{true, false}) {
+            initializeBpfOffloadConfiguration(res, "false");
+            final TetheringConfiguration disableByDevConOverride =
+                    new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
+            assertFalse(disableByDevConOverride.enableBpfOffload);
+        }
+    }
+
     @Test
     public void testNewDhcpServerDisabled() {
         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
                 true);
-        doReturn(false).when(
-                () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
-                eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+        doReturn("false").when(
+                () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+                eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
 
         final TetheringConfiguration enableByRes =
                 new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -292,9 +337,9 @@
 
         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
                 false);
-        doReturn(true).when(
-                () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
-                eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+        doReturn("true").when(
+                () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+                eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
 
         final TetheringConfiguration enableByDevConfig =
                 new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
@@ -305,9 +350,9 @@
     public void testNewDhcpServerEnabled() {
         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
                 false);
-        doReturn(false).when(
-                () -> DeviceConfig.getBoolean(eq(NAMESPACE_CONNECTIVITY),
-                eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER), anyBoolean()));
+        doReturn("false").when(
+                () -> DeviceConfig.getProperty(eq(NAMESPACE_CONNECTIVITY),
+                eq(TetheringConfiguration.TETHER_ENABLE_LEGACY_DHCP_SERVER)));
 
         final TetheringConfiguration cfg =
                 new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
index 51bad9a..4a667b1 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
@@ -82,8 +82,7 @@
         mTetheringConnector = mockConnector.getTetheringConnector();
         final MockTetheringService service = mockConnector.getService();
         mTethering = service.getTethering();
-        verify(mTethering).startStateMachineUpdaters();
-        when(mTethering.hasTetherableConfiguration()).thenReturn(true);
+        when(mTethering.isTetheringSupported()).thenReturn(true);
     }
 
     @After
@@ -96,7 +95,7 @@
         when(mTethering.tether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
         final TestTetheringResult result = new TestTetheringResult();
         mTetheringConnector.tether(TEST_IFACE_NAME, TEST_CALLER_PKG, result);
-        verify(mTethering).hasTetherableConfiguration();
+        verify(mTethering).isTetheringSupported();
         verify(mTethering).tether(TEST_IFACE_NAME);
         verifyNoMoreInteractions(mTethering);
         result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -107,7 +106,7 @@
         when(mTethering.untether(TEST_IFACE_NAME)).thenReturn(TETHER_ERROR_NO_ERROR);
         final TestTetheringResult result = new TestTetheringResult();
         mTetheringConnector.untether(TEST_IFACE_NAME, TEST_CALLER_PKG, result);
-        verify(mTethering).hasTetherableConfiguration();
+        verify(mTethering).isTetheringSupported();
         verify(mTethering).untether(TEST_IFACE_NAME);
         verifyNoMoreInteractions(mTethering);
         result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -118,7 +117,7 @@
         when(mTethering.setUsbTethering(true /* enable */)).thenReturn(TETHER_ERROR_NO_ERROR);
         final TestTetheringResult result = new TestTetheringResult();
         mTetheringConnector.setUsbTethering(true /* enable */, TEST_CALLER_PKG, result);
-        verify(mTethering).hasTetherableConfiguration();
+        verify(mTethering).isTetheringSupported();
         verify(mTethering).setUsbTethering(true /* enable */);
         verifyNoMoreInteractions(mTethering);
         result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -130,7 +129,7 @@
         final TetheringRequestParcel request = new TetheringRequestParcel();
         request.tetheringType = TETHERING_WIFI;
         mTetheringConnector.startTethering(request, TEST_CALLER_PKG, result);
-        verify(mTethering).hasTetherableConfiguration();
+        verify(mTethering).isTetheringSupported();
         verify(mTethering).startTethering(eq(request), eq(result));
         verifyNoMoreInteractions(mTethering);
     }
@@ -139,7 +138,7 @@
     public void testStopTethering() throws Exception {
         final TestTetheringResult result = new TestTetheringResult();
         mTetheringConnector.stopTethering(TETHERING_WIFI, TEST_CALLER_PKG, result);
-        verify(mTethering).hasTetherableConfiguration();
+        verify(mTethering).isTetheringSupported();
         verify(mTethering).stopTethering(TETHERING_WIFI);
         verifyNoMoreInteractions(mTethering);
         result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -150,7 +149,7 @@
         final ResultReceiver result = new ResultReceiver(null);
         mTetheringConnector.requestLatestTetheringEntitlementResult(TETHERING_WIFI, result,
                 true /* showEntitlementUi */, TEST_CALLER_PKG);
-        verify(mTethering).hasTetherableConfiguration();
+        verify(mTethering).isTetheringSupported();
         verify(mTethering).requestLatestTetheringEntitlementResult(eq(TETHERING_WIFI),
                 eq(result), eq(true) /* showEntitlementUi */);
         verifyNoMoreInteractions(mTethering);
@@ -177,7 +176,7 @@
     public void testStopAllTethering() throws Exception {
         final TestTetheringResult result = new TestTetheringResult();
         mTetheringConnector.stopAllTethering(TEST_CALLER_PKG, result);
-        verify(mTethering).hasTetherableConfiguration();
+        verify(mTethering).isTetheringSupported();
         verify(mTethering).untetherAll();
         verifyNoMoreInteractions(mTethering);
         result.assertResult(TETHER_ERROR_NO_ERROR);
@@ -187,7 +186,7 @@
     public void testIsTetheringSupported() throws Exception {
         final TestTetheringResult result = new TestTetheringResult();
         mTetheringConnector.isTetheringSupported(TEST_CALLER_PKG, result);
-        verify(mTethering).hasTetherableConfiguration();
+        verify(mTethering).isTetheringSupported();
         verifyNoMoreInteractions(mTethering);
         result.assertResult(TETHER_ERROR_NO_ERROR);
     }
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 2bd8ae0..0132aba 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -312,8 +312,8 @@
         }
 
         @Override
-        protected boolean getDeviceConfigBoolean(final String name) {
-            return false;
+        protected String getDeviceConfigProperty(final String name) {
+            return null;
         }
 
         @Override
@@ -485,18 +485,6 @@
         MockitoAnnotations.initMocks(this);
         when(mResources.getStringArray(R.array.config_tether_dhcp_range))
                 .thenReturn(new String[0]);
-        when(mResources.getStringArray(R.array.config_tether_usb_regexs))
-                .thenReturn(new String[] { "test_rndis\\d" });
-        when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
-                .thenReturn(new String[]{ "test_wlan\\d" });
-        when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
-                .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
-        when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
-                .thenReturn(new String[0]);
-        when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
-                .thenReturn(new String[] { "test_ncm\\d" });
-        when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
-        when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(false);
         when(mResources.getBoolean(R.bool.config_tether_enable_legacy_dhcp_server)).thenReturn(
                 false);
         when(mNetd.interfaceGetList())
@@ -515,6 +503,7 @@
         mServiceContext = new TestContext(mContext);
         mContentResolver = new MockContentResolver(mServiceContext);
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+        setTetheringSupported(true /* supported */);
         mIntents = new Vector<>();
         mBroadcastReceiver = new BroadcastReceiver() {
             @Override
@@ -525,7 +514,6 @@
         mServiceContext.registerReceiver(mBroadcastReceiver,
                 new IntentFilter(ACTION_TETHER_STATE_CHANGED));
         mTethering = makeTethering();
-        mTethering.startStateMachineUpdaters();
         verify(mStatsManager, times(1)).registerNetworkStatsProvider(anyString(), any());
         verify(mNetd).registerUnsolicitedEventListener(any());
         final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor =
@@ -536,6 +524,31 @@
         mPhoneStateListener = phoneListenerCaptor.getValue();
     }
 
+    private void setTetheringSupported(final boolean supported) {
+        Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED,
+                supported ? 1 : 0);
+        when(mUserManager.hasUserRestriction(
+                UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(!supported);
+        // Setup tetherable configuration.
+        when(mResources.getStringArray(R.array.config_tether_usb_regexs))
+                .thenReturn(new String[] { "test_rndis\\d" });
+        when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
+                .thenReturn(new String[]{ "test_wlan\\d" });
+        when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
+                .thenReturn(new String[]{ "test_p2p-p2p\\d-.*" });
+        when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
+                .thenReturn(new String[0]);
+        when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
+                .thenReturn(new String[] { "test_ncm\\d" });
+        when(mResources.getIntArray(R.array.config_tether_upstream_types)).thenReturn(new int[0]);
+        when(mResources.getBoolean(R.bool.config_tether_upstream_automatic)).thenReturn(true);
+    }
+
+    private void initTetheringUpstream(UpstreamNetworkState upstreamState) {
+        when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
+        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
+    }
+
     private Tethering makeTethering() {
         mTetheringDependencies.reset();
         return new Tethering(mTetheringDependencies);
@@ -672,9 +685,7 @@
     }
 
     private void prepareUsbTethering(UpstreamNetworkState upstreamState) {
-        when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
-        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
-                .thenReturn(upstreamState);
+        initTetheringUpstream(upstreamState);
 
         // Emulate pressing the USB tethering button in Settings UI.
         mTethering.startTethering(createTetheringRequestParcel(TETHERING_USB), null);
@@ -700,7 +711,7 @@
         verify(mNetd, times(1)).interfaceGetList();
 
         // UpstreamNetworkMonitor should receive selected upstream
-        verify(mUpstreamNetworkMonitor, times(1)).selectPreferredUpstreamType(any());
+        verify(mUpstreamNetworkMonitor, times(1)).getCurrentPreferredUpstream();
         verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(upstreamState.network);
     }
 
@@ -872,8 +883,7 @@
 
         // Then 464xlat comes up
         upstreamState = buildMobile464xlatUpstreamState();
-        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
-                .thenReturn(upstreamState);
+        initTetheringUpstream(upstreamState);
 
         // Upstream LinkProperties changed: UpstreamNetworkMonitor sends EVENT_ON_LINKPROPERTIES.
         mTetheringDependencies.mUpstreamNetworkMonitorMasterSM.sendMessage(
@@ -1344,9 +1354,7 @@
         callback.expectOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
         // 2. Enable wifi tethering.
         UpstreamNetworkState upstreamState = buildMobileDualStackUpstreamState();
-        when(mUpstreamNetworkMonitor.getCurrentPreferredUpstream()).thenReturn(upstreamState);
-        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any()))
-                .thenReturn(upstreamState);
+        initTetheringUpstream(upstreamState);
         when(mWifiManager.startTetheredHotspot(any(SoftApConfiguration.class))).thenReturn(true);
         mTethering.interfaceStatusChanged(TEST_WLAN_IFNAME, true);
         mLooper.dispatchAll();
@@ -1723,7 +1731,7 @@
         final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
                 mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
-        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
+        initTetheringUpstream(upstreamState);
         stateMachine.chooseUpstreamType(true);
 
         verify(mUpstreamNetworkMonitor, times(1)).setCurrentUpstream(eq(upstreamState.network));
@@ -1735,7 +1743,7 @@
         final Tethering.TetherMasterSM stateMachine = (Tethering.TetherMasterSM)
                 mTetheringDependencies.mUpstreamNetworkMonitorMasterSM;
         final UpstreamNetworkState upstreamState = buildMobileIPv4UpstreamState();
-        when(mUpstreamNetworkMonitor.selectPreferredUpstreamType(any())).thenReturn(upstreamState);
+        initTetheringUpstream(upstreamState);
         stateMachine.chooseUpstreamType(true);
 
         stateMachine.handleUpstreamNetworkMonitorCallback(EVENT_ON_CAPABILITIES, upstreamState);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 6d848d1..b3867a3 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -132,6 +132,7 @@
 import java.util.Set;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.function.Predicate;
 
 /**
  * This class is instantiated by the system as a system level service and can be
@@ -391,7 +392,7 @@
                         return;
                     }
                     // We will update when the automation service dies.
-                    AccessibilityUserState userState = getCurrentUserStateLocked();
+                    final AccessibilityUserState userState = getCurrentUserStateLocked();
                     // We have to reload the installed services since some services may
                     // have different attributes, resolve info (does not support equals),
                     // etc. Remove them then to force reload.
@@ -440,15 +441,18 @@
                     if (userId != mCurrentUserId) {
                         return;
                     }
-                    AccessibilityUserState userState = getUserStateLocked(userId);
-                    Iterator<ComponentName> it = userState.mEnabledServices.iterator();
+                    final AccessibilityUserState userState = getUserStateLocked(userId);
+                    final Predicate<ComponentName> filter =
+                            component -> component != null && component.getPackageName().equals(
+                                    packageName);
+                    userState.mBindingServices.removeIf(filter);
+                    userState.mCrashedServices.removeIf(filter);
+                    final Iterator<ComponentName> it = userState.mEnabledServices.iterator();
                     while (it.hasNext()) {
-                        ComponentName comp = it.next();
-                        String compPkg = comp.getPackageName();
+                        final ComponentName comp = it.next();
+                        final String compPkg = comp.getPackageName();
                         if (compPkg.equals(packageName)) {
                             it.remove();
-                            userState.getBindingServicesLocked().remove(comp);
-                            userState.getCrashedServicesLocked().remove(comp);
                             // Update the enabled services setting.
                             persistComponentNamesToSettingLocked(
                                     Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
@@ -476,11 +480,11 @@
                     if (userId != mCurrentUserId) {
                         return false;
                     }
-                    AccessibilityUserState userState = getUserStateLocked(userId);
-                    Iterator<ComponentName> it = userState.mEnabledServices.iterator();
+                    final AccessibilityUserState userState = getUserStateLocked(userId);
+                    final Iterator<ComponentName> it = userState.mEnabledServices.iterator();
                     while (it.hasNext()) {
-                        ComponentName comp = it.next();
-                        String compPkg = comp.getPackageName();
+                        final ComponentName comp = it.next();
+                        final String compPkg = comp.getPackageName();
                         for (String pkg : packages) {
                             if (compPkg.equals(pkg)) {
                                 if (!doit) {
@@ -1208,7 +1212,7 @@
         final Intent intent = new Intent();
         final Bundle bundle = ActivityOptions.makeBasic().setLaunchDisplayId(displayId).toBundle();
         intent.setComponent(name);
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         try {
             mContext.startActivityAsUser(intent, bundle, UserHandle.of(mCurrentUserId));
         } catch (ActivityNotFoundException ignore) {
@@ -1540,6 +1544,7 @@
             } else {
                 if (service != null) {
                     service.unbindLocked();
+                    removeShortcutTargetForUnboundServiceLocked(userState, service);
                 }
             }
         }
@@ -2314,6 +2319,36 @@
         scheduleNotifyClientsOfServicesStateChangeLocked(userState);
     }
 
+    /**
+     * Remove the shortcut target for the unbound service which is requesting accessibility button
+     * and targeting sdk > Q from the accessibility button and shortcut.
+     *
+     * @param userState The accessibility user state.
+     * @param service The unbound service.
+     */
+    private void removeShortcutTargetForUnboundServiceLocked(AccessibilityUserState userState,
+            AccessibilityServiceConnection service) {
+        if (!service.mRequestAccessibilityButton
+                || service.getServiceInfo().getResolveInfo().serviceInfo.applicationInfo
+                .targetSdkVersion <= Build.VERSION_CODES.Q) {
+            return;
+        }
+        final ComponentName serviceName = service.getComponentName();
+        if (userState.removeShortcutTargetLocked(ACCESSIBILITY_SHORTCUT_KEY, serviceName)) {
+            final Set<String> currentTargets = userState.getShortcutTargetsLocked(
+                    ACCESSIBILITY_SHORTCUT_KEY);
+            persistColonDelimitedSetToSettingLocked(
+                    Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
+                    userState.mUserId, currentTargets, str -> str);
+        }
+        if (userState.removeShortcutTargetLocked(ACCESSIBILITY_BUTTON, serviceName)) {
+            final Set<String> currentTargets = userState.getShortcutTargetsLocked(
+                    ACCESSIBILITY_BUTTON);
+            persistColonDelimitedSetToSettingLocked(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS,
+                    userState.mUserId, currentTargets, str -> str);
+        }
+    }
+
     private void updateRecommendedUiTimeoutLocked(AccessibilityUserState userState) {
         int newNonInteractiveUiTimeout = userState.getUserNonInteractiveUiTimeoutLocked();
         int newInteractiveUiTimeout = userState.getUserInteractiveUiTimeoutLocked();
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index bad649a..43bb4b3 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -631,6 +631,25 @@
     }
 
     /**
+     * Removes given shortcut target in the list.
+     *
+     * @param shortcutType The shortcut type.
+     * @param target The component name of the shortcut target.
+     * @return true if the shortcut target is removed.
+     */
+    public boolean removeShortcutTargetLocked(@ShortcutType int shortcutType,
+            ComponentName target) {
+        return getShortcutTargetsLocked(shortcutType).removeIf(name -> {
+            ComponentName componentName;
+            if (name == null
+                    || (componentName = ComponentName.unflattenFromString(name)) == null) {
+                return false;
+            }
+            return componentName.equals(target);
+        });
+    }
+
+    /**
      * Returns installed accessibility service info by the given service component name.
      */
     public AccessibilityServiceInfo getInstalledServiceInfoLocked(ComponentName componentName) {
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java
index a14584a..4b89731 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/MultiFingerSwipe.java
@@ -20,9 +20,9 @@
 
 import static com.android.server.accessibility.gestures.GestureUtils.MM_PER_CM;
 import static com.android.server.accessibility.gestures.GestureUtils.getActionIndex;
-import static com.android.server.accessibility.gestures.Swipe.CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS;
-import static com.android.server.accessibility.gestures.Swipe.CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS;
 import static com.android.server.accessibility.gestures.Swipe.GESTURE_CONFIRM_CM;
+import static com.android.server.accessibility.gestures.Swipe.MAX_TIME_TO_CONTINUE_SWIPE_MS;
+import static com.android.server.accessibility.gestures.Swipe.MAX_TIME_TO_START_SWIPE_MS;
 import static com.android.server.accessibility.gestures.TouchExplorer.DEBUG;
 
 import android.content.Context;
@@ -387,10 +387,10 @@
         cancelPendingTransitions();
         switch (getState()) {
             case STATE_CLEAR:
-                cancelAfter(CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS, event, rawEvent, policyFlags);
+                cancelAfter(MAX_TIME_TO_START_SWIPE_MS, event, rawEvent, policyFlags);
                 break;
             case STATE_GESTURE_STARTED:
-                cancelAfter(CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS, event, rawEvent, policyFlags);
+                cancelAfter(MAX_TIME_TO_CONTINUE_SWIPE_MS, event, rawEvent, policyFlags);
                 break;
             default:
                 break;
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/Swipe.java b/services/accessibility/java/com/android/server/accessibility/gestures/Swipe.java
index 9108c69..041b424 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/Swipe.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/Swipe.java
@@ -49,11 +49,10 @@
     // Buffer for storing points for gesture detection.
     private final ArrayList<PointF> mStrokeBuffer = new ArrayList<>(100);
 
-    // The minimal delta between moves to add a gesture point.
-    private static final int TOUCH_TOLERANCE_PIX = 3;
-
-    // The minimal score for accepting a predicted gesture.
-    private static final float MIN_PREDICTION_SCORE = 2.0f;
+    // Constants for sampling motion event points.
+    // We sample based on a minimum distance between points, primarily to improve accuracy by
+    // reducing noisy minor changes in direction.
+    private static final float MIN_CM_BETWEEN_SAMPLES = 0.25f;
 
     // Distance a finger must travel before we decide if it is a gesture or not.
     public static final int GESTURE_CONFIRM_CM = 1;
@@ -67,22 +66,19 @@
     // all gestures started with the initial movement taking less than 100ms.
     // When touch exploring, the first movement almost always takes longer than
     // 200ms.
-    public static final long CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS = 150;
+    public static final long MAX_TIME_TO_START_SWIPE_MS = 150 * GESTURE_CONFIRM_CM;
 
     // Time threshold used to determine if a gesture should be cancelled.  If
-    // the finger takes more than this time to move 1cm, the ongoing gesture is
-    // cancelled.
-    public static final long CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS = 300;
+    // the finger takes more than this time to move  to the next sample point, the ongoing gesture
+    // is cancelled.
+    public static final long MAX_TIME_TO_CONTINUE_SWIPE_MS = 350 * GESTURE_CONFIRM_CM;
 
     private int[] mDirections;
     private float mBaseX;
     private float mBaseY;
+    private long mBaseTime;
     private float mPreviousGestureX;
     private float mPreviousGestureY;
-    // Constants for sampling motion event points.
-    // We sample based on a minimum distance between points, primarily to improve accuracy by
-    // reducing noisy minor changes in direction.
-    private static final float MIN_CM_BETWEEN_SAMPLES = 0.25f;
     private final float mMinPixelsBetweenSamplesX;
     private final float mMinPixelsBetweenSamplesY;
     // The minmimum distance the finger must travel before we evaluate the initial direction of the
@@ -134,16 +130,19 @@
     protected void clear() {
         mBaseX = Float.NaN;
         mBaseY = Float.NaN;
+        mBaseTime = 0;
+        mPreviousGestureX = Float.NaN;
+        mPreviousGestureY = Float.NaN;
         mStrokeBuffer.clear();
         super.clear();
     }
 
     @Override
     protected void onDown(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
-        cancelAfterPauseThreshold(event, rawEvent, policyFlags);
         if (Float.isNaN(mBaseX) && Float.isNaN(mBaseY)) {
             mBaseX = rawEvent.getX();
             mBaseY = rawEvent.getY();
+            mBaseTime = rawEvent.getEventTime();
             mPreviousGestureX = mBaseX;
             mPreviousGestureY = mBaseY;
         }
@@ -154,9 +153,11 @@
     protected void onMove(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
         final float x = rawEvent.getX();
         final float y = rawEvent.getY();
+        final long time = rawEvent.getEventTime();
         final float dX = Math.abs(x - mPreviousGestureX);
         final float dY = Math.abs(y - mPreviousGestureY);
         final double moveDelta = Math.hypot(Math.abs(x - mBaseX), Math.abs(y - mBaseY));
+        final long timeDelta = time - mBaseTime;
         if (DEBUG) {
             Slog.d(
                     getGestureName(),
@@ -171,34 +172,38 @@
                 return;
             } else if (mStrokeBuffer.size() == 0) {
                 // First, make sure the pointer is going in the right direction.
-                cancelAfterPauseThreshold(event, rawEvent, policyFlags);
                 int direction = toDirection(x - mBaseX, y - mBaseY);
                 if (direction != mDirections[0]) {
                     cancelGesture(event, rawEvent, policyFlags);
                     return;
-                } else {
-                    // This is confirmed to be some kind of swipe so start tracking points.
-                    mStrokeBuffer.add(new PointF(mBaseX, mBaseY));
                 }
-            }
-            if (moveDelta > mGestureDetectionThresholdPixels) {
-                // If the pointer has moved more than the threshold,
-                // update the stored values.
-                mBaseX = x;
-                mBaseY = y;
-                if (getState() == STATE_CLEAR) {
-                    startGesture(event, rawEvent, policyFlags);
-                    cancelAfterPauseThreshold(event, rawEvent, policyFlags);
-                }
+                // This is confirmed to be some kind of swipe so start tracking points.
+                mStrokeBuffer.add(new PointF(mBaseX, mBaseY));
             }
         }
-        if (getState() == STATE_GESTURE_STARTED) {
-            if (dX >= mMinPixelsBetweenSamplesX || dY >= mMinPixelsBetweenSamplesY) {
-                mPreviousGestureX = x;
-                mPreviousGestureY = y;
-                mStrokeBuffer.add(new PointF(x, y));
-                cancelAfterPauseThreshold(event, rawEvent, policyFlags);
+        if (moveDelta > mGestureDetectionThresholdPixels) {
+            // This is a gesture, not touch exploration.
+            mBaseX = x;
+            mBaseY = y;
+            mBaseTime = time;
+            startGesture(event, rawEvent, policyFlags);
+        } else if (getState() == STATE_CLEAR) {
+            if (timeDelta > MAX_TIME_TO_START_SWIPE_MS) {
+                // The user isn't moving fast enough.
+                cancelGesture(event, rawEvent, policyFlags);
+                return;
             }
+        } else if (getState() == STATE_GESTURE_STARTED) {
+            if (timeDelta > MAX_TIME_TO_CONTINUE_SWIPE_MS) {
+                cancelGesture(event, rawEvent, policyFlags);
+                return;
+            }
+        }
+        if (dX >= mMinPixelsBetweenSamplesX || dY >= mMinPixelsBetweenSamplesY) {
+            // At this point gesture detection has started and we are sampling points.
+            mPreviousGestureX = x;
+            mPreviousGestureY = y;
+            mStrokeBuffer.add(new PointF(x, y));
         }
     }
 
@@ -230,25 +235,6 @@
     }
 
     /**
-     * queues a transition to STATE_GESTURE_CANCEL based on the current state. If we have
-     * transitioned to STATE_GESTURE_STARTED the delay is longer.
-     */
-    private void cancelAfterPauseThreshold(
-            MotionEvent event, MotionEvent rawEvent, int policyFlags) {
-        cancelPendingTransitions();
-        switch (getState()) {
-            case STATE_CLEAR:
-                cancelAfter(CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS, event, rawEvent, policyFlags);
-                break;
-            case STATE_GESTURE_STARTED:
-                cancelAfter(CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS, event, rawEvent, policyFlags);
-                break;
-            default:
-                break;
-        }
-    }
-
-    /**
      * Looks at the sequence of motions in mStrokeBuffer, classifies the gesture, then calls
      * Listener callbacks for success or failure.
      *
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index fdc5f81..103151d 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -267,6 +267,9 @@
         mRemoteService.destroy();
         mRemoteService = null;
 
+        synchronized (mLock) {
+            mZombie = true;
+        }
         mRemoteService = getRemoteServiceLocked();
         if (mRemoteService != null) {
             if (isDebug()) {
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 74e4e4a..d7a3a32 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -19,7 +19,6 @@
 import static android.content.Context.KEYGUARD_SERVICE;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import android.annotation.UserIdInt;
@@ -101,7 +100,6 @@
 import android.view.Display;
 import android.view.View;
 import android.widget.RemoteViews;
-
 import com.android.internal.R;
 import com.android.internal.app.SuspendedAppActivity;
 import com.android.internal.app.UnlaunchableAppActivity;
@@ -116,11 +114,6 @@
 import com.android.server.LocalServices;
 import com.android.server.WidgetBackupProvider;
 import com.android.server.policy.IconUtilities;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -142,6 +135,9 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
 
 class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBackupProvider,
         OnCrossProfileWidgetProvidersChangeListener {
@@ -4887,7 +4883,7 @@
                 final int widgetCount = mWidgets.size();
                 for (int i = 0; i < widgetCount; i++) {
                     final Widget widget = mWidgets.get(i);
-                    if  (widget.host.id.uid == uid) {
+                    if  (widget.host.id.uid == uid && widget.provider != null) {
                         if (widgetPackages == null) {
                             widgetPackages = new ArraySet<>();
                         }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java
index 3282870..3dd2433 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSessionController.java
@@ -67,8 +67,8 @@
      * Requests the IME to create an {@link InlineSuggestionsRequest} for {@code autofillId}.
      *
      * @param autofillId      the Id of the field for which the request is for.
-     * @param requestConsumer the callback which will be invoked when IME responded or if it times
-     *                        out waiting for IME response.
+     * @param requestConsumer the callback to be invoked when the IME responds. Note that this is
+     *                        never invoked if the IME doesn't respond.
      */
     @GuardedBy("mLock")
     void onCreateInlineSuggestionsRequestLocked(@NonNull AutofillId autofillId,
diff --git a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
index 0bf8993..1a3baba 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillInlineSuggestionsRequestSession.java
@@ -55,16 +55,6 @@
 
     private static final String TAG = AutofillInlineSuggestionsRequestSession.class.getSimpleName();
 
-    // This timeout controls how long Autofill should wait for the IME to respond either
-    // unsupported or an {@link InlineSuggestionsRequest}. The timeout is needed to take into
-    // account the latency between the two events after a field is focused, 1) an Autofill
-    // request is triggered on framework; 2) the InputMethodService#onStartInput() event is
-    // triggered on the IME side. When 1) happens, Autofill may call the IME to return an {@link
-    // InlineSuggestionsRequest}, but the IME will only return it after 2) happens (or return
-    // immediately if the IME doesn't support inline suggestions). Also there is IPC latency
-    // between the framework and the IME but that should be small compare to that.
-    private static final int CREATE_INLINE_SUGGESTIONS_REQUEST_TIMEOUT_MS = 1000;
-
     @NonNull
     private final InputMethodManagerInternal mInputMethodManagerInternal;
     private final int mUserId;
@@ -92,9 +82,6 @@
     @GuardedBy("mLock")
     @Nullable
     private IInlineSuggestionsResponseCallback mResponseCallback;
-    @GuardedBy("mLock")
-    @Nullable
-    private Runnable mTimeoutCallback;
 
     @GuardedBy("mLock")
     @Nullable
@@ -174,12 +161,17 @@
     }
 
     /**
-     * This method must be called when the session is destroyed, to avoid further callbacks from/to
-     * the IME.
+     * Prevents further interaction with the IME. Must be called before starting a new request
+     * session to avoid unwanted behavior from two overlapping requests.
      */
     @GuardedBy("mLock")
     void destroySessionLocked() {
         mDestroyed = true;
+
+        if (!mImeRequestReceived) {
+            Slog.w(TAG,
+                    "Never received an InlineSuggestionsRequest from the IME for " + mAutofillId);
+        }
     }
 
     /**
@@ -196,11 +188,6 @@
         mInputMethodManagerInternal.onCreateInlineSuggestionsRequest(mUserId,
                 new InlineSuggestionsRequestInfo(mComponentName, mAutofillId, mUiExtras),
                 new InlineSuggestionsRequestCallbackImpl(this));
-        mTimeoutCallback = () -> {
-            Slog.w(TAG, "Timed out waiting for IME callback InlineSuggestionsRequest.");
-            handleOnReceiveImeRequest(null, null);
-        };
-        mHandler.postDelayed(mTimeoutCallback, CREATE_INLINE_SUGGESTIONS_REQUEST_TIMEOUT_MS);
     }
 
     /**
@@ -212,12 +199,12 @@
         if (mDestroyed || mResponseCallback == null) {
             return;
         }
-        if (!mImeInputViewStarted && mPreviousResponseIsNotEmpty) {
-            // 1. if previous response is not empty, and IME just become invisible, then send
-            // empty response to make sure existing responses don't stick around on the IME.
+        if (!mImeInputStarted && mPreviousResponseIsNotEmpty) {
+            // 1. if previous response is not empty, and IME is just disconnected from the view,
+            // then send empty response to make sure existing responses don't stick around.
             // Although the inline suggestions should disappear when IME hides which removes them
-            // from the view hierarchy, but we still send an empty response to be extra safe.
-
+            // from the view hierarchy, but we still send an empty response to indicate that the
+            // previous suggestions are invalid now.
             if (sVerbose) Slog.v(TAG, "Send empty inline response");
             updateResponseToImeUncheckLocked(new InlineSuggestionsResponse(Collections.EMPTY_LIST));
             mPreviousResponseIsNotEmpty = false;
@@ -264,11 +251,6 @@
             }
             mImeRequestReceived = true;
 
-            if (mTimeoutCallback != null) {
-                if (sVerbose) Slog.v(TAG, "removing timeout callback");
-                mHandler.removeCallbacks(mTimeoutCallback);
-                mTimeoutCallback = null;
-            }
             if (request != null && callback != null) {
                 mImeRequest = request;
                 mResponseCallback = callback;
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index ef17d13..1d3ab9b 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2581,7 +2581,6 @@
                     if (sVerbose) Slog.v(TAG, "Exiting view " + id);
                     mUi.hideFillUi(this);
                     hideAugmentedAutofillLocked(viewState);
-                    mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
                     mCurrentViewId = null;
                 }
                 break;
@@ -2655,6 +2654,9 @@
                 if (sVerbose) {
                     Slog.v(TAG, "ignoring autofilled change on id " + id);
                 }
+                // TODO(b/156099633): remove this once framework gets out of business of resending
+                // inline suggestions when IME visibility changes.
+                mInlineSessionController.hideInlineSuggestionsUiLocked(viewState.id);
                 viewState.resetState(ViewState.STATE_CHANGED);
                 return;
             } else if ((viewState.id.equals(this.mCurrentViewId))
@@ -3348,7 +3350,9 @@
                 if (generateEvent) {
                     mService.logDatasetSelected(dataset.getId(), id, mClientState);
                 }
-
+                if (mCurrentViewId != null) {
+                    mInlineSessionController.hideInlineSuggestionsUiLocked(mCurrentViewId);
+                }
                 autoFillApp(dataset);
                 return;
             }
diff --git a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
index 089eeb2..c8485b7 100644
--- a/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
+++ b/services/autofill/java/com/android/server/autofill/ui/InlineSuggestionFactory.java
@@ -57,7 +57,6 @@
             @NonNull AutoFillUI.AutoFillUiCallback client, @NonNull Runnable onErrorCallback,
             @Nullable RemoteInlineSuggestionRenderService remoteRenderService) {
         final BiConsumer<Dataset, Integer> onClickFactory = (dataset, datasetIndex) -> {
-            client.requestHideFillUi(autofillId);
             client.authenticate(response.getRequestId(),
                     datasetIndex, response.getAuthentication(), response.getClientState(),
                     /* authenticateInline= */ true);
@@ -65,7 +64,8 @@
         final Consumer<IntentSender> intentSenderConsumer = (intentSender) ->
                 client.startIntentSender(intentSender, new Intent());
         InlinePresentation inlineAuthentication = response.getInlinePresentation();
-        return createInlineAuthSuggestion(inlineAuthentication,
+        return createInlineAuthSuggestion(
+                mergedInlinePresentation(request, 0, inlineAuthentication),
                 remoteRenderService, onClickFactory, onErrorCallback, intentSenderConsumer,
                 request.getHostInputToken(), request.getHostDisplayId());
     }
@@ -85,7 +85,6 @@
         final Consumer<IntentSender> intentSenderConsumer = (intentSender) ->
                 client.startIntentSender(intentSender, new Intent());
         final BiConsumer<Dataset, Integer> onClickFactory = (dataset, datasetIndex) -> {
-            client.requestHideFillUi(autofillId);
             client.fill(requestId, datasetIndex, dataset);
         };
 
diff --git a/services/core/Android.bp b/services/core/Android.bp
index cf85b1d..a95a0c2 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -97,7 +97,7 @@
         "android.hardware.power-V1.0-java",
         "android.hardware.tv.cec-V1.0-java",
         "android.hardware.vibrator-java",
-        "android.net.ipsec.ike.stubs.module_libs_api",
+        "android.net.ipsec.ike.stubs.module_lib",
         "app-compat-annotations",
         "framework-tethering-stubs-module_libs_api",
         "service-permission-stubs",
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2c63c6f..1197154 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2740,7 +2740,7 @@
                         // the Messenger, but if this ever changes, not making a defensive copy
                         // here will give attack vectors to clients using this code path.
                         networkCapabilities = new NetworkCapabilities(networkCapabilities);
-                        networkCapabilities.restrictCapabilitesForTestNetwork();
+                        networkCapabilities.restrictCapabilitesForTestNetwork(nai.creatorUid);
                     }
                     updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
                     break;
@@ -3087,10 +3087,6 @@
 
         @Override
         public void notifyDataStallSuspected(DataStallReportParcelable p) {
-            final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
-                    ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED,
-                    p.detectionMethod, mNetId, p.timestampMillis);
-
             final PersistableBundle extras = new PersistableBundle();
             switch (p.detectionMethod) {
                 case DETECTION_METHOD_DNS_EVENTS:
@@ -3105,12 +3101,9 @@
                     log("Unknown data stall detection method, ignoring: " + p.detectionMethod);
                     return;
             }
-            msg.setData(new Bundle(extras));
 
-            // NetworkStateTrackerHandler currently doesn't take any actions based on data
-            // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
-            // the cost of going through two handlers.
-            mConnectivityDiagnosticsHandler.sendMessage(msg);
+            proxyDataStallToConnectivityDiagnosticsHandler(
+                    p.detectionMethod, mNetId, p.timestampMillis, extras);
         }
 
         @Override
@@ -3124,6 +3117,19 @@
         }
     }
 
+    private void proxyDataStallToConnectivityDiagnosticsHandler(int detectionMethod, int netId,
+            long timestampMillis, @NonNull PersistableBundle extras) {
+        final Message msg = mConnectivityDiagnosticsHandler.obtainMessage(
+                    ConnectivityDiagnosticsHandler.EVENT_DATA_STALL_SUSPECTED,
+                    detectionMethod, netId, timestampMillis);
+        msg.setData(new Bundle(extras));
+
+        // NetworkStateTrackerHandler currently doesn't take any actions based on data
+        // stalls so send the message directly to ConnectivityDiagnosticsHandler and avoid
+        // the cost of going through two handlers.
+        mConnectivityDiagnosticsHandler.sendMessage(msg);
+    }
+
     private boolean networkRequiresPrivateDnsValidation(NetworkAgentInfo nai) {
         return isPrivateDnsValidationRequired(nai.networkCapabilities);
     }
@@ -5859,7 +5865,7 @@
             // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
             // sees capabilities that may be malicious, which might prevent mistakes in the future.
             networkCapabilities = new NetworkCapabilities(networkCapabilities);
-            networkCapabilities.restrictCapabilitesForTestNetwork();
+            networkCapabilities.restrictCapabilitesForTestNetwork(Binder.getCallingUid());
         } else {
             enforceNetworkFactoryPermission();
         }
@@ -5872,7 +5878,7 @@
         final NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(),
                 new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
                 currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
-                this, mNetd, mDnsResolver, mNMS, providerId);
+                this, mNetd, mDnsResolver, mNMS, providerId, Binder.getCallingUid());
 
         // Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
         nai.getAndSetNetworkCapabilities(mixInCapabilities(nai, nc));
@@ -5973,7 +5979,8 @@
             // Start or stop DNS64 detection and 464xlat according to network state.
             networkAgent.clatd.update();
             notifyIfacesChangedForNetworkStats();
-            networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
+            networkAgent.networkMonitor().notifyLinkPropertiesChanged(
+                    new LinkProperties(newLp, true /* parcelSensitiveFields */));
             if (networkAgent.everConnected) {
                 notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
             }
@@ -7153,7 +7160,9 @@
                 networkAgent.networkMonitor().setAcceptPartialConnectivity();
             }
             networkAgent.networkMonitor().notifyNetworkConnected(
-                    networkAgent.linkProperties, networkAgent.networkCapabilities);
+                    new LinkProperties(networkAgent.linkProperties,
+                            true /* parcelSensitiveFields */),
+                    networkAgent.networkCapabilities);
             scheduleUnvalidatedPrompt(networkAgent);
 
             // Whether a particular NetworkRequest listen should cause signal strength thresholds to
@@ -8151,4 +8160,24 @@
                         0,
                         callback));
     }
+
+    @Override
+    public void simulateDataStall(int detectionMethod, long timestampMillis,
+            @NonNull Network network, @NonNull PersistableBundle extras) {
+        enforceAnyPermissionOf(android.Manifest.permission.MANAGE_TEST_NETWORKS,
+                android.Manifest.permission.NETWORK_STACK);
+        final NetworkCapabilities nc = getNetworkCapabilitiesInternal(network);
+        if (!nc.hasTransport(TRANSPORT_TEST)) {
+            throw new SecurityException("Data Stall simluation is only possible for test networks");
+        }
+
+        final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+        if (nai == null || nai.creatorUid != Binder.getCallingUid()) {
+            throw new SecurityException("Data Stall simulation is only possible for network "
+                + "creators");
+        }
+
+        proxyDataStallToConnectivityDiagnosticsHandler(
+                detectionMethod, network.netId, timestampMillis, extras);
+    }
 }
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 43ed853..e2a0c29 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -121,6 +121,7 @@
 import android.os.storage.VolumeInfo;
 import android.os.storage.VolumeRecord;
 import android.provider.DeviceConfig;
+import android.provider.DocumentsContract;
 import android.provider.Downloads;
 import android.provider.MediaStore;
 import android.provider.Settings;
@@ -432,6 +433,8 @@
 
     private volatile int mDownloadsAuthorityAppId = -1;
 
+    private volatile int mExternalStorageAuthorityAppId = -1;
+
     private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
 
     private final Installer mInstaller;
@@ -1923,24 +1926,22 @@
         mIAppOpsService = IAppOpsService.Stub.asInterface(
                 ServiceManager.getService(Context.APP_OPS_SERVICE));
 
-        ProviderInfo provider = mPmInternal.resolveContentProvider(
-                MediaStore.AUTHORITY, PackageManager.MATCH_DIRECT_BOOT_AWARE
-                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                UserHandle.getUserId(UserHandle.USER_SYSTEM));
+        ProviderInfo provider = getProviderInfo(MediaStore.AUTHORITY);
         if (provider != null) {
             mMediaStoreAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
             sMediaStoreAuthorityProcessName = provider.applicationInfo.processName;
         }
 
-        provider = mPmInternal.resolveContentProvider(
-                Downloads.Impl.AUTHORITY, PackageManager.MATCH_DIRECT_BOOT_AWARE
-                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                UserHandle.getUserId(UserHandle.USER_SYSTEM));
-
+        provider = getProviderInfo(Downloads.Impl.AUTHORITY);
         if (provider != null) {
             mDownloadsAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
         }
 
+        provider = getProviderInfo(DocumentsContract.EXTERNAL_STORAGE_PROVIDER_AUTHORITY);
+        if (provider != null) {
+            mExternalStorageAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
+        }
+
         if (!mIsFuseEnabled) {
             try {
                 mIAppOpsService.startWatchingMode(OP_REQUEST_INSTALL_PACKAGES, null,
@@ -1951,6 +1952,13 @@
         }
     }
 
+    private ProviderInfo getProviderInfo(String authority) {
+        return mPmInternal.resolveContentProvider(
+                authority, PackageManager.MATCH_DIRECT_BOOT_AWARE
+                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+                UserHandle.getUserId(UserHandle.USER_SYSTEM));
+    }
+
     private void updateLegacyStorageApps(String packageName, int uid, boolean hasLegacy) {
         synchronized (mLock) {
             if (hasLegacy) {
@@ -4191,9 +4199,11 @@
                 return Zygote.MOUNT_EXTERNAL_PASS_THROUGH;
             }
 
-            if (mIsFuseEnabled && mDownloadsAuthorityAppId == UserHandle.getAppId(uid)) {
+            if (mIsFuseEnabled && (mDownloadsAuthorityAppId == UserHandle.getAppId(uid)
+                    || mExternalStorageAuthorityAppId == UserHandle.getAppId(uid))) {
                 // DownloadManager can write in app-private directories on behalf of apps;
                 // give it write access to Android/
+                // ExternalStorageProvider can access Android/{data,obb} dirs in managed mode
                 return Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE;
             }
 
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index 0ea7346..d6bd5a1 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -317,39 +317,34 @@
                     "Cannot create network for non ipsec, non-testtun interface");
         }
 
-        // Setup needs to be done with NETWORK_STACK privileges.
-        int callingUid = Binder.getCallingUid();
-        Binder.withCleanCallingIdentity(
-                () -> {
-                    try {
-                        mNMS.setInterfaceUp(iface);
+        try {
+            // This requires NETWORK_STACK privileges.
+            Binder.withCleanCallingIdentity(() -> mNMS.setInterfaceUp(iface));
 
-                        // Synchronize all accesses to mTestNetworkTracker to prevent the case
-                        // where:
-                        // 1. TestNetworkAgent successfully binds to death of binder
-                        // 2. Before it is added to the mTestNetworkTracker, binder dies,
-                        // binderDied() is called (on a different thread)
-                        // 3. This thread is pre-empted, put() is called after remove()
-                        synchronized (mTestNetworkTracker) {
-                            TestNetworkAgent agent =
-                                    registerTestNetworkAgent(
-                                            mHandler.getLooper(),
-                                            mContext,
-                                            iface,
-                                            lp,
-                                            isMetered,
-                                            callingUid,
-                                            administratorUids,
-                                            binder);
+            // Synchronize all accesses to mTestNetworkTracker to prevent the case where:
+            // 1. TestNetworkAgent successfully binds to death of binder
+            // 2. Before it is added to the mTestNetworkTracker, binder dies, binderDied() is called
+            // (on a different thread)
+            // 3. This thread is pre-empted, put() is called after remove()
+            synchronized (mTestNetworkTracker) {
+                TestNetworkAgent agent =
+                        registerTestNetworkAgent(
+                                mHandler.getLooper(),
+                                mContext,
+                                iface,
+                                lp,
+                                isMetered,
+                                Binder.getCallingUid(),
+                                administratorUids,
+                                binder);
 
-                            mTestNetworkTracker.put(agent.getNetwork().netId, agent);
-                        }
-                    } catch (SocketException e) {
-                        throw new UncheckedIOException(e);
-                    } catch (RemoteException e) {
-                        throw e.rethrowFromSystemServer();
-                    }
-                });
+                mTestNetworkTracker.put(agent.getNetwork().netId, agent);
+            }
+        } catch (SocketException e) {
+            throw new UncheckedIOException(e);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /** Teardown a test network */
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d914bda..2b86d7f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -11083,18 +11083,22 @@
 
     void dumpLruEntryLocked(PrintWriter pw, int index, ProcessRecord proc, String prefix) {
         pw.print(prefix);
-        pw.print("#");
+        pw.print('#');
+        if (index < 10) {
+            pw.print(' ');
+        }
         pw.print(index);
         pw.print(": ");
         pw.print(ProcessList.makeOomAdjString(proc.setAdj, false));
-        pw.print(" ");
+        pw.print(' ');
         pw.print(ProcessList.makeProcStateString(proc.getCurProcState()));
-        pw.print(" ");
+        pw.print(' ');
+        ActivityManager.printCapabilitiesSummary(pw, proc.curCapability);
+        pw.print(' ');
         pw.print(proc.toShortString());
-        pw.print(" ");
         if (proc.hasActivitiesOrRecentTasks() || proc.hasClientActivities()
                 || proc.treatLikeActivity) {
-            pw.print(" activity=");
+            pw.print(" act:");
             boolean printed = false;
             if (proc.hasActivities()) {
                 pw.print("activities");
@@ -12559,7 +12563,7 @@
             char schedGroup;
             switch (r.setSchedGroup) {
                 case ProcessList.SCHED_GROUP_BACKGROUND:
-                    schedGroup = 'B';
+                    schedGroup = 'b';
                     break;
                 case ProcessList.SCHED_GROUP_DEFAULT:
                     schedGroup = 'F';
@@ -12570,6 +12574,9 @@
                 case ProcessList.SCHED_GROUP_RESTRICTED:
                     schedGroup = 'R';
                     break;
+                case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
+                    schedGroup = 'B';
+                    break;
                 default:
                     schedGroup = '?';
                     break;
@@ -12597,7 +12604,10 @@
             pw.print(foreground);
             pw.print('/');
             pw.print(procState);
-            pw.print(" trm:");
+            pw.print(' ');
+            ActivityManager.printCapabilitiesSummary(pw, r.curCapability);
+            pw.print(' ');
+            pw.print(" t:");
             if (r.trimMemoryLevel < 10) pw.print(' ');
             pw.print(r.trimMemoryLevel);
             pw.print(' ');
@@ -13597,7 +13607,9 @@
                         pw.print(" unmapped + ");
                         pw.print(stringifyKBSize(ionPool));
                         pw.println(" pools)");
-                kernelUsed += ionUnmapped;
+                // Note: mapped ION memory is not accounted in PSS due to VM_PFNMAP flag being
+                // set on ION VMAs, therefore consider the entire ION heap as used kernel memory
+                kernelUsed += ionHeap;
             }
             final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
@@ -14403,7 +14415,9 @@
             memInfoBuilder.append("       ION: ");
             memInfoBuilder.append(stringifyKBSize(ionHeap + ionPool));
             memInfoBuilder.append("\n");
-            kernelUsed += ionUnmapped;
+            // Note: mapped ION memory is not accounted in PSS due to VM_PFNMAP flag being
+            // set on ION VMAs, therefore consider the entire ION heap as used kernel memory
+            kernelUsed += ionHeap;
         }
         memInfoBuilder.append("  Used RAM: ");
         memInfoBuilder.append(stringifyKBSize(
diff --git a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java b/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
deleted file mode 100644
index 0e34801..0000000
--- a/services/core/java/com/android/server/am/CarUserSwitchingDialog.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.am;
-
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowInsets;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.internal.R;
-
-
-/**
- * Dialog to show when a user switch it about to happen for the car. The intent is to snapshot the
- * screen immediately after the dialog shows so that the user is informed that something is
- * happening in the background rather than just freeze the screen and not know if the user-switch
- * affordance was being handled.
- */
-final class CarUserSwitchingDialog extends UserSwitchingDialog {
-
-    private static final String TAG = "ActivityManagerCarUserSwitchingDialog";
-    private View mView;
-
-    public CarUserSwitchingDialog(ActivityManagerService service, Context context, UserInfo oldUser,
-            UserInfo newUser, boolean aboveSystem, String switchingFromSystemUserMessage,
-            String switchingToSystemUserMessage) {
-        super(service, context, oldUser, newUser, aboveSystem, switchingFromSystemUserMessage,
-                switchingToSystemUserMessage);
-    }
-
-    @Override
-    void inflateContent() {
-        // Set up the dialog contents
-        setCancelable(false);
-        Resources res = getContext().getResources();
-        // Custom view due to alignment and font size requirements
-        getContext().setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert_UserSwitchingDialog);
-        mView = LayoutInflater.from(getContext()).inflate(
-                R.layout.car_user_switching_dialog,
-                null);
-
-        UserManager userManager =
-                (UserManager) getContext().getSystemService(Context.USER_SERVICE);
-        Bitmap bitmap = userManager.getUserIcon(mNewUser.id);
-        if (bitmap != null) {
-            CircleFramedDrawable drawable = CircleFramedDrawable.getInstance(bitmap,
-                    res.getDimension(R.dimen.car_fullscreen_user_pod_image_avatar_height));
-            ((ImageView) mView.findViewById(R.id.user_loading_avatar))
-                    .setImageDrawable(drawable);
-        }
-
-        TextView msgView = mView.findViewById(R.id.user_loading);
-
-        // TODO(b/145132885): use constant from CarSettings
-        boolean showInfo = "true".equals(Settings.Global.getString(
-                getContext().getContentResolver(),
-                "android.car.ENABLE_USER_SWITCH_DEVELOPER_MESSAGE"));
-
-        if (showInfo) {
-            msgView.setText(res.getString(R.string.car_loading_profile) + " user\n(from "
-                    + mOldUser.id + " to " + mNewUser.id + ")");
-        } else {
-            msgView.setText(res.getString(R.string.car_loading_profile));
-        }
-        setView(mView);
-    }
-
-    @Override
-    public void show() {
-        super.show();
-        hideNavigationBar();
-    }
-
-    private void hideNavigationBar() {
-        mView.getWindowInsetsController().hide(WindowInsets.Type.navigationBars());
-    }
-
-    /**
-     * Converts the user icon to a circularly clipped one.  This is used in the User Picker and
-     * Settings.
-     */
-    static class CircleFramedDrawable extends Drawable {
-
-        private final Bitmap mBitmap;
-        private final int mSize;
-        private final Paint mPaint;
-
-        private float mScale;
-        private Rect mSrcRect;
-        private RectF mDstRect;
-
-        public static CircleFramedDrawable getInstance(Bitmap icon, float iconSize) {
-            CircleFramedDrawable instance = new CircleFramedDrawable(icon, (int) iconSize);
-            return instance;
-        }
-
-        public CircleFramedDrawable(Bitmap icon, int size) {
-            super();
-            mSize = size;
-
-            mBitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
-            final Canvas canvas = new Canvas(mBitmap);
-
-            final int width = icon.getWidth();
-            final int height = icon.getHeight();
-            final int square = Math.min(width, height);
-
-            final Rect cropRect = new Rect((width - square) / 2, (height - square) / 2,
-                    square, square);
-            final RectF circleRect = new RectF(0f, 0f, mSize, mSize);
-
-            final Path fillPath = new Path();
-            fillPath.addArc(circleRect, 0f, 360f);
-
-            canvas.drawColor(0, PorterDuff.Mode.CLEAR);
-
-            // opaque circle
-            mPaint = new Paint();
-            mPaint.setAntiAlias(true);
-            mPaint.setColor(Color.BLACK);
-            mPaint.setStyle(Paint.Style.FILL);
-            canvas.drawPath(fillPath, mPaint);
-
-            // mask in the icon where the bitmap is opaque
-            mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
-            canvas.drawBitmap(icon, cropRect, circleRect, mPaint);
-
-            // prepare paint for frame drawing
-            mPaint.setXfermode(null);
-
-            mScale = 1f;
-
-            mSrcRect = new Rect(0, 0, mSize, mSize);
-            mDstRect = new RectF(0, 0, mSize, mSize);
-        }
-
-        @Override
-        public void draw(Canvas canvas) {
-            final float inside = mScale * mSize;
-            final float pad = (mSize - inside) / 2f;
-
-            mDstRect.set(pad, pad, mSize - pad, mSize - pad);
-            canvas.drawBitmap(mBitmap, mSrcRect, mDstRect, null);
-        }
-
-        @Override
-        public int getOpacity() {
-            return PixelFormat.TRANSLUCENT;
-        }
-
-        @Override
-        public void setAlpha(int alpha) {
-            // Needed to implement abstract method.  Do nothing.
-        }
-
-        @Override
-        public void setColorFilter(ColorFilter colorFilter) {
-            // Needed to implement abstract method.  Do nothing.
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index ad85853..c13bb5a 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -151,15 +151,6 @@
     @EnabledAfter(targetSdkVersion=android.os.Build.VERSION_CODES.Q)
     static final long CAMERA_MICROPHONE_CAPABILITY_CHANGE_ID = 136219221L;
 
-    // TODO: remove this when development is done.
-    // These are debug flags used between OomAdjuster and AppOpsService to detect and report absence
-    // of the real flags.
-    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q = 1 << 27;
-    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q = 1 << 28;
-    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE = 1 << 29;
-    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA = 1 << 30;
-    public static final int DEBUG_PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1 << 31;
-
     /**
      * For some direct access we need to power manager.
      */
@@ -1506,8 +1497,9 @@
                     //lost the capability, use temp location capability to mark this case.
                     //TODO: remove this block when development is done.
                     capabilityFromFGS |=
-                            (fgsType & FOREGROUND_SERVICE_TYPE_LOCATION)
-                                    != 0 ? DEBUG_PROCESS_CAPABILITY_FOREGROUND_LOCATION : 0;
+                            (fgsType & FOREGROUND_SERVICE_TYPE_LOCATION) != 0
+                                    ? ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_LOCATION
+                                    : 0;
                 }
                 if (s.mAllowWhileInUsePermissionInFgs) {
                     boolean enabled = false;
@@ -1520,22 +1512,22 @@
                         capabilityFromFGS |=
                                 (fgsType & FOREGROUND_SERVICE_TYPE_CAMERA)
                                         != 0 ? PROCESS_CAPABILITY_FOREGROUND_CAMERA
-                                        : DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA;
+                                        : ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA;
                         capabilityFromFGS |=
                                 (fgsType & FOREGROUND_SERVICE_TYPE_MICROPHONE)
                                         != 0 ? PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
-                                        : DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+                                        : ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
                     } else {
                         // Remove fgsType check and assign PROCESS_CAPABILITY_FOREGROUND_CAMERA
                         // and MICROPHONE when finish debugging.
                         capabilityFromFGS |=
                                 (fgsType & FOREGROUND_SERVICE_TYPE_CAMERA)
                                         != 0 ? PROCESS_CAPABILITY_FOREGROUND_CAMERA
-                                        : DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q;
+                                        : ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q;
                         capabilityFromFGS |=
                                 (fgsType & FOREGROUND_SERVICE_TYPE_MICROPHONE)
                                         != 0 ? PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
-                                        : DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q;
+                                        : ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q;
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index b753de9..108fb7d 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -972,7 +972,7 @@
             return buildOomTag("vis", "vis", "   ", setAdj,
                     ProcessList.VISIBLE_APP_ADJ, compact);
         } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
-            return buildOomTag("fore  ", "fore", null, setAdj,
+            return buildOomTag("fg ", "fg ", "   ", setAdj,
                     ProcessList.FOREGROUND_APP_ADJ, compact);
         } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) {
             return buildOomTag("psvc  ", "psvc", null, setAdj,
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index fc6931d..c5152c0 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -431,16 +431,46 @@
                 pw.print(" nextPssTime=");
                 TimeUtils.formatDuration(nextPssTime, nowUptime, pw);
                 pw.println();
-        pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
-                pw.print(" lruSeq="); pw.print(lruSeq);
-                pw.print(" lastPss="); DebugUtils.printSizeValue(pw, lastPss*1024);
-                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, lastSwapPss*1024);
-                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, lastCachedPss*1024);
-                pw.print(" lastCachedSwapPss="); DebugUtils.printSizeValue(pw, lastCachedSwapPss*1024);
-        pw.print(" lastRss="); DebugUtils.printSizeValue(pw, mLastRss * 1024);
+        pw.print(prefix); pw.print("lastPss="); DebugUtils.printSizeValue(pw, lastPss * 1024);
+                pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, lastSwapPss * 1024);
+                pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, lastCachedPss * 1024);
+                pw.print(" lastCachedSwapPss="); DebugUtils.printSizeValue(pw,
+                        lastCachedSwapPss * 1024);
+                pw.print(" lastRss="); DebugUtils.printSizeValue(pw, mLastRss * 1024);
                 pw.println();
         pw.print(prefix); pw.print("procStateMemTracker: ");
         procStateMemTracker.dumpLine(pw);
+        pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
+                pw.print(" lruSeq="); pw.println(lruSeq);
+        pw.print(prefix); pw.print("oom adj: max="); pw.print(maxAdj);
+                pw.print(" curRaw="); pw.print(mCurRawAdj);
+                pw.print(" setRaw="); pw.print(setRawAdj);
+                pw.print(" cur="); pw.print(curAdj);
+                pw.print(" set="); pw.println(setAdj);
+        pw.print(prefix); pw.print("lastCompactTime="); pw.print(lastCompactTime);
+                pw.print(" lastCompactAction="); pw.println(lastCompactAction);
+        pw.print(prefix); pw.print("mCurSchedGroup="); pw.print(mCurSchedGroup);
+                pw.print(" setSchedGroup="); pw.print(setSchedGroup);
+                pw.print(" systemNoUi="); pw.print(systemNoUi);
+                pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
+        pw.print(prefix); pw.print("curProcState="); pw.print(getCurProcState());
+                pw.print(" mRepProcState="); pw.print(mRepProcState);
+                pw.print(" pssProcState="); pw.print(pssProcState);
+                pw.print(" setProcState="); pw.print(setProcState);
+                pw.print(" lastStateTime=");
+                TimeUtils.formatDuration(lastStateTime, nowUptime, pw);
+                pw.println();
+        pw.print(prefix); pw.print("curCapability=");
+                ActivityManager.printCapabilitiesFull(pw, curCapability);
+                pw.print(" setCapability=");
+                ActivityManager.printCapabilitiesFull(pw, setCapability);
+                pw.println();
+        if (hasShownUi || mPendingUiClean || hasAboveClient || treatLikeActivity) {
+            pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
+                    pw.print(" pendingUiClean="); pw.print(mPendingUiClean);
+                    pw.print(" hasAboveClient="); pw.print(hasAboveClient);
+                    pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
+        }
         pw.print(prefix); pw.print("cached="); pw.print(mCached);
                 pw.print(" empty="); pw.println(empty);
         if (serviceb) {
@@ -451,32 +481,6 @@
             pw.print(prefix); pw.print("notCachedSinceIdle="); pw.print(notCachedSinceIdle);
                     pw.print(" initialIdlePss="); pw.println(initialIdlePss);
         }
-        pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
-                pw.print(" curRaw="); pw.print(mCurRawAdj);
-                pw.print(" setRaw="); pw.print(setRawAdj);
-                pw.print(" cur="); pw.print(curAdj);
-                pw.print(" set="); pw.println(setAdj);
-        pw.print(prefix); pw.print("lastCompactTime="); pw.print(lastCompactTime);
-                pw.print(" lastCompactAction="); pw.print(lastCompactAction);
-        pw.print(prefix); pw.print("mCurSchedGroup="); pw.print(mCurSchedGroup);
-                pw.print(" setSchedGroup="); pw.print(setSchedGroup);
-                pw.print(" systemNoUi="); pw.print(systemNoUi);
-                pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
-        pw.print(prefix); pw.print("curProcState="); pw.print(getCurProcState());
-                pw.print(" mRepProcState="); pw.print(mRepProcState);
-                pw.print(" pssProcState="); pw.print(pssProcState);
-                pw.print(" setProcState="); pw.print(setProcState);
-                pw.print(" curCapability="); pw.print(curCapability);
-                pw.print(" setCapability="); pw.print(setCapability);
-                pw.print(" lastStateTime=");
-                TimeUtils.formatDuration(lastStateTime, nowUptime, pw);
-                pw.println();
-        if (hasShownUi || mPendingUiClean || hasAboveClient || treatLikeActivity) {
-            pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
-                    pw.print(" pendingUiClean="); pw.print(mPendingUiClean);
-                    pw.print(" hasAboveClient="); pw.print(hasAboveClient);
-                    pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
-        }
         if (connectionService != null || connectionGroup != 0) {
             pw.print(prefix); pw.print("connectionGroup="); pw.print(connectionGroup);
             pw.print(" Importance="); pw.print(connectionImportance);
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 5b12933..fac4a1e 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -2736,19 +2736,13 @@
 
         void showUserSwitchingDialog(UserInfo fromUser, UserInfo toUser,
                 String switchingFromSystemUserMessage, String switchingToSystemUserMessage) {
-            Dialog d;
             if (!mService.mContext.getPackageManager()
                     .hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
-                d = new UserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
-                    true /* above system */, switchingFromSystemUserMessage,
-                    switchingToSystemUserMessage);
-            } else {
-                d = new CarUserSwitchingDialog(mService, mService.mContext, fromUser, toUser,
-                    true /* above system */, switchingFromSystemUserMessage,
-                    switchingToSystemUserMessage);
+                final Dialog d = new UserSwitchingDialog(mService, mService.mContext, fromUser,
+                        toUser, true /* above system */, switchingFromSystemUserMessage,
+                        switchingToSystemUserMessage);
+                d.show();
             }
-
-            d.show();
         }
 
         void reportGlobalUsageEventLocked(int event) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 5ebfb00..ae38e81 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -66,11 +66,11 @@
 import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
 import static android.content.pm.PermissionInfo.PROTECTION_FLAG_APPOP;
 
-import static com.android.server.am.OomAdjuster.DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA;
-import static com.android.server.am.OomAdjuster.DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q;
-import static com.android.server.am.OomAdjuster.DEBUG_PROCESS_CAPABILITY_FOREGROUND_LOCATION;
-import static com.android.server.am.OomAdjuster.DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
-import static com.android.server.am.OomAdjuster.DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q;
+import static android.app.ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA;
+import static android.app.ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_CAMERA_Q;
+import static android.app.ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_LOCATION;
+import static android.app.ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
+import static android.app.ActivityManager.DEBUG_PROCESS_CAPABILITY_FOREGROUND_MICROPHONE_Q;
 import static com.android.server.appop.AppOpsService.ModeCallback.ALL_OPS;
 
 import static java.lang.Long.max;
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index befd6b1..3ee3d50 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -286,6 +286,13 @@
         final BtDeviceConnectionInfo info = new BtDeviceConnectionInfo(device, state, profile,
                 suppressNoisyIntent, a2dpVolume);
 
+        new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE + MediaMetrics.SEPARATOR
+                + "postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent")
+                .set(MediaMetrics.Property.STATE, state == BluetoothProfile.STATE_CONNECTED
+                        ? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
+                .set(MediaMetrics.Property.INDEX, a2dpVolume)
+                .record();
+
         // operations of removing and posting messages related to A2DP device state change must be
         // mutually exclusive
         synchronized (mDeviceStateLock) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 8068e37..e5a7daf 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -52,7 +52,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
@@ -570,6 +569,10 @@
     private int[] mAccessibilityServiceUids;
     private final Object mAccessibilityServiceUidsLock = new Object();
 
+    // Uid of the active input method service to check if caller is the one or not.
+    private int mInputMethodServiceUid = android.os.Process.INVALID_UID;
+    private final Object mInputMethodServiceUidLock = new Object();
+
     private int mEncodedSurroundMode;
     private String mEnabledSurroundFormats;
     private boolean mSurroundModeChanged;
@@ -1078,12 +1081,14 @@
             sendEncodedSurroundMode(mContentResolver, "onAudioServerDied");
             sendEnabledSurroundFormats(mContentResolver, true);
             updateAssistantUId(true);
-            updateCurrentImeUid(true);
             AudioSystem.setRttEnabled(mRttEnabled);
         }
         synchronized (mAccessibilityServiceUidsLock) {
             AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
         }
+        synchronized (mInputMethodServiceUidLock) {
+            mAudioSystem.setCurrentImeUid(mInputMethodServiceUid);
+        }
         synchronized (mHdmiClientLock) {
             if (mHdmiManager != null && mHdmiTvClient != null) {
                 setHdmiSystemAudioSupported(mHdmiSystemAudioSupported);
@@ -1629,37 +1634,6 @@
         }
     }
 
-    @GuardedBy("mSettingsLock")
-    private void updateCurrentImeUid(boolean forceUpdate) {
-        String imeId = Settings.Secure.getStringForUser(
-                mContentResolver,
-                Settings.Secure.DEFAULT_INPUT_METHOD, UserHandle.USER_CURRENT);
-        if (TextUtils.isEmpty(imeId)) {
-            Log.e(TAG, "updateCurrentImeUid() could not find current IME");
-            return;
-        }
-        ComponentName componentName = ComponentName.unflattenFromString(imeId);
-        if (componentName == null) {
-            Log.e(TAG, "updateCurrentImeUid() got invalid service name for "
-                    + Settings.Secure.DEFAULT_INPUT_METHOD + ": " + imeId);
-            return;
-        }
-        String packageName = componentName.getPackageName();
-        int currentUserId = LocalServices.getService(ActivityManagerInternal.class)
-                .getCurrentUserId();
-        int currentImeUid = LocalServices.getService(PackageManagerInternal.class)
-                .getPackageUidInternal(packageName, 0 /* flags */, currentUserId);
-        if (currentImeUid < 0) {
-            Log.e(TAG, "updateCurrentImeUid() could not find UID for package: " + packageName);
-            return;
-        }
-
-        if (currentImeUid != mCurrentImeUid || forceUpdate) {
-            mAudioSystem.setCurrentImeUid(currentImeUid);
-            mCurrentImeUid = currentImeUid;
-        }
-    }
-
     private void readPersistedSettings() {
         if (!mSystemServer.isPrivileged()) {
             return;
@@ -1707,7 +1681,6 @@
             sendEncodedSurroundMode(cr, "readPersistedSettings");
             sendEnabledSurroundFormats(cr, true);
             updateAssistantUId(true);
-            updateCurrentImeUid(true);
             AudioSystem.setRttEnabled(mRttEnabled);
         }
 
@@ -6217,8 +6190,6 @@
 
             mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.VOICE_INTERACTION_SERVICE), false, this);
-            mContentResolver.registerContentObserver(Settings.Secure.getUriFor(
-                    Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
         }
 
         @Override
@@ -6242,7 +6213,6 @@
                 updateEncodedSurroundOutput();
                 sendEnabledSurroundFormats(mContentResolver, mSurroundModeChanged);
                 updateAssistantUId(false);
-                updateCurrentImeUid(false);
             }
         }
 
@@ -7584,6 +7554,19 @@
                 AudioSystem.setA11yServicesUids(mAccessibilityServiceUids);
             }
         }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void setInputMethodServiceUid(int uid) {
+            synchronized (mInputMethodServiceUidLock) {
+                if (mInputMethodServiceUid != uid) {
+                    mAudioSystem.setCurrentImeUid(uid);
+                    mInputMethodServiceUid = uid;
+                }
+            }
+        }
     }
 
     //==========================================================================================
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 9e7b428..b6ffcef 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -358,14 +358,11 @@
      * @return false if SCO isn't connected
      */
     /*package*/ synchronized boolean isBluetoothScoOn() {
-        if ((mBluetoothHeadset != null)
-                && (mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
-                != BluetoothHeadset.STATE_AUDIO_CONNECTED)) {
-            Log.w(TAG, "isBluetoothScoOn(true) returning false because "
-                    + mBluetoothHeadsetDevice + " is not in audio connected mode");
+        if (mBluetoothHeadset == null) {
             return false;
         }
-        return true;
+        return mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
+                == BluetoothHeadset.STATE_AUDIO_CONNECTED;
     }
 
     /**
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index 808f8c21..5a6ab4e5 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -978,6 +978,10 @@
     }
 
     protected void addLockoutResetCallback(IBiometricServiceLockoutResetCallback callback) {
+        if (callback == null) {
+            Slog.w(getTag(), "Null LockoutResetCallback");
+            return;
+        }
         mHandler.post(() -> {
            final LockoutResetMonitor monitor = new LockoutResetMonitor(callback);
            if (!mLockoutMonitors.contains(monitor)) {
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index 8520f5a..d90f3af 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -330,6 +330,7 @@
         @Override
         public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback)
                 throws RemoteException {
+            checkPermission(USE_BIOMETRIC_INTERNAL);
             FingerprintService.super.addLockoutResetCallback(callback);
         }
 
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 15628f0..37b2de1 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -168,6 +168,9 @@
     // Obtained by ConnectivityService and merged into NetworkAgent-provided information.
     public CaptivePortalData captivePortalData;
 
+    // The UID of the remote entity that created this Network.
+    public final int creatorUid;
+
     // Networks are lingered when they become unneeded as a result of their NetworkRequests being
     // satisfied by a higher-scoring network. so as to allow communication to wrap up before the
     // network is taken down.  This usually only happens to the default network. Lingering ends with
@@ -268,7 +271,8 @@
     public NetworkAgentInfo(Messenger messenger, AsyncChannel ac, Network net, NetworkInfo info,
             LinkProperties lp, NetworkCapabilities nc, int score, Context context,
             Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
-            IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber) {
+            IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber,
+            int creatorUid) {
         this.messenger = messenger;
         asyncChannel = ac;
         network = net;
@@ -282,6 +286,7 @@
         mHandler = handler;
         networkAgentConfig = config;
         this.factorySerialNumber = factorySerialNumber;
+        this.creatorUid = creatorUid;
     }
 
     /**
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 5541b11..1810963 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -44,9 +44,6 @@
 public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
     private static final String TAG = "HdmiCecLocalDevicePlayback";
 
-    private static final boolean WAKE_ON_HOTPLUG =
-            SystemProperties.getBoolean(Constants.PROPERTY_WAKE_ON_HOTPLUG, false);
-
     private static final boolean SET_MENU_LANGUAGE =
             HdmiProperties.set_menu_language().orElse(false);
 
@@ -152,9 +149,6 @@
         assertRunOnServiceThread();
         mCecMessageCache.flushAll();
         // We'll not clear mIsActiveSource on the hotplug event to pass CETC 11.2.2-2 ~ 3.
-        if (WAKE_ON_HOTPLUG && connected && mService.isPowerStandbyOrTransient()) {
-            mService.wakeUp();
-        }
         if (!connected) {
             getWakeLock().release();
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 1ed5cd8..549e336 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -2207,7 +2207,9 @@
         @Override
         public void setHdmiCecVolumeControlEnabled(final boolean isHdmiCecVolumeControlEnabled) {
             enforceAccessPermission();
+            long token = Binder.clearCallingIdentity();
             HdmiControlService.this.setHdmiCecVolumeControlEnabled(isHdmiCecVolumeControlEnabled);
+            Binder.restoreCallingIdentity(token);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index d49d4b2..de13bd8 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -45,6 +45,12 @@
     }
 
     /**
+     * Called by the power manager to tell the input method manager whether it
+     * should start watching for wake events.
+     */
+    public abstract void setInteractive(boolean interactive);
+
+    /**
      * Hides the current input method, if visible.
      */
     public abstract void hideCurrentInputMethod(@SoftInputShowHideReason int reason);
@@ -108,6 +114,10 @@
     private static final InputMethodManagerInternal NOP =
             new InputMethodManagerInternal() {
                 @Override
+                public void setInteractive(boolean interactive) {
+                }
+
+                @Override
                 public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) {
                 }
 
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index b949d6b..52116a0 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -56,6 +56,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.Configuration;
@@ -67,6 +68,7 @@
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.input.InputManagerInternal;
 import android.inputmethodservice.InputMethodService;
+import android.media.AudioManagerInternal;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -223,6 +225,8 @@
 
     static final int MSG_INLINE_SUGGESTIONS_REQUEST = 6000;
 
+    static final int MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE = 7000;
+
     static final long TIME_TO_RECONNECT = 3 * 1000;
 
     static final int SECURE_SUGGESTION_SPANS_MAX_SIZE = 20;
@@ -308,6 +312,7 @@
     final SettingsObserver mSettingsObserver;
     final IWindowManager mIWindowManager;
     final WindowManagerInternal mWindowManagerInternal;
+    final PackageManagerInternal mPackageManagerInternal;
     final InputManagerInternal mInputManagerInternal;
     private final DisplayManagerInternal mDisplayManagerInternal;
     final HandlerCaller mCaller;
@@ -320,6 +325,16 @@
     private final UserManager mUserManager;
     private final UserManagerInternal mUserManagerInternal;
 
+    /**
+     * Cache the result of {@code LocalServices.getService(AudioManagerInternal.class)}.
+     *
+     * <p>This field is used only within {@link #handleMessage(Message)} hence synchronization is
+     * not necessary.</p>
+     */
+    @Nullable
+    private AudioManagerInternal mAudioManagerInternal = null;
+
+
     // All known input methods.  mMethodMap also serves as the global
     // lock for this class.
     final ArrayList<InputMethodInfo> mMethodList = new ArrayList<>();
@@ -643,6 +658,11 @@
     IInputMethod mCurMethod;
 
     /**
+     * If not {@link Process#INVALID_UID}, then the UID of {@link #mCurIntent}.
+     */
+    int mCurMethodUid = Process.INVALID_UID;
+
+    /**
      * Time that we last initiated a bind to the input method, to determine
      * if we should try to disconnect and reconnect to it.
      */
@@ -1625,6 +1645,7 @@
         mIWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
         mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
         mImeDisplayValidator = displayId -> mWindowManagerInternal.shouldShowIme(displayId);
@@ -2521,11 +2542,26 @@
         return checker.displayCanShowIme(displayId) ? displayId : FALLBACK_DISPLAY_ID;
     }
 
+    @AnyThread
+    private void scheduleNotifyImeUidToAudioService(int uid) {
+        mCaller.removeMessages(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE);
+        mCaller.obtainMessageI(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE, uid).sendToTarget();
+    }
+
     @Override
     public void onServiceConnected(ComponentName name, IBinder service) {
         synchronized (mMethodMap) {
             if (mCurIntent != null && name.equals(mCurIntent.getComponent())) {
                 mCurMethod = IInputMethod.Stub.asInterface(service);
+                final String curMethodPackage = mCurIntent.getComponent().getPackageName();
+                final int curMethodUid = mPackageManagerInternal.getPackageUidInternal(
+                        curMethodPackage, 0 /* flags */, mSettings.getCurrentUserId());
+                if (curMethodUid < 0) {
+                    Slog.e(TAG, "Failed to get UID for package=" + curMethodPackage);
+                    mCurMethodUid = Process.INVALID_UID;
+                } else {
+                    mCurMethodUid = curMethodUid;
+                }
                 if (mCurToken == null) {
                     Slog.w(TAG, "Service connected without a token!");
                     unbindCurrentMethodLocked();
@@ -2535,6 +2571,7 @@
                 // Dispatch display id for InputMethodService to update context display.
                 executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(
                         MSG_INITIALIZE_IME, mCurTokenDisplayId, mCurMethod, mCurToken));
+                scheduleNotifyImeUidToAudioService(mCurMethodUid);
                 if (mCurClient != null) {
                     clearClientSessionLocked(mCurClient);
                     requestClientSessionLocked(mCurClient);
@@ -2656,6 +2693,8 @@
             finishSessionLocked(mEnabledSession);
             mEnabledSession = null;
             mCurMethod = null;
+            mCurMethodUid = Process.INVALID_UID;
+            scheduleNotifyImeUidToAudioService(mCurMethodUid);
         }
         if (mStatusBar != null) {
             mStatusBar.setIconVisibility(mSlotIme, false);
@@ -4202,6 +4241,9 @@
                             + ((ClientState)msg.obj).uid);
                 }
                 return true;
+            case MSG_SET_INTERACTIVE:
+                handleSetInteractive(msg.arg1 != 0);
+                return true;
             case MSG_REPORT_FULLSCREEN_MODE: {
                 final boolean fullscreen = msg.arg1 != 0;
                 final ClientState clientState = (ClientState)msg.obj;
@@ -4259,7 +4301,7 @@
             }
 
             // ---------------------------------------------------------------
-            case MSG_INLINE_SUGGESTIONS_REQUEST:
+            case MSG_INLINE_SUGGESTIONS_REQUEST: {
                 args = (SomeArgs) msg.obj;
                 final InlineSuggestionsRequestInfo requestInfo =
                         (InlineSuggestionsRequestInfo) args.arg2;
@@ -4271,11 +4313,38 @@
                 } catch (RemoteException e) {
                     Slog.w(TAG, "RemoteException calling onCreateInlineSuggestionsRequest(): " + e);
                 }
+                args.recycle();
                 return true;
+            }
+
+            // ---------------------------------------------------------------
+            case MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE: {
+                if (mAudioManagerInternal == null) {
+                    mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
+                }
+                if (mAudioManagerInternal != null) {
+                    mAudioManagerInternal.setInputMethodServiceUid(msg.arg1 /* uid */);
+                }
+                return true;
+            }
         }
         return false;
     }
 
+    private void handleSetInteractive(final boolean interactive) {
+        synchronized (mMethodMap) {
+            mIsInteractive = interactive;
+            updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition);
+
+            // Inform the current client of the change in active status
+            if (mCurClient != null && mCurClient.client != null) {
+                executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO(
+                        MSG_SET_ACTIVE, mIsInteractive ? 1 : 0, mInFullscreenMode ? 1 : 0,
+                        mCurClient));
+            }
+        }
+    }
+
     private boolean chooseNewDefaultIMELocked() {
         final InputMethodInfo imi = InputMethodUtils.getMostApplicableDefaultIME(
                 mSettings.getEnabledInputMethodListLocked());
@@ -4885,6 +4954,13 @@
         }
 
         @Override
+        public void setInteractive(boolean interactive) {
+            // Do everything in handler so as not to block the caller.
+            mService.mHandler.obtainMessage(MSG_SET_INTERACTIVE, interactive ? 1 : 0, 0)
+                    .sendToTarget();
+        }
+
+        @Override
         public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) {
             mService.mHandler.removeMessages(MSG_HIDE_CURRENT_INPUT_METHOD);
             mService.mHandler.obtainMessage(MSG_HIDE_CURRENT_INPUT_METHOD, reason).sendToTarget();
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
index 0b73e4f..2129e9b 100644
--- a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -171,6 +171,11 @@
             LocalServices.addService(InputMethodManagerInternal.class,
                     new InputMethodManagerInternal() {
                         @Override
+                        public void setInteractive(boolean interactive) {
+                            reportNotSupported();
+                        }
+
+                        @Override
                         public void hideCurrentInputMethod(@SoftInputShowHideReason int reason) {
                             reportNotSupported();
                         }
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 905a10b..817902d 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -190,6 +190,9 @@
     public void updateRuleSet(
             String version, ParceledListSlice<Rule> rules, IntentSender statusReceiver) {
         String ruleProvider = getCallerPackageNameOrThrow(Binder.getCallingUid());
+        if (DEBUG_INTEGRITY_COMPONENT) {
+            Slog.i(TAG, String.format("Calling rule provider name is: %s.", ruleProvider));
+        }
 
         mHandler.post(
                 () -> {
@@ -201,6 +204,9 @@
                         success = false;
                     }
 
+                    if (DEBUG_INTEGRITY_COMPONENT) {
+                        Slog.i(TAG, String.format("Successfully pushed rule set: %s", version));
+                    }
                     FrameworkStatsLog.write(
                             FrameworkStatsLog.INTEGRITY_RULES_PUSHED,
                             success,
@@ -673,9 +679,6 @@
 
         // Identify the package names in the caller list.
         List<String> callingPackageNames = getPackageListForUid(callingUid);
-        if (DEBUG_INTEGRITY_COMPONENT) {
-            Slog.i(TAG, String.format("Calling packages are: ", callingPackageNames));
-        }
 
         // Find the intersection between the allowed and calling packages. Ideally, we will have
         // at most one package name here. But if we have more, it is fine.
@@ -685,10 +688,7 @@
                 allowedCallingPackages.add(packageName);
             }
         }
-        if (DEBUG_INTEGRITY_COMPONENT) {
-            Slog.i(TAG,
-                    String.format("Calling rule pusher packages are: ", allowedCallingPackages));
-        }
+
         return allowedCallingPackages.isEmpty() ? null : allowedCallingPackages.get(0);
     }
 
@@ -706,9 +706,6 @@
                 Arrays.asList(
                         mContext.getResources()
                                 .getStringArray(R.array.config_integrityRuleProviderPackages));
-        if (DEBUG_INTEGRITY_COMPONENT) {
-            Slog.i(TAG, String.format("Rule provider list contains: %s", integrityRuleProviders));
-        }
 
         // Filter out the rule provider packages that are not system apps.
         List<String> systemAppRuleProviders = new ArrayList<>();
diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java
index 8888108..c4f8441 100644
--- a/services/core/java/com/android/server/lights/LightsService.java
+++ b/services/core/java/com/android/server/lights/LightsService.java
@@ -41,9 +41,12 @@
 import com.android.internal.BrightnessSynchronizer;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.DumpUtils;
 import com.android.internal.util.Preconditions;
 import com.android.server.SystemService;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -174,6 +177,36 @@
             closeSessionInternal(token);
         }
 
+        @Override
+        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+            if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
+
+            synchronized (LightsService.this) {
+                if (mVintfLights != null) {
+                    pw.println("Service: aidl (" + mVintfLights.get() + ")");
+                } else {
+                    pw.println("Service: hidl");
+                }
+
+                pw.println("Lights:");
+                for (int i = 0; i < mLightsById.size(); i++) {
+                    final LightImpl light = mLightsById.valueAt(i);
+                    pw.println(String.format("  Light id=%d ordinal=%d color=%08x",
+                            light.mHwLight.id, light.mHwLight.ordinal, light.getColor()));
+                }
+
+                pw.println("Session clients:");
+                for (Session session : mSessions) {
+                    pw.println("  Session token=" + session.mToken);
+                    for (int i = 0; i < session.mRequests.size(); i++) {
+                        pw.println(String.format("    Request id=%d color=%08x",
+                                session.mRequests.keyAt(i),
+                                session.mRequests.valueAt(i).getColor()));
+                    }
+                }
+            }
+        }
+
         private void closeSessionInternal(IBinder token) {
             synchronized (LightsService.this) {
                 final Session session = getSessionLocked(token);
diff --git a/services/core/java/com/android/server/location/gnss/GnssVisibilityControl.java b/services/core/java/com/android/server/location/gnss/GnssVisibilityControl.java
index 75fd7dc..927fcfb 100644
--- a/services/core/java/com/android/server/location/gnss/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/gnss/GnssVisibilityControl.java
@@ -630,7 +630,7 @@
         }
 
         Notification.Builder builder = new Notification.Builder(mContext,
-                SystemNotificationChannels.NETWORK_ALERTS)
+                SystemNotificationChannels.NETWORK_STATUS)
                 .setSmallIcon(R.drawable.stat_sys_gps_on)
                 .setCategory(Notification.CATEGORY_SYSTEM)
                 .setVisibility(Notification.VISIBILITY_SECRET)
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ac982dd..1a8de97 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -312,7 +312,7 @@
         }
 
         void register(LockSettingsStrongAuth strongAuth) {
-            strongAuth.registerStrongAuthTracker(this.mStub);
+            strongAuth.registerStrongAuthTracker(getStub());
         }
     }
 
diff --git a/services/core/java/com/android/server/media/BluetoothRouteProvider.java b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
index 54958d3..fd8e03e 100644
--- a/services/core/java/com/android/server/media/BluetoothRouteProvider.java
+++ b/services/core/java/com/android/server/media/BluetoothRouteProvider.java
@@ -28,10 +28,12 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.media.AudioManager;
+import android.media.AudioSystem;
 import android.media.MediaRoute2Info;
 import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
 
 import com.android.internal.R;
 
@@ -55,6 +57,9 @@
     @SuppressWarnings("WeakerAccess") /* synthetic access */
     BluetoothHearingAid mHearingAidProfile;
 
+    // Route type -> volume map
+    private final SparseIntArray mVolumeMap = new SparseIntArray();
+
     private final Context mContext;
     private final BluetoothAdapter mBluetoothAdapter;
     private final BluetoothRoutesUpdatedListener mListener;
@@ -192,11 +197,30 @@
         return routes;
     }
 
-    boolean setSelectedRouteVolume(int volume) {
-        if (mSelectedRoute == null) return false;
+    /**
+     * Updates the volume for {@link AudioManager#getDevicesForStream(int) devices}.
+     *
+     * @return true if devices can be handled by the provider.
+     */
+    public boolean updateVolumeForDevices(int devices, int volume) {
+        int routeType;
+        if ((devices & (AudioSystem.DEVICE_OUT_HEARING_AID)) != 0) {
+            routeType = MediaRoute2Info.TYPE_HEARING_AID;
+        } else if ((devices & (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP
+                | AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES
+                | AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
+            routeType = MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
+        } else {
+            return false;
+        }
+        mVolumeMap.put(routeType, volume);
+        if (mSelectedRoute == null || mSelectedRoute.route.getType() != routeType) {
+            return true;
+        }
         mSelectedRoute.route = new MediaRoute2Info.Builder(mSelectedRoute.route)
                 .setVolume(volume)
                 .build();
+        notifyBluetoothRoutesUpdated();
         return true;
     }
 
@@ -222,6 +246,7 @@
                         R.string.bluetooth_a2dp_audio_route_name).toString())
                 .setType(MediaRoute2Info.TYPE_BLUETOOTH_A2DP)
                 .setVolumeHandling(MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
+                .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
                 .build();
         newBtRoute.connectedProfiles = new SparseBooleanArray();
         return newBtRoute;
@@ -240,13 +265,10 @@
         // Update volume when the connection state is changed.
         MediaRoute2Info.Builder builder = new MediaRoute2Info.Builder(btRoute.route)
                 .setConnectionState(state);
-        builder.setType(btRoute.connectedProfiles.get(BluetoothProfile.HEARING_AID, false)
-                ? MediaRoute2Info.TYPE_HEARING_AID : MediaRoute2Info.TYPE_BLUETOOTH_A2DP);
+        builder.setType(btRoute.getRouteType());
 
         if (state == MediaRoute2Info.CONNECTION_STATE_CONNECTED) {
-            int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
-            int currentVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
-            builder.setVolumeMax(maxVolume).setVolume(currentVolume);
+            builder.setVolume(mVolumeMap.get(btRoute.getRouteType(), 0));
         }
         btRoute.route = builder.build();
     }
@@ -259,6 +281,15 @@
         public BluetoothDevice btDevice;
         public MediaRoute2Info route;
         public SparseBooleanArray connectedProfiles;
+
+        @MediaRoute2Info.Type
+        int getRouteType() {
+            // Let hearing aid profile have a priority.
+            if (connectedProfiles.get(BluetoothProfile.HEARING_AID, false)) {
+                return MediaRoute2Info.TYPE_HEARING_AID;
+            }
+            return MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
+        }
     }
 
     // These callbacks run on the main thread.
@@ -285,13 +316,12 @@
                     btRoute = createBluetoothRoute(device);
                     mBluetoothRoutes.put(device.getAddress(), btRoute);
                 }
+                btRoute.connectedProfiles.put(profile, true);
                 if (activeDevices.contains(device)) {
                     mSelectedRoute = btRoute;
                     setRouteConnectionState(mSelectedRoute,
                             MediaRoute2Info.CONNECTION_STATE_CONNECTED);
                 }
-
-                btRoute.connectedProfiles.put(profile, true);
             }
             notifyBluetoothRoutesUpdated();
         }
@@ -348,6 +378,8 @@
                     BluetoothDevice.ERROR);
             BluetoothRouteInfo btRoute = mBluetoothRoutes.get(device.getAddress());
             if (bondState == BluetoothDevice.BOND_BONDED && btRoute == null) {
+                //TODO: The type of the new route is A2DP even when it's HEARING_AID.
+                // We may determine the type of route when create the route.
                 btRoute = createBluetoothRoute(device);
                 if (mA2dpProfile != null && mA2dpProfile.getConnectedDevices().contains(device)) {
                     btRoute.connectedProfiles.put(BluetoothProfile.A2DP, true);
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 5e865e7..d7bd794 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -584,7 +584,8 @@
         mAllRouterRecords.put(binder, routerRecord);
 
         userRecord.mHandler.sendMessage(
-                obtainMessage(UserHandler::notifyRoutesToRouter, userRecord.mHandler, router));
+                obtainMessage(UserHandler::notifyRoutesToRouter,
+                        userRecord.mHandler, routerRecord));
     }
 
     private void unregisterRouter2Locked(@NonNull IMediaRouter2 router, boolean died) {
@@ -1775,16 +1776,36 @@
             }
         }
 
-        private void notifyRoutesToRouter(@NonNull IMediaRouter2 router) {
+        private void notifyRoutesToRouter(@NonNull RouterRecord routerRecord) {
             List<MediaRoute2Info> routes = new ArrayList<>();
+
+            MediaRoute2ProviderInfo systemProviderInfo = null;
             for (MediaRoute2ProviderInfo providerInfo : mLastProviderInfos) {
+                // TODO: Create MediaRoute2ProviderInfo#isSystemProvider()
+                if (TextUtils.equals(providerInfo.getUniqueId(), mSystemProvider.getUniqueId())) {
+                    // Adding routes from system provider will be handled below, so skip it here.
+                    systemProviderInfo = providerInfo;
+                    continue;
+                }
                 routes.addAll(providerInfo.getRoutes());
             }
+
+            if (routerRecord.mHasModifyAudioRoutingPermission) {
+                if (systemProviderInfo != null) {
+                    routes.addAll(systemProviderInfo.getRoutes());
+                } else {
+                    // This shouldn't happen.
+                    Slog.w(TAG, "notifyRoutesToRouter: System route provider not found.");
+                }
+            } else {
+                routes.add(mSystemProvider.getDefaultRoute());
+            }
+
             if (routes.size() == 0) {
                 return;
             }
             try {
-                router.notifyRoutesAdded(routes);
+                routerRecord.mRouter.notifyRoutesAdded(routes);
             } catch (RemoteException ex) {
                 Slog.w(TAG, "Failed to notify all routes. Router probably died.", ex);
             }
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index b585b49..fdee9f8 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -81,6 +81,7 @@
     MediaRoute2Info mDeviceRoute;
     RoutingSessionInfo mDefaultSessionInfo;
     final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
+    int mDeviceVolume;
 
     private final Object mRequestLock = new Object();
     @GuardedBy("mRequestLock")
@@ -127,8 +128,9 @@
         });
         updateSessionInfosIfNeeded();
 
-        mContext.registerReceiver(new VolumeChangeReceiver(),
-                new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
+        IntentFilter intentFilter = new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION);
+        intentFilter.addAction(AudioManager.STREAM_DEVICES_CHANGED_ACTION);
+        mContext.registerReceiver(new AudioManagerBroadcastReceiver(), intentFilter);
 
         if (mBtRouteProvider != null) {
             mHandler.post(() -> {
@@ -136,6 +138,7 @@
                 notifyProviderState();
             });
         }
+        updateVolume();
     }
 
     @Override
@@ -248,8 +251,8 @@
                 .setVolumeHandling(mAudioManager.isVolumeFixed()
                         ? MediaRoute2Info.PLAYBACK_VOLUME_FIXED
                         : MediaRoute2Info.PLAYBACK_VOLUME_VARIABLE)
+                .setVolume(mDeviceVolume)
                 .setVolumeMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC))
-                .setVolume(mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))
                 .setType(type)
                 .addFeature(FEATURE_LIVE_AUDIO)
                 .addFeature(FEATURE_LIVE_VIDEO)
@@ -361,36 +364,43 @@
         }
     }
 
-    private class VolumeChangeReceiver extends BroadcastReceiver {
+    void updateVolume() {
+        int devices = mAudioManager.getDevicesForStream(AudioManager.STREAM_MUSIC);
+        int volume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
+
+        if (mDefaultRoute.getVolume() != volume) {
+            mDefaultRoute = new MediaRoute2Info.Builder(mDefaultRoute)
+                    .setVolume(volume)
+                    .build();
+        }
+
+        if (mBtRouteProvider != null && mBtRouteProvider.updateVolumeForDevices(devices, volume)) {
+            return;
+        }
+        if (mDeviceVolume != volume) {
+            mDeviceVolume = volume;
+            mDeviceRoute = new MediaRoute2Info.Builder(mDeviceRoute)
+                    .setVolume(volume)
+                    .build();
+        }
+        publishProviderState();
+    }
+
+    private class AudioManagerBroadcastReceiver extends BroadcastReceiver {
         // This will be called in the main thread.
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (!intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)) {
+            if (!intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)
+                    && !intent.getAction().equals(AudioManager.STREAM_DEVICES_CHANGED_ACTION)) {
                 return;
             }
 
-            final int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
+            int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
             if (streamType != AudioManager.STREAM_MUSIC) {
                 return;
             }
 
-            final int newVolume = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
-            final int oldVolume = intent.getIntExtra(
-                    AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0);
-
-            if (newVolume != oldVolume) {
-                if (TextUtils.equals(mDeviceRoute.getId(), mSelectedRouteId)) {
-                    mDeviceRoute = new MediaRoute2Info.Builder(mDeviceRoute)
-                            .setVolume(newVolume)
-                            .build();
-                } else if (mBtRouteProvider != null) {
-                    mBtRouteProvider.setSelectedRouteVolume(newVolume);
-                }
-                mDefaultRoute = new MediaRoute2Info.Builder(mDefaultRoute)
-                        .setVolume(newVolume)
-                        .build();
-                publishProviderState();
-            }
+            updateVolume();
         }
     }
 }
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index adf0176..dcbdfdf 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -119,7 +119,6 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.PowerManager;
-import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
@@ -160,6 +159,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
@@ -227,12 +227,6 @@
     private static final String PREFIX_UID_TAG = "uid_tag";
 
     /**
-     * Virtual network interface for video telephony. This is for VT data usage counting purpose.
-     */
-    // TODO: Remove this after no one is using it.
-    public static final String VT_INTERFACE = NetworkStats.IFACE_VT;
-
-    /**
      * Settings that can be changed externally.
      */
     public interface NetworkStatsSettings {
@@ -304,8 +298,8 @@
             new DropBoxNonMonotonicObserver();
 
     private static final int MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS = 100;
-    private final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
-            new RemoteCallbackList<>();
+    private final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList =
+            new CopyOnWriteArrayList<>();
     /** Semaphore used to wait for stats provider to respond to request stats update. */
     private final Semaphore mStatsProviderSem = new Semaphore(0, true);
 
@@ -1466,10 +1460,14 @@
         final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
 
         // Request asynchronous stats update from all providers for next poll. And wait a bit of
-        // time to allow providers report-in given that normally binder call should be fast.
+        // time to allow providers report-in given that normally binder call should be fast. Note
+        // that size of list might be changed because addition/removing at the same time. For
+        // addition, the stats of the missed provider can only be collected in next poll;
+        // for removal, wait might take up to MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS
+        // once that happened.
         // TODO: request with a valid token.
         Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate");
-        final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount();
+        final int registeredCallbackCount = mStatsProviderCbList.size();
         mStatsProviderSem.drainPermits();
         invokeForAllStatsProviderCallbacks(
                 (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */));
@@ -1643,7 +1641,7 @@
 
         @Override
         public void setStatsProviderLimitAsync(@NonNull String iface, long quota) {
-            Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
+            if (LOGV) Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")");
             invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota));
         }
     }
@@ -1934,7 +1932,7 @@
             NetworkStatsProviderCallbackImpl callback = new NetworkStatsProviderCallbackImpl(
                     tag, provider, mStatsProviderSem, mAlertObserver,
                     mStatsProviderCbList);
-            mStatsProviderCbList.register(callback);
+            mStatsProviderCbList.add(callback);
             Log.d(TAG, "registerNetworkStatsProvider from " + callback.mTag + " uid/pid="
                     + getCallingUid() + "/" + getCallingPid());
             return callback;
@@ -1958,20 +1956,11 @@
 
     private void invokeForAllStatsProviderCallbacks(
             @NonNull ThrowingConsumer<NetworkStatsProviderCallbackImpl, RemoteException> task) {
-        synchronized (mStatsLock) {
-            final int length = mStatsProviderCbList.beginBroadcast();
+        for (final NetworkStatsProviderCallbackImpl cb : mStatsProviderCbList) {
             try {
-                for (int i = 0; i < length; i++) {
-                    final NetworkStatsProviderCallbackImpl cb =
-                            mStatsProviderCbList.getBroadcastItem(i);
-                    try {
-                        task.accept(cb);
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e);
-                    }
-                }
-            } finally {
-                mStatsProviderCbList.finishBroadcast();
+                task.accept(cb);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Fail to broadcast to provider: " + cb.mTag, e);
             }
         }
     }
@@ -1983,7 +1972,7 @@
         @NonNull final INetworkStatsProvider mProvider;
         @NonNull private final Semaphore mSemaphore;
         @NonNull final INetworkManagementEventObserver mAlertObserver;
-        @NonNull final RemoteCallbackList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
+        @NonNull final CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> mStatsProviderCbList;
 
         @NonNull private final Object mProviderStatsLock = new Object();
 
@@ -1997,7 +1986,7 @@
                 @NonNull String tag, @NonNull INetworkStatsProvider provider,
                 @NonNull Semaphore semaphore,
                 @NonNull INetworkManagementEventObserver alertObserver,
-                @NonNull RemoteCallbackList<NetworkStatsProviderCallbackImpl> cbList)
+                @NonNull CopyOnWriteArrayList<NetworkStatsProviderCallbackImpl> cbList)
                 throws RemoteException {
             mTag = tag;
             mProvider = provider;
@@ -2054,13 +2043,13 @@
         @Override
         public void binderDied() {
             Log.d(TAG, mTag + ": binderDied");
-            mStatsProviderCbList.unregister(this);
+            mStatsProviderCbList.remove(this);
         }
 
         @Override
         public void unregister() {
             Log.d(TAG, mTag + ": unregister");
-            mStatsProviderCbList.unregister(this);
+            mStatsProviderCbList.remove(this);
         }
 
     }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bc7bd23..86e8734 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2725,9 +2725,18 @@
         Context appContext = r.getSbn().getPackageContext(getContext());
         Notification.Builder nb =
                 Notification.Builder.recoverBuilder(appContext, r.getNotification());
-        if (nb.getStyle() instanceof Notification.MessagingStyle && r.getShortcutInfo() == null) {
-            mPreferencesHelper.setMessageSent(r.getSbn().getPackageName(), r.getUid());
-            handleSavePolicyFile();
+        if (nb.getStyle() instanceof Notification.MessagingStyle) {
+            if (r.getShortcutInfo() != null) {
+                if (mPreferencesHelper.setValidMessageSent(
+                        r.getSbn().getPackageName(), r.getUid())) {
+                    handleSavePolicyFile();
+                }
+            } else {
+                if (mPreferencesHelper.setInvalidMessageSent(
+                        r.getSbn().getPackageName(), r.getUid())) {
+                    handleSavePolicyFile();
+                }
+            }
         }
     }
 
@@ -3158,9 +3167,22 @@
         }
 
         @Override
-        public boolean hasSentMessage(String pkg, int uid) {
+        public boolean isInInvalidMsgState(String pkg, int uid) {
             checkCallerIsSystem();
-            return mPreferencesHelper.hasSentMessage(pkg, uid);
+            return mPreferencesHelper.isInInvalidMsgState(pkg, uid);
+        }
+
+        @Override
+        public boolean hasUserDemotedInvalidMsgApp(String pkg, int uid) {
+            checkCallerIsSystem();
+            return mPreferencesHelper.hasUserDemotedInvalidMsgApp(pkg, uid);
+        }
+
+        @Override
+        public void setInvalidMsgAppDemoted(String pkg, int uid, boolean isDemoted) {
+            checkCallerIsSystem();
+            mPreferencesHelper.setInvalidMsgAppDemoted(pkg, uid, isDemoted);
+            handleSavePolicyFile();
         }
 
         @Override
@@ -5698,6 +5720,9 @@
             Slog.w(TAG, "notification " + r.getKey() + " added an invalid shortcut");
         }
         r.setShortcutInfo(info);
+        r.setHasSentValidMsg(mPreferencesHelper.hasSentValidMsg(pkg, notificationUid));
+        r.userDemotedAppFromConvoSpace(
+                mPreferencesHelper.hasUserDemotedInvalidMsgApp(pkg, notificationUid));
 
         if (!checkDisqualifyingFeatures(userId, notificationUid, id, tag, r,
                 r.getSbn().getOverrideGroupKey() != null)) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index a9fa2b1..c107822 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -188,6 +188,8 @@
     private boolean mHasSeenSmartReplies;
     private boolean mFlagBubbleRemoved;
     private boolean mPostSilently;
+    private boolean mHasSentValidMsg;
+    private boolean mAppDemotedFromConvo;
     /**
      * Whether this notification (and its channels) should be considered user locked. Used in
      * conjunction with user sentiment calculation.
@@ -1377,6 +1379,14 @@
         return mShortcutInfo;
     }
 
+    public void setHasSentValidMsg(boolean hasSentValidMsg) {
+        mHasSentValidMsg = hasSentValidMsg;
+    }
+
+    public void userDemotedAppFromConvoSpace(boolean userDemoted) {
+        mAppDemotedFromConvo = userDemoted;
+    }
+
     /**
      * Whether this notification is a conversation notification.
      */
@@ -1397,6 +1407,12 @@
             && mShortcutInfo == null) {
             return false;
         }
+        if (mHasSentValidMsg && mShortcutInfo == null) {
+            return false;
+        }
+        if (mAppDemotedFromConvo) {
+            return false;
+        }
         return true;
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
index c6ec95a..2b8ee92 100644
--- a/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
+++ b/services/core/java/com/android/server/notification/NotificationRecordLoggerImpl.java
@@ -62,7 +62,7 @@
                 /* android.stats.sysui.NotificationImportance importance_asst = 19 */
                 r.getAssistantImportance(),
                 /* int32 assistant_hash = 20 */ p.getAssistantHash(),
-                /* float assistant_ranking_score = 21 */ 0 // TODO connect up ranking score
+                /* float assistant_ranking_score = 21 */ r.getRankingScore()
         );
     }
 
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index ec0fc4a..38c65f1 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -116,7 +116,9 @@
     private static final String ATT_ENABLED = "enabled";
     private static final String ATT_USER_ALLOWED = "allowed";
     private static final String ATT_HIDE_SILENT = "hide_gentle";
-    private static final String ATT_SENT_MESSAGE = "sent_invalid_msg";
+    private static final String ATT_SENT_INVALID_MESSAGE = "sent_invalid_msg";
+    private static final String ATT_SENT_VALID_MESSAGE = "sent_valid_msg";
+    private static final String ATT_USER_DEMOTED_INVALID_MSG_APP = "user_demote_msg_app";
 
     private static final int DEFAULT_PRIORITY = Notification.PRIORITY_DEFAULT;
     private static final int DEFAULT_VISIBILITY = NotificationManager.VISIBILITY_NO_OVERRIDE;
@@ -253,8 +255,12 @@
                                     parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE);
                             r.lockedAppFields = XmlUtils.readIntAttribute(parser,
                                     ATT_APP_USER_LOCKED_FIELDS, DEFAULT_LOCKED_APP_FIELDS);
-                            r.hasSentMessage = XmlUtils.readBooleanAttribute(
-                                    parser, ATT_SENT_MESSAGE, false);
+                            r.hasSentInvalidMessage = XmlUtils.readBooleanAttribute(
+                                    parser, ATT_SENT_INVALID_MESSAGE, false);
+                            r.hasSentValidMessage = XmlUtils.readBooleanAttribute(
+                                    parser, ATT_SENT_VALID_MESSAGE, false);
+                            r.userDemotedMsgApp = XmlUtils.readBooleanAttribute(
+                                    parser, ATT_USER_DEMOTED_INVALID_MSG_APP, false);
 
                             final int innerDepth = parser.getDepth();
                             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -497,7 +503,9 @@
                                 || r.groups.size() > 0
                                 || r.delegate != null
                                 || r.bubblePreference != DEFAULT_BUBBLE_PREFERENCE
-                                || r.hasSentMessage;
+                                || r.hasSentInvalidMessage
+                                || r.userDemotedMsgApp
+                                || r.hasSentValidMessage;
                 if (hasNonDefaultSettings) {
                     out.startTag(null, TAG_PACKAGE);
                     out.attribute(null, ATT_NAME, r.pkg);
@@ -516,7 +524,12 @@
                     out.attribute(null, ATT_SHOW_BADGE, Boolean.toString(r.showBadge));
                     out.attribute(null, ATT_APP_USER_LOCKED_FIELDS,
                             Integer.toString(r.lockedAppFields));
-                    out.attribute(null, ATT_SENT_MESSAGE, Boolean.toString(r.hasSentMessage));
+                    out.attribute(null, ATT_SENT_INVALID_MESSAGE,
+                            Boolean.toString(r.hasSentInvalidMessage));
+                    out.attribute(null, ATT_SENT_VALID_MESSAGE,
+                            Boolean.toString(r.hasSentValidMessage));
+                    out.attribute(null, ATT_USER_DEMOTED_INVALID_MSG_APP,
+                            Boolean.toString(r.userDemotedMsgApp));
 
                     if (!forBackup) {
                         out.attribute(null, ATT_UID, Integer.toString(r.uid));
@@ -635,15 +648,68 @@
         updateConfig();
     }
 
-    public boolean hasSentMessage(String packageName, int uid) {
+    public boolean isInInvalidMsgState(String packageName, int uid) {
         synchronized (mPackagePreferences) {
-            return getOrCreatePackagePreferencesLocked(packageName, uid).hasSentMessage;
+            PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
+            return r.hasSentInvalidMessage && !r.hasSentValidMessage;
         }
     }
 
-    public void setMessageSent(String packageName, int uid) {
+    public boolean hasUserDemotedInvalidMsgApp(String packageName, int uid) {
         synchronized (mPackagePreferences) {
-            getOrCreatePackagePreferencesLocked(packageName, uid).hasSentMessage = true;
+            PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
+            return isInInvalidMsgState(packageName, uid) ? r.userDemotedMsgApp : false;
+        }
+    }
+
+    public void setInvalidMsgAppDemoted(String packageName, int uid, boolean isDemoted) {
+        synchronized (mPackagePreferences) {
+            PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
+            r.userDemotedMsgApp = isDemoted;
+        }
+    }
+
+    public boolean setInvalidMessageSent(String packageName, int uid) {
+        synchronized (mPackagePreferences) {
+            PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
+            boolean valueChanged = r.hasSentInvalidMessage == false;
+            r.hasSentInvalidMessage = true;
+
+            return valueChanged;
+        }
+    }
+
+    public boolean setValidMessageSent(String packageName, int uid) {
+        synchronized (mPackagePreferences) {
+            PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
+            boolean valueChanged = r.hasSentValidMessage == false;
+            r.hasSentValidMessage = true;
+
+            return valueChanged;
+        }
+    }
+
+    @VisibleForTesting
+    boolean hasSentInvalidMsg(String packageName, int uid) {
+        synchronized (mPackagePreferences) {
+            PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
+            return r.hasSentInvalidMessage;
+        }
+    }
+
+    @VisibleForTesting
+    boolean hasSentValidMsg(String packageName, int uid) {
+        synchronized (mPackagePreferences) {
+            PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
+            return r.hasSentValidMessage;
+        }
+    }
+
+    @VisibleForTesting
+    boolean didUserEverDemoteInvalidMsgApp(String packageName, int uid) {
+        synchronized (mPackagePreferences) {
+            PackagePreferences r = getOrCreatePackagePreferencesLocked(packageName, uid);
+            return r.userDemotedMsgApp;
         }
     }
 
@@ -2273,7 +2339,11 @@
         boolean oemLockedImportance = DEFAULT_OEM_LOCKED_IMPORTANCE;
         List<String> oemLockedChannels = new ArrayList<>();
         boolean defaultAppLockedImportance = DEFAULT_APP_LOCKED_IMPORTANCE;
-        boolean hasSentMessage = false;
+
+        boolean hasSentInvalidMessage = false;
+        boolean hasSentValidMessage = false;
+        // notE: only valid while hasSentMessage is false and hasSentInvalidMessage is true
+        boolean userDemotedMsgApp = false;
 
         Delegate delegate = null;
         ArrayMap<String, NotificationChannel> channels = new ArrayMap<>();
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index 28c8642d..e82ee22 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -50,6 +50,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.permission.PermissionManager;
 import android.stats.devicepolicy.DevicePolicyEnums;
 import android.text.TextUtils;
 import android.util.Slog;
@@ -458,6 +459,10 @@
                     + packageName + " on user ID " + userId);
             return;
         }
+
+        final boolean hadPermission = hasInteractAcrossProfilesPermission(
+                packageName, uid, PermissionChecker.PID_UNKNOWN);
+
         final int callingUid = mInjector.getCallingUid();
         if (isPermissionGranted(
                 Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES, callingUid)) {
@@ -472,6 +477,22 @@
         }
         sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(userId));
         maybeLogSetInteractAcrossProfilesAppOp(packageName, newMode, userId, logMetrics, uid);
+        maybeKillUid(packageName, uid, hadPermission);
+    }
+
+    /**
+     * Kills the process represented by the given UID if it has lost the permission to
+     * interact across profiles.
+     */
+    private void maybeKillUid(
+            String packageName, int uid, boolean hadPermission) {
+        if (!hadPermission) {
+            return;
+        }
+        if (hasInteractAcrossProfilesPermission(packageName, uid, PermissionChecker.PID_UNKNOWN)) {
+            return;
+        }
+        mInjector.killUid(packageName, uid);
     }
 
     private void maybeLogSetInteractAcrossProfilesAppOp(
@@ -774,6 +795,18 @@
                 String permission, int uid, int owningUid, boolean exported) {
             return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported);
         }
+
+        @Override
+        public void killUid(String packageName, int uid) {
+            try {
+                ActivityManager.getService().killApplication(
+                        packageName,
+                        UserHandle.getAppId(uid),
+                        UserHandle.getUserId(uid),
+                        PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED);
+            } catch (RemoteException ignored) {
+            }
+        }
     }
 
     @VisibleForTesting
@@ -813,6 +846,8 @@
         void sendBroadcastAsUser(Intent intent, UserHandle user);
 
         int checkComponentPermission(String permission, int uid, int owningUid, boolean exported);
+
+        void killUid(String packageName, int uid);
     }
 
     class LocalService extends CrossProfileAppsInternal {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 7af0787..1741aa7 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -395,7 +395,6 @@
 
     private boolean mDataLoaderFinished = false;
 
-    // TODO(b/146080380): merge file list with Callback installation.
     private IncrementalFileStorages mIncrementalFileStorages;
 
     private static final FileFilter sAddedApkFilter = new FileFilter() {
@@ -2698,6 +2697,7 @@
 
     /**
      * Makes sure files are present in staging location.
+     * @return if the image is ready for installation
      */
     @GuardedBy("mLock")
     private boolean prepareDataLoaderLocked()
@@ -2709,6 +2709,17 @@
             return true;
         }
 
+        // Retrying commit.
+        if (mIncrementalFileStorages != null) {
+            try {
+                mIncrementalFileStorages.startLoading();
+            } catch (IOException e) {
+                throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE, e.getMessage(),
+                        e.getCause());
+            }
+            return false;
+        }
+
         final List<InstallationFileParcel> addedFiles = new ArrayList<>();
         final List<String> removedFiles = new ArrayList<>();
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3ead72c..3e587bf 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -608,6 +608,12 @@
     private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
 
     /**
+     * The default maximum time to wait for the integrity verification to return in
+     * milliseconds.
+     */
+    private static final long DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT = 30 * 1000;
+
+    /**
      * Timeout duration in milliseconds for enabling package rollback. If we fail to enable
      * rollback within that period, the install will proceed without rollback enabled.
      *
@@ -1560,13 +1566,17 @@
     // Recordkeeping of restore-after-install operations that are currently in flight
     // between the Package Manager and the Backup Manager
     static class PostInstallData {
+        @Nullable
         public final InstallArgs args;
+        @NonNull
         public final PackageInstalledInfo res;
+        @Nullable
         public final Runnable mPostInstallRunnable;
 
-        PostInstallData(InstallArgs _a, PackageInstalledInfo _r, Runnable postInstallRunnable) {
-            args = _a;
-            res = _r;
+        PostInstallData(@Nullable InstallArgs args, @NonNull PackageInstalledInfo res,
+                @Nullable Runnable postInstallRunnable) {
+            this.args = args;
+            this.res = res;
             mPostInstallRunnable = postInstallRunnable;
         }
     }
@@ -1708,7 +1718,7 @@
 
                     if (data != null && data.mPostInstallRunnable != null) {
                         data.mPostInstallRunnable.run();
-                    } else if (data != null) {
+                    } else if (data != null && data.args != null) {
                         InstallArgs args = data.args;
                         PackageInstalledInfo parentRes = data.res;
 
@@ -1726,26 +1736,12 @@
                                 : args.whitelistedRestrictedPermissions;
                         int autoRevokePermissionsMode = args.autoRevokePermissionsMode;
 
-                        // Handle the parent package
                         handlePackagePostInstall(parentRes, grantPermissions,
                                 killApp, virtualPreload, grantedPermissions,
                                 whitelistedRestrictedPermissions, autoRevokePermissionsMode,
                                 didRestore, args.installSource.installerPackageName, args.observer,
                                 args.mDataLoaderType);
 
-                        // Handle the child packages
-                        final int childCount = (parentRes.addedChildPackages != null)
-                                ? parentRes.addedChildPackages.size() : 0;
-                        for (int i = 0; i < childCount; i++) {
-                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
-                            handlePackagePostInstall(childRes, grantPermissions,
-                                    killApp, virtualPreload, grantedPermissions,
-                                    whitelistedRestrictedPermissions, autoRevokePermissionsMode,
-                                    false /*didRestore*/,
-                                    args.installSource.installerPackageName, args.observer,
-                                    args.mDataLoaderType);
-                        }
-
                         // Log tracing if needed
                         if (args.traceMethod != null) {
                             Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
@@ -2300,27 +2296,8 @@
             // Work that needs to happen on first install within each user
             if (firstUserIds != null && firstUserIds.length > 0) {
                 for (int userId : firstUserIds) {
-                    // If this app is a browser and it's newly-installed for some
-                    // users, clear any default-browser state in those users. The
-                    // app's nature doesn't depend on the user, so we can just check
-                    // its browser nature in any user and generalize.
-                    if (packageIsBrowser(packageName, userId)) {
-                        // If this browser is restored from user's backup, do not clear
-                        // default-browser state for this user
-                        if (pkgSetting.getInstallReason(userId)
-                                != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
-                            mPermissionManager.setDefaultBrowser(null, true, true, userId);
-                        }
-                    }
-
-                    // We may also need to apply pending (restored) runtime permission grants
-                    // within these users.
-                    mPermissionManager.restoreDelayedRuntimePermissions(packageName,
-                            UserHandle.of(userId));
-
-                    // Persistent preferred activity might have came into effect due to this
-                    // install.
-                    updateDefaultHomeNotLocked(userId);
+                    clearRolesAndRestorePermissionsForNewUserInstall(packageName,
+                            pkgSetting.getInstallReason(userId), userId);
                 }
             }
 
@@ -7204,11 +7181,14 @@
                     sortResult = true;
                 }
             } else {
-                final AndroidPackage pkg = mPackages.get(pkgName);
+                final PackageSetting setting =
+                        getPackageSettingInternal(pkgName, Process.SYSTEM_UID);
                 result = null;
-                if (pkg != null) {
+                if (setting != null && setting.pkg != null
+                        && !shouldFilterApplicationLocked(setting, filterCallingUid, userId)) {
                     result = filterIfNotSystemUser(mComponentResolver.queryActivities(
-                            intent, resolvedType, flags, pkg.getActivities(), userId), userId);
+                            intent, resolvedType, flags, setting.pkg.getActivities(), userId),
+                            userId);
                 }
                 if (result == null || result.size() == 0) {
                     // the caller wants to resolve for a particular package; however, there
@@ -13116,9 +13096,15 @@
                         createPackageInstalledInfo(PackageManager.INSTALL_SUCCEEDED);
                 res.pkg = pkgSetting.pkg;
                 res.newUsers = new int[]{ userId };
-                PostInstallData postInstallData = intentSender == null ? null :
-                        new PostInstallData(null, res, () -> onRestoreComplete(res.returnCode,
-                              mContext, intentSender));
+
+                PostInstallData postInstallData =
+                        new PostInstallData(null, res, () -> {
+                            clearRolesAndRestorePermissionsForNewUserInstall(packageName,
+                                    pkgSetting.getInstallReason(userId), userId);
+                            if (intentSender != null) {
+                                onRestoreComplete(res.returnCode, mContext, intentSender);
+                            }
+                        });
                 restoreAndPostInstall(userId, res, postInstallData);
             }
         } finally {
@@ -13838,6 +13824,19 @@
     }
 
     /**
+     * Get the integrity verification timeout.
+     *
+     * @return verification timeout in milliseconds
+     */
+    private long getIntegrityVerificationTimeout() {
+        long timeout = Global.getLong(mContext.getContentResolver(),
+                Global.APP_INTEGRITY_VERIFICATION_TIMEOUT, DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
+        // The setting can be used to increase the timeout but not decrease it, since that is
+        // equivalent to disabling the integrity component.
+        return Math.max(timeout, DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
+    }
+
+    /**
      * Get the default verification agent response code.
      *
      * @return default verification response code
@@ -15032,8 +15031,7 @@
                             final Message msg =
                                     mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
                             msg.arg1 = verificationId;
-                            // TODO: do we want to use the same timeout?
-                            mHandler.sendMessageDelayed(msg, getVerificationTimeout());
+                            mHandler.sendMessageDelayed(msg, getIntegrityVerificationTimeout());
                         }
                     }, /* scheduler= */ null,
                     /* initialCode= */ 0,
@@ -15783,7 +15781,6 @@
         String returnMsg;
         String installerPackageName;
         PackageRemovedInfo removedInfo;
-        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
         // The set of packages consuming this shared library or null if no consumers exist.
         ArrayList<AndroidPackage> libraryConsumers;
         PackageFreezer freezer;
@@ -15797,37 +15794,21 @@
         public void setError(String msg, PackageParserException e) {
             setReturnCode(e.error);
             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
-            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
-            for (int i = 0; i < childCount; i++) {
-                addedChildPackages.valueAt(i).setError(msg, e);
-            }
             Slog.w(TAG, msg, e);
         }
 
         public void setError(String msg, PackageManagerException e) {
             returnCode = e.error;
             setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
-            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
-            for (int i = 0; i < childCount; i++) {
-                addedChildPackages.valueAt(i).setError(msg, e);
-            }
             Slog.w(TAG, msg, e);
         }
 
         public void setReturnCode(int returnCode) {
             this.returnCode = returnCode;
-            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
-            for (int i = 0; i < childCount; i++) {
-                addedChildPackages.valueAt(i).returnCode = returnCode;
-            }
         }
 
         private void setReturnMessage(String returnMsg) {
             this.returnMsg = returnMsg;
-            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
-            for (int i = 0; i < childCount; i++) {
-                addedChildPackages.valueAt(i).returnMsg = returnMsg;
-            }
         }
 
         // In some error cases we want to convey more info back to the observer
@@ -17377,7 +17358,6 @@
             int targetParseFlags = parseFlags;
             final PackageSetting ps;
             final PackageSetting disabledPs;
-            final PackageSetting[] childPackages;
             if (replace) {
                 if (parsedPackage.isStaticSharedLibrary()) {
                     // Static libs have a synthetic package name containing the version
@@ -18379,7 +18359,6 @@
             final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
             info.sendPackageRemovedBroadcasts(killApp);
             info.sendSystemPackageUpdatedBroadcasts();
-            info.sendSystemPackageAppearedBroadcasts();
         }
         // Force a gc here.
         Runtime.getRuntime().gc();
@@ -18437,7 +18416,6 @@
         SparseArray<int[]> broadcastWhitelist;
         // Clean up resources deleted packages.
         InstallArgs args = null;
-        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
 
         PackageRemovedInfo(PackageSender packageSender) {
             this.packageSender = packageSender;
@@ -18453,18 +18431,6 @@
             }
         }
 
-        void sendSystemPackageAppearedBroadcasts() {
-            final int packageCount = (appearedChildPackages != null)
-                    ? appearedChildPackages.size() : 0;
-            for (int i = 0; i < packageCount; i++) {
-                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
-                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
-                    true /*sendBootCompleted*/, false /*startReceiver*/,
-                        UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null,
-                        DataLoaderType.NONE);
-            }
-        }
-
         private void sendSystemPackageUpdatedBroadcastsInternal() {
             Bundle extras = new Bundle(2);
             extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
@@ -19731,6 +19697,30 @@
         }
     }
 
+    private void clearRolesAndRestorePermissionsForNewUserInstall(String packageName,
+            int installReason, @UserIdInt int userId) {
+        // If this app is a browser and it's newly-installed for some
+        // users, clear any default-browser state in those users. The
+        // app's nature doesn't depend on the user, so we can just check
+        // its browser nature in any user and generalize.
+        if (packageIsBrowser(packageName, userId)) {
+            // If this browser is restored from user's backup, do not clear
+            // default-browser state for this user
+            if (installReason != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
+                mPermissionManager.setDefaultBrowser(null, true, true, userId);
+            }
+        }
+
+        // We may also need to apply pending (restored) runtime permission grants
+        // within these users.
+        mPermissionManager.restoreDelayedRuntimePermissions(packageName,
+                UserHandle.of(userId));
+
+        // Persistent preferred activity might have came into effect due to this
+        // install.
+        updateDefaultHomeNotLocked(userId);
+    }
+
     @Override
     public void resetApplicationPreferences(int userId) {
         mContext.enforceCallingOrSelfPermission(
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index bc94528..0dc4d13 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3172,7 +3172,7 @@
             metadata = (streamingVersion == 0) ? Metadata.forDataOnlyStreaming(fileId)
                     : Metadata.forStreaming(fileId);
             try {
-                if (V4Signature.readFrom(signature) == null) {
+                if ((signature.length > 0) && (V4Signature.readFrom(signature) == null)) {
                     getErrPrintWriter().println("V4 signature is invalid in: " + arg);
                     return 1;
                 }
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index b805a24..79805e3 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -69,6 +69,8 @@
 import com.android.internal.content.PackageHelper;
 import com.android.internal.os.BackgroundThread;
 import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.SystemServiceManager;
 import com.android.server.pm.parsing.PackageParser2;
 import com.android.server.pm.parsing.pkg.AndroidPackage;
 import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
@@ -110,6 +112,9 @@
     private final List<String> mFailedPackageNames = new ArrayList<>();
     private String mNativeFailureReason;
 
+    @GuardedBy("mSuccessfulStagedSessionIds")
+    private final List<Integer> mSuccessfulStagedSessionIds = new ArrayList<>();
+
     StagingManager(PackageInstallerService pi, Context context,
             Supplier<PackageParser2> packageParserSupplier) {
         mPi = pi;
@@ -122,6 +127,34 @@
                 BackgroundThread.get().getLooper());
     }
 
+    /**
+     This class manages lifecycle events for StagingManager.
+     */
+    public static final class Lifecycle extends SystemService {
+        private static StagingManager sStagingManager;
+
+        public Lifecycle(Context context) {
+            super(context);
+        }
+
+        void startService(StagingManager stagingManager) {
+            sStagingManager = stagingManager;
+            LocalServices.getService(SystemServiceManager.class).startService(this);
+        }
+
+        @Override
+        public void onStart() {
+            // no-op
+        }
+
+        @Override
+        public void onBootPhase(int phase) {
+            if (phase == SystemService.PHASE_BOOT_COMPLETED && sStagingManager != null) {
+                sStagingManager.markStagedSessionsAsSuccessful();
+            }
+        }
+    }
+
     private void updateStoredSession(@NonNull PackageInstallerSession sessionInfo) {
         synchronized (mStagedSessions) {
             PackageInstallerSession storedSession = mStagedSessions.get(sessionInfo.sessionId);
@@ -652,7 +685,22 @@
         Slog.d(TAG, "Marking session " + session.sessionId + " as applied");
         session.setStagedSessionApplied();
         if (hasApex) {
-            mApexManager.markStagedSessionSuccessful(session.sessionId);
+            try {
+                if (supportsCheckpoint()) {
+                    // Store the session ID, which will be marked as successful by ApexManager
+                    // upon boot completion.
+                    synchronized (mSuccessfulStagedSessionIds) {
+                        mSuccessfulStagedSessionIds.add(session.sessionId);
+                    }
+                } else {
+                    // Mark sessions as successful immediately on non-checkpointing devices.
+                    mApexManager.markStagedSessionSuccessful(session.sessionId);
+                }
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Checkpoint support unknown, marking session as successful "
+                        + "immediately.");
+                mApexManager.markStagedSessionSuccessful(session.sessionId);
+            }
         }
     }
 
@@ -1121,7 +1169,16 @@
         }
     }
 
+    void markStagedSessionsAsSuccessful() {
+        synchronized (mSuccessfulStagedSessionIds) {
+            for (int i = 0; i < mSuccessfulStagedSessionIds.size(); i++) {
+                mApexManager.markStagedSessionSuccessful(mSuccessfulStagedSessionIds.get(i));
+            }
+        }
+    }
+
     void systemReady() {
+        new Lifecycle(mContext).startService(this);
         // Register the receiver of boot completed intent for staging manager.
         mContext.registerReceiver(new BroadcastReceiver() {
             @Override
diff --git a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
index f8d039c..530c115 100644
--- a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
+++ b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
@@ -344,7 +344,7 @@
      */
     @NonNull
     private List<String> getPackagesWhitelistErrors(@PackageWhitelistMode int mode) {
-        if ((!isEnforceMode(mode) || isImplicitWhitelistMode(mode)) && !isLogMode(mode)) {
+        if ((!isEnforceMode(mode) || isImplicitWhitelistMode(mode))) {
             return Collections.emptyList();
         }
 
@@ -752,6 +752,10 @@
         } else if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) {
             mode = getDeviceDefaultWhitelistMode();
         }
+        if (criticalOnly) {
+            // Flip-out log mode
+            mode &= ~USER_TYPE_PACKAGE_WHITELIST_MODE_LOG;
+        }
         Slog.v(TAG, "dumpPackageWhitelistProblems(): using mode " + modeToString(mode));
 
         final List<String> errors = getPackagesWhitelistErrors(mode);
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 8648a23..76c6a7a 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -25,6 +25,8 @@
 import static android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED;
+import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED;
 import static android.content.pm.PackageManager.GET_PERMISSIONS;
 import static android.content.pm.PackageManager.MATCH_ALL;
 
@@ -45,7 +47,6 @@
 import android.content.pm.PackageManagerInternal.PackageListObserver;
 import android.content.pm.PermissionInfo;
 import android.os.Build;
-import android.os.Handler;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -57,7 +58,6 @@
 import android.telecom.TelecomManager;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.Log;
 import android.util.LongSparseLongArray;
 import android.util.Pair;
 import android.util.Slog;
@@ -93,6 +93,7 @@
 public final class PermissionPolicyService extends SystemService {
     private static final String LOG_TAG = PermissionPolicyService.class.getSimpleName();
     private static final boolean DEBUG = false;
+    private static final long USER_SENSITIVE_UPDATE_DELAY_MS = 10000;
 
     private final Object mLock = new Object();
 
@@ -378,8 +379,6 @@
      * TODO ntmyren: Remove once propagated, and state is repaired
      */
     private void restoreReadPhoneStatePermissions(int userId) {
-        PermissionControllerManager manager = new PermissionControllerManager(this.getContext(),
-                Handler.getMain());
         PackageManager pm = getContext().getPackageManager();
         List<PackageInfo> packageInfos = pm.getInstalledPackagesAsUser(
                 MATCH_ALL | GET_PERMISSIONS, userId);
@@ -389,26 +388,21 @@
                 continue;
             }
 
-            boolean hasReadPhoneState = false;
+            UserHandle user = UserHandle.getUserHandleForUid(pI.applicationInfo.uid);
             for (int j = pI.requestedPermissions.length - 1; j >= 0; j--) {
                 if (pI.requestedPermissions[j].equals(READ_PHONE_STATE)) {
-                    hasReadPhoneState = true;
+                    int flags = pm.getPermissionFlags(READ_PHONE_STATE, pI.packageName, user);
+                    // If the app is auto revoked for read phone state, and is only user sensitive
+                    // when granted, clear auto revoked flag.
+                    if ((flags & FLAG_PERMISSION_AUTO_REVOKED) != 0
+                            && (flags & FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) != 0
+                            && (flags & FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED) == 0) {
+                        pm.updatePermissionFlags(READ_PHONE_STATE, pI.packageName,
+                                FLAG_PERMISSION_AUTO_REVOKED, 0, user);
+                    }
+                    break;
                 }
             }
-            if (!hasReadPhoneState) {
-                continue;
-            }
-
-            Log.i(LOG_TAG, "Updating read phone state for " + pI.packageName + " "
-                    + pI.applicationInfo.uid);
-            manager.updateUserSensitiveForApp(pI.applicationInfo.uid);
-
-            UserHandle user = UserHandle.getUserHandleForUid(pI.applicationInfo.uid);
-            int permFlags = pm.getPermissionFlags(READ_PHONE_STATE, pI.packageName, user);
-            if ((permFlags & FLAG_PERMISSION_AUTO_REVOKED) != 0) {
-                pm.updatePermissionFlags(READ_PHONE_STATE, pI.packageName,
-                        FLAG_PERMISSION_AUTO_REVOKED, 0, user);
-            }
         }
     }
 
@@ -460,7 +454,8 @@
                 throw new IllegalStateException(e);
             }
 
-            permissionControllerManager.updateUserSensitive();
+            FgThread.getHandler().postDelayed(permissionControllerManager::updateUserSensitive,
+                    USER_SENSITIVE_UPDATE_DELAY_MS);
 
             packageManagerInternal.updateRuntimePermissionsFingerprint(userId);
         }
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 199cb49..0b95be1 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -413,6 +413,7 @@
 
             // Start input as soon as we start waking up or going to sleep.
             mInputManagerInternal.setInteractive(interactive);
+            mInputMethodManagerInternal.setInteractive(interactive);
 
             // Notify battery stats.
             try {
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 3b4c423..12309f4 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -21,11 +21,14 @@
 import static android.app.usage.NetworkStatsManager.FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN;
 import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
 import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
 import static android.os.Debug.getIonHeapsSizeKb;
 import static android.os.Process.getUidForPid;
 import static android.os.storage.VolumeInfo.TYPE_PRIVATE;
 import static android.os.storage.VolumeInfo.TYPE_PUBLIC;
+import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION;
 import static android.util.MathUtils.abs;
 import static android.util.MathUtils.constrain;
 
@@ -38,6 +41,7 @@
 import static com.android.server.stats.pull.ProcfsMemoryUtil.readCmdlineFromProcfs;
 import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs;
 
+import static java.util.concurrent.TimeUnit.HOURS;
 import static java.util.concurrent.TimeUnit.MICROSECONDS;
 
 import android.annotation.NonNull;
@@ -133,6 +137,7 @@
 import com.android.internal.os.PowerProfile;
 import com.android.internal.os.ProcessCpuTracker;
 import com.android.internal.os.StoragedUidIoStatsReader;
+import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.BatteryService;
 import com.android.server.BinderCallsStatsService;
@@ -202,6 +207,12 @@
     private static final long MILLIS_PER_SEC = 1000;
     private static final long MILLI_AMP_HR_TO_NANO_AMP_SECS = 1_000_000L * 3600L;
 
+    /**
+     * The default bucket duration used when query a snapshot from NetworkStatsService.
+     * The value should be sync with NetworkStatsService#DefaultNetworkStatsSettings#getUidConfig.
+     */
+    private static final long NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS = HOURS.toMillis(2);
+
     private static final int MAX_BATTERY_STATS_HELPER_FREQUENCY_MS = 1000;
     private static final int CPU_TIME_PER_THREAD_FREQ_MAX_NUM_FREQUENCIES = 8;
     private static final int OP_FLAGS_PULLED = OP_FLAG_SELF | OP_FLAG_TRUSTED_PROXY;
@@ -279,6 +290,13 @@
 
     private int mAppOpsSamplingRate = 0;
 
+    // Baselines that stores list of NetworkStats right after initializing, with associated
+    // information. This is used to calculate difference when pulling
+    // {Mobile|Wifi}BytesTransfer* atoms. Note that this is not thread-safe, and must
+    // only be accessed on the background thread.
+    @NonNull
+    private final List<NetworkStatsExt> mNetworkStatsBaselines = new ArrayList<>();
+
     public StatsPullAtomService(Context context) {
         super(context);
         mContext = context;
@@ -302,13 +320,17 @@
             try {
                 switch (atomTag) {
                     case FrameworkStatsLog.WIFI_BYTES_TRANSFER:
-                        return pullWifiBytesTransfer(atomTag, data, false);
+                        return pullDataBytesTransfer(atomTag, data, TRANSPORT_WIFI,
+                                /*withFgbg=*/ false);
                     case FrameworkStatsLog.WIFI_BYTES_TRANSFER_BY_FG_BG:
-                        return pullWifiBytesTransfer(atomTag, data, true);
+                        return pullDataBytesTransfer(atomTag, data, TRANSPORT_WIFI,
+                                /*withFgbg=*/ true);
                     case FrameworkStatsLog.MOBILE_BYTES_TRANSFER:
-                        return pullMobileBytesTransfer(atomTag, data, false);
+                        return pullDataBytesTransfer(atomTag, data, TRANSPORT_CELLULAR,
+                                /*withFgbg=*/ false);
                     case FrameworkStatsLog.MOBILE_BYTES_TRANSFER_BY_FG_BG:
-                        return pullMobileBytesTransfer(atomTag, data, true);
+                        return pullDataBytesTransfer(atomTag, data, TRANSPORT_CELLULAR,
+                                /*withFgbg=*/ true);
                     case FrameworkStatsLog.BLUETOOTH_BYTES_TRANSFER:
                         return pullBluetoothBytesTransfer(atomTag, data);
                     case FrameworkStatsLog.KERNEL_WAKELOCK:
@@ -423,6 +445,8 @@
                         return pullAttributedAppOps(atomTag, data);
                     case FrameworkStatsLog.SETTING_SNAPSHOT:
                         return pullSettingsStats(atomTag, data);
+                    case FrameworkStatsLog.DISPLAY_WAKE_REASON:
+                        return pullDisplayWakeStats(atomTag, data);
                     default:
                         throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
                 }
@@ -444,9 +468,12 @@
             BackgroundThread.getHandler().post(() -> {
                 nativeInit();
                 initializePullersState();
-                registerAllPullers();
+                registerPullers();
                 registerEventListeners();
             });
+        } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+            // Network stats related pullers can only be initialized after service is ready.
+            BackgroundThread.getHandler().post(() -> initAndRegisterNetworkStatsPullers());
         }
     }
 
@@ -521,15 +548,11 @@
         }
     }
 
-    void registerAllPullers() {
+    void registerPullers() {
         if (DEBUG) {
-            Slog.d(TAG, "Registering all pullers with statsd");
+            Slog.d(TAG, "Registering pullers with statsd");
         }
         mStatsCallbackImpl = new StatsPullAtomCallbackImpl();
-        registerWifiBytesTransfer();
-        registerWifiBytesTransferBackground();
-        registerMobileBytesTransfer();
-        registerMobileBytesTransferBackground();
         registerBluetoothBytesTransfer();
         registerKernelWakelock();
         registerCpuTimePerFreq();
@@ -588,6 +611,23 @@
         registerBatteryVoltage();
         registerBatteryCycleCount();
         registerSettingsStats();
+        registerDisplayWakeStats();
+    }
+
+    private void initAndRegisterNetworkStatsPullers() {
+        if (DEBUG) {
+            Slog.d(TAG, "Registering NetworkStats pullers with statsd");
+        }
+        // Initialize NetworkStats baselines.
+        mNetworkStatsBaselines.addAll(collectWifiBytesTransferSnapshot(/*withFgbg=*/ false));
+        mNetworkStatsBaselines.addAll(collectWifiBytesTransferSnapshot(/*withFgbg=*/ true));
+        mNetworkStatsBaselines.addAll(collectMobileBytesTransferSnapshot(/*withFgbg=*/ false));
+        mNetworkStatsBaselines.addAll(collectMobileBytesTransferSnapshot(/*withFgbg=*/ true));
+
+        registerWifiBytesTransfer();
+        registerWifiBytesTransferBackground();
+        registerMobileBytesTransfer();
+        registerMobileBytesTransferBackground();
     }
 
     /**
@@ -723,37 +763,87 @@
         );
     }
 
-    private int pullWifiBytesTransfer(
-            int atomTag, @NonNull List<StatsEvent> pulledData, boolean withFgbg) {
-        final NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard();
-        final NetworkStats stats = getUidNetworkStatsSinceBoot(template, withFgbg);
+    /**
+     * A data class to store a NetworkStats object with information associated to it.
+     */
+    private static class NetworkStatsExt {
+        @NonNull
+        public final NetworkStats stats;
+        public final int transport;
+        public final boolean withFgbg;
 
-        // Return with PULL_SKIP to indicate there is an error.
-        if (stats == null) return StatsManager.PULL_SKIP;
-
-        addNetworkStats(atomTag, pulledData, stats, withFgbg, 0 /* ratType */);
-        return StatsManager.PULL_SUCCESS;
+        NetworkStatsExt(@NonNull NetworkStats stats, int transport, boolean withFgbg) {
+            this.stats = stats;
+            this.transport = transport;
+            this.withFgbg = withFgbg;
+        }
     }
 
-    private int pullMobileBytesTransfer(
-            int atomTag, @NonNull List<StatsEvent> pulledData, boolean withFgbg) {
+    @NonNull
+    private List<NetworkStatsExt> collectWifiBytesTransferSnapshot(boolean withFgbg) {
+        final List<NetworkStatsExt> ret = new ArrayList<>();
+        final NetworkTemplate template = NetworkTemplate.buildTemplateWifiWildcard();
+        final NetworkStats stats = getUidNetworkStatsSnapshot(template, withFgbg);
+        if (stats != null) {
+            ret.add(new NetworkStatsExt(stats, TRANSPORT_WIFI, withFgbg));
+        }
+        return ret;
+    }
+
+    // Get a snapshot of mobile data usage. The snapshot contains NetworkStats with its associated
+    // information, and wrapped by a list since multiple NetworkStatsExt objects might be collected.
+    // TODO: Slice NetworkStats to multiple objects by RAT type or subscription.
+    @NonNull
+    private List<NetworkStatsExt> collectMobileBytesTransferSnapshot(boolean withFgbg) {
+        final List<NetworkStatsExt> ret = new ArrayList<>();
         final NetworkTemplate template =
                 NetworkTemplate.buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL);
-        final NetworkStats stats = getUidNetworkStatsSinceBoot(template, withFgbg);
+        final NetworkStats stats = getUidNetworkStatsSnapshot(template, withFgbg);
+        if (stats != null) {
+            ret.add(new NetworkStatsExt(stats, TRANSPORT_CELLULAR, withFgbg));
+        }
+        return ret;
+    }
 
-        // Return with PULL_SKIP to indicate there is an error.
-        if (stats == null) return StatsManager.PULL_SKIP;
+    private int pullDataBytesTransfer(
+            int atomTag, @NonNull List<StatsEvent> pulledData, int transport, boolean withFgbg) {
+        final List<NetworkStatsExt> current =
+                (transport == TRANSPORT_CELLULAR ? collectMobileBytesTransferSnapshot(withFgbg)
+                        : collectWifiBytesTransferSnapshot(withFgbg));
 
-        addNetworkStats(atomTag, pulledData, stats, withFgbg, NETWORK_TYPE_ALL);
+        if (current == null) {
+            Slog.e(TAG, "current snapshot is null for " + atomTag + ", return.");
+            return StatsManager.PULL_SKIP;
+        }
+
+        for (final NetworkStatsExt item : current) {
+            final NetworkStatsExt baseline = CollectionUtils.find(mNetworkStatsBaselines,
+                    it -> it.withFgbg == item.withFgbg && it.transport == item.transport);
+
+            // No matched baseline indicates error has occurred during initialization stage,
+            // skip reporting anything since the snapshot is invalid.
+            if (baseline == null) {
+                Slog.e(TAG, "baseline is null for " + atomTag + ", transport="
+                        + item.transport + " , withFgbg=" + withFgbg + ", return.");
+                return StatsManager.PULL_SKIP;
+            }
+            final NetworkStatsExt diff = new NetworkStatsExt(item.stats.subtract(
+                    baseline.stats).removeEmptyEntries(), item.transport, item.withFgbg);
+
+            // If no diff, skip.
+            if (diff.stats.size() == 0) continue;
+
+            addNetworkStats(atomTag, pulledData, diff);
+        }
         return StatsManager.PULL_SUCCESS;
     }
 
     private void addNetworkStats(int atomTag, @NonNull List<StatsEvent> ret,
-            @NonNull NetworkStats stats, boolean withFgbg, int ratType) {
-        int size = stats.size();
+            @NonNull NetworkStatsExt statsExt) {
+        int size = statsExt.stats.size();
         final NetworkStats.Entry entry = new NetworkStats.Entry(); // For recycling
         for (int j = 0; j < size; j++) {
-            stats.getValues(j, entry);
+            statsExt.stats.getValues(j, entry);
             StatsEvent.Builder e = StatsEvent.newBuilder();
             e.setAtomId(atomTag);
             switch (atomTag) {
@@ -765,7 +855,7 @@
             }
             e.writeInt(entry.uid);
             e.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
-            if (withFgbg) {
+            if (statsExt.withFgbg) {
                 e.writeInt(entry.set);
             }
             e.writeLong(entry.rxBytes);
@@ -776,14 +866,23 @@
         }
     }
 
-    @Nullable private NetworkStats getUidNetworkStatsSinceBoot(
+    /**
+     * Create a snapshot of NetworkStats since boot, but add 1 bucket duration before boot as a
+     * buffer to ensure at least one full bucket will be included.
+     * Note that this should be only used to calculate diff since the snapshot might contains
+     * some traffic before boot.
+     */
+    @Nullable private NetworkStats getUidNetworkStatsSnapshot(
             @NonNull NetworkTemplate template, boolean withFgbg) {
 
         final long elapsedMillisSinceBoot = SystemClock.elapsedRealtime();
         final long currentTimeInMillis = MICROSECONDS.toMillis(SystemClock.currentTimeMicro());
+        final long bucketDuration = Settings.Global.getLong(mContext.getContentResolver(),
+                NETSTATS_UID_BUCKET_DURATION, NETSTATS_UID_DEFAULT_BUCKET_DURATION_MS);
         try {
             final NetworkStats stats = getNetworkStatsSession().getSummaryForAllUid(template,
-                    currentTimeInMillis - elapsedMillisSinceBoot, currentTimeInMillis, false);
+                    currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration,
+                    currentTimeInMillis, /*includeTags=*/false);
             return withFgbg ? rollupNetworkStatsByFgbg(stats) : stats.groupedByUid();
         } catch (RemoteException | NullPointerException e) {
             Slog.e(TAG, "Pulling netstats for " + template
@@ -3295,6 +3394,21 @@
         return StatsManager.PULL_SUCCESS;
     }
 
+    private void registerDisplayWakeStats() {
+        int tagId = FrameworkStatsLog.DISPLAY_WAKE_REASON;
+        mStatsManager.setPullAtomCallback(
+                tagId,
+                null, // use default PullAtomMetadata values
+                BackgroundThread.getExecutor(),
+                mStatsCallbackImpl
+        );
+    }
+
+    int pullDisplayWakeStats(int atomTag, List<StatsEvent> pulledData) {
+        //TODO: Denny, implement read/write DisplayWakeStats, b/154172964
+        return 0;
+    }
+
     // Thermal event received from vendor thermal management subsystem
     private static final class ThermalEventListener extends IThermalEventListener.Stub {
         @Override
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 63952b0..31fbaff 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -2743,7 +2743,7 @@
                     mContext, 0,
                     Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
                             mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
-                    0, null, new UserHandle(serviceUserId)));
+                    PendingIntent.FLAG_IMMUTABLE, null, new UserHandle(serviceUserId)));
             if (!mContext.bindServiceAsUser(intent, newConn,
                     Context.BIND_AUTO_CREATE | Context.BIND_SHOWING_UI
                             | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 785ca90..34998a0 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -50,7 +50,7 @@
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.view.Display;
-import android.view.InsetsState;
+import android.view.InsetsSource;
 import android.view.MagnificationSpec;
 import android.view.Surface;
 import android.view.Surface.OutOfResourcesException;
@@ -80,6 +80,7 @@
 
     private final WindowManagerService mService;
 
+    private static final Rect EMPTY_RECT = new Rect();
     private static final float[] sTempFloats = new float[9];
 
     public AccessibilityController(WindowManagerService service) {
@@ -1166,9 +1167,9 @@
     }
 
     static Rect getNavBarInsets(DisplayContent displayContent) {
-        final InsetsState insetsState =
-                displayContent.getInsetsStateController().getRawInsetsState();
-        return insetsState.getSource(ITYPE_NAVIGATION_BAR).getFrame();
+        final InsetsSource source = displayContent.getInsetsStateController().getRawInsetsState()
+                .peekSource(ITYPE_NAVIGATION_BAR);
+        return source != null ? source.getFrame() : EMPTY_RECT;
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 131e449..91c849c 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1705,7 +1705,7 @@
     boolean addStartingWindow(String pkg, int theme, CompatibilityInfo compatInfo,
             CharSequence nonLocalizedLabel, int labelRes, int icon, int logo, int windowFlags,
             IBinder transferFrom, boolean newTask, boolean taskSwitch, boolean processRunning,
-            boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents) {
+            boolean allowTaskSnapshot, boolean activityCreated) {
         // If the display is frozen, we won't do anything until the actual window is
         // displayed so there is no reason to put in the starting window.
         if (!okToDisplay()) {
@@ -1726,7 +1726,7 @@
                 mWmService.mTaskSnapshotController.getSnapshot(task.mTaskId, task.mUserId,
                         false /* restoreFromDisk */, false /* isLowResolution */);
         final int type = getStartingWindowType(newTask, taskSwitch, processRunning,
-                allowTaskSnapshot, activityCreated, fromRecents, snapshot);
+                allowTaskSnapshot, activityCreated, snapshot);
 
         if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
             if (isActivityTypeHome()) {
@@ -1888,12 +1888,12 @@
     private final AddStartingWindow mAddStartingWindow = new AddStartingWindow();
 
     private int getStartingWindowType(boolean newTask, boolean taskSwitch, boolean processRunning,
-            boolean allowTaskSnapshot, boolean activityCreated, boolean fromRecents,
+            boolean allowTaskSnapshot, boolean activityCreated,
             ActivityManager.TaskSnapshot snapshot) {
         if (newTask || !processRunning || (taskSwitch && !activityCreated)) {
             return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
         } else if (taskSwitch && allowTaskSnapshot) {
-            if (snapshotOrientationSameAsTask(snapshot) || (snapshot != null && fromRecents)) {
+            if (isSnapshotCompatible(snapshot)) {
                 return STARTING_WINDOW_TYPE_SNAPSHOT;
             }
             if (!isActivityTypeHome()) {
@@ -1905,11 +1905,22 @@
         }
     }
 
-    private boolean snapshotOrientationSameAsTask(ActivityManager.TaskSnapshot snapshot) {
+    /**
+     * Returns {@code true} if the task snapshot is compatible with this activity (at least the
+     * rotation must be the same).
+     */
+    @VisibleForTesting
+    boolean isSnapshotCompatible(ActivityManager.TaskSnapshot snapshot) {
         if (snapshot == null) {
             return false;
         }
-        return task.getConfiguration().orientation == snapshot.getOrientation();
+        final int rotation = mDisplayContent.rotationForActivityInDifferentOrientation(this);
+        final int targetRotation = rotation != ROTATION_UNDEFINED
+                // The display may rotate according to the orientation of this activity.
+                ? rotation
+                // The activity won't change display orientation.
+                : task.getWindowConfiguration().getRotation();
+        return snapshot.getRotation() == targetRotation;
     }
 
     void removeStartingWindow() {
@@ -2184,8 +2195,10 @@
 
     @Override
     boolean isFocusable() {
-        return super.isFocusable()
-                && (getWindowConfiguration().canReceiveKeys() || isAlwaysFocusable());
+        // TODO(156521483): Propagate the state down the hierarchy instead of checking the parent
+        boolean canReceiveKeys = getWindowConfiguration().canReceiveKeys()
+                && getTask().getWindowConfiguration().canReceiveKeys();
+        return super.isFocusable() && (canReceiveKeys || isAlwaysFocusable());
     }
 
     boolean isResizeable() {
@@ -4785,16 +4798,7 @@
         if (!task.hasChild(this)) {
             throw new IllegalStateException("Activity not found in its task");
         }
-        final ActivityRecord activityAbove = task.getActivityAbove(this);
-        if (activityAbove == null) {
-            // It's the topmost activity in the task - should become resumed now
-            return true;
-        }
-        // Check if activity above is finishing now and this one becomes the topmost in task.
-        if (activityAbove.finishing) {
-            return true;
-        }
-        return false;
+        return task.topRunningActivity() == this;
     }
 
     void handleAlreadyVisible() {
@@ -5673,11 +5677,6 @@
     }
 
     void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch) {
-        showStartingWindow(prev, newTask, taskSwitch, false /* fromRecents */);
-    }
-
-    void showStartingWindow(ActivityRecord prev, boolean newTask, boolean taskSwitch,
-            boolean fromRecents) {
         if (mTaskOverlay) {
             // We don't show starting window for overlay activities.
             return;
@@ -5694,8 +5693,7 @@
                 compatInfo, nonLocalizedLabel, labelRes, icon, logo, windowFlags,
                 prev != null ? prev.appToken : null, newTask, taskSwitch, isProcessRunning(),
                 allowTaskSnapshot(),
-                mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal(),
-                fromRecents);
+                mState.ordinal() >= STARTED.ordinal() && mState.ordinal() <= STOPPED.ordinal());
         if (shown) {
             mStartingWindowState = STARTING_WINDOW_SHOWN;
         }
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index dca0860..cb2d98c 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -1307,17 +1307,8 @@
     /**
      * Make sure that all activities that need to be visible in the stack (that is, they
      * currently can be seen by the user) actually are and update their configuration.
-     * @param starting The top most activity in the task.
-     *                 The activity is either starting or resuming.
-     *                 Caller should ensure starting activity is visible.
-     * @param preserveWindows Flag indicating whether windows should be preserved when updating
-     *                        configuration in {@link mEnsureActivitiesVisibleHelper}.
-     * @param configChanges Parts of the configuration that changed for this activity for evaluating
-     *                      if the screen should be frozen as part of
-     *                      {@link mEnsureActivitiesVisibleHelper}.
-     *
      */
-    void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
+    void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
             boolean preserveWindows) {
         ensureActivitiesVisible(starting, configChanges, preserveWindows, true /* notifyClients */);
     }
@@ -1326,19 +1317,9 @@
      * Ensure visibility with an option to also update the configuration of visible activities.
      * @see #ensureActivitiesVisible(ActivityRecord, int, boolean)
      * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
-     * @param starting The top most activity in the task.
-     *                 The activity is either starting or resuming.
-     *                 Caller should ensure starting activity is visible.
-     * @param notifyClients Flag indicating whether the visibility updates should be sent to the
-     *                      clients in {@link mEnsureActivitiesVisibleHelper}.
-     * @param preserveWindows Flag indicating whether windows should be preserved when updating
-     *                        configuration in {@link mEnsureActivitiesVisibleHelper}.
-     * @param configChanges Parts of the configuration that changed for this activity for evaluating
-     *                      if the screen should be frozen as part of
-     *                      {@link mEnsureActivitiesVisibleHelper}.
      */
     // TODO: Should be re-worked based on the fact that each task as a stack in most cases.
-    void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
+    void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
             boolean preserveWindows, boolean notifyClients) {
         mTopActivityOccludesKeyguard = false;
         mTopDismissingKeyguardActivity = null;
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 3e7e0c8..62979ff 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -2498,7 +2498,7 @@
                         mActivityMetricsLogger.notifyActivityLaunching(task.intent);
                 try {
                     mService.moveTaskToFrontLocked(null /* appThread */, null /* callingPackage */,
-                            task.mTaskId, 0, options, true /* fromRecents */);
+                            task.mTaskId, 0, options);
                     // Apply options to prevent pendingOptions be taken by client to make sure
                     // the override pending app transition will be applied immediately.
                     targetActivity.applyOptionsLocked();
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index bcdd6e3..79e8ee3 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1539,10 +1539,7 @@
      *
      * Note: This method should only be called from {@link #startActivityUnchecked}.
      */
-
-    // TODO(b/152429287): Make it easier to exercise code paths through startActivityInner
-    @VisibleForTesting
-    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
+    private int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
             int startFlags, boolean doResume, ActivityOptions options, Task inTask,
             boolean restrictedBgActivity) {
@@ -1663,10 +1660,7 @@
                 // Also, we don't want to resume activities in a task that currently has an overlay
                 // as the starting activity just needs to be in the visible paused state until the
                 // over is removed.
-                // Passing {@code null} as the start parameter ensures all activities are made
-                // visible.
-                mTargetStack.ensureActivitiesVisible(null /* starting */,
-                        0 /* configChanges */, !PRESERVE_WINDOWS);
+                mTargetStack.ensureActivitiesVisible(mStartActivity, 0, !PRESERVE_WINDOWS);
                 // Go ahead and tell window manager to execute app transition for this activity
                 // since the app transition will not be triggered through the resume channel.
                 mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index f21ec6b..78e4237 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2476,13 +2476,12 @@
         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
         synchronized (mGlobalLock) {
             moveTaskToFrontLocked(appThread, callingPackage, taskId, flags,
-                    SafeActivityOptions.fromBundle(bOptions), false /* fromRecents */);
+                    SafeActivityOptions.fromBundle(bOptions));
         }
     }
 
     void moveTaskToFrontLocked(@Nullable IApplicationThread appThread,
-            @Nullable String callingPackage, int taskId, int flags, SafeActivityOptions options,
-            boolean fromRecents) {
+            @Nullable String callingPackage, int taskId, int flags, SafeActivityOptions options) {
         final int callingPid = Binder.getCallingPid();
         final int callingUid = Binder.getCallingUid();
         assertPackageMatchesCallingUid(callingPackage);
@@ -2527,7 +2526,7 @@
                 // We are reshowing a task, use a starting window to hide the initial draw delay
                 // so the transition can start earlier.
                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
-                        true /* taskSwitch */, fromRecents);
+                        true /* taskSwitch */);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
@@ -3213,7 +3212,7 @@
             if (TextUtils.equals(pae.intent.getAction(),
                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
                 // Start voice interaction through VoiceInteractionManagerService.
-                mAssistUtils.showSessionForActiveService(sendBundle, SHOW_SOURCE_APPLICATION,
+                mAssistUtils.showSessionForActiveService(pae.extras, SHOW_SOURCE_APPLICATION,
                         null, null);
             } else {
                 pae.intent.replaceExtras(pae.extras);
diff --git a/services/core/java/com/android/server/wm/AnimationAdapter.java b/services/core/java/com/android/server/wm/AnimationAdapter.java
index 0519b80..529c4f6 100644
--- a/services/core/java/com/android/server/wm/AnimationAdapter.java
+++ b/services/core/java/com/android/server/wm/AnimationAdapter.java
@@ -85,4 +85,25 @@
     }
 
     void dumpDebug(ProtoOutputStream proto);
+
+    /**
+     * Gets called when the animation is about to finish and gives the client the opportunity to
+     * defer finishing the animation, i.e. it keeps the leash around until the client calls
+     * endDeferFinishCallback.
+     * <p>
+     * This has the same effect as
+     * {@link com.android.server.wm.SurfaceAnimator.Animatable#shouldDeferAnimationFinish(Runnable)}
+     * . The later will be evaluated first and has precedence over this method if it returns true,
+     * which means that if the {@link com.android.server.wm.SurfaceAnimator.Animatable} requests to
+     * defer its finish, this method won't be called so this adapter will never have access to the
+     * finish callback. On the other hand, if the
+     * {@link com.android.server.wm.SurfaceAnimator.Animatable}, doesn't request to defer, this
+     * {@link AnimationAdapter} is responsible for ending the animation.
+     *
+     * @param endDeferFinishCallback The callback to call when defer finishing should be ended.
+     * @return Whether the client would like to defer the animation finish.
+     */
+    default boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e31eaf7..3acb127 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -235,7 +235,6 @@
         implements WindowManagerPolicy.DisplayContentInfo {
     private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
     private static final String TAG_STACK = TAG + POSTFIX_STACK;
-    private static final int NO_ROTATION = -1;
 
     /** The default scaling mode that scales content automatically. */
     static final int FORCE_SCALING_MODE_AUTO = 0;
@@ -499,6 +498,8 @@
      */
     ActivityRecord mFixedRotationLaunchingApp;
 
+    FixedRotationAnimationController mFixedRotationAnimationController;
+
     final FixedRotationTransitionListener mFixedRotationTransitionListener =
             new FixedRotationTransitionListener();
 
@@ -1392,36 +1393,40 @@
         final WindowContainer orientationSource = getLastOrientationSource();
         final ActivityRecord r =
                 orientationSource != null ? orientationSource.asActivityRecord() : null;
-        if (r != null && r.getTask() != null
-                && orientation != r.getTask().mLastReportedRequestedOrientation) {
+        if (r != null) {
             final Task task = r.getTask();
-            task.mLastReportedRequestedOrientation = orientation;
-            mAtmService.getTaskChangeNotificationController()
-                    .notifyTaskRequestedOrientationChanged(task.mTaskId, orientation);
-        }
-        // Currently there is no use case from non-activity.
-        if (r != null && handleTopActivityLaunchingInDifferentOrientation(r)) {
-            // Display orientation should be deferred until the top fixed rotation is finished.
-            return false;
+            if (task != null && orientation != task.mLastReportedRequestedOrientation) {
+                task.mLastReportedRequestedOrientation = orientation;
+                mAtmService.getTaskChangeNotificationController()
+                        .notifyTaskRequestedOrientationChanged(task.mTaskId, orientation);
+            }
+            // Currently there is no use case from non-activity.
+            if (handleTopActivityLaunchingInDifferentOrientation(r, true /* checkOpening */)) {
+                // Display orientation should be deferred until the top fixed rotation is finished.
+                return false;
+            }
         }
         return mDisplayRotation.updateOrientation(orientation, forceUpdate);
     }
 
-    /** @return a valid rotation if the activity can use different orientation than the display. */
+    /**
+     * Returns a valid rotation if the activity can use different orientation than the display.
+     * Otherwise {@link #ROTATION_UNDEFINED}.
+     */
     @Surface.Rotation
-    private int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
+    int rotationForActivityInDifferentOrientation(@NonNull ActivityRecord r) {
         if (!mWmService.mIsFixedRotationTransformEnabled) {
-            return NO_ROTATION;
+            return ROTATION_UNDEFINED;
         }
         if (r.inMultiWindowMode()
                 || r.getRequestedConfigurationOrientation() == getConfiguration().orientation) {
-            return NO_ROTATION;
+            return ROTATION_UNDEFINED;
         }
         final int currentRotation = getRotation();
         final int rotation = mDisplayRotation.rotationForOrientation(r.getRequestedOrientation(),
                 currentRotation);
         if (rotation == currentRotation) {
-            return NO_ROTATION;
+            return ROTATION_UNDEFINED;
         }
         return rotation;
     }
@@ -1431,9 +1436,13 @@
      * is launching until the launch animation is done to avoid showing the previous activity
      * inadvertently in a wrong orientation.
      *
+     * @param r The launching activity which may change display orientation.
+     * @param checkOpening Whether to check if the activity is animating by transition. Set to
+     *                     {@code true} if the caller is not sure whether the activity is launching.
      * @return {@code true} if the fixed rotation is started.
      */
-    private boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r) {
+    boolean handleTopActivityLaunchingInDifferentOrientation(@NonNull ActivityRecord r,
+            boolean checkOpening) {
         if (!mWmService.mIsFixedRotationTransformEnabled) {
             return false;
         }
@@ -1444,19 +1453,18 @@
             // It has been set and not yet finished.
             return true;
         }
-        if (!mAppTransition.isTransitionSet()) {
-            // Apply normal rotation animation in case of the activity set different requested
-            // orientation without activity switch.
-            return false;
-        }
-        if (!mOpeningApps.contains(r)
-                // Without screen rotation, the rotation behavior of non-top visible activities is
-                // undefined. So the fixed rotated activity needs to cover the screen.
-                && r.findMainWindow() != mDisplayPolicy.getTopFullscreenOpaqueWindow()) {
+        if (checkOpening) {
+            if (!mAppTransition.isTransitionSet() && !mOpeningApps.contains(r)) {
+                // Apply normal rotation animation in case of the activity set different requested
+                // orientation without activity switch.
+                return false;
+            }
+        } else if (r != topRunningActivity()) {
+            // If the transition has not started yet, the activity must be the top.
             return false;
         }
         final int rotation = rotationForActivityInDifferentOrientation(r);
-        if (rotation == NO_ROTATION) {
+        if (rotation == ROTATION_UNDEFINED) {
             return false;
         }
         if (!r.getParent().matchParentBounds()) {
@@ -1509,6 +1517,10 @@
             sendNewConfiguration();
             return;
         }
+        if (mDisplayRotation.isWaitingForRemoteRotation()) {
+            // There is pending rotation change to apply.
+            return;
+        }
         // The orientation of display is not changed.
         clearFixedRotationLaunchingApp();
     }
@@ -1528,6 +1540,11 @@
     }
 
     private void startFixedRotationTransform(WindowToken token, int rotation) {
+        if (mFixedRotationAnimationController == null) {
+            mFixedRotationAnimationController = new FixedRotationAnimationController(
+                    this);
+        }
+        mFixedRotationAnimationController.hide(rotation);
         mTmpConfiguration.unset();
         final DisplayInfo info = computeScreenConfiguration(mTmpConfiguration, rotation);
         final WmDisplayCutout cutout = calculateDisplayCutoutForRotation(rotation);
@@ -1544,11 +1561,18 @@
      */
     void rotateInDifferentOrientationIfNeeded(ActivityRecord activityRecord) {
         int rotation = rotationForActivityInDifferentOrientation(activityRecord);
-        if (rotation != NO_ROTATION) {
+        if (rotation != ROTATION_UNDEFINED) {
             startFixedRotationTransform(activityRecord, rotation);
         }
     }
 
+    void finishFixedRotationAnimation() {
+        if (mFixedRotationAnimationController != null
+                && mFixedRotationAnimationController.show()) {
+            mFixedRotationAnimationController = null;
+        }
+    }
+
     /**
      * Update rotation of the display.
      *
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index eb5cff6..2e18fbf 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -874,10 +874,6 @@
                 }
                 break;
 
-            case TYPE_SCREENSHOT:
-                attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-                break;
-
             case TYPE_TOAST:
                 // While apps should use the dedicated toast APIs to add such windows
                 // it possible legacy apps to add the window directly. Therefore, we
@@ -2036,9 +2032,13 @@
             final Rect dfu = displayFrames.mUnrestricted;
             Insets insets = Insets.of(0, 0, 0, 0);
             for (int i = types.size() - 1; i >= 0; i--) {
-                insets = Insets.max(insets, mDisplayContent.getInsetsPolicy()
-                        .getInsetsForDispatch(win).getSource(types.valueAt(i))
-                        .calculateInsets(dfu, attrs.isFitInsetsIgnoringVisibility()));
+                final InsetsSource source = mDisplayContent.getInsetsPolicy()
+                        .getInsetsForDispatch(win).peekSource(types.valueAt(i));
+                if (source == null) {
+                    continue;
+                }
+                insets = Insets.max(insets, source.calculateInsets(
+                        dfu, attrs.isFitInsetsIgnoringVisibility()));
             }
             final int left = (sidesToFit & Side.LEFT) != 0 ? insets.left : 0;
             final int top = (sidesToFit & Side.TOP) != 0 ? insets.top : 0;
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index ebfe70c..c3f9061 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -560,6 +560,7 @@
         }, true /* traverseTopToBottom */);
         mSeamlessRotationCount = 0;
         mRotatingSeamlessly = false;
+        mDisplayContent.finishFixedRotationAnimation();
     }
 
     private void prepareSeamlessRotation() {
@@ -646,6 +647,7 @@
                     "Performing post-rotate rotation after seamless rotation");
             // Finish seamless rotation.
             mRotatingSeamlessly = false;
+            mDisplayContent.finishFixedRotationAnimation();
 
             updateRotationAndSendNewConfigIfChanged();
         }
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index 9bbd4cd..5a24847 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -135,6 +135,7 @@
         final int mOwnerPid;
         final WindowManagerService mWmService;
         InputChannel mInputChannel;
+        final int mWindowType;
 
         /**
          * @param clientToken client token used to clean up the map if the embedding process dies
@@ -146,7 +147,7 @@
          * @param ownerPid  calling pid used for anr blaming
          */
         EmbeddedWindow(WindowManagerService service, IWindow clientToken,
-                WindowState hostWindowState, int ownerUid, int ownerPid) {
+                WindowState hostWindowState, int ownerUid, int ownerPid, int windowType) {
             mWmService = service;
             mClient = clientToken;
             mHostWindowState = hostWindowState;
@@ -154,6 +155,7 @@
                     : null;
             mOwnerUid = ownerUid;
             mOwnerPid = ownerPid;
+            mWindowType = windowType;
         }
 
         String getName() {
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index c4e03f5..c92de2b 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -21,7 +21,6 @@
 import static com.android.server.wm.ActivityStack.TAG_VISIBILITY;
 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
 
-import android.annotation.Nullable;
 import android.util.Slog;
 
 import com.android.internal.util.function.pooled.PooledConsumer;
@@ -43,16 +42,6 @@
         mContiner = container;
     }
 
-    /**
-     * Update all attributes except {@link mContiner} to use in subsequent calculations.
-     *
-     * @param starting The activity that is being started
-     * @param configChanges Parts of the configuration that changed for this activity for evaluating
-     *                      if the screen should be frozen.
-     * @param preserveWindows Flag indicating whether windows should be preserved when updating.
-     * @param notifyClients Flag indicating whether the configuration and visibility changes shoulc
-     *                      be sent to the clients.
-     */
     void reset(ActivityRecord starting, int configChanges, boolean preserveWindows,
             boolean notifyClients) {
         mStarting = starting;
@@ -71,17 +60,8 @@
      * Ensure visibility with an option to also update the configuration of visible activities.
      * @see ActivityStack#ensureActivitiesVisible(ActivityRecord, int, boolean)
      * @see RootWindowContainer#ensureActivitiesVisible(ActivityRecord, int, boolean)
-     * @param starting The top most activity in the task.
-     *                 The activity is either starting or resuming.
-     *                 Caller should ensure starting activity is visible.
-     *
-     * @param configChanges Parts of the configuration that changed for this activity for evaluating
-     *                      if the screen should be frozen.
-     * @param preserveWindows Flag indicating whether windows should be preserved when updating.
-     * @param notifyClients Flag indicating whether the configuration and visibility changes shoulc
-     *                      be sent to the clients.
      */
-    void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows,
+    void process(ActivityRecord starting, int configChanges, boolean preserveWindows,
             boolean notifyClients) {
         reset(starting, configChanges, preserveWindows, notifyClients);
 
diff --git a/services/core/java/com/android/server/wm/FixedRotationAnimationController.java b/services/core/java/com/android/server/wm/FixedRotationAnimationController.java
new file mode 100644
index 0000000..7aca637
--- /dev/null
+++ b/services/core/java/com/android/server/wm/FixedRotationAnimationController.java
@@ -0,0 +1,197 @@
+/*
+ * 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.server.wm;
+
+import static com.android.server.wm.AnimationSpecProto.WINDOW;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_FIXED_TRANSFORM;
+import static com.android.server.wm.WindowAnimationSpecProto.ANIMATION;
+
+import android.content.res.Configuration;
+import android.util.proto.ProtoOutputStream;
+import android.view.SurfaceControl;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Transformation;
+
+import com.android.internal.R;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Controller to fade out and in system ui when applying a fixed rotation transform to a window
+ * token.
+ *
+ * The system bars will be fade out when the fixed rotation transform starts and will be fade in
+ * once all surfaces have been rotated.
+ */
+public class FixedRotationAnimationController {
+
+    private final WindowManagerService mWmService;
+    private boolean mShowRequested = true;
+    private int mTargetRotation = Configuration.ORIENTATION_UNDEFINED;
+    private final ArrayList<WindowState> mAnimatedWindowStates = new ArrayList<>(2);
+    private final Runnable[] mDeferredFinishCallbacks;
+
+    public FixedRotationAnimationController(DisplayContent displayContent) {
+        mWmService = displayContent.mWmService;
+        addAnimatedWindow(displayContent.getDisplayPolicy().getStatusBar());
+        addAnimatedWindow(displayContent.getDisplayPolicy().getNavigationBar());
+        mDeferredFinishCallbacks = new Runnable[mAnimatedWindowStates.size()];
+    }
+
+    private void addAnimatedWindow(WindowState windowState) {
+        if (windowState != null) {
+            mAnimatedWindowStates.add(windowState);
+        }
+    }
+
+    /**
+     * Show the previously hidden {@link WindowToken} if their surfaces have already been rotated.
+     *
+     * @return True if the show animation has been started, in which case the caller no longer needs
+     * this {@link FixedRotationAnimationController}.
+     */
+    boolean show() {
+        if (!mShowRequested && readyToShow()) {
+            mShowRequested = true;
+            for (int i = mAnimatedWindowStates.size() - 1; i >= 0; i--) {
+                WindowState windowState = mAnimatedWindowStates.get(i);
+                fadeWindowToken(true, windowState.getParent(), i);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    void hide(int targetRotation) {
+        mTargetRotation = targetRotation;
+        if (mShowRequested) {
+            mShowRequested = false;
+            for (int i = mAnimatedWindowStates.size() - 1; i >= 0; i--) {
+                WindowState windowState = mAnimatedWindowStates.get(i);
+                fadeWindowToken(false /* show */, windowState.getParent(), i);
+            }
+        }
+    }
+
+    void cancel() {
+        for (int i = mAnimatedWindowStates.size() - 1; i >= 0; i--) {
+            WindowState windowState = mAnimatedWindowStates.get(i);
+            mShowRequested = true;
+            fadeWindowToken(true /* show */, windowState.getParent(), i);
+        }
+    }
+
+    private void fadeWindowToken(boolean show, WindowContainer<WindowToken> windowToken,
+            int index) {
+        Animation animation = AnimationUtils.loadAnimation(mWmService.mContext,
+                show ? R.anim.fade_in : R.anim.fade_out);
+        LocalAnimationAdapter.AnimationSpec windowAnimationSpec = createAnimationSpec(animation);
+
+        FixedRotationAnimationAdapter animationAdapter = new FixedRotationAnimationAdapter(
+                windowAnimationSpec, windowToken.getSurfaceAnimationRunner(), show, index);
+
+        // We deferred the end of the animation when hiding the token, so we need to end it now that
+        // it's shown again.
+        SurfaceAnimator.OnAnimationFinishedCallback finishedCallback = show ? (t, r) -> {
+            if (mDeferredFinishCallbacks[index] != null) {
+                mDeferredFinishCallbacks[index].run();
+                mDeferredFinishCallbacks[index] = null;
+            }
+        } : null;
+        windowToken.startAnimation(windowToken.getPendingTransaction(), animationAdapter,
+                mShowRequested, ANIMATION_TYPE_FIXED_TRANSFORM, finishedCallback);
+    }
+
+    /**
+     * Check if all the mAnimatedWindowState's surfaces have been rotated to the
+     * mTargetRotation.
+     */
+    private boolean readyToShow() {
+        for (int i = mAnimatedWindowStates.size() - 1; i >= 0; i--) {
+            WindowState windowState = mAnimatedWindowStates.get(i);
+            if (windowState.getConfiguration().windowConfiguration.getRotation()
+                    != mTargetRotation || windowState.mPendingSeamlessRotate != null) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    private LocalAnimationAdapter.AnimationSpec createAnimationSpec(Animation animation) {
+        return new LocalAnimationAdapter.AnimationSpec() {
+
+            Transformation mTransformation = new Transformation();
+
+            @Override
+            public boolean getShowWallpaper() {
+                return true;
+            }
+
+            @Override
+            public long getDuration() {
+                return animation.getDuration();
+            }
+
+            @Override
+            public void apply(SurfaceControl.Transaction t, SurfaceControl leash,
+                    long currentPlayTime) {
+                mTransformation.clear();
+                animation.getTransformation(currentPlayTime, mTransformation);
+                t.setAlpha(leash, mTransformation.getAlpha());
+            }
+
+            @Override
+            public void dump(PrintWriter pw, String prefix) {
+                pw.print(prefix);
+                pw.println(animation);
+            }
+
+            @Override
+            public void dumpDebugInner(ProtoOutputStream proto) {
+                final long token = proto.start(WINDOW);
+                proto.write(ANIMATION, animation.toString());
+                proto.end(token);
+            }
+        };
+    }
+
+    private class FixedRotationAnimationAdapter extends LocalAnimationAdapter {
+        private final boolean mShow;
+        private final int mIndex;
+
+        FixedRotationAnimationAdapter(AnimationSpec windowAnimationSpec,
+                SurfaceAnimationRunner surfaceAnimationRunner, boolean show, int index) {
+            super(windowAnimationSpec, surfaceAnimationRunner);
+            mShow = show;
+            mIndex = index;
+        }
+
+        @Override
+        public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
+            // We defer the end of the hide animation to ensure the tokens stay hidden until
+            // we show them again.
+            if (!mShow) {
+                mDeferredFinishCallbacks[mIndex] = endDeferFinishCallback;
+                return true;
+            }
+            return false;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index c93b735..a2979e6 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -327,7 +327,7 @@
             documentData = isDocument ? intent.getData() : null;
 
             if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + target + " in " + parent);
-            parent.forAllTasks(this);
+            parent.forAllLeafTasks(this);
         }
 
         void clear() {
@@ -2188,6 +2188,10 @@
                 // display area, so reparent.
                 stack.reparent(taskDisplayArea, true /* onTop */);
             }
+            // Defer the windowing mode change until after the transition to prevent the activity
+            // from doing work and changing the activity visuals while animating
+            // TODO(task-org): Figure-out more structured way to do this long term.
+            r.setWindowingMode(stack.getWindowingMode());
             stack.setWindowingMode(WINDOWING_MODE_PINNED);
 
             // Reset the state that indicates it can enter PiP while pausing after we've moved it
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index bf20cb9..e225809 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -91,6 +91,7 @@
     private float mLastReportedAnimatorScale;
     private String mPackageName;
     private String mRelayoutTag;
+    private final InsetsSourceControl[] mDummyControls =  new InsetsSourceControl[0];
 
     public Session(WindowManagerService service, IWindowSessionCallback callback) {
         mService = service;
@@ -184,7 +185,7 @@
         return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
                 new Rect() /* outFrame */, outContentInsets, outStableInsets,
                 new DisplayCutout.ParcelableWrapper() /* cutout */, null /* outInputChannel */,
-                outInsetsState, null, UserHandle.getUserId(mUid));
+                outInsetsState, mDummyControls, UserHandle.getUserId(mUid));
     }
 
     @Override
@@ -661,17 +662,23 @@
 
     @Override
     public void grantInputChannel(int displayId, SurfaceControl surface,
-            IWindow window, IBinder hostInputToken, int flags, InputChannel outInputChannel) {
+            IWindow window, IBinder hostInputToken, int flags, int type,
+            InputChannel outInputChannel) {
         if (hostInputToken == null && !mCanAddInternalSystemWindow) {
             // Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
             // embedded windows without providing a host window input token
             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
         }
 
+        if (!mCanAddInternalSystemWindow && type != 0) {
+            Slog.w(TAG_WM, "Requires INTERNAL_SYSTEM_WINDOW permission if assign type to"
+                    + " input");
+        }
+
         final long identity = Binder.clearCallingIdentity();
         try {
             mService.grantInputChannel(mUid, mPid, displayId, surface, window, hostInputToken,
-                    flags, outInputChannel);
+                    flags, mCanAddInternalSystemWindow ? type : 0, outInputChannel);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index 18e32c0..0143eb1 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -109,7 +109,10 @@
                         animationFinishCallback.onAnimationFinished(type, anim);
                     }
                 };
-                if (!mAnimatable.shouldDeferAnimationFinish(resetAndInvokeFinish)) {
+                // If both the Animatable and AnimationAdapter requests to be deferred, only the
+                // first one will be called.
+                if (!(mAnimatable.shouldDeferAnimationFinish(resetAndInvokeFinish)
+                        || anim.shouldDeferAnimationFinish(resetAndInvokeFinish))) {
                     resetAndInvokeFinish.run();
                 }
             }
@@ -486,6 +489,12 @@
     static final int ANIMATION_TYPE_INSETS_CONTROL = 1 << 5;
 
     /**
+     * Animation when a fixed rotation transform is applied to a window token.
+     * @hide
+     */
+    static final int ANIMATION_TYPE_FIXED_TRANSFORM = 1 << 6;
+
+    /**
      * Bitmask to include all animation types. This is NOT an {@link AnimationType}
      * @hide
      */
@@ -502,7 +511,8 @@
             ANIMATION_TYPE_DIMMER,
             ANIMATION_TYPE_RECENTS,
             ANIMATION_TYPE_WINDOW_ANIMATION,
-            ANIMATION_TYPE_INSETS_CONTROL
+            ANIMATION_TYPE_INSETS_CONTROL,
+            ANIMATION_TYPE_FIXED_TRANSFORM
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface AnimationType {}
@@ -592,6 +602,12 @@
          * Gets called when the animation is about to finish and gives the client the opportunity to
          * defer finishing the animation, i.e. it keeps the leash around until the client calls
          * {@link #cancelAnimation}.
+         * <p>
+         * {@link AnimationAdapter} has a similar method which is called only if this method returns
+         * false. This mean that if both this {@link Animatable} and the {@link AnimationAdapter}
+         * request to be deferred, this method is the sole responsible to call
+         * endDeferFinishCallback. On the other hand, the animation finish might still be deferred
+         * if this method return false and the one from the {@link AnimationAdapter} returns true.
          *
          * @param endDeferFinishCallback The callback to call when defer finishing should be ended.
          * @return Whether the client would like to defer the animation finish.
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b9e6513..cc72dcf 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -942,7 +942,7 @@
             return;
         }
 
-        affinity = info.taskAffinity;
+        affinity = isLeafTask() ? info.taskAffinity : null;
         if (intent == null) {
             // If this task already has an intent associated with it, don't set the root
             // affinity -- we don't want it changing after initially set, but the initially
@@ -1940,7 +1940,6 @@
                 setLastNonFullscreenBounds(currentBounds);
             }
         }
-        // TODO: Should also take care of Pip mode changes here.
 
         saveLaunchingStateIfNeeded();
         final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */);
@@ -3400,6 +3399,24 @@
     }
 
     @Override
+    boolean forAllLeafTasks(Function<Task, Boolean> callback) {
+        boolean isLeafTask = true;
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final Task child = mChildren.get(i).asTask();
+            if (child != null) {
+                isLeafTask = false;
+                if (child.forAllLeafTasks(callback)) {
+                    return true;
+                }
+            }
+        }
+        if (isLeafTask) {
+            return callback.apply(this);
+        }
+        return false;
+    }
+
+    @Override
     Task getTask(Predicate<Task> callback, boolean traverseTopToBottom) {
         final Task t = super.getTask(callback, traverseTopToBottom);
         if (t != null) return t;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 0f5cafe..1a2672b 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -297,6 +297,13 @@
             Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task);
             return false;
         }
+        if (activity.hasFixedRotationTransform()) {
+            if (DEBUG_SCREENSHOT) {
+                Slog.i(TAG_WM, "Skip taking screenshot. App has fixed rotation " + activity);
+            }
+            // The activity is in a temporal state that it has different rotation than the task.
+            return false;
+        }
 
         builder.setIsRealSnapshot(true);
         builder.setId(System.currentTimeMillis());
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 24cd7d1..3925570 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -195,6 +195,16 @@
                         + activity);
                 return null;
             }
+            if (topFullscreenActivity.getWindowConfiguration().getRotation()
+                    != snapshot.getRotation()) {
+                // The snapshot should have been checked by ActivityRecord#isSnapshotCompatible
+                // that the activity will be updated to the same rotation as the snapshot. Since
+                // the transition is not started yet, fixed rotation transform needs to be applied
+                // earlier to make the snapshot show in a rotated container.
+                activity.mDisplayContent.handleTopActivityLaunchingInDifferentOrientation(
+                        topFullscreenActivity, false /* checkOpening */);
+            }
+
             sysUiVis = topFullscreenOpaqueWindow.getSystemUiVisibility();
             WindowManager.LayoutParams attrs = topFullscreenOpaqueWindow.mAttrs;
             windowFlags = attrs.flags;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 3f8d7b5..5d7ec12 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1552,6 +1552,15 @@
         return false;
     }
 
+    boolean forAllLeafTasks(Function<Task, Boolean> callback) {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            if (mChildren.get(i).forAllLeafTasks(callback)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * For all tasks at or below this container call the callback.
      *
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 4c1d6f3..5c21b2b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1387,6 +1387,7 @@
             DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
             InsetsState outInsetsState, InsetsSourceControl[] outActiveControls,
             int requestUserId) {
+        Arrays.fill(outActiveControls, null);
         int[] appOp = new int[1];
         final boolean isRoundedCornerOverlay = (attrs.privateFlags
                 & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0;
@@ -2133,6 +2134,7 @@
             SurfaceControl outSurfaceControl, InsetsState outInsetsState,
             InsetsSourceControl[] outActiveControls, Point outSurfaceSize,
             SurfaceControl outBLASTSurfaceControl) {
+        Arrays.fill(outActiveControls, null);
         int result = 0;
         boolean configChanged;
         final int pid = Binder.getCallingPid();
@@ -2470,23 +2472,20 @@
     }
 
     private void getInsetsSourceControls(WindowState win, InsetsSourceControl[] outControls) {
-        if (outControls != null) {
-            final InsetsSourceControl[] controls =
-                    win.getDisplayContent().getInsetsStateController().getControlsForDispatch(win);
-            Arrays.fill(outControls, null);
-            if (controls != null) {
-                final int length = Math.min(controls.length, outControls.length);
-                for (int i = 0; i < length; i++) {
-                    // We will leave the critical section before returning the leash to the client,
-                    // so we need to copy the leash to prevent others release the one that we are
-                    // about to return.
-                    // TODO: We will have an extra copy if the client is not local.
-                    //       For now, we rely on GC to release it.
-                    //       Maybe we can modify InsetsSourceControl.writeToParcel so it can release
-                    //       the extra leash as soon as possible.
-                    outControls[i] = controls[i] != null
-                            ? new InsetsSourceControl(controls[i]) : null;
-                }
+        final InsetsSourceControl[] controls =
+                win.getDisplayContent().getInsetsStateController().getControlsForDispatch(win);
+        if (controls != null) {
+            final int length = Math.min(controls.length, outControls.length);
+            for (int i = 0; i < length; i++) {
+                // We will leave the critical section before returning the leash to the client,
+                // so we need to copy the leash to prevent others release the one that we are
+                // about to return.
+                // TODO: We will have an extra copy if the client is not local.
+                //       For now, we rely on GC to release it.
+                //       Maybe we can modify InsetsSourceControl.writeToParcel so it can release
+                //       the extra leash as soon as possible.
+                outControls[i] = controls[i] != null
+                        ? new InsetsSourceControl(controls[i]) : null;
             }
         }
     }
@@ -8027,14 +8026,15 @@
      * views.
      */
     void grantInputChannel(int callingUid, int callingPid, int displayId, SurfaceControl surface,
-            IWindow window, IBinder hostInputToken, int flags, InputChannel outInputChannel) {
+            IWindow window, IBinder hostInputToken, int flags, int type,
+            InputChannel outInputChannel) {
         final InputApplicationHandle applicationHandle;
         final String name;
         final InputChannel clientChannel;
         synchronized (mGlobalLock) {
             EmbeddedWindowController.EmbeddedWindow win =
                     new EmbeddedWindowController.EmbeddedWindow(this, window,
-                            mInputToWindowMap.get(hostInputToken), callingUid, callingPid);
+                            mInputToWindowMap.get(hostInputToken), callingUid, callingPid, type);
             clientChannel = win.openInputChannel();
             mEmbeddedWindowController.add(clientChannel.getToken(), win);
             applicationHandle = win.getApplicationHandle();
@@ -8042,7 +8042,7 @@
         }
 
         updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface,
-                name, applicationHandle, flags, null /* region */);
+                name, applicationHandle, flags, type, null /* region */);
 
         clientChannel.transferTo(outInputChannel);
         clientChannel.dispose();
@@ -8050,7 +8050,7 @@
 
     private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
             int displayId, SurfaceControl surface, String name,
-            InputApplicationHandle applicationHandle, int flags, Region region) {
+            InputApplicationHandle applicationHandle, int flags, int type, Region region) {
         InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
         h.token = channelToken;
         h.name = name;
@@ -8058,7 +8058,7 @@
         final int sanitizedFlags = flags & (LayoutParams.FLAG_NOT_TOUCHABLE
                 | LayoutParams.FLAG_SLIPPERY);
         h.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | sanitizedFlags;
-        h.layoutParamsType = 0;
+        h.layoutParamsType = type;
         h.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
         h.canReceiveKeys = false;
         h.hasFocus = false;
@@ -8082,6 +8082,7 @@
         t.setInputWindowInfo(surface, h);
         t.apply();
         t.close();
+        surface.release();
     }
 
     /**
@@ -8105,7 +8106,7 @@
         }
 
         updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name,
-                applicationHandle, flags, region);
+                applicationHandle, flags, win.mWindowType, region);
     }
 
     /** Return whether layer tracing is enabled */
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index c4cb4b5..707a789 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -138,6 +138,13 @@
                             Slog.e(TAG, "Attempt to operate on detached container: " + wc);
                             continue;
                         }
+                        // Make sure we add to the syncSet before performing
+                        // operations so we don't end up splitting effects between the WM
+                        // pending transaction and the BLASTSync transaction.
+                        if (syncId >= 0) {
+                            mBLASTSyncEngine.addToSyncSet(syncId, wc);
+                        }
+
                         int containerEffect = applyWindowContainerChange(wc, entry.getValue());
                         effects |= containerEffect;
 
@@ -146,9 +153,6 @@
                                 && (containerEffect & TRANSACT_EFFECTS_CLIENT_CONFIG) != 0) {
                             haveConfigChanges.add(wc);
                         }
-                        if (syncId >= 0) {
-                            mBLASTSyncEngine.addToSyncSet(syncId, wc);
-                        }
                     }
                     // Hierarchy changes
                     final List<WindowContainerTransaction.HierarchyOp> hops = t.getHierarchyOps();
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 768f89e..8739bad4 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -642,6 +642,9 @@
         final int originalRotation = getWindowConfiguration().getRotation();
         onConfigurationChanged(parent.getConfiguration());
         onCancelFixedRotationTransform(originalRotation);
+        if (mDisplayContent.mFixedRotationAnimationController != null) {
+            mDisplayContent.mFixedRotationAnimationController.cancel();
+        }
     }
 
     /**
diff --git a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
index 6cf8133..e904645 100644
--- a/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
+++ b/services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp
@@ -18,6 +18,7 @@
 #define LOG_TAG "PackageManagerShellCommandDataLoader-jni"
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/no_destructor.h>
 #include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
 #include <core_jni_helpers.h>
@@ -65,6 +66,7 @@
 static constexpr MagicType INCR = 0x52434e49; // BE INCR
 
 static constexpr auto PollTimeoutMs = 5000;
+static constexpr auto TraceTagCheckInterval = 1s;
 
 struct JniIds {
     jclass packageManagerShellCommandDataLoader;
@@ -337,9 +339,47 @@
     return env;
 }
 
-class PackageManagerShellCommandDataLoaderDataLoader : public android::dataloader::DataLoader {
+class PMSCDataLoader;
+
+struct OnTraceChanged {
+    OnTraceChanged();
+    ~OnTraceChanged() {
+        mRunning = false;
+        mChecker.join();
+    }
+
+    void registerCallback(PMSCDataLoader* callback) {
+        std::unique_lock lock(mMutex);
+        mCallbacks.insert(callback);
+    }
+
+    void unregisterCallback(PMSCDataLoader* callback) {
+        std::unique_lock lock(mMutex);
+        mCallbacks.erase(callback);
+    }
+
+private:
+    std::mutex mMutex;
+    std::unordered_set<PMSCDataLoader*> mCallbacks;
+    std::atomic<bool> mRunning{true};
+    std::thread mChecker;
+};
+
+static OnTraceChanged& onTraceChanged() {
+    static android::base::NoDestructor<OnTraceChanged> instance;
+    return *instance;
+}
+
+class PMSCDataLoader : public android::dataloader::DataLoader {
 public:
-    PackageManagerShellCommandDataLoaderDataLoader(JavaVM* jvm) : mJvm(jvm) { CHECK(mJvm); }
+    PMSCDataLoader(JavaVM* jvm) : mJvm(jvm) { CHECK(mJvm); }
+    ~PMSCDataLoader() { onTraceChanged().unregisterCallback(this); }
+
+    void updateReadLogsState(const bool enabled) {
+        if (enabled != mReadLogsEnabled.exchange(enabled)) {
+            mIfs->setParams({.readLogsEnabled = enabled});
+        }
+    }
 
 private:
     // Lifecycle.
@@ -353,7 +393,8 @@
         mArgs = params.arguments();
         mIfs = ifs;
         mStatusListener = statusListener;
-        mIfs->setParams({.readLogsEnabled = true});
+        updateReadLogsState(atrace_is_tag_enabled(ATRACE_TAG));
+        onTraceChanged().registerCallback(this);
         return true;
     }
     bool onStart() final { return true; }
@@ -365,6 +406,7 @@
         }
     }
     void onDestroy() final {
+        onTraceChanged().unregisterCallback(this);
         // Make sure the receiver thread stopped.
         CHECK(!mReceiverThread.joinable());
     }
@@ -757,10 +799,28 @@
     android::base::unique_fd mEventFd;
     std::thread mReceiverThread;
     std::atomic<bool> mStopReceiving = false;
+    std::atomic<bool> mReadLogsEnabled = false;
     /** Tracks which files have been requested */
     std::unordered_set<FileIdx> mRequestedFiles;
 };
 
+OnTraceChanged::OnTraceChanged() {
+    mChecker = std::thread([this]() {
+        bool oldTrace = atrace_is_tag_enabled(ATRACE_TAG);
+        while (mRunning) {
+            bool newTrace = atrace_is_tag_enabled(ATRACE_TAG);
+            if (oldTrace != newTrace) {
+                std::unique_lock lock(mMutex);
+                for (auto&& callback : mCallbacks) {
+                    callback->updateReadLogsState(newTrace);
+                }
+            }
+            oldTrace = newTrace;
+            std::this_thread::sleep_for(TraceTagCheckInterval);
+        }
+    });
+}
+
 BlockHeader readHeader(std::span<uint8_t>& data) {
     BlockHeader header;
     if (data.size() < sizeof(header)) {
@@ -794,7 +854,7 @@
             [](auto jvm, const auto& params) -> android::dataloader::DataLoaderPtr {
                 if (params.type() == DATA_LOADER_TYPE_INCREMENTAL) {
                     // This DataLoader only supports incremental installations.
-                    return std::make_unique<PackageManagerShellCommandDataLoaderDataLoader>(jvm);
+                    return std::make_unique<PMSCDataLoader>(jvm);
                 }
                 return {};
             });
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index a9dc92f..78439db 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -748,7 +748,7 @@
         return -EINVAL;
     }
 
-    LOG(INFO) << "Removing bind point " << target;
+    LOG(INFO) << "Removing bind point " << target << " for storage " << storage;
 
     // Here we should only look up by the exact target, not by a subdirectory of any existing mount,
     // otherwise there's a chance to unmount something completely unrelated
@@ -1807,6 +1807,8 @@
         targetStatus = mTargetStatus;
     }
 
+    LOG(DEBUG) << "fsmStep: " << mId << ": " << currentStatus << " -> " << targetStatus;
+
     if (currentStatus == targetStatus) {
         return true;
     }
@@ -1868,8 +1870,8 @@
         listener = mListener;
 
         if (mCurrentStatus == IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE) {
-            // For unavailable, reset target status.
-            setTargetStatusLocked(IDataLoaderStatusListener::DATA_LOADER_UNAVAILABLE);
+            // For unavailable, unbind from DataLoader to ensure proper re-commit.
+            setTargetStatusLocked(IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
         }
     }
 
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 325218d..2e4625c 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -677,10 +677,10 @@
     mDataLoaderManager->bindToDataLoaderSuccess();
     mDataLoaderManager->getDataLoaderSuccess();
     EXPECT_CALL(*mDataLoaderManager, bindToDataLoader(_, _, _, _)).Times(2);
-    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(1);
+    EXPECT_CALL(*mDataLoaderManager, unbindFromDataLoader(_)).Times(2);
     EXPECT_CALL(*mDataLoader, create(_, _, _, _)).Times(2);
     EXPECT_CALL(*mDataLoader, start(_)).Times(0);
-    EXPECT_CALL(*mDataLoader, destroy(_)).Times(1);
+    EXPECT_CALL(*mDataLoader, destroy(_)).Times(2);
     EXPECT_CALL(*mVold, unmountIncFs(_)).Times(2);
     EXPECT_CALL(*mLooper, addFd(MockIncFs::kPendingReadsFd, _, _, _, _)).Times(1);
     EXPECT_CALL(*mLooper, removeFd(MockIncFs::kPendingReadsFd)).Times(1);
diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
index f8d197a..d78dad5 100644
--- a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
+++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
@@ -46,6 +46,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
 import android.os.Process;
 import android.os.UserHandle;
@@ -106,6 +107,7 @@
             new CrossProfileAppsServiceImpl(mContext, mInjector);
     private final Map<UserHandle, Set<Intent>> mSentUserBroadcasts = new HashMap<>();
     private final Map<Integer, List<ApplicationInfo>> installedApplications = new HashMap<>();
+    private final Set<Integer> mKilledUids = new HashSet<>();
 
     @Mock private PackageManagerInternal mPackageManagerInternal;
     @Mock private IPackageManager mIPackageManager;
@@ -389,6 +391,33 @@
     }
 
     @Test
+    public void setInteractAcrossProfilesAppOp_toAllowed_doesNotKillApp() {
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+        assertThat(mKilledUids).isEmpty();
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_toDisallowed_killsAppsInBothProfiles() {
+        shadowOf(mPackageManager).addPermissionInfo(createCrossProfilesPermissionInfo());
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED);
+
+        mCrossProfileAppsServiceImpl.setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_DEFAULT);
+
+        assertThat(mKilledUids).contains(WORK_PROFILE_UID);
+        assertThat(mKilledUids).contains(PERSONAL_PROFILE_UID);
+    }
+
+    private PermissionInfo createCrossProfilesPermissionInfo() {
+        PermissionInfo permissionInfo = new PermissionInfo();
+        permissionInfo.name = Manifest.permission.INTERACT_ACROSS_PROFILES;
+        permissionInfo.protectionLevel = PermissionInfo.PROTECTION_FLAG_APPOP;
+        return permissionInfo;
+    }
+
+    @Test
     public void canConfigureInteractAcrossProfiles_packageNotInstalledInProfile_returnsFalse() {
         mockUninstallCrossProfileAppFromWorkProfile();
         assertThat(mCrossProfileAppsServiceImpl
@@ -678,5 +707,10 @@
             // ShadowActivityThread with Robolectric. This method is currently not supported there.
             return mContext.checkPermission(permission, Process.myPid(), uid);
         }
+
+        @Override
+        public void killUid(String packageName, int uid) {
+            mKilledUids.add(uid);
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
index e79b5af..a2393a8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/CrossProfileAppsServiceImplTest.java
@@ -32,8 +32,10 @@
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.permission.PermissionManager;
 import android.platform.test.annotations.Presubmit;
 import android.util.SparseArray;
 
@@ -692,5 +694,17 @@
                 String permission, int uid, int owningUid, boolean exported) {
             return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported);
         }
+
+        @Override
+        public void killUid(String packageName, int uid) {
+            try {
+                ActivityManager.getService().killApplication(
+                        packageName,
+                        UserHandle.getAppId(uid),
+                        UserHandle.getUserId(uid),
+                        PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED);
+            } catch (RemoteException ignored) {
+            }
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
index d136614..6c1c019 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -22,10 +22,14 @@
 import android.os.Parcelable;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.support.test.uiautomator.UiDevice;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.text.TextUtils;
 import android.util.AtomicFile;
 
+import androidx.test.InstrumentationRegistry;
+
 import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
@@ -74,6 +78,14 @@
         assertEquals(accountName, um.getUserAccount(tempUserId));
     }
 
+    public void testUserSystemPackageWhitelist() throws Exception {
+        String cmd = "cmd user report-system-user-package-whitelist-problems --critical-only";
+        final String result = runShellCommand(cmd);
+        if (!TextUtils.isEmpty(result)) {
+            fail("Command '" + cmd + " reported errors:\n" + result);
+        }
+    }
+
     private Bundle createBundle() {
         Bundle result = new Bundle();
         // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[]
@@ -118,4 +130,8 @@
         assertEquals(1, childBundle.getInt("bundle_int"));
     }
 
+    private static String runShellCommand(String cmd) throws Exception {
+        return UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+                .executeShellCommand(cmd);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 48e22f6..e410220 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -63,6 +63,7 @@
 import android.appwidget.AppWidgetManager;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -107,6 +108,10 @@
     private static final int UID_1 = 10000;
     private static final String PACKAGE_EXEMPTED_1 = "com.android.exempted";
     private static final int UID_EXEMPTED_1 = 10001;
+    private static final String PACKAGE_SYSTEM_HEADFULL = "com.example.system.headfull";
+    private static final int UID_SYSTEM_HEADFULL = 10002;
+    private static final String PACKAGE_SYSTEM_HEADLESS = "com.example.system.headless";
+    private static final int UID_SYSTEM_HEADLESS = 10003;
     private static final int USER_ID = 0;
     private static final int USER_ID2 = 10;
     private static final UserHandle USER_HANDLE_USER2 = new UserHandle(USER_ID2);
@@ -305,18 +310,33 @@
         pie.packageName = PACKAGE_EXEMPTED_1;
         packages.add(pie);
 
+        PackageInfo pis = new PackageInfo();
+        pis.activities = new ActivityInfo[]{mock(ActivityInfo.class)};
+        pis.applicationInfo = new ApplicationInfo();
+        pis.applicationInfo.uid = UID_SYSTEM_HEADFULL;
+        pis.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
+        pis.packageName = PACKAGE_SYSTEM_HEADFULL;
+        packages.add(pis);
+
+        PackageInfo pish = new PackageInfo();
+        pish.applicationInfo = new ApplicationInfo();
+        pish.applicationInfo.uid = UID_SYSTEM_HEADLESS;
+        pish.applicationInfo.flags = ApplicationInfo.FLAG_SYSTEM;
+        pish.packageName = PACKAGE_SYSTEM_HEADLESS;
+        packages.add(pish);
+
         doReturn(packages).when(mockPm).getInstalledPackagesAsUser(anyInt(), anyInt());
         try {
-            doReturn(UID_1).when(mockPm).getPackageUidAsUser(eq(PACKAGE_1), anyInt());
-            doReturn(UID_1).when(mockPm).getPackageUidAsUser(eq(PACKAGE_1), anyInt(), anyInt());
-            doReturn(UID_EXEMPTED_1).when(mockPm).getPackageUidAsUser(eq(PACKAGE_EXEMPTED_1),
-                    anyInt());
-            doReturn(UID_EXEMPTED_1).when(mockPm).getPackageUidAsUser(eq(PACKAGE_EXEMPTED_1),
-                    anyInt(), anyInt());
-            doReturn(pi.applicationInfo).when(mockPm).getApplicationInfo(eq(pi.packageName),
-                    anyInt());
-            doReturn(pie.applicationInfo).when(mockPm).getApplicationInfo(eq(pie.packageName),
-                    anyInt());
+            for (int i = 0; i < packages.size(); ++i) {
+                PackageInfo pkg = packages.get(i);
+
+                doReturn(pkg.applicationInfo.uid).when(mockPm)
+                        .getPackageUidAsUser(eq(pkg.packageName), anyInt());
+                doReturn(pkg.applicationInfo.uid).when(mockPm)
+                        .getPackageUidAsUser(eq(pkg.packageName), anyInt(), anyInt());
+                doReturn(pkg.applicationInfo).when(mockPm)
+                        .getApplicationInfo(eq(pkg.packageName), anyInt());
+            }
         } catch (PackageManager.NameNotFoundException nnfe) {}
     }
 
@@ -514,7 +534,11 @@
     }
 
     private void assertBucket(int bucket) {
-        assertEquals(bucket, getStandbyBucket(mController, PACKAGE_1));
+        assertBucket(bucket, PACKAGE_1);
+    }
+
+    private void assertBucket(int bucket, String pkg) {
+        assertEquals(bucket, getStandbyBucket(mController, pkg));
     }
 
     private void assertNotBucket(int bucket) {
@@ -1462,6 +1486,32 @@
         assertBucket(STANDBY_BUCKET_RESTRICTED);
     }
 
+    @Test
+    public void testSystemHeadlessAppElevated() {
+        reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
+        reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime,
+                PACKAGE_SYSTEM_HEADFULL);
+        reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime,
+                PACKAGE_SYSTEM_HEADLESS);
+        mInjector.mElapsedRealtime += RESTRICTED_THRESHOLD;
+
+
+        mController.setAppStandbyBucket(PACKAGE_SYSTEM_HEADFULL, USER_ID, STANDBY_BUCKET_RARE,
+                REASON_MAIN_TIMEOUT);
+        assertBucket(STANDBY_BUCKET_RARE, PACKAGE_SYSTEM_HEADFULL);
+
+        // Make sure headless system apps don't get lowered.
+        mController.setAppStandbyBucket(PACKAGE_SYSTEM_HEADLESS, USER_ID, STANDBY_BUCKET_RARE,
+                REASON_MAIN_TIMEOUT);
+        assertBucket(STANDBY_BUCKET_ACTIVE, PACKAGE_SYSTEM_HEADLESS);
+
+        // Package 1 doesn't have activities and is headless, but is not a system app, so it can
+        // be lowered.
+        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
+                REASON_MAIN_TIMEOUT);
+        assertBucket(STANDBY_BUCKET_RARE, PACKAGE_1);
+    }
+
     private String getAdminAppsStr(int userId) {
         return getAdminAppsStr(userId, mController.getActiveAdminAppsForTest(userId));
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 289933e..d45ecc9 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -6650,18 +6650,14 @@
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
-        assertTrue(mBinderService.hasSentMessage(PKG, mUid));
+        assertTrue(mBinderService.isInInvalidMsgState(PKG, mUid));
     }
 
     @Test
     public void testRecordMessages_validMsg() throws RemoteException {
-        // Messaging notification with shortcut info
-        Notification.BubbleMetadata metadata =
-                new Notification.BubbleMetadata.Builder("id").build();
         Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
                 null /* groupKey */, false /* isSummary */);
-        nb.setShortcutId("id");
-        nb.setBubbleMetadata(metadata);
+        nb.setShortcutId(null);
         StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
                 "testRecordMessages_validMsg", mUid, 0, nb.build(), new UserHandle(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
@@ -6670,7 +6666,43 @@
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
-        assertFalse(mBinderService.hasSentMessage(PKG, mUid));
+        assertTrue(mBinderService.isInInvalidMsgState(PKG, mUid));
+
+        nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
+                "testRecordMessages_validMsg");
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
+        waitForIdle();
+
+        assertFalse(mBinderService.isInInvalidMsgState(PKG, mUid));
+    }
+
+    @Test
+    public void testRecordMessages_invalidMsg_afterValidMsg() throws RemoteException {
+        NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
+                "testRecordMessages_invalidMsg_afterValidMsg_1");
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
+        waitForIdle();
+        assertTrue(mService.getNotificationRecord(nr.getKey()).isConversation());
+
+        mBinderService.cancelAllNotifications(PKG, mUid);
+        waitForIdle();
+
+        Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
+                null /* groupKey */, false /* isSummary */);
+        nb.setShortcutId(null);
+        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+                "testRecordMessages_invalidMsg_afterValidMsg_2", mUid, 0, nb.build(),
+                new UserHandle(mUid), null, 0);
+         nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
+        waitForIdle();
+
+        assertFalse(mService.getNotificationRecord(nr.getKey()).isConversation());
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index b03596a..6df3c7b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -1137,6 +1137,26 @@
     }
 
     @Test
+    public void testIsConversation_noShortcut_appHasPreviousSentFullConversation() {
+        StatusBarNotification sbn = getMessagingStyleNotification();
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+        record.setShortcutInfo(null);
+        record.setHasSentValidMsg(true);
+
+        assertFalse(record.isConversation());
+    }
+
+    @Test
+    public void testIsConversation_noShortcut_userDemotedApp() {
+        StatusBarNotification sbn = getMessagingStyleNotification();
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+        record.setShortcutInfo(null);
+        record.userDemotedAppFromConvoSpace(true);
+
+        assertFalse(record.isConversation());
+    }
+
+    @Test
     public void testIsConversation_noShortcut_targetsR() {
         StatusBarNotification sbn = getMessagingStyleNotification(PKG_R);
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 4320f1c..f4e5d56 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -454,7 +454,9 @@
         mHelper.createNotificationChannel(PKG_O, UID_O, getChannel(), true, false);
 
         mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
-        mHelper.setMessageSent(PKG_P, UID_P);
+        mHelper.setInvalidMessageSent(PKG_P, UID_P);
+        mHelper.setValidMessageSent(PKG_P, UID_P);
+        mHelper.setInvalidMsgAppDemoted(PKG_P, UID_P, true);
 
         mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_NONE);
 
@@ -470,8 +472,10 @@
 
         assertEquals(IMPORTANCE_NONE, mHelper.getImportance(PKG_O, UID_O));
         assertTrue(mHelper.canShowBadge(PKG_N_MR1, UID_N_MR1));
-        assertTrue(mHelper.hasSentMessage(PKG_P, UID_P));
-        assertFalse(mHelper.hasSentMessage(PKG_N_MR1, UID_N_MR1));
+        assertTrue(mHelper.hasSentInvalidMsg(PKG_P, UID_P));
+        assertFalse(mHelper.hasSentInvalidMsg(PKG_N_MR1, UID_N_MR1));
+        assertTrue(mHelper.hasSentValidMsg(PKG_P, UID_P));
+        assertTrue(mHelper.didUserEverDemoteInvalidMsgApp(PKG_P, UID_P));
         assertEquals(channel1,
                 mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1.getId(), false));
         compareChannels(channel2,
@@ -3380,15 +3384,49 @@
     }
 
     @Test
-    public void testMessageSent() {
+    public void testInvalidMessageSent() {
         // create package preferences
         mHelper.canShowBadge(PKG_P, UID_P);
 
         // check default value
-        assertFalse(mHelper.hasSentMessage(PKG_P, UID_P));
+        assertFalse(mHelper.isInInvalidMsgState(PKG_P, UID_P));
 
         // change it
-        mHelper.setMessageSent(PKG_P, UID_P);
-        assertTrue(mHelper.hasSentMessage(PKG_P, UID_P));
+        mHelper.setInvalidMessageSent(PKG_P, UID_P);
+        assertTrue(mHelper.isInInvalidMsgState(PKG_P, UID_P));
+        assertTrue(mHelper.hasSentInvalidMsg(PKG_P, UID_P));
+    }
+
+    @Test
+    public void testValidMessageSent() {
+        // create package preferences
+        mHelper.canShowBadge(PKG_P, UID_P);
+
+        // get into the bad state
+        mHelper.setInvalidMessageSent(PKG_P, UID_P);
+
+        // and then fix it
+        mHelper.setValidMessageSent(PKG_P, UID_P);
+
+        assertTrue(mHelper.hasSentValidMsg(PKG_P, UID_P));
+        assertFalse(mHelper.isInInvalidMsgState(PKG_P, UID_P));
+    }
+
+    @Test
+    public void testUserDemotedInvalidMsgApp() {
+        // create package preferences
+        mHelper.canShowBadge(PKG_P, UID_P);
+
+        // demotion means nothing before msg notif sent
+        mHelper.setInvalidMsgAppDemoted(PKG_P, UID_P, true);
+        assertFalse(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
+
+        // it's valid when incomplete msgs have been sent
+        mHelper.setInvalidMessageSent(PKG_P, UID_P);
+        assertTrue(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
+
+        // and is invalid once complete msgs are sent
+        mHelper.setValidMessageSent(PKG_P, UID_P);
+        assertFalse(mHelper.hasUserDemotedInvalidMsgApp(PKG_P, UID_P));
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 8cfe96f..4da5adf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -35,6 +35,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
@@ -69,6 +70,7 @@
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.never;
 
+import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityOptions;
 import android.app.WindowConfiguration;
 import android.app.servertransaction.ActivityConfigurationChangeItem;
@@ -82,14 +84,18 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.PersistableBundle;
+import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 import android.util.MergedConfiguration;
 import android.util.MutableBoolean;
 import android.view.DisplayInfo;
 import android.view.IRemoteAnimationFinishedCallback;
 import android.view.IRemoteAnimationRunner.Stub;
+import android.view.IWindowSession;
 import android.view.RemoteAnimationAdapter;
 import android.view.RemoteAnimationTarget;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
 
 import androidx.test.filters.MediumTest;
 
@@ -488,6 +494,16 @@
     }
 
     @Test
+    public void testShouldMakeActive_nonTopVisible() {
+        ActivityRecord finishingActivity = new ActivityBuilder(mService).setTask(mTask).build();
+        finishingActivity.finishing = true;
+        ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+        mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
+
+        assertEquals(false, mActivity.shouldMakeActive(null /* activeActivity */));
+    }
+
+    @Test
     public void testShouldResume_stackVisibility() {
         mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
         spyOn(mStack);
@@ -1394,6 +1410,10 @@
 
         assertTrue(displayRotation.isRotatingSeamlessly());
 
+        // The launching rotated app should not be cleared when waiting for remote rotation.
+        display.continueUpdateOrientationForDiffOrienLaunchingApp();
+        assertNotNull(display.mFixedRotationLaunchingApp);
+
         // Simulate the rotation has been updated to previous one, e.g. sensor updates before the
         // remote rotation is completed.
         doReturn(originalRotation).when(displayRotation).rotationForOrientation(
@@ -1426,6 +1446,73 @@
     }
 
     @Test
+    public void testIsSnapshotCompatible() {
+        mService.mWindowManager.mIsFixedRotationTransformEnabled = true;
+        final TaskSnapshot snapshot = new TaskSnapshotPersisterTestBase.TaskSnapshotBuilder()
+                .setRotation(mActivity.getWindowConfiguration().getRotation())
+                .build();
+
+        assertTrue(mActivity.isSnapshotCompatible(snapshot));
+
+        setRotatedScreenOrientationSilently(mActivity);
+
+        assertFalse(mActivity.isSnapshotCompatible(snapshot));
+    }
+
+    @Test
+    public void testFixedRotationSnapshotStartingWindow() {
+        mService.mWindowManager.mIsFixedRotationTransformEnabled = true;
+        // TaskSnapshotSurface requires a fullscreen opaque window.
+        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
+        params.width = params.height = WindowManager.LayoutParams.MATCH_PARENT;
+        final WindowTestUtils.TestWindowState w = new WindowTestUtils.TestWindowState(
+                mService.mWindowManager, mock(Session.class), new TestIWindow(), params, mActivity);
+        mActivity.addWindow(w);
+
+        // Assume the activity is launching in different rotation, and there was an available
+        // snapshot accepted by {@link Activity#isSnapshotCompatible}.
+        final TaskSnapshot snapshot = new TaskSnapshotPersisterTestBase.TaskSnapshotBuilder()
+                .setRotation((mActivity.getWindowConfiguration().getRotation() + 1) % 4)
+                .build();
+        setRotatedScreenOrientationSilently(mActivity);
+
+        final IWindowSession session = WindowManagerGlobal.getWindowSession();
+        spyOn(session);
+        try {
+            // Return error to skip unnecessary operation.
+            doReturn(WindowManagerGlobal.ADD_STARTING_NOT_NEEDED).when(session).addToDisplay(
+                    any() /* window */, anyInt() /* seq */, any() /* attrs */,
+                    anyInt() /* viewVisibility */, anyInt() /* displayId */, any() /* outFrame */,
+                    any() /* outContentInsets */, any() /* outStableInsets */,
+                    any() /* outDisplayCutout */, any() /* outInputChannel */,
+                    any() /* outInsetsState */, any() /* outActiveControls */);
+            TaskSnapshotSurface.create(mService.mWindowManager, mActivity, snapshot);
+        } catch (RemoteException ignored) {
+        } finally {
+            reset(session);
+        }
+
+        // Because the rotation of snapshot and the corresponding top activity are different, fixed
+        // rotation should be applied when creating snapshot surface if the display rotation may be
+        // changed according to the activity orientation.
+        assertTrue(mActivity.hasFixedRotationTransform());
+        assertEquals(mActivity, mActivity.mDisplayContent.mFixedRotationLaunchingApp);
+    }
+
+    /**
+     * Sets orientation without notifying the parent to simulate that the display has not applied
+     * the requested orientation yet.
+     */
+    private static void setRotatedScreenOrientationSilently(ActivityRecord r) {
+        final int rotatedOrentation = r.getConfiguration().orientation == ORIENTATION_PORTRAIT
+                ? SCREEN_ORIENTATION_LANDSCAPE
+                : SCREEN_ORIENTATION_PORTRAIT;
+        doReturn(false).when(r).onDescendantOrientationChanged(any(), any());
+        r.setOrientation(rotatedOrentation);
+    }
+
+    @Test
     public void testActivityOnDifferentDisplayUpdatesProcessOverride() {
         final ActivityRecord secondaryDisplayActivity =
                 createActivityOnDisplay(false /* defaultDisplay */, null /* process */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 02d1f9b..edc9756 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -49,7 +49,6 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 
@@ -57,10 +56,10 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyObject;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 
@@ -100,6 +99,7 @@
 @Presubmit
 @RunWith(WindowTestRunner.class)
 public class ActivityStarterTests extends ActivityTestsBase {
+    private ActivityStarter mStarter;
     private ActivityStartController mController;
     private ActivityMetricsLogger mActivityMetricsLogger;
     private PackageManagerInternal mMockPackageManager;
@@ -127,6 +127,8 @@
         mController = mock(ActivityStartController.class);
         mActivityMetricsLogger = mock(ActivityMetricsLogger.class);
         clearInvocations(mActivityMetricsLogger);
+        mStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor,
+                mock(ActivityStartInterceptor.class));
     }
 
     @Test
@@ -179,7 +181,6 @@
      * {@link ActivityStarter#execute} based on these preconditions and ensures the result matches
      * the expected. It is important to note that the method also checks side effects of the start,
      * such as ensuring {@link ActivityOptions#abort()} is called in the relevant scenarios.
-     *
      * @param preconditions A bitmask representing the preconditions for the launch
      * @param launchFlags The launch flags to be provided by the launch {@link Intent}.
      * @param expectedResult The expected result from the launch.
@@ -201,7 +202,7 @@
         final WindowProcessController wpc =
                 containsConditions(preconditions, PRECONDITION_NO_CALLER_APP)
                 ? null : new WindowProcessController(service, ai, null, 0, -1, null, listener);
-        doReturn(wpc).when(service).getProcessController(any());
+        doReturn(wpc).when(service).getProcessController(anyObject());
 
         final Intent intent = new Intent();
         intent.setFlags(launchFlags);
@@ -1033,46 +1034,4 @@
 
         verify(recentTasks, times(1)).add(any());
     }
-
-    @Test
-    public void testStartActivityInner_allSplitScreenPrimaryActivitiesVisible() {
-        // Given
-        final ActivityStarter starter = prepareStarter(0, false);
-
-        starter.setReason("testAllSplitScreenPrimaryActivitiesAreResumed");
-
-        final ActivityRecord targetRecord = new ActivityBuilder(mService).build();
-        targetRecord.setFocusable(false);
-        targetRecord.setVisibility(false);
-        final ActivityRecord sourceRecord = new ActivityBuilder(mService).build();
-
-        final ActivityStack stack = spy(
-                mRootWindowContainer.getDefaultTaskDisplayArea()
-                        .createStack(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD,
-                                /* onTop */true));
-
-        stack.addChild(targetRecord);
-
-        doReturn(stack).when(mRootWindowContainer)
-                .getLaunchStack(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt());
-
-        starter.mStartActivity = new ActivityBuilder(mService).build();
-
-        // When
-        starter.startActivityInner(
-                /* r */targetRecord,
-                /* sourceRecord */ sourceRecord,
-                /* voiceSession */null,
-                /* voiceInteractor */ null,
-                /* startFlags */ 0,
-                /* doResume */true,
-                /* options */null,
-                /* inTask */null,
-                /* restrictedBgActivity */false);
-
-        // Then
-        verify(stack).ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
-        verify(targetRecord).makeVisibleIfNeeded(null, true);
-        assertTrue(targetRecord.mVisibleRequested);
-    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 5c21853..8f18f64 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -307,7 +307,7 @@
     public void testCreateRemoveStartingWindow() {
         mActivity.addStartingWindow(mPackageName,
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                false, false);
+                false);
         waitUntilHandlersIdle();
         assertHasStartingWindow(mActivity);
         mActivity.removeStartingWindow();
@@ -316,20 +316,16 @@
     }
 
     @Test
-    @FlakyTest(bugId = 130392471)
     public void testAddRemoveRace() {
         // There was once a race condition between adding and removing starting windows
+        final ActivityRecord appToken = mAppWindow.mActivityRecord;
         for (int i = 0; i < 1000; i++) {
-            final ActivityRecord appToken = createIsolatedTestActivityRecord();
-
             appToken.addStartingWindow(mPackageName,
                     android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                    false, false);
+                    false);
             appToken.removeStartingWindow();
             waitUntilHandlersIdle();
             assertNoStartingWindow(appToken);
-
-            appToken.getParent().getParent().removeImmediately();
         }
     }
 
@@ -339,11 +335,11 @@
         final ActivityRecord activity2 = createIsolatedTestActivityRecord();
         activity1.addStartingWindow(mPackageName,
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                false, false);
+                false);
         waitUntilHandlersIdle();
         activity2.addStartingWindow(mPackageName,
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1.appToken.asBinder(),
-                true, true, false, true, false, false);
+                true, true, false, true, false);
         waitUntilHandlersIdle();
         assertNoStartingWindow(activity1);
         assertHasStartingWindow(activity2);
@@ -359,11 +355,11 @@
                     activity2.addStartingWindow(mPackageName,
                             android.R.style.Theme, null, "Test", 0, 0, 0, 0,
                             activity1.appToken.asBinder(), true, true, false,
-                            true, false, false);
+                            true, false);
                 });
         activity1.addStartingWindow(mPackageName,
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                false, false);
+                false);
         waitUntilHandlersIdle();
         assertNoStartingWindow(activity1);
         assertHasStartingWindow(activity2);
@@ -375,11 +371,11 @@
         final ActivityRecord activity2 = createIsolatedTestActivityRecord();
         activity1.addStartingWindow(mPackageName,
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                false, false);
+                false);
         waitUntilHandlersIdle();
         activity2.addStartingWindow(mPackageName,
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, activity1.appToken.asBinder(),
-                true, true, false, true, false, false);
+                true, true, false, true, false);
         waitUntilHandlersIdle();
         assertNoStartingWindow(activity1);
         assertHasStartingWindow(activity2);
@@ -417,7 +413,7 @@
         // Add a starting window.
         activityTop.addStartingWindow(mPackageName,
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
-                false, false);
+                false);
         waitUntilHandlersIdle();
 
         // Make the top one invisible, and try transferring the starting window from the top to the
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index ac95a81..7b23bfb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -57,6 +57,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_FIXED_TRANSFORM;
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
@@ -1059,6 +1060,8 @@
     @Test
     public void testApplyTopFixedRotationTransform() {
         mWm.mIsFixedRotationTransformEnabled = true;
+        mDisplayContent.getDisplayPolicy().addWindowLw(mStatusBarWindow, mStatusBarWindow.mAttrs);
+        mDisplayContent.getDisplayPolicy().addWindowLw(mNavBarWindow, mNavBarWindow.mAttrs);
         final Configuration config90 = new Configuration();
         mDisplayContent.computeScreenConfiguration(config90, ROTATION_90);
 
@@ -1079,6 +1082,12 @@
                 ROTATION_0 /* oldRotation */, ROTATION_90 /* newRotation */,
                 false /* forceUpdate */));
 
+        assertNotNull(mDisplayContent.mFixedRotationAnimationController);
+        assertTrue(mStatusBarWindow.getParent().isAnimating(WindowContainer.AnimationFlags.PARENTS,
+                ANIMATION_TYPE_FIXED_TRANSFORM));
+        assertTrue(mNavBarWindow.getParent().isAnimating(WindowContainer.AnimationFlags.PARENTS,
+                ANIMATION_TYPE_FIXED_TRANSFORM));
+
         final Rect outFrame = new Rect();
         final Rect outInsets = new Rect();
         final Rect outStableInsets = new Rect();
@@ -1131,6 +1140,9 @@
         assertFalse(app.hasFixedRotationTransform());
         assertFalse(app2.hasFixedRotationTransform());
         assertEquals(config90.orientation, mDisplayContent.getConfiguration().orientation);
+
+        mDisplayContent.finishFixedRotationAnimation();
+        assertNull(mDisplayContent.mFixedRotationAnimationController);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index d605ab2..27c4e9b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -27,9 +27,7 @@
 import static android.view.Surface.ROTATION_270;
 import static android.view.Surface.ROTATION_90;
 import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
-import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
 import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
@@ -40,7 +38,6 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
-import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
@@ -50,7 +47,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThat;
-import static org.junit.Assume.assumeTrue;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.spy;
 import static org.testng.Assert.expectThrows;
@@ -64,18 +60,15 @@
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.InsetsState;
-import android.view.ViewRootImpl;
 import android.view.WindowInsets.Side;
 import android.view.WindowInsets.Type;
 import android.view.WindowManager;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.wm.utils.WmDisplayCutout;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -116,12 +109,6 @@
         updateDisplayFrames();
     }
 
-    @After
-    public void tearDown() {
-        PolicyControl.setFilters("");
-        mWindow.getDisplayContent().mInputMethodTarget = null;
-    }
-
     public void setRotation(int rotation) {
         mRotation = rotation;
         updateDisplayFrames();
@@ -210,8 +197,6 @@
 
     @Test
     public void layoutWindowLw_fitStatusBars() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         mWindow.mAttrs.setFitInsetsTypes(Type.statusBars());
         addWindow(mWindow);
 
@@ -228,8 +213,6 @@
 
     @Test
     public void layoutWindowLw_fitNavigationBars() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         mWindow.mAttrs.setFitInsetsTypes(Type.navigationBars());
         addWindow(mWindow);
 
@@ -246,8 +229,6 @@
 
     @Test
     public void layoutWindowLw_fitAllSides() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         mWindow.mAttrs.setFitInsetsSides(Side.all());
         addWindow(mWindow);
 
@@ -264,8 +245,6 @@
 
     @Test
     public void layoutWindowLw_fitTopOnly() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         mWindow.mAttrs.setFitInsetsSides(Side.TOP);
         addWindow(mWindow);
 
@@ -282,8 +261,6 @@
 
     @Test
     public void layoutWindowLw_fitInsetsIgnoringVisibility() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         final InsetsState state =
                 mDisplayContent.getInsetsPolicy().getInsetsForDispatch(mWindow);
         state.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
@@ -304,8 +281,6 @@
 
     @Test
     public void layoutWindowLw_fitInsetsNotIgnoringVisibility() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
-
         final InsetsState state =
                 mDisplayContent.getInsetsPolicy().getInsetsForDispatch(mWindow);
         state.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);
@@ -326,7 +301,6 @@
 
     @Test
     public void layoutWindowLw_fitDisplayCutout() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_FULL);
         addDisplayCutout();
 
         mWindow.mAttrs.setFitInsetsTypes(Type.displayCutout());
@@ -683,31 +657,6 @@
     }
 
     @Test
-    public void layoutWindowLw_withForwardInset_SoftInputAdjustResize() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode == ViewRootImpl.NEW_INSETS_MODE_NONE);
-
-        mWindow.mAttrs.flags =
-                FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
-        mWindow.mAttrs.setFitInsetsTypes(0 /* types */);
-        mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
-        addWindow(mWindow);
-
-        final int forwardedInsetBottom = 50;
-        mDisplayPolicy.setForwardedInsets(Insets.of(0, 0, 0, forwardedInsetBottom));
-        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-        assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
-        assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
-        assertInsetByTopBottom(mWindow.getContentFrameLw(),
-                STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom);
-        assertInsetByTopBottom(mWindow.getVisibleFrameLw(),
-                STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT + forwardedInsetBottom);
-        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
-        assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
-    }
-
-    @Test
     public void layoutWindowLw_withForwardInset_SoftInputAdjustNothing() {
         mWindow.mAttrs.flags =
                 FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
@@ -728,117 +677,6 @@
         assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
     }
 
-    // TODO(b/118118435): remove after removing PolicyControl
-    @FlakyTest(bugId = 129711077)
-    @Test
-    public void layoutWindowLw_withImmersive_SoftInputAdjustResize() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL);
-
-        synchronized (mWm.mGlobalLock) {
-            mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
-            mWindow.mAttrs.flags = 0;
-            mWindow.mAttrs.systemUiVisibility =
-                    SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
-                            | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
-
-            addWindow(mWindow);
-
-            mWindow.getDisplayContent().mInputMethodTarget = mWindow;
-            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-            mFrames.mContent.bottom = mFrames.mVoiceContent.bottom = INPUT_METHOD_WINDOW_TOP;
-            mFrames.mCurrent.bottom = INPUT_METHOD_WINDOW_TOP;
-            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-            int bottomInset = mFrames.mDisplayHeight - INPUT_METHOD_WINDOW_TOP;
-            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-            assertInsetByTopBottom(mWindow.getContentFrameLw(), 0, 0);
-            assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, bottomInset);
-        }
-    }
-
-    // TODO(b/118118435): remove after removing PolicyControl
-    @FlakyTest(bugId = 129711077)
-    @Test
-    public void layoutWindowLw_withImmersive_SoftInputAdjustNothing() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL);
-
-        synchronized (mWm.mGlobalLock) {
-            mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_NOTHING;
-            mWindow.mAttrs.flags = 0;
-            mWindow.mAttrs.systemUiVisibility =
-                    SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
-                            | SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
-
-            addWindow(mWindow);
-
-            mWindow.getDisplayContent().mInputMethodTarget = mWindow;
-            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-            mFrames.mContent.bottom = mFrames.mVoiceContent.bottom = INPUT_METHOD_WINDOW_TOP;
-            mFrames.mCurrent.bottom = INPUT_METHOD_WINDOW_TOP;
-            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-            assertInsetByTopBottom(mWindow.getContentFrameLw(), 0, 0);
-            assertInsetByTopBottom(mWindow.getVisibleFrameLw(), 0, 0);
-        }
-    }
-
-    // TODO(b/118118435): remove after removing PolicyControl
-    @FlakyTest(bugId = 129711077)
-    @Test
-    public void layoutWindowLw_withForceImmersive_fullscreen() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL);
-
-        synchronized (mWm.mGlobalLock) {
-            mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
-            mWindow.mAttrs.flags = 0;
-            mWindow.mAttrs.systemUiVisibility = 0;
-            PolicyControl.setFilters(PolicyControl.NAME_IMMERSIVE_FULL + "=*");
-
-            addWindow(mWindow);
-
-            mWindow.getDisplayContent().mInputMethodTarget = mWindow;
-            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-            mFrames.mContent.bottom = mFrames.mVoiceContent.bottom = INPUT_METHOD_WINDOW_TOP;
-            mFrames.mCurrent.bottom = INPUT_METHOD_WINDOW_TOP;
-            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-            int bottomInset = mFrames.mDisplayHeight - INPUT_METHOD_WINDOW_TOP;
-            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
-            assertInsetByTopBottom(mWindow.getContentFrameLw(), 0, 0);
-            assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, bottomInset);
-        }
-    }
-
-    // TODO(b/118118435): remove after removing PolicyControl
-    @FlakyTest(bugId = 129711077)
-    @Test
-    public void layoutWindowLw_withForceImmersive_nonFullscreen() {
-        assumeTrue(ViewRootImpl.sNewInsetsMode != ViewRootImpl.NEW_INSETS_MODE_FULL);
-
-        synchronized (mWm.mGlobalLock) {
-            mWindow.mAttrs.softInputMode = SOFT_INPUT_ADJUST_RESIZE;
-            mWindow.mAttrs.flags = 0;
-            mWindow.mAttrs.systemUiVisibility = 0;
-            mWindow.mAttrs.width = DISPLAY_WIDTH / 2;
-            mWindow.mAttrs.height = DISPLAY_HEIGHT / 2;
-            PolicyControl.setFilters(PolicyControl.NAME_IMMERSIVE_FULL + "=*");
-
-            addWindow(mWindow);
-
-            mWindow.getDisplayContent().mInputMethodTarget = mWindow;
-            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
-            mFrames.mContent.bottom = mFrames.mVoiceContent.bottom = INPUT_METHOD_WINDOW_TOP;
-            mFrames.mCurrent.bottom = INPUT_METHOD_WINDOW_TOP;
-            mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
-            int bottomInset = mFrames.mDisplayHeight - INPUT_METHOD_WINDOW_TOP;
-            assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, bottomInset);
-            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, bottomInset);
-            assertInsetByTopBottom(mWindow.getVisibleFrameLw(), STATUS_BAR_HEIGHT, bottomInset);
-        }
-    }
-
     @Test
     public void layoutHint_appWindow() {
         mWindow.mAttrs.flags =
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 552c476..79ba175 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -33,6 +33,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 
 import android.platform.test.annotations.Presubmit;
+import android.util.proto.ProtoOutputStream;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Builder;
 import android.view.SurfaceControl.Transaction;
@@ -52,6 +53,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.io.PrintWriter;
+
 /**
  * Test class for {@link SurfaceAnimatorTest}.
  *
@@ -267,6 +270,27 @@
         assertFalse(mDeferFinishAnimatable.mFinishedCallbackCalled);
     }
 
+    @Test
+    public void testDeferFinishFromAdapter() {
+
+        DeferredFinishAdapter deferredFinishAdapter = new DeferredFinishAdapter();
+        // Start animation
+        mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, deferredFinishAdapter,
+                true /* hidden */,
+                ANIMATION_TYPE_APP_TRANSITION);
+        assertAnimating(mAnimatable);
+        deferredFinishAdapter.mFinishCallback.onAnimationFinished(ANIMATION_TYPE_APP_TRANSITION,
+                deferredFinishAdapter);
+
+        assertAnimating(mAnimatable);
+        assertFalse(mAnimatable.mFinishedCallbackCalled);
+        // Now end defer finishing.
+        deferredFinishAdapter.mEndDeferFinishCallback.run();
+        assertNotAnimating(mAnimatable);
+        assertTrue(mAnimatable.mFinishedCallbackCalled);
+        verify(mTransaction).remove(eq(deferredFinishAdapter.mAnimationLeash));
+    }
+
     private OnAnimationFinishedCallback startDeferFinishAnimatable(AnimationAdapter anim) {
         mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, anim,
                 true /* hidden */, ANIMATION_TYPE_APP_TRANSITION);
@@ -389,4 +413,51 @@
             return true;
         }
     }
+
+    private static class DeferredFinishAdapter implements AnimationAdapter {
+
+        private Runnable mEndDeferFinishCallback;
+        private OnAnimationFinishedCallback mFinishCallback;
+        private SurfaceControl mAnimationLeash;
+
+        @Override
+        public boolean getShowWallpaper() {
+            return true;
+        }
+
+        @Override
+        public void startAnimation(SurfaceControl animationLeash, Transaction t, int type,
+                OnAnimationFinishedCallback finishCallback) {
+            mFinishCallback = finishCallback;
+            mAnimationLeash = animationLeash;
+        }
+
+        @Override
+        public void onAnimationCancelled(SurfaceControl animationLeash) {
+        }
+
+        @Override
+        public long getDurationHint() {
+            return 100;
+        }
+
+        @Override
+        public long getStatusBarTransitionsStartTime() {
+            return 100;
+        }
+
+        @Override
+        public void dump(PrintWriter pw, String prefix) {
+        }
+
+        @Override
+        public void dumpDebug(ProtoOutputStream proto) {
+        }
+
+        @Override
+        public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
+            mEndDeferFinishCallback = endDeferFinishCallback;
+            return true;
+        }
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 20d9aff..f985a14 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -192,10 +192,18 @@
 
         final ActivityManager.TaskSnapshot.Builder builder =
                 new ActivityManager.TaskSnapshot.Builder();
-        mWm.mTaskSnapshotController.prepareTaskSnapshot(mAppWindow.mActivityRecord.getTask(),
-                PixelFormat.UNKNOWN, builder);
+        boolean success = mWm.mTaskSnapshotController.prepareTaskSnapshot(
+                mAppWindow.mActivityRecord.getTask(), PixelFormat.UNKNOWN, builder);
 
+        assertTrue(success);
         // The pixel format should be selected automatically.
         assertNotEquals(PixelFormat.UNKNOWN, builder.getPixelFormat());
+
+        // Snapshot should not be taken while the rotation of activity and task are different.
+        doReturn(true).when(mAppWindow.mActivityRecord).hasFixedRotationTransform();
+        success = mWm.mTaskSnapshotController.prepareTaskSnapshot(
+                mAppWindow.mActivityRecord.getTask(), PixelFormat.UNKNOWN, builder);
+
+        assertFalse(success);
     }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 65fb2c0..0346329 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -22,7 +22,6 @@
 import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
 import static android.view.Surface.ROTATION_0;
-import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -75,17 +74,13 @@
 import android.view.DisplayCutout;
 import android.view.InsetsSource;
 import android.view.SurfaceControl;
-import android.view.ViewRootImpl;
 import android.view.WindowManager;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import com.android.server.wm.utils.WmDisplayCutout;
 
-import org.junit.AfterClass;
 import org.junit.Before;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -103,21 +98,6 @@
 @Presubmit
 @RunWith(WindowTestRunner.class)
 public class WindowStateTests extends WindowTestsBase {
-    private static int sPreviousNewInsetsMode;
-
-    @BeforeClass
-    public static void setUpOnce() {
-        // TODO: Make use of SettingsSession when it becomes feasible for this.
-        sPreviousNewInsetsMode = ViewRootImpl.sNewInsetsMode;
-        // To let the insets provider control the insets visibility, the insets mode has to be
-        // NEW_INSETS_MODE_FULL.
-        ViewRootImpl.sNewInsetsMode = NEW_INSETS_MODE_FULL;
-    }
-
-    @AfterClass
-    public static void tearDownOnce() {
-        ViewRootImpl.sNewInsetsMode = sPreviousNewInsetsMode;
-    }
 
     @Before
     public void setUp() {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index b59556f..060ed51 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -88,6 +88,7 @@
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -815,6 +816,13 @@
                     } catch (IllegalArgumentException iae) {
                         Slog.e(TAG, "Failed to note usage start", iae);
                     }
+                    FrameworkStatsLog.write(
+                            FrameworkStatsLog.APP_USAGE_EVENT_OCCURRED,
+                            mPackageManagerInternal.getPackageUid(event.mPackage, 0, userId),
+                            event.mPackage,
+                            event.mClass,
+                            FrameworkStatsLog
+                                .APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_FOREGROUND);
                     break;
                 case Event.ACTIVITY_PAUSED:
                     if (event.mTaskRootPackage == null) {
@@ -829,6 +837,13 @@
                             event.mTaskRootClass = prevData.mTaskRootClass;
                         }
                     }
+                    FrameworkStatsLog.write(
+                            FrameworkStatsLog.APP_USAGE_EVENT_OCCURRED,
+                            mPackageManagerInternal.getPackageUid(event.mPackage, 0, userId),
+                            event.mPackage,
+                            event.mClass,
+                            FrameworkStatsLog
+                                .APP_USAGE_EVENT_OCCURRED__EVENT_TYPE__MOVE_TO_BACKGROUND);
                     break;
                 case Event.ACTIVITY_DESTROYED:
                     // Treat activity destroys like activity stops.
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index ead90bb..3365ab7 100755
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -22,6 +22,7 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.pm.ServiceInfo;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -1635,13 +1636,21 @@
 
     /**
      * Instructs Telecom to put the call into the background audio processing state.
-     *
+     * <p>
      * This method can be called either when the call is in {@link #STATE_RINGING} or
      * {@link #STATE_ACTIVE}. After Telecom acknowledges the request by setting the call's state to
      * {@link #STATE_AUDIO_PROCESSING}, your app may setup the audio paths with the audio stack in
      * order to capture and play audio on the call stream.
-     *
+     * <p>
      * This method can only be called by the default dialer app.
+     * <p>
+     * Apps built with SDK version {@link android.os.Build.VERSION_CODES#R} or later which are using
+     * the microphone as part of audio processing should specify the foreground service type using
+     * the attribute {@link android.R.attr#foregroundServiceType} in the {@link InCallService}
+     * service element of the app's manifest file.
+     * The {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE} attribute should be specified.
+     * @see <a href="https://developer.android.com/preview/privacy/foreground-service-types">
+     * the Android Developer Site</a> for more information.
      * @hide
      */
     @SystemApi
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index f8722f4..8abab90 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -23,6 +23,7 @@
 import android.app.Service;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.content.pm.ServiceInfo;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.IBinder;
@@ -281,9 +282,20 @@
              * Sets whether to request background audio processing so that the in-call service can
              * screen the call further. If set to {@code true}, {@link #setDisallowCall} should be
              * called with {@code false}, and all other parameters in this builder will be ignored.
-             *
+             * <p>
              * This request will only be honored if the {@link CallScreeningService} shares the same
              * uid as the default dialer app. Otherwise, the call will go through as usual.
+             * <p>
+             * Apps built with SDK version {@link android.os.Build.VERSION_CODES#R} or later which
+             * are using the microphone as part of audio processing should specify the
+             * foreground service type using the attribute
+             * {@link android.R.attr#foregroundServiceType} in the {@link CallScreeningService}
+             * service element of the app's manifest file.
+             * The {@link ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE} attribute should be
+             * specified.
+             * @see
+             * <a href="https://developer.android.com/preview/privacy/foreground-service-types">
+             *     the Android Developer Site</a> for more information.
              *
              * @param shouldScreenCallViaAudioProcessing Whether to request further call screening.
              * @hide
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index a28f281..50ff8f4 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1632,6 +1632,12 @@
             "show_precise_failed_cause_bool";
 
     /**
+     * Boolean to decide whether NR is enabled.
+     * @hide
+     */
+    public static final String KEY_NR_ENABLED_BOOL = "nr_enabled_bool";
+
+    /**
      * Boolean to decide whether LTE is enabled.
      */
     public static final String KEY_LTE_ENABLED_BOOL = "lte_enabled_bool";
@@ -4139,6 +4145,7 @@
         sDefaults.putString(KEY_OPERATOR_NAME_FILTER_PATTERN_STRING, "");
         sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, "");
         sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true);
+        sDefaults.putBoolean(KEY_NR_ENABLED_BOOL, true);
         sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true);
         sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false);
         sDefaults.putStringArray(KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY, null);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e85dfbe..4246aef 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -10415,7 +10415,7 @@
      * <p>To recognize a carrier (including MVNO) as a first-class identity, Android assigns each
      * carrier with a canonical integer a.k.a. carrier id. The carrier ID is an Android
      * platform-wide identifier for a carrier. AOSP maintains carrier ID assignments in
-     * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+     * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
      *
      * <p>Apps which have carrier-specific configurations or business logic can use the carrier id
      * as an Android platform-wide identifier for carriers.
@@ -10477,7 +10477,7 @@
      *
      * <p>For carriers without fine-grained specific carrier ids, return {@link #getSimCarrierId()}
      * <p>Specific carrier ids are defined in the same way as carrier id
-     * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+     * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
      * except each with a "parent" id linking to its top-level carrier id.
      *
      * @return Returns fine-grained carrier id of the current subscription.
@@ -10526,7 +10526,7 @@
      * This is used for fallback when configurations/logic for exact carrier id
      * {@link #getSimCarrierId()} are not found.
      *
-     * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+     * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
      * can be updated out-of-band, its possible a MVNO (Mobile Virtual Network Operator) carrier
      * was not fully recognized and assigned to its MNO (Mobile Network Operator) carrier id
      * by default. After carrier id table update, a new carrier id was assigned. If apps don't
@@ -10553,7 +10553,7 @@
       * used for fallback when configurations/logic for exact carrier id {@link #getSimCarrierId()}
       * are not found.
       *
-      * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+      * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/latest_carrier_id/carrier_list.textpb">here</a>
       * can be updated out-of-band, its possible a MVNO (Mobile Virtual Network Operator) carrier
       * was not fully recognized and assigned to its MNO (Mobile Network Operator) carrier id
       * by default. After carrier id table update, a new carrier id was assigned. If apps don't
diff --git a/tests/NullHomeTest/Android.bp b/tests/NullHomeTest/Android.bp
new file mode 100644
index 0000000..99248bf
--- /dev/null
+++ b/tests/NullHomeTest/Android.bp
@@ -0,0 +1,22 @@
+// Copyright 2020 Google Inc. All Rights Reserved.
+//
+// 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.
+
+android_test {
+    name: "NullHomeTest",
+    srcs: ["src/**/*.java"],
+    certificate: "platform",
+    platform_apis: true,
+    static_libs: ["android-support-test"],
+    test_suites: ["device-tests"],
+}
diff --git a/tests/NullHomeTest/AndroidManifest.xml b/tests/NullHomeTest/AndroidManifest.xml
new file mode 100644
index 0000000..dc6402e
--- /dev/null
+++ b/tests/NullHomeTest/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.test.nullhome"
+    android:sharedUserId="android.uid.system" >
+
+    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" />
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.test.nullhome"
+        android:label="Check if no null Home exists/is enabled" />
+
+    <application android:label="Null Home Test">
+        <uses-library android:name="android.test.runner" />
+    </application>
+</manifest>
diff --git a/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java b/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.java
new file mode 100644
index 0000000..1d77cdc
--- /dev/null
+++ b/tests/NullHomeTest/src/com/android/test/nullhome/NullHomeTest.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 com.android.test.nullhome;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.support.test.InstrumentationRegistry;
+import android.util.Log;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/*
+ * Check if NullHome/SystemUserHome activity does not exist/is disabled.
+ *
+ * SystemUserHome is only enabled in bootable CSI (csi_x86, csi_arm64)
+ * products and should not be enabled in other products.
+ *
+ * Shell's NullHome is empty and caused issues in sevaral manual GUI tests
+ * that try to select/use it, and should be removed.
+ *
+ * Settings' FallbackHome is fine because it's specially handled by Settings.
+ *
+ */
+
+@RunWith(JUnit4.class)
+public class NullHomeTest {
+    private static final String TAG = "NullHomeTest";
+    private Context mContext;
+    private PackageManager mPm;
+
+    @Before
+    public void before() {
+        Log.d(TAG, "beforeClass()");
+        mContext = InstrumentationRegistry.getInstrumentation().getContext();
+        mPm = mContext.getPackageManager();
+    }
+
+    @Test
+    public void checkNullHome() {
+        final List<ResolveInfo> homeActivities = new ArrayList<>();
+
+        mPm.getHomeActivities(homeActivities);
+        for (ResolveInfo activity : homeActivities) {
+            Log.d(TAG, "Home activity: " + activity.activityInfo.packageName);
+            Assert.assertNotEquals(activity.activityInfo.packageName,
+                    "com.android.internal.app.SystemUserHomeActivity");
+            Assert.assertNotEquals(activity.activityInfo.packageName,
+                    "com.android.shell");
+        }
+    }
+}
diff --git a/tests/UiBench/src/com/android/test/uibench/ClippedListActivity.java b/tests/UiBench/src/com/android/test/uibench/ClippedListActivity.java
index 2bf6040..e21dec3 100644
--- a/tests/UiBench/src/com/android/test/uibench/ClippedListActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/ClippedListActivity.java
@@ -15,27 +15,24 @@
  */
 package com.android.test.uibench;
 
-import android.os.Bundle;
 import android.view.MenuItem;
 import android.widget.ArrayAdapter;
 import android.widget.ListAdapter;
 
 import androidx.appcompat.app.ActionBarDrawerToggle;
-import androidx.appcompat.app.AppCompatActivity;
 import androidx.appcompat.widget.Toolbar;
 import androidx.core.view.GravityCompat;
 import androidx.drawerlayout.widget.DrawerLayout;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.ListFragment;
+
+import com.android.test.uibench.listview.CompatListActivity;
 
 import com.google.android.material.navigation.NavigationView;
 
-public class ClippedListActivity extends AppCompatActivity
+public class ClippedListActivity extends CompatListActivity
         implements NavigationView.OnNavigationItemSelectedListener {
 
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
+    protected void initializeActivity() {
         setContentView(R.layout.activity_navigation_drawer);
         Toolbar toolbar = findViewById(R.id.toolbar);
         setSupportActionBar(toolbar);
@@ -48,15 +45,17 @@
 
         NavigationView navigationView = findViewById(R.id.nav_view);
         navigationView.setNavigationItemSelectedListener(this);
+    }
 
-        FragmentManager fm = getSupportFragmentManager();
-        if (fm.findFragmentById(android.R.id.content) == null) {
-            ListFragment listFragment = new ListFragment();
-            ListAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
-                    TextUtils.buildSimpleStringList(40));
-            listFragment.setListAdapter(adapter);
-            fm.beginTransaction().add(R.id.app_bar_layout, listFragment).commit();
-        }
+    @Override
+    protected ListAdapter createListAdapter() {
+        return new ArrayAdapter<>(this, android.R.layout.simple_list_item_1,
+                TextUtils.buildSimpleStringList(40));
+    }
+
+    @Override
+    protected int getListFragmentContainerViewId() {
+        return R.id.app_bar_layout;
     }
 
     @Override
diff --git a/tests/UiBench/src/com/android/test/uibench/MainActivity.java b/tests/UiBench/src/com/android/test/uibench/MainActivity.java
index 0a7aa42..77a6c32 100644
--- a/tests/UiBench/src/com/android/test/uibench/MainActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/MainActivity.java
@@ -19,13 +19,15 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.ListFragment;
-import androidx.appcompat.app.AppCompatActivity;
 import android.view.View;
+import android.widget.ListAdapter;
 import android.widget.ListView;
 import android.widget.SimpleAdapter;
 
+import androidx.fragment.app.ListFragment;
+
+import com.android.test.uibench.listview.CompatListActivity;
+
 import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -34,10 +36,12 @@
 import java.util.List;
 import java.util.Map;
 
-public class MainActivity extends AppCompatActivity {
+public class MainActivity extends CompatListActivity {
     private static final String EXTRA_PATH = "activity_path";
     private static final String CATEGORY_HWUI_TEST = "com.android.test.uibench.TEST";
 
+    private String mActivityPath = "";
+
     public static class TestListFragment extends ListFragment {
         @Override
         @SuppressWarnings("unchecked")
@@ -56,9 +60,7 @@
     }
 
     @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
+    protected void initializeActivity() {
         Intent intent = getIntent();
         String path = intent.getStringExtra(EXTRA_PATH);
 
@@ -68,15 +70,19 @@
             // not root level, display where we are in the hierarchy
             setTitle(path);
         }
+        mActivityPath = path;
+    }
 
-        FragmentManager fm = getSupportFragmentManager();
-        if (fm.findFragmentById(android.R.id.content) == null) {
-            ListFragment listFragment = new TestListFragment();
-            listFragment.setListAdapter(new SimpleAdapter(this, getData(path),
-                    android.R.layout.simple_list_item_1, new String[] { "title" },
-                    new int[] { android.R.id.text1 }));
-            fm.beginTransaction().add(android.R.id.content, listFragment).commit();
-        }
+    @Override
+    protected ListAdapter createListAdapter() {
+        return new SimpleAdapter(this, getData(mActivityPath),
+                android.R.layout.simple_list_item_1, new String[] { "title" },
+                new int[] { android.R.id.text1 });
+    }
+
+    @Override
+    protected ListFragment createListFragment() {
+        return new TestListFragment();
     }
 
     protected List<Map<String, Object>> getData(String prefix) {
diff --git a/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java b/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java
index af7c65a..d6e1d06 100644
--- a/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/ShadowGridActivity.java
@@ -16,13 +16,15 @@
 package com.android.test.uibench;
 
 import android.os.Bundle;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.ListFragment;
-import androidx.appcompat.app.AppCompatActivity;
 import android.view.View;
 import android.widget.ArrayAdapter;
+import android.widget.ListAdapter;
 
-public class ShadowGridActivity extends AppCompatActivity {
+import androidx.fragment.app.ListFragment;
+
+import com.android.test.uibench.listview.CompatListActivity;
+
+public class ShadowGridActivity extends CompatListActivity {
     public static class NoDividerListFragment extends ListFragment {
         @Override
         public void onViewCreated(View view, Bundle savedInstanceState) {
@@ -31,18 +33,14 @@
         }
     };
 
+    @Override
+    protected ListAdapter createListAdapter() {
+        return new ArrayAdapter<>(this, R.layout.card_row, R.id.card_text,
+                TextUtils.buildSimpleStringList());
+    }
 
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        FragmentManager fm = getSupportFragmentManager();
-        if (fm.findFragmentById(android.R.id.content) == null) {
-            ListFragment listFragment = new NoDividerListFragment();
-
-            listFragment.setListAdapter(new ArrayAdapter<>(this,
-                    R.layout.card_row, R.id.card_text, TextUtils.buildSimpleStringList()));
-            fm.beginTransaction().add(android.R.id.content, listFragment).commit();
-        }
+    protected ListFragment createListFragment() {
+        return new NoDividerListFragment();
     }
 }
diff --git a/tests/UiBench/src/com/android/test/uibench/listview/CompatListActivity.java b/tests/UiBench/src/com/android/test/uibench/listview/CompatListActivity.java
index 6659558..9a4b527 100644
--- a/tests/UiBench/src/com/android/test/uibench/listview/CompatListActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/listview/CompatListActivity.java
@@ -16,22 +16,29 @@
 package com.android.test.uibench.listview;
 
 import android.os.Bundle;
+import android.widget.ListAdapter;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
 import androidx.fragment.app.ListFragment;
-import androidx.appcompat.app.AppCompatActivity;
-import android.widget.ListAdapter;
 
 public abstract class CompatListActivity extends AppCompatActivity {
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        initializeActivity();
 
+        int containerViewId = getListFragmentContainerViewId();
         FragmentManager fm = getSupportFragmentManager();
-        if (fm.findFragmentById(android.R.id.content) == null) {
+        Fragment fragment = fm.findFragmentById(containerViewId);
+        if (fragment == null) {
             ListFragment listFragment = createListFragment();
             listFragment.setListAdapter(createListAdapter());
-            fm.beginTransaction().add(android.R.id.content, listFragment).commit();
+            fm.beginTransaction().add(containerViewId, listFragment).commit();
+        } else if (fragment instanceof ListFragment) {
+            ((ListFragment) fragment).setListAdapter(createListAdapter());
         }
     }
 
@@ -40,4 +47,11 @@
     protected ListFragment createListFragment() {
         return new ListFragment();
     }
+
+    protected int getListFragmentContainerViewId() {
+        return android.R.id.content;
+    }
+
+    protected void initializeActivity() {
+    }
 }
diff --git a/tests/UiBench/src/com/android/test/uibench/recyclerview/RvCompatListActivity.java b/tests/UiBench/src/com/android/test/uibench/recyclerview/RvCompatListActivity.java
index bd313ad..2f0d6ab 100644
--- a/tests/UiBench/src/com/android/test/uibench/recyclerview/RvCompatListActivity.java
+++ b/tests/UiBench/src/com/android/test/uibench/recyclerview/RvCompatListActivity.java
@@ -17,16 +17,17 @@
 
 import android.content.Context;
 import android.os.Bundle;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
 import com.android.test.uibench.R;
 
 public abstract class RvCompatListActivity extends AppCompatActivity {
@@ -51,14 +52,21 @@
         super.onCreate(savedInstanceState);
 
         FragmentManager fm = getSupportFragmentManager();
-        if (fm.findFragmentById(android.R.id.content) == null) {
+        Fragment existingFragment = fm.findFragmentById(android.R.id.content);
+        if (existingFragment == null) {
             RecyclerViewFragment fragment = new RecyclerViewFragment();
-            fragment.layoutManager = createLayoutManager(this);
-            fragment.adapter = createAdapter();
+            initializeRecyclerViewFragment(fragment);
             fm.beginTransaction().add(android.R.id.content, fragment).commit();
+        } else if (existingFragment instanceof RecyclerViewFragment) {
+            initializeRecyclerViewFragment((RecyclerViewFragment) existingFragment);
         }
     }
 
+    private void initializeRecyclerViewFragment(RecyclerViewFragment fragment) {
+        fragment.layoutManager = createLayoutManager(this);
+        fragment.adapter = createAdapter();
+    }
+
     protected RecyclerView.LayoutManager createLayoutManager(Context context) {
         return new LinearLayoutManager(context);
     }
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
index eec3cdbe..8c2de40 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/TestNetworkStackService.kt
@@ -52,7 +52,7 @@
         doReturn(mock(IBinder::class.java)).`when`(it).getSystemService(Context.NETD_SERVICE)
     }
 
-    private class TestPermissionChecker : NetworkStackConnector.PermissionChecker() {
+    private class TestPermissionChecker : NetworkStackService.PermissionChecker() {
         override fun enforceNetworkStackCallingPermission() = Unit
     }
 
@@ -62,8 +62,8 @@
         override fun sendNetworkConditionsBroadcast(context: Context, broadcast: Intent) = Unit
     }
 
-    private inner class TestNetworkStackConnector(context: Context) :
-            NetworkStackConnector(context, TestPermissionChecker()) {
+    private inner class TestNetworkStackConnector(context: Context) : NetworkStackConnector(
+            context, TestPermissionChecker(), NetworkStackService.Dependencies()) {
 
         private val network = Network(TEST_NETID)
         private val privateDnsBypassNetwork = TestNetwork(TEST_NETID)
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index a992778..d2b26d3 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -75,6 +75,7 @@
 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 import static android.net.RouteInfo.RTN_UNREACHABLE;
+import static android.os.Process.INVALID_UID;
 import static android.system.OsConstants.IPPROTO_TCP;
 
 import static com.android.server.ConnectivityServiceTestUtilsKt.transportToLegacyType;
@@ -6945,7 +6946,7 @@
         final NetworkAgentInfo naiWithoutUid =
                 new NetworkAgentInfo(
                         null, null, null, null, null, new NetworkCapabilities(), 0,
-                        mServiceContext, null, null, mService, null, null, null, 0);
+                        mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
 
         mServiceContext.setPermission(
                 android.Manifest.permission.NETWORK_STACK, PERMISSION_GRANTED);
@@ -6961,7 +6962,7 @@
         final NetworkAgentInfo naiWithoutUid =
                 new NetworkAgentInfo(
                         null, null, null, null, null, new NetworkCapabilities(), 0,
-                        mServiceContext, null, null, mService, null, null, null, 0);
+                        mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
 
         mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
 
@@ -6977,7 +6978,7 @@
         final NetworkAgentInfo naiWithoutUid =
                 new NetworkAgentInfo(
                         null, null, null, null, null, new NetworkCapabilities(), 0,
-                        mServiceContext, null, null, mService, null, null, null, 0);
+                        mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
 
         mServiceContext.setPermission(android.Manifest.permission.NETWORK_STACK, PERMISSION_DENIED);
 
@@ -6994,7 +6995,7 @@
         final NetworkAgentInfo naiWithoutUid =
                 new NetworkAgentInfo(
                         null, null, network, null, null, new NetworkCapabilities(), 0,
-                        mServiceContext, null, null, mService, null, null, null, 0);
+                        mServiceContext, null, null, mService, null, null, null, 0, INVALID_UID);
 
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
@@ -7028,7 +7029,7 @@
         final NetworkAgentInfo naiWithUid =
                 new NetworkAgentInfo(
                         null, null, null, null, null, nc, 0, mServiceContext, null, null,
-                        mService, null, null, null, 0);
+                        mService, null, null, null, 0, INVALID_UID);
 
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
@@ -7050,7 +7051,7 @@
         final NetworkAgentInfo naiWithUid =
                 new NetworkAgentInfo(
                         null, null, null, null, null, nc, 0, mServiceContext, null, null,
-                        mService, null, null, null, 0);
+                        mService, null, null, null, 0, INVALID_UID);
 
         setupLocationPermissions(Build.VERSION_CODES.Q, true, AppOpsManager.OPSTR_FINE_LOCATION,
                 Manifest.permission.ACCESS_FINE_LOCATION);
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 24a8717..aafa18a 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -38,6 +38,7 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.NetworkProvider;
+import android.os.Binder;
 import android.os.INetworkManagementService;
 import android.text.format.DateUtils;
 
@@ -354,7 +355,7 @@
         caps.addTransportType(transport);
         NetworkAgentInfo nai = new NetworkAgentInfo(null, null, new Network(netId), info, null,
                 caps, 50, mCtx, null, null /* config */, mConnService, mNetd, mDnsResolver, mNMS,
-                NetworkProvider.ID_NONE);
+                NetworkProvider.ID_NONE, Binder.getCallingUid());
         nai.everValidated = true;
         return nai;
     }
diff --git a/tests/testables/src/android/testing/TestableLooper.java b/tests/testables/src/android/testing/TestableLooper.java
index fe0224a..ebe9b57 100644
--- a/tests/testables/src/android/testing/TestableLooper.java
+++ b/tests/testables/src/android/testing/TestableLooper.java
@@ -222,6 +222,10 @@
         return sLoopers.get(test);
     }
 
+    public static void remove(Object test) {
+        sLoopers.remove(test);
+    }
+
     static class LooperFrameworkMethod extends FrameworkMethod {
         private HandlerThread mHandlerThread;
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 7d20d0d..5f46cb3 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -817,6 +817,9 @@
     /**
      * Broadcast intent action indicating that the wifi network settings
      * had been reset.
+     *
+     * Note: This intent is sent as a directed broadcast to each manifest registered receiver.
+     * Intent will not be received by dynamically registered receivers.
      * @hide
      */
     @SystemApi
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index d299cdc..94771ac 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -131,10 +131,10 @@
     public @interface WifiBand {}
 
     /**
-     * Max band value
+     * All bands
      * @hide
      */
-    public static final int WIFI_BAND_MAX = 0x10;
+    public static final int WIFI_BAND_ALL = (1 << WIFI_BAND_COUNT) - 1;
 
     /** Minimum supported scanning period */
     public static final int MIN_SCAN_PERIOD_MS = 1000;
@@ -168,6 +168,22 @@
     }
 
     /**
+     * Test if scan is a full scan. i.e. scanning all available bands.
+     * For backward compatibility, since some apps don't include 6GHz in their requests yet,
+     * lacking 6GHz band does not cause the result to be false.
+     *
+     * @param bandScanned bands that are fully scanned
+     * @param excludeDfs when true, DFS band is excluded from the check
+     * @return true if all bands are scanned, false otherwise
+     *
+     * @hide
+     */
+    public static boolean isFullBandScan(@WifiBand int bandScanned, boolean excludeDfs) {
+        return (bandScanned | WIFI_BAND_6_GHZ | (excludeDfs ? WIFI_BAND_5_GHZ_DFS_ONLY : 0))
+                == WIFI_BAND_ALL;
+    }
+
+    /**
      * Returns a list of all the possible channels for the given band(s).
      *
      * @param band one of the WifiScanner#WIFI_BAND_* constants, e.g. {@link #WIFI_BAND_24_GHZ}
diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
index 4881200..b68616f 100644
--- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
@@ -613,4 +613,22 @@
         verify(mExecutor, never()).execute(any());
         verify(mScanListener, never()).onResults(mScanData);
     }
+
+    /**
+     * Tests isFullBandScan() method with and without DFS check
+     */
+    @Test
+    public void testIsFullBandScan() throws Exception {
+        assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_24_GHZ, true));
+        assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_5_GHZ, true));
+        assertFalse(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_6_GHZ, true));
+        assertFalse(WifiScanner.isFullBandScan(
+                WifiScanner.WIFI_BAND_6_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true));
+        assertTrue(WifiScanner.isFullBandScan(
+                WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, true));
+        assertFalse(WifiScanner.isFullBandScan(
+                WifiScanner.WIFI_BAND_24_GHZ | WifiScanner.WIFI_BAND_5_GHZ, false));
+        assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, true));
+        assertTrue(WifiScanner.isFullBandScan(WifiScanner.WIFI_BAND_BOTH_WITH_DFS, false));
+    }
 }