Merge "Add package name when initializing SoundPool." into rvc-qpr-dev
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index 8f5dbc4..62ac84b 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -222,4 +222,16 @@
      * Returns the profile owner component for the given user, or {@code null} if there is not one.
      */
     public abstract ComponentName getProfileOwnerAsUser(int userHandle);
+
+    /**
+     * Returns whether this class supports being deferred the responsibility for resetting the given
+     * op.
+     */
+    public abstract boolean supportsResetOp(int op);
+
+    /**
+     * Resets the given op across the profile group of the given user for the given package. Assumes
+     * {@link #supportsResetOp(int)} is true.
+     */
+    public abstract void resetOp(int op, String packageName, @UserIdInt int userId);
 }
diff --git a/core/java/android/content/pm/CrossProfileAppsInternal.java b/core/java/android/content/pm/CrossProfileAppsInternal.java
index 16a749f..255aeac 100644
--- a/core/java/android/content/pm/CrossProfileAppsInternal.java
+++ b/core/java/android/content/pm/CrossProfileAppsInternal.java
@@ -17,6 +17,7 @@
 package android.content.pm;
 
 import android.annotation.UserIdInt;
+import android.app.AppOpsManager.Mode;
 import android.os.UserHandle;
 
 import java.util.List;
@@ -62,4 +63,14 @@
      */
     public abstract List<UserHandle> getTargetUserProfiles(
             String packageName, @UserIdInt int userId);
+
+    /**
+     * Sets the app-op for {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES} that is
+     * configurable by users in Settings. This configures it for the profile group of the given
+     * user.
+     *
+     * @see CrossProfileApps#setInteractAcrossProfilesAppOp(String, int)
+     */
+    public abstract void setInteractAcrossProfilesAppOp(
+            String packageName, @Mode int newMode, @UserIdInt int userId);
 }
diff --git a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
index 0d16cc4..26af615 100644
--- a/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/AppPredictionServiceResolverComparator.java
@@ -188,7 +188,7 @@
         }
         Integer rank = mTargetRanks.get(name);
         if (rank == null) {
-            Log.w(TAG, "Score requested for unknown component.");
+            Log.w(TAG, "Score requested for unknown component. Did you call compute yet?");
             return 0f;
         }
         int consecutiveSumOfRanks = (mTargetRanks.size() - 1) * (mTargetRanks.size()) / 2;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a3c00ff..796a557 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -826,8 +826,6 @@
                 queryDirectShareTargets(chooserListAdapter, true);
                 return;
             }
-            final List<DisplayResolveInfo> driList =
-                    getDisplayResolveInfos(chooserListAdapter);
             final List<ShortcutManager.ShareShortcutInfo> shareShortcutInfos =
                     new ArrayList<>();
 
@@ -855,7 +853,7 @@
                         new ComponentName(
                                 appTarget.getPackageName(), appTarget.getClassName())));
             }
-            sendShareShortcutInfoList(shareShortcutInfos, driList, resultList,
+            sendShareShortcutInfoList(shareShortcutInfos, chooserListAdapter, resultList,
                     chooserListAdapter.getUserHandle());
         };
     }
@@ -1974,32 +1972,6 @@
         }
     }
 
-    private List<DisplayResolveInfo> getDisplayResolveInfos(ChooserListAdapter adapter) {
-        // Need to keep the original DisplayResolveInfos to be able to reconstruct ServiceResultInfo
-        // and use the old code path. This Ugliness should go away when Sharesheet is refactored.
-        List<DisplayResolveInfo> driList = new ArrayList<>();
-        int targetsToQuery = 0;
-        for (int i = 0, n = adapter.getDisplayResolveInfoCount(); i < n; i++) {
-            final DisplayResolveInfo dri = adapter.getDisplayResolveInfo(i);
-            if (adapter.getScore(dri) == 0) {
-                // A score of 0 means the app hasn't been used in some time;
-                // don't query it as it's not likely to be relevant.
-                continue;
-            }
-            driList.add(dri);
-            targetsToQuery++;
-            // TODO(b/121287224): Do we need this here? (similar to queryTargetServices)
-            if (targetsToQuery >= SHARE_TARGET_QUERY_PACKAGE_LIMIT) {
-                if (DEBUG) {
-                    Log.d(TAG, "queryTargets hit query target limit "
-                            + SHARE_TARGET_QUERY_PACKAGE_LIMIT);
-                }
-                break;
-            }
-        }
-        return driList;
-    }
-
     @VisibleForTesting
     protected void queryDirectShareTargets(
                 ChooserListAdapter adapter, boolean skipAppPredictionService) {
@@ -2017,14 +1989,13 @@
         if (filter == null) {
             return;
         }
-        final List<DisplayResolveInfo> driList = getDisplayResolveInfos(adapter);
 
         AsyncTask.execute(() -> {
             Context selectedProfileContext = createContextAsUser(userHandle, 0 /* flags */);
             ShortcutManager sm = (ShortcutManager) selectedProfileContext
                     .getSystemService(Context.SHORTCUT_SERVICE);
             List<ShortcutManager.ShareShortcutInfo> resultList = sm.getShareTargets(filter);
-            sendShareShortcutInfoList(resultList, driList, null, userHandle);
+            sendShareShortcutInfoList(resultList, adapter, null, userHandle);
         });
     }
 
@@ -2061,7 +2032,7 @@
 
     private void sendShareShortcutInfoList(
                 List<ShortcutManager.ShareShortcutInfo> resultList,
-                List<DisplayResolveInfo> driList,
+                ChooserListAdapter chooserListAdapter,
                 @Nullable List<AppTarget> appTargets, UserHandle userHandle) {
         if (appTargets != null && appTargets.size() != resultList.size()) {
             throw new RuntimeException("resultList and appTargets must have the same size."
@@ -2087,10 +2058,10 @@
         // for direct share targets. After ShareSheet is refactored we should use the
         // ShareShortcutInfos directly.
         boolean resultMessageSent = false;
-        for (int i = 0; i < driList.size(); i++) {
+        for (int i = 0; i < chooserListAdapter.getDisplayResolveInfoCount(); i++) {
             List<ShortcutManager.ShareShortcutInfo> matchingShortcuts = new ArrayList<>();
             for (int j = 0; j < resultList.size(); j++) {
-                if (driList.get(i).getResolvedComponentName().equals(
+                if (chooserListAdapter.getDisplayResolveInfo(i).getResolvedComponentName().equals(
                             resultList.get(j).getTargetComponent())) {
                     matchingShortcuts.add(resultList.get(j));
                 }
@@ -2105,7 +2076,8 @@
 
             final Message msg = Message.obtain();
             msg.what = ChooserHandler.SHORTCUT_MANAGER_SHARE_TARGET_RESULT;
-            msg.obj = new ServiceResultInfo(driList.get(i), chooserTargets, null, userHandle);
+            msg.obj = new ServiceResultInfo(chooserListAdapter.getDisplayResolveInfo(i),
+                    chooserTargets, null, userHandle);
             msg.arg1 = shortcutType;
             mChooserHandler.sendMessage(msg);
             resultMessageSent = true;
diff --git a/core/proto/android/stats/mediametrics/mediametrics.proto b/core/proto/android/stats/mediametrics/mediametrics.proto
index 9f0ff59..2a27fa2 100644
--- a/core/proto/android/stats/mediametrics/mediametrics.proto
+++ b/core/proto/android/stats/mediametrics/mediametrics.proto
@@ -166,12 +166,23 @@
  * Logged from:
  *   frameworks/av/media/libstagefright/RemoteMediaExtractor.cpp
  *   frameworks/av/services/mediaanalytics/statsd_extractor.cpp
- * Next Tag: 4
+ * Next Tag: 5
  */
 message ExtractorData {
     optional string format = 1;
     optional string mime = 2;
     optional int32 tracks = 3;
+
+    enum EntryPoint {
+        UNSET = 0; // For backwards compatibility with clients that don't
+                   // collect the entry point.
+        SDK = 1;
+        NDK_WITH_JVM = 2;
+        NDK_NO_JVM = 3;
+        OTHER = 4; // For extractor users that don't make use of the APIs.
+    }
+
+    optional EntryPoint entry_point = 4 [default = UNSET];
 }
 
 /**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 162fa70..0992379 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -377,6 +377,7 @@
     <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST" />
     <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION" />
     <protected-broadcast android:name="android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW" />
+    <protected-broadcast android:name="android.net.wifi.action.REFRESH_USER_PROVISIONING" />
     <protected-broadcast android:name="android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION" />
     <protected-broadcast android:name="android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.supplicant.CONNECTION_CHANGE" />
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 57f2d6a..d41868e 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -20,12 +20,12 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="byteShort" msgid="202579285008794431">"B"</string>
+    <string name="byteShort" msgid="202579285008794431">"ባ"</string>
     <string name="kilobyteShort" msgid="2214285521564195803">"ኪባ"</string>
-    <string name="megabyteShort" msgid="6649361267635823443">"MB"</string>
-    <string name="gigabyteShort" msgid="7515809460261287991">"GB"</string>
-    <string name="terabyteShort" msgid="1822367128583886496">"TB"</string>
-    <string name="petabyteShort" msgid="5651571254228534832">"PB"</string>
+    <string name="megabyteShort" msgid="6649361267635823443">"ሜባ"</string>
+    <string name="gigabyteShort" msgid="7515809460261287991">"ጊባ"</string>
+    <string name="terabyteShort" msgid="1822367128583886496">"ቴባ"</string>
+    <string name="petabyteShort" msgid="5651571254228534832">"ፔባ"</string>
     <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="3381766946944136678">"&lt;ርዕስ አልባ&gt;"</string>
     <string name="emptyPhoneNumber" msgid="5812172618020360048">"(ምንም ስልክ ቁጥር የለም)"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 7b6dea3..13f1b56 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -823,7 +823,7 @@
     <string name="keyguard_password_enter_pin_password_code" msgid="7792964196473964340">"Introduce el código PIN para desbloquear."</string>
     <string name="keyguard_password_wrong_pin_code" msgid="8583732939138432793">"Código PIN incorrecto"</string>
     <string name="keyguard_label_text" msgid="3841953694564168384">"Para desbloquear el teléfono, pulsa la tecla de menú y, a continuación, pulsa 0."</string>
-    <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Llamada de emergencia"</string>
+    <string name="emergency_call_dialog_number_for_display" msgid="2978165477085612673">"Número de emergencia"</string>
     <string name="lockscreen_carrier_default" msgid="6192313772955399160">"Sin servicio"</string>
     <string name="lockscreen_screen_locked" msgid="7364905540516041817">"Pantalla bloqueada"</string>
     <string name="lockscreen_instructions_when_pattern_enabled" msgid="7982445492532123308">"Pulsa la tecla de menú para desbloquear el teléfono o realizar una llamada de emergencia."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index e8d6408..29fe136 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -52,7 +52,6 @@
     <string name="enablePin" msgid="2543771964137091212">"Opération infructueuse. Activez le verrouillage SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
       <item quantity="one">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM soit verrouillée.</item>
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
       <item quantity="other">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM soit verrouillée.</item>
     </plurals>
     <string name="imei" msgid="2157082351232630390">"Code IIEM"</string>
@@ -180,7 +179,6 @@
     <string name="low_memory" product="default" msgid="2539532364144025569">"La mémoire du téléphone est pleine. Veuillez supprimer des fichiers pour libérer de l\'espace."</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
       <item quantity="one">Autorité de certification installée</item>
-      <item quantity="many">Certificate authorities installed</item>
       <item quantity="other">Autorités de certification installées</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Par un tiers inconnu"</string>
@@ -253,7 +251,6 @@
     <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilisez cette option pour qu\'il y ait le moins d\'interférences système possible lorsque votre appareil ne répond pas ou qu\'il est trop lent, ou lorsque vous avez besoin de toutes les sections du rapport de bogue. Aucune capture d\'écran supplémentaire ne peut être capturée, et vous ne pouvez entrer aucune autre information."</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="3906120379260059206">
       <item quantity="one">Saisie d\'écran pour le rapport de bogue dans <xliff:g id="NUMBER_1">%d</xliff:g> seconde.</item>
-      <item quantity="many">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
       <item quantity="other">Saisie d\'écran pour le rapport de bogue dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes.</item>
     </plurals>
     <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Capture d\'écran prise avec le rapport de bogue"</string>
@@ -997,7 +994,6 @@
     <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Il y a plus d\'un mois"</string>
     <plurals name="last_num_days" formatted="false" msgid="687443109145393632">
       <item quantity="one">Le dernier <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
-      <item quantity="many">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
       <item quantity="other">Le dernier <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
     </plurals>
     <string name="last_month" msgid="1528906781083518683">"Le mois dernier"</string>
@@ -1020,82 +1016,66 @@
     <string name="now_string_shortest" msgid="3684914126941650330">"maintenant"</string>
     <plurals name="duration_minutes_shortest" formatted="false" msgid="7519574894537185135">
       <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
     </plurals>
     <plurals name="duration_hours_shortest" formatted="false" msgid="2838655994500499651">
       <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
     </plurals>
     <plurals name="duration_days_shortest" formatted="false" msgid="3686058472983158496">
       <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
     </plurals>
     <plurals name="duration_years_shortest" formatted="false" msgid="8299112348723640338">
       <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>y</item>
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
     </plurals>
     <plurals name="duration_minutes_shortest_future" formatted="false" msgid="849196137176399440">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>m</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
     </plurals>
     <plurals name="duration_hours_shortest_future" formatted="false" msgid="5386373597343170388">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>h</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
     </plurals>
     <plurals name="duration_days_shortest_future" formatted="false" msgid="814754627092787227">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>d</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
     </plurals>
     <plurals name="duration_years_shortest_future" formatted="false" msgid="7683731800140202145">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
     </plurals>
     <plurals name="duration_minutes_relative" formatted="false" msgid="6569851308583028344">
       <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item>
       <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
     </plurals>
     <plurals name="duration_hours_relative" formatted="false" msgid="420434788589102019">
       <item quantity="one">il y a<xliff:g id="COUNT_1">%d</xliff:g> heure</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item>
       <item quantity="other">il y a<xliff:g id="COUNT_1">%d</xliff:g> heures</item>
     </plurals>
     <plurals name="duration_days_relative" formatted="false" msgid="6056425878237482431">
       <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item>
       <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
     </plurals>
     <plurals name="duration_years_relative" formatted="false" msgid="2179998228861172159">
       <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> an</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
       <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
     </plurals>
     <plurals name="duration_minutes_relative_future" formatted="false" msgid="5759885720917567723">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
     </plurals>
     <plurals name="duration_hours_relative_future" formatted="false" msgid="8963511608507707959">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
     </plurals>
     <plurals name="duration_days_relative_future" formatted="false" msgid="1964709470979250702">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
     </plurals>
     <plurals name="duration_years_relative_future" formatted="false" msgid="3985129025134896371">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
     </plurals>
     <string name="VideoView_error_title" msgid="5750686717225068016">"Problème vidéo"</string>
@@ -1466,7 +1446,6 @@
     <string name="find_on_page" msgid="5400537367077438198">"Rechercher sur la page"</string>
     <plurals name="matches_found" formatted="false" msgid="1101758718194295554">
       <item quantity="one"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
-      <item quantity="many"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
       <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
     </plurals>
     <string name="action_mode_done" msgid="2536182504764803222">"Terminé"</string>
@@ -1603,7 +1582,6 @@
     <string name="kg_wrong_pin" msgid="3680925703673166482">"NIP incorrect."</string>
     <plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="236717428673283568">
       <item quantity="one">Réessayer dans <xliff:g id="NUMBER">%d</xliff:g> seconde.</item>
-      <item quantity="many">Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds.</item>
       <item quantity="other">Réessayer dans <xliff:g id="NUMBER">%d</xliff:g> secondes.</item>
     </plurals>
     <string name="kg_pattern_instructions" msgid="8366024510502517748">"Dessinez votre schéma."</string>
@@ -1790,7 +1768,6 @@
     <string name="restr_pin_error_too_short" msgid="1547007808237941065">"Le NIP est trop court. Il doit comporter au moins 4 chiffres."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
       <item quantity="one">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> seconde</item>
-      <item quantity="many">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
       <item quantity="other">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> secondes</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="5897719962541636727">"Réessayez plus tard"</string>
@@ -1822,42 +1799,34 @@
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
       <item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
-      <item quantity="many">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="4230730310318858312">
       <item quantity="one">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
-      <item quantity="many">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758">
       <item quantity="one">Pendant %1$d heure (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
-      <item quantity="many">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="588719069121765642">
       <item quantity="one">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
-      <item quantity="many">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_minutes" formatted="false" msgid="1148568456958944998">
       <item quantity="one">Pendant %d minute</item>
-      <item quantity="many">For %d minutes</item>
       <item quantity="other">Pendant %d minutes</item>
     </plurals>
     <plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2742377799995454859">
       <item quantity="one">Pendant %d min</item>
-      <item quantity="many">For %d min</item>
       <item quantity="other">Pendant %d min</item>
     </plurals>
     <plurals name="zen_mode_duration_hours" formatted="false" msgid="525401855645490022">
       <item quantity="one">Pendant %d heure</item>
-      <item quantity="many">For %d hours</item>
       <item quantity="other">Pendant %d heures</item>
     </plurals>
     <plurals name="zen_mode_duration_hours_short" formatted="false" msgid="7644653189680911640">
       <item quantity="one">Pendant %d h</item>
-      <item quantity="many">For %d hr</item>
       <item quantity="other">Pendant %d h</item>
     </plurals>
     <string name="zen_mode_until" msgid="2250286190237669079">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
@@ -1898,7 +1867,6 @@
     <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
     <plurals name="selected_count" formatted="false" msgid="3946212171128200491">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
     </plurals>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
@@ -1966,7 +1934,6 @@
     <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Aucune suggestion de remplissage automatique"</string>
     <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="6651883186966959978">
       <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> suggestion de remplissage automatique</item>
-      <item quantity="many"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item>
       <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> suggestions de remplissage automatique</item>
     </plurals>
     <string name="autofill_save_title" msgid="7719802414283739775">"Enregistrer sous "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>"?"</string>
@@ -2060,7 +2027,6 @@
     <string name="car_loading_profile" msgid="8219978381196748070">"Chargement en cours…"</string>
     <plurals name="file_count" formatted="false" msgid="7063513834724389247">
       <item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichier</item>
-      <item quantity="many"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> files</item>
       <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichiers</item>
     </plurals>
     <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index fc91c47..a5b1626 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -52,7 +52,6 @@
     <string name="enablePin" msgid="2543771964137091212">"Échec de l\'opération. Veuillez activer le verrouillage de la carte SIM/RUIM."</string>
     <plurals name="pinpuk_attempts" formatted="false" msgid="1619867269012213584">
       <item quantity="one">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentative avant que votre carte SIM ne soit verrouillée.</item>
-      <item quantity="many">You have <xliff:g id="NUMBER_1">%d</xliff:g> remaining attempts before SIM is locked.</item>
       <item quantity="other">Il vous reste <xliff:g id="NUMBER_1">%d</xliff:g> tentatives avant que votre carte SIM ne soit verrouillée.</item>
     </plurals>
     <string name="imei" msgid="2157082351232630390">"Code IMEI"</string>
@@ -180,7 +179,6 @@
     <string name="low_memory" product="default" msgid="2539532364144025569">"La mémoire du téléphone est pleine. Veuillez supprimer des fichiers pour libérer de l\'espace."</string>
     <plurals name="ssl_ca_cert_warning" formatted="false" msgid="2288194355006173029">
       <item quantity="one">Autorité de certification installée</item>
-      <item quantity="many">Certificate authorities installed</item>
       <item quantity="other">Autorités de certification installées</item>
     </plurals>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4961102218216815242">"Par un tiers inconnu"</string>
@@ -253,7 +251,6 @@
     <string name="bugreport_option_full_summary" msgid="1975130009258435885">"Utilisez cette option pour qu\'il y ait le moins d\'interférences système possible lorsque votre appareil ne répond pas ou qu\'il est trop lent, ou lorsque vous avez besoin de toutes les sections du rapport de bug. Aucune capture d\'écran supplémentaire ne peut être prise, et vous ne pouvez saisir aucune autre information."</string>
     <plurals name="bugreport_countdown" formatted="false" msgid="3906120379260059206">
       <item quantity="one">Capture d\'écran pour le rapport de bug dans <xliff:g id="NUMBER_1">%d</xliff:g> seconde</item>
-      <item quantity="many">Taking screenshot for bug report in <xliff:g id="NUMBER_1">%d</xliff:g> seconds.</item>
       <item quantity="other">Capture d\'écran pour le rapport de bug dans <xliff:g id="NUMBER_1">%d</xliff:g> secondes</item>
     </plurals>
     <string name="bugreport_screenshot_success_toast" msgid="7986095104151473745">"Capture d\'écran avec rapport de bug effectuée"</string>
@@ -997,7 +994,6 @@
     <string name="beforeOneMonthDurationPast" msgid="8315149541372065392">"Il y a plus d\'un mois"</string>
     <plurals name="last_num_days" formatted="false" msgid="687443109145393632">
       <item quantity="one">Le dernier jour (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
-      <item quantity="many">Last <xliff:g id="COUNT_1">%d</xliff:g> days</item>
       <item quantity="other">Les <xliff:g id="COUNT_1">%d</xliff:g> derniers jours</item>
     </plurals>
     <string name="last_month" msgid="1528906781083518683">"Le mois dernier"</string>
@@ -1020,82 +1016,66 @@
     <string name="now_string_shortest" msgid="3684914126941650330">"mainten."</string>
     <plurals name="duration_minutes_shortest" formatted="false" msgid="7519574894537185135">
       <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>m</item>
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> m</item>
     </plurals>
     <plurals name="duration_hours_shortest" formatted="false" msgid="2838655994500499651">
       <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>h</item>
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> h</item>
     </plurals>
     <plurals name="duration_days_shortest" formatted="false" msgid="3686058472983158496">
       <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>d</item>
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> j</item>
     </plurals>
     <plurals name="duration_years_shortest" formatted="false" msgid="8299112348723640338">
       <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g>y</item>
       <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a</item>
     </plurals>
     <plurals name="duration_minutes_shortest_future" formatted="false" msgid="849196137176399440">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>m</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> m</item>
     </plurals>
     <plurals name="duration_hours_shortest_future" formatted="false" msgid="5386373597343170388">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>h</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> h</item>
     </plurals>
     <plurals name="duration_days_shortest_future" formatted="false" msgid="814754627092787227">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>d</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> j</item>
     </plurals>
     <plurals name="duration_years_shortest_future" formatted="false" msgid="7683731800140202145">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
     </plurals>
     <plurals name="duration_minutes_relative" formatted="false" msgid="6569851308583028344">
       <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> minutes ago</item>
       <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
     </plurals>
     <plurals name="duration_hours_relative" formatted="false" msgid="420434788589102019">
       <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> hours ago</item>
       <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
     </plurals>
     <plurals name="duration_days_relative" formatted="false" msgid="6056425878237482431">
       <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> days ago</item>
       <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
     </plurals>
     <plurals name="duration_years_relative" formatted="false" msgid="2179998228861172159">
       <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> an</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
       <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
     </plurals>
     <plurals name="duration_minutes_relative_future" formatted="false" msgid="5759885720917567723">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
     </plurals>
     <plurals name="duration_hours_relative_future" formatted="false" msgid="8963511608507707959">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
     </plurals>
     <plurals name="duration_days_relative_future" formatted="false" msgid="1964709470979250702">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
     </plurals>
     <plurals name="duration_years_relative_future" formatted="false" msgid="3985129025134896371">
       <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> an</item>
-      <item quantity="many">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
       <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
     </plurals>
     <string name="VideoView_error_title" msgid="5750686717225068016">"Problème vidéo"</string>
@@ -1466,7 +1446,6 @@
     <string name="find_on_page" msgid="5400537367077438198">"Rechercher sur la page"</string>
     <plurals name="matches_found" formatted="false" msgid="1101758718194295554">
       <item quantity="one"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
-      <item quantity="many"><xliff:g id="INDEX">%d</xliff:g> of <xliff:g id="TOTAL">%d</xliff:g></item>
       <item quantity="other"><xliff:g id="INDEX">%d</xliff:g> sur <xliff:g id="TOTAL">%d</xliff:g></item>
     </plurals>
     <string name="action_mode_done" msgid="2536182504764803222">"OK"</string>
@@ -1603,7 +1582,6 @@
     <string name="kg_wrong_pin" msgid="3680925703673166482">"Code PIN incorrect."</string>
     <plurals name="kg_too_many_failed_attempts_countdown" formatted="false" msgid="236717428673283568">
       <item quantity="one">Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> seconde.</item>
-      <item quantity="many">Try again in <xliff:g id="NUMBER">%d</xliff:g> seconds.</item>
       <item quantity="other">Réessayez dans <xliff:g id="NUMBER">%d</xliff:g> secondes.</item>
     </plurals>
     <string name="kg_pattern_instructions" msgid="8366024510502517748">"Dessinez votre schéma."</string>
@@ -1790,7 +1768,6 @@
     <string name="restr_pin_error_too_short" msgid="1547007808237941065">"Le code PIN est trop court. Il doit comporter au moins 4 chiffres."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
       <item quantity="one">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> seconde</item>
-      <item quantity="many">Try again in <xliff:g id="COUNT">%d</xliff:g> seconds</item>
       <item quantity="other">Réessayer dans <xliff:g id="COUNT">%d</xliff:g> secondes</item>
     </plurals>
     <string name="restr_pin_try_later" msgid="5897719962541636727">"Veuillez réessayer ultérieurement."</string>
@@ -1822,42 +1799,34 @@
     <string name="data_saver_enable_button" msgid="4399405762586419726">"Activer"</string>
     <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="2877101784123058273">
       <item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
-      <item quantity="many">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_minutes_summary_short" formatted="false" msgid="4230730310318858312">
       <item quantity="one">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
-      <item quantity="many">For %1$d min (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d min (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="7725354244196466758">
       <item quantity="one">Pendant %1$d heure (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
-      <item quantity="many">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_hours_summary_short" formatted="false" msgid="588719069121765642">
       <item quantity="one">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
-      <item quantity="many">For %1$d hr (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
       <item quantity="other">Pendant %1$d h (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
     </plurals>
     <plurals name="zen_mode_duration_minutes" formatted="false" msgid="1148568456958944998">
       <item quantity="one">Pendant %d minute</item>
-      <item quantity="many">For %d minutes</item>
       <item quantity="other">Pendant %d minutes</item>
     </plurals>
     <plurals name="zen_mode_duration_minutes_short" formatted="false" msgid="2742377799995454859">
       <item quantity="one">Pendant %d min</item>
-      <item quantity="many">For %d min</item>
       <item quantity="other">Pendant %d min</item>
     </plurals>
     <plurals name="zen_mode_duration_hours" formatted="false" msgid="525401855645490022">
       <item quantity="one">Pendant %d heure</item>
-      <item quantity="many">For %d hours</item>
       <item quantity="other">Pendant %d heures</item>
     </plurals>
     <plurals name="zen_mode_duration_hours_short" formatted="false" msgid="7644653189680911640">
       <item quantity="one">Pendant %d h</item>
-      <item quantity="many">For %d hr</item>
       <item quantity="other">Pendant %d h</item>
     </plurals>
     <string name="zen_mode_until" msgid="2250286190237669079">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
@@ -1898,7 +1867,6 @@
     <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g> : <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
     <plurals name="selected_count" formatted="false" msgid="3946212171128200491">
       <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item>
     </plurals>
     <string name="default_notification_channel_label" msgid="3697928973567217330">"Sans catégorie"</string>
@@ -1966,7 +1934,6 @@
     <string name="autofill_picker_no_suggestions" msgid="1076022650427481509">"Aucune suggestion de saisie automatique"</string>
     <plurals name="autofill_picker_some_suggestions" formatted="false" msgid="6651883186966959978">
       <item quantity="one"><xliff:g id="COUNT">%1$s</xliff:g> suggestion de saisie automatique</item>
-      <item quantity="many"><xliff:g id="COUNT">%1$s</xliff:g> autofill suggestions</item>
       <item quantity="other"><xliff:g id="COUNT">%1$s</xliff:g> suggestions de saisie automatique</item>
     </plurals>
     <string name="autofill_save_title" msgid="7719802414283739775">"Enregistrer dans "<b>"<xliff:g id="LABEL">%1$s</xliff:g>"</b>" ?"</string>
@@ -2060,7 +2027,6 @@
     <string name="car_loading_profile" msgid="8219978381196748070">"Chargement…"</string>
     <plurals name="file_count" formatted="false" msgid="7063513834724389247">
       <item quantity="one"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichier</item>
-      <item quantity="many"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> files</item>
       <item quantity="other"><xliff:g id="FILE_NAME_2">%s</xliff:g> + <xliff:g id="COUNT_3">%d</xliff:g> fichiers</item>
     </plurals>
     <string name="chooser_no_direct_share_targets" msgid="1511722103987329028">"Aucune recommandation de personnes avec lesquelles effectuer un partage"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 95e1a48e1..054344e 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1441,7 +1441,7 @@
     <string name="car_mode_disable_notification_message" msgid="8954550232288567515">"Tocca per uscire dall\'app di guida."</string>
     <string name="back_button_label" msgid="4078224038025043387">"Indietro"</string>
     <string name="next_button_label" msgid="6040209156399907780">"Avanti"</string>
-    <string name="skip_button_label" msgid="3566599811326688389">"Ignora"</string>
+    <string name="skip_button_label" msgid="3566599811326688389">"Salta"</string>
     <string name="no_matches" msgid="6472699895759164599">"Nessuna corrispondenza"</string>
     <string name="find_on_page" msgid="5400537367077438198">"Trova nella pagina"</string>
     <plurals name="matches_found" formatted="false" msgid="1101758718194295554">
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index a87c7e7..657f680 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -472,10 +472,10 @@
     <string name="permdesc_transmitIr" product="tablet" msgid="5884738958581810253">"Апп-д таблетын хэт улаан дамжуулагчийг ашиглахыг зөвшөөрнө."</string>
     <string name="permdesc_transmitIr" product="tv" msgid="3278506969529173281">"Аппад таны Android TV төхөөрөмжийн хэт улаан туяаны дамжуулагчийг ашиглахыг зөвшөөрнө."</string>
     <string name="permdesc_transmitIr" product="default" msgid="8484193849295581808">"Апп-д утасны хэт улаан дамжуулагчийг ашиглахыг зөвшөөрнө."</string>
-    <string name="permlab_setWallpaper" msgid="6959514622698794511">"ханын зургийг тохируулах"</string>
-    <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Апп нь системийн ханын зургийг тохируулах боломжтой."</string>
-    <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"Таны ханын зурагны хэмжээг тохируулах"</string>
-    <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Апп нь системийн ханын зургийн хэмжээний саналыг тохируулах боломжтой"</string>
+    <string name="permlab_setWallpaper" msgid="6959514622698794511">"дэлгэцийн зургийг тохируулах"</string>
+    <string name="permdesc_setWallpaper" msgid="2973996714129021397">"Апп нь системийн дэлгэцийн зургийг тохируулах боломжтой."</string>
+    <string name="permlab_setWallpaperHints" msgid="1153485176642032714">"Таны дэлгэцийн зургийн хэмжээг тохируулах"</string>
+    <string name="permdesc_setWallpaperHints" msgid="6257053376990044668">"Апп нь системийн дэлгэцийн зургийн хэмжээний саналыг тохируулах боломжтой"</string>
     <string name="permlab_setTimeZone" msgid="7922618798611542432">"цагийн бүсийн тохиргоо"</string>
     <string name="permdesc_setTimeZone" product="tablet" msgid="1788868809638682503">"Апп нь таблетын цагийн бүсийг солих боломжтой."</string>
     <string name="permdesc_setTimeZone" product="tv" msgid="9069045914174455938">"Аппад таны Android TV төхөөрөмжийн цагийн бүсийг өөрчлөхийг зөвшөөрнө."</string>
@@ -1418,8 +1418,8 @@
     <string name="input_method_binding_label" msgid="1166731601721983656">"Оруулах арга"</string>
     <string name="sync_binding_label" msgid="469249309424662147">"Синк"</string>
     <string name="accessibility_binding_label" msgid="1974602776545801715">"Хандалт"</string>
-    <string name="wallpaper_binding_label" msgid="1197440498000786738">"Ханын зураг"</string>
-    <string name="chooser_wallpaper" msgid="3082405680079923708">"Ханын зураг солих"</string>
+    <string name="wallpaper_binding_label" msgid="1197440498000786738">"Дэлгэцийн зураг"</string>
+    <string name="chooser_wallpaper" msgid="3082405680079923708">"Дэлгэцийн зураг солих"</string>
     <string name="notification_listener_binding_label" msgid="2702165274471499713">"Мэдэгдэл сонсогч"</string>
     <string name="vr_listener_binding_label" msgid="8013112996671206429">"VR сонсогч"</string>
     <string name="condition_provider_service_binding_label" msgid="8490641013951857673">"Нөхцөл нийлүүлэгч"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 6723e66..e2cf7f9 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1956,7 +1956,7 @@
     <string name="autofill_save_type_debit_card" msgid="3169397504133097468">"डेबिट कार्ड"</string>
     <string name="autofill_save_type_payment_card" msgid="6555012156728690856">"भुक्तानी कार्ड"</string>
     <string name="autofill_save_type_generic_card" msgid="1019367283921448608">"कार्ड"</string>
-    <string name="autofill_save_type_username" msgid="1018816929884640882">"प्रयोगकर्ताको नाम"</string>
+    <string name="autofill_save_type_username" msgid="1018816929884640882">"युजरनेम"</string>
     <string name="autofill_save_type_email_address" msgid="1303262336895591924">"इमेल ठेगाना"</string>
     <string name="etws_primary_default_message_earthquake" msgid="8401079517718280669">"शान्त रहनुहोस् र नजिकै आश्रयस्थल खोज्नुहोस्।"</string>
     <string name="etws_primary_default_message_tsunami" msgid="5828171463387976279">"तटीय क्षेत्र र नदीछेउका ठाउँहरू छाडी उच्च सतहमा अवस्थित कुनै अझ सुरक्षित ठाउँमा जानुहोस्।"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index df5cdac..624d554 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -162,7 +162,7 @@
     <string name="httpErrorAuth" msgid="469553140922938968">"Nepodarilo sa overiť totožnosť."</string>
     <string name="httpErrorProxyAuth" msgid="7229662162030113406">"Overenie pomocou servera proxy bolo neúspešné."</string>
     <string name="httpErrorConnect" msgid="3295081579893205617">"K serveru sa nepodarilo pripojiť."</string>
-    <string name="httpErrorIO" msgid="3860318696166314490">"Nepodarilo sa nadviazať komunikáciu so serverom. Skúste to znova neskôr."</string>
+    <string name="httpErrorIO" msgid="3860318696166314490">"Nepodarilo sa nadviazať komunikáciu so serverom. Skúste to neskôr."</string>
     <string name="httpErrorTimeout" msgid="7446272815190334204">"Časový limit pripojenia na server vypršal."</string>
     <string name="httpErrorRedirectLoop" msgid="8455757777509512098">"Stránka obsahuje príliš veľa presmerovaní servera."</string>
     <string name="httpErrorUnsupportedScheme" msgid="2664108769858966374">"Protokol nie je podporovaný."</string>
@@ -563,7 +563,7 @@
     <string name="fingerprint_error_timeout" msgid="2946635815726054226">"Časový limit rozpoznania odtlačku prsta vypršal. Skúste to znova."</string>
     <string name="fingerprint_error_canceled" msgid="540026881380070750">"Operácia týkajúca sa odtlačku prsta bola zrušená"</string>
     <string name="fingerprint_error_user_canceled" msgid="7685676229281231614">"Overenie odtlačku prsta zrušil používateľ."</string>
-    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Príliš veľa pokusov. Skúste to znova neskôr."</string>
+    <string name="fingerprint_error_lockout" msgid="7853461265604738671">"Príliš veľa pokusov. Skúste to neskôr."</string>
     <string name="fingerprint_error_lockout_permanent" msgid="3895478283943513746">"Príliš veľa pokusov. Senzor odtlačkov prstov bol deaktivovaný."</string>
     <string name="fingerprint_error_unable_to_process" msgid="1148553603490048742">"Skúste to znova"</string>
     <string name="fingerprint_error_no_fingerprints" msgid="8671811719699072411">"Neregistrovali ste žiadne odtlačky prstov."</string>
@@ -607,7 +607,7 @@
     <string name="face_error_no_space" msgid="5649264057026021723">"Nové údaje o tvári sa nedajú uložiť. Najprv odstráňte jeden zo starých záznamov."</string>
     <string name="face_error_canceled" msgid="2164434737103802131">"Operácia týkajúca sa tváre bola zrušená"</string>
     <string name="face_error_user_canceled" msgid="8553045452825849843">"Odomknutie tvárou zrušil používateľ."</string>
-    <string name="face_error_lockout" msgid="7864408714994529437">"Príliš veľa pokusov. Skúste to znova neskôr."</string>
+    <string name="face_error_lockout" msgid="7864408714994529437">"Príliš veľa pokusov. Skúste to neskôr."</string>
     <string name="face_error_lockout_permanent" msgid="8277853602168960343">"Príliš veľa pokusov. Odomknutie tvárou bolo zakázané."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Nedá sa overiť tvár. Skúste to znova."</string>
     <string name="face_error_not_enrolled" msgid="7369928733504691611">"Nenastavili ste odomknutie tvárou."</string>
@@ -1816,7 +1816,7 @@
       <item quantity="other">Skúste to znova o <xliff:g id="COUNT">%d</xliff:g> sekúnd</item>
       <item quantity="one">Skúste to znova o 1 sekundu</item>
     </plurals>
-    <string name="restr_pin_try_later" msgid="5897719962541636727">"Skúste to znova neskôr"</string>
+    <string name="restr_pin_try_later" msgid="5897719962541636727">"Skúste to neskôr"</string>
     <string name="immersive_cling_title" msgid="2307034298721541791">"Zobrazenie na celú obrazovku"</string>
     <string name="immersive_cling_description" msgid="7092737175345204832">"Ukončíte potiahnutím zhora nadol."</string>
     <string name="immersive_cling_positive" msgid="7047498036346489883">"Dobre"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 9e409f1..2b83c82 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -584,7 +584,7 @@
     <string name="face_acquired_too_right" msgid="2513391513020932655">"Telefonni chapga suring."</string>
     <string name="face_acquired_too_left" msgid="8882499346502714350">"Telefonni oʻngga suring."</string>
     <string name="face_acquired_poor_gaze" msgid="4427153558773628020">"Qurilmaga tik qarang."</string>
-    <string name="face_acquired_not_detected" msgid="2945945257956443257">"Telefoningizga yuzingizni tik tuting."</string>
+    <string name="face_acquired_not_detected" msgid="2945945257956443257">"Telefonni yuzingizga tik qarating."</string>
     <string name="face_acquired_too_much_motion" msgid="8199691445085189528">"Ortiqcha harakatlanmoqda. Qimirlatmasdan ushlang."</string>
     <string name="face_acquired_recalibrate" msgid="8724013080976469746">"Yuzingizni qaytadan qayd qildiring."</string>
     <string name="face_acquired_too_different" msgid="4699657338753282542">"Yuz tanilmadi. Qaytadan urining."</string>
@@ -1765,7 +1765,7 @@
     <string name="restr_pin_confirm_pin" msgid="7143161971614944989">"Yangi PIN kodni tasdiqlash"</string>
     <string name="restr_pin_create_pin" msgid="917067613896366033">"Cheklovlarni o‘zgartirish uchun PIN-kod yaratish"</string>
     <string name="restr_pin_error_doesnt_match" msgid="7063392698489280556">"PIN-kod mos kelmadi. Qayta urinib ko‘ring."</string>
-    <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN kod kamida 4 ta raqamdan iborat bo‘lishi shart."</string>
+    <string name="restr_pin_error_too_short" msgid="1547007808237941065">"PIN kod juda qisqa, kamida 4 ta raqam kiriting."</string>
     <plurals name="restr_pin_countdown" formatted="false" msgid="4427486903285216153">
       <item quantity="other"><xliff:g id="COUNT">%d</xliff:g> soniyadan so‘ng qayta urinib ko‘ring</item>
       <item quantity="one">1 soniyadan so‘ng qayta urinib ko‘ring</item>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index ffb5b93..bb5360e 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -808,7 +808,7 @@
     <string name="relationTypeReferredBy" msgid="5285082289602849400">"Kusikiselwe ngu-"</string>
     <string name="relationTypeRelative" msgid="3396498519818009134">"Isihlobo"</string>
     <string name="relationTypeSister" msgid="3721676005094140671">"Usisi"</string>
-    <string name="relationTypeSpouse" msgid="6916682664436031703">"Umlingane"</string>
+    <string name="relationTypeSpouse" msgid="6916682664436031703">"Umlingani"</string>
     <string name="sipAddressTypeCustom" msgid="6283889809842649336">"Ngokwezifiso"</string>
     <string name="sipAddressTypeHome" msgid="5918441930656878367">"Ekhaya"</string>
     <string name="sipAddressTypeWork" msgid="7873967986701216770">"Umsebenzi"</string>
diff --git a/data/etc/com.android.cellbroadcastreceiver.xml b/data/etc/com.android.cellbroadcastreceiver.xml
index dd2df42..228ec54 100644
--- a/data/etc/com.android.cellbroadcastreceiver.xml
+++ b/data/etc/com.android.cellbroadcastreceiver.xml
@@ -22,5 +22,6 @@
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
         <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
+        <permission name="android.permission.STATUS_BAR" />
     </privapp-permissions>
 </permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index b1669e3..3b6abd5 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -52,6 +52,7 @@
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/>
         <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
+        <permission name="android.permission.STATUS_BAR" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.cellbroadcastservice">
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 528dc62..c60203ea 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -68,7 +68,7 @@
     mClass = (jclass)env->NewGlobalRef(clazz);
     mObject = env->NewWeakGlobalRef(thiz);
 
-    mImpl = new NuMediaExtractor;
+    mImpl = new NuMediaExtractor(NuMediaExtractor::EntryPoint::SDK);
 }
 
 JMediaExtractor::~JMediaExtractor() {
diff --git a/packages/CarSystemUI/res/values-uz/strings.xml b/packages/CarSystemUI/res/values-uz/strings.xml
index adef2ad..15b2b7a 100644
--- a/packages/CarSystemUI/res/values-uz/strings.xml
+++ b/packages/CarSystemUI/res/values-uz/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="hvac_min_text" msgid="8167124789068494624">"Daq."</string>
+    <string name="hvac_min_text" msgid="8167124789068494624">"Min"</string>
     <string name="hvac_max_text" msgid="3669693372074755551">"Maks."</string>
     <string name="voice_recognition_toast" msgid="1149934534584052842">"Endi ovozni tanish Bluetooth qurilma ulanganda amalga oshadi"</string>
     <string name="car_guest" msgid="318393171202663722">"Mehmon"</string>
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
index 082c148..3b7775a 100644
--- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -57,7 +57,6 @@
     <string name="print_forget_printer" msgid="5035287497291910766">"Supprimer l\'imprimante"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
       <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimante trouvée</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimante trouvées</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> - <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
@@ -78,7 +77,6 @@
     <string name="all_services_title" msgid="5578662754874906455">"Tous les services"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
       <item quantity="one">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimante</item>
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
       <item quantity="other">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes</item>
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> en cours…"</string>
diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml
index 560c5dc..f6e901d 100644
--- a/packages/PrintSpooler/res/values-fr/strings.xml
+++ b/packages/PrintSpooler/res/values-fr/strings.xml
@@ -57,7 +57,6 @@
     <string name="print_forget_printer" msgid="5035287497291910766">"Supprimer l\'imprimante"</string>
     <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868">
       <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimante trouvée</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$s</xliff:g> printers found</item>
       <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes trouvées</item>
     </plurals>
     <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string>
@@ -78,7 +77,6 @@
     <string name="all_services_title" msgid="5578662754874906455">"Tous les services"</string>
     <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138">
       <item quantity="one">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimante</item>
-      <item quantity="many">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item>
       <item quantity="other">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes</item>
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 4397b35..a3f26ef 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -489,7 +489,6 @@
     <string name="wifi_status_mac_randomized" msgid="466382542497832189">"Les adresses MAC sont randomisées"</string>
     <plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
       <item quantity="one">%1$d appareil connecté</item>
-      <item quantity="many">%1$d devices connected</item>
       <item quantity="other">%1$d appareils connectés</item>
     </plurals>
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Plus longtemps."</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 6d7428d..a467540 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -251,7 +251,7 @@
     <string name="wifi_display_certification" msgid="1805579519992520381">"Certification affichage sans fil"</string>
     <string name="wifi_verbose_logging" msgid="1785910450009679371">"Autoriser l\'enregistrement d\'infos Wi-Fi détaillées"</string>
     <string name="wifi_scan_throttling" msgid="2985624788509913617">"Limiter la recherche Wi‑Fi"</string>
-    <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Chgt aléatoire d\'adresse MAC en Wi-Fi"</string>
+    <string name="wifi_enhanced_mac_randomization" msgid="5437378364995776979">"Changement aléatoire d\'adresse MAC en Wi-Fi"</string>
     <string name="mobile_data_always_on" msgid="8275958101875563572">"Données mobiles toujours actives"</string>
     <string name="tethering_hardware_offload" msgid="4116053719006939161">"Accélération matérielle pour le partage de connexion"</string>
     <string name="bluetooth_show_devices_without_names" msgid="923584526471885819">"Afficher les appareils Bluetooth sans nom"</string>
@@ -489,7 +489,6 @@
     <string name="wifi_status_mac_randomized" msgid="466382542497832189">"La sélection des adresses MAC est aléatoire"</string>
     <plurals name="wifi_tether_connected_summary" formatted="false" msgid="6317236306047306139">
       <item quantity="one">%1$d appareil connecté</item>
-      <item quantity="many">%1$d devices connected</item>
       <item quantity="other">%1$d appareils connectés</item>
     </plurals>
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Plus longtemps."</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index a4cea79..9562498 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -826,7 +826,7 @@
     <string name="switch_bar_on" msgid="1770868129120096114">"Идэвхтэй"</string>
     <string name="switch_bar_off" msgid="5669805115416379556">"Идэвхгүй"</string>
     <string name="tile_unavailable" msgid="3095879009136616920">"Боломжгүй"</string>
-    <string name="nav_bar" msgid="4642708685386136807">"Навигацийн самбар"</string>
+    <string name="nav_bar" msgid="4642708685386136807">"Навигацын самбар"</string>
     <string name="nav_bar_layout" msgid="4716392484772899544">"Бүдүүвч"</string>
     <string name="left_nav_bar_button_type" msgid="2634852842345192790">"Нэмэлт зүүн товчлуураар шивэх"</string>
     <string name="right_nav_bar_button_type" msgid="4472566498647364715">"Нэмэлт баруун товчлуураар шивэх"</string>
@@ -848,7 +848,7 @@
     <string name="reset" msgid="8715144064608810383">"Шинэчлэх"</string>
     <string name="adjust_button_width" msgid="8313444823666482197">"Товчлуурын өргөнг тохируулах"</string>
     <string name="clipboard" msgid="8517342737534284617">"Түр санах ой"</string>
-    <string name="accessibility_key" msgid="3471162841552818281">"Навигацийн товчлуурыг өөрчлөх"</string>
+    <string name="accessibility_key" msgid="3471162841552818281">"Навигацын товчлуурыг өөрчлөх"</string>
     <string name="left_keycode" msgid="8211040899126637342">"Зүүн түлхүүрийн код"</string>
     <string name="right_keycode" msgid="2480715509844798438">"Баруун түлхүүрийн код"</string>
     <string name="left_icon" msgid="5036278531966897006">"Зүүн дүрс тэмдэг"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
index dc42997..603679a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
@@ -75,6 +75,7 @@
 import com.android.systemui.tracing.nano.SystemUiTraceProto;
 
 import java.io.PrintWriter;
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -204,10 +205,15 @@
     private BackGestureTfClassifierProvider mBackGestureTfClassifierProvider;
     private Map<String, Integer> mVocab;
     private boolean mUseMLModel;
+    // minimum width below which we do not run the model
+    private int mMLEnableWidth;
     private float mMLModelThreshold;
     private String mPackageName;
     private float mMLResults;
 
+    private static final int MAX_LOGGED_PREDICTIONS = 10;
+    private ArrayDeque<String> mPredictionLog = new ArrayDeque<>();
+
     private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
 
     private final NavigationEdgeBackPlugin.BackCallback mBackCallback =
@@ -292,6 +298,11 @@
         mBottomGestureHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gestureHeight,
                 dm);
 
+        // Set the minimum bounds to activate ML to 12dp or the minimum of configured values
+        mMLEnableWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12.0f, dm);
+        if (mMLEnableWidth > mEdgeWidthRight) mMLEnableWidth = mEdgeWidthRight;
+        if (mMLEnableWidth > mEdgeWidthLeft) mMLEnableWidth = mEdgeWidthLeft;
+
         // Reduce the default touch slop to ensure that we can intercept the gesture
         // before the app starts to react to it.
         // TODO(b/130352502) Tune this value and extract into a constant
@@ -500,8 +511,8 @@
         }
     }
 
-    private float getBackGesturePredictionsCategory(int x, int y) {
-        if (!mVocab.containsKey(mPackageName)) {
+    private int getBackGesturePredictionsCategory(int x, int y, int app) {
+        if (app == -1) {
             return -1;
         }
 
@@ -519,20 +530,19 @@
             new long[]{(long) mDisplaySize.x},
             new long[]{(long) distanceFromEdge},
             new long[]{(long) location},
-            new long[]{(long) mVocab.get(mPackageName)},
+            new long[]{(long) app},
             new long[]{(long) y},
         };
 
         mMLResults = mBackGestureTfClassifierProvider.predict(featuresVector);
-        if (mMLResults == -1) return -1;
+        if (mMLResults == -1) {
+            return -1;
+        }
 
         return mMLResults >= mMLModelThreshold ? 1 : 0;
     }
 
     private boolean isWithinTouchRegion(int x, int y) {
-        boolean withinRange = false;
-        float results = -1;
-
         // Disallow if we are in the bottom gesture area
         if (y >= (mDisplaySize.y - mBottomGestureHeight)) {
             return false;
@@ -546,15 +556,33 @@
             return false;
         }
 
-        if (mUseMLModel &&  (results = getBackGesturePredictionsCategory(x, y)) != -1) {
-            withinRange = results == 1 ? true : false;
-        } else {
-            // Denotes whether we should proceed with the gesture.
-            // Even if it is false, we may want to log it assuming
-            // it is not invalid due to exclusion.
-            withinRange = x <= mEdgeWidthLeft + mLeftInset
-                    || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);
+        int app = -1;
+        if (mVocab != null) {
+            app = mVocab.getOrDefault(mPackageName, -1);
         }
+        // Check if we are within the tightest bounds beyond which
+        // we would not need to run the ML model.
+        boolean withinRange = x <= mMLEnableWidth + mLeftInset
+                || x >= (mDisplaySize.x - mMLEnableWidth - mRightInset);
+        if (!withinRange) {
+            int results = -1;
+            if (mUseMLModel && (results = getBackGesturePredictionsCategory(x, y, app)) != -1) {
+                withinRange = results == 1;
+            } else {
+                // Denotes whether we should proceed with the gesture.
+                // Even if it is false, we may want to log it assuming
+                // it is not invalid due to exclusion.
+                withinRange = x <= mEdgeWidthLeft + mLeftInset
+                        || x >= (mDisplaySize.x - mEdgeWidthRight - mRightInset);
+            }
+        }
+
+        // For debugging purposes
+        if (mPredictionLog.size() >= MAX_LOGGED_PREDICTIONS) {
+            mPredictionLog.removeFirst();
+        }
+        mPredictionLog.addLast(String.format("[%d,%d,%d,%f,%d]",
+                x, y, app, mMLResults, withinRange ? 1 : 0));
 
         // Always allow if the user is in a transient sticky immersive state
         if (mIsNavBarShownTransiently) {
@@ -753,6 +781,8 @@
         pw.println("  mIsAttached=" + mIsAttached);
         pw.println("  mEdgeWidthLeft=" + mEdgeWidthLeft);
         pw.println("  mEdgeWidthRight=" + mEdgeWidthRight);
+        pw.println("  mIsNavBarShownTransiently=" + mIsNavBarShownTransiently);
+        pw.println("  mPredictionLog=" + String.join(";", mPredictionLog));
     }
 
     private boolean isGestureBlockingActivityRunning() {
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index de96aaa..9d71489 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -44,6 +44,9 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+import com.android.internal.logging.UiEventLoggerImpl;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.server.LocalServices;
 import com.android.server.statusbar.StatusBarManagerInternal;
@@ -129,16 +132,41 @@
     private boolean mCameraDoubleTapPowerEnabled;
     private long mLastPowerDown;
     private int mPowerButtonConsecutiveTaps;
+    private final UiEventLogger mUiEventLogger;
 
+    @VisibleForTesting
+    public enum GestureLauncherEvent implements UiEventLogger.UiEventEnum {
+        @UiEvent(doc = "The user lifted the device just the right way to launch the camera.")
+        GESTURE_CAMERA_LIFT(658),
+
+        @UiEvent(doc = "The user wiggled the device just the right way to launch the camera.")
+        GESTURE_CAMERA_WIGGLE(659),
+
+        @UiEvent(doc = "The user double-tapped power quickly enough to launch the camera.")
+        GESTURE_CAMERA_DOUBLE_TAP_POWER(660);
+
+        private final int mId;
+
+        GestureLauncherEvent(int id) {
+            mId = id;
+        }
+
+        @Override
+        public int getId() {
+            return mId;
+        }
+    }
     public GestureLauncherService(Context context) {
-        this(context, new MetricsLogger());
+        this(context, new MetricsLogger(), new UiEventLoggerImpl());
     }
 
     @VisibleForTesting
-    GestureLauncherService(Context context, MetricsLogger metricsLogger) {
+    GestureLauncherService(Context context, MetricsLogger metricsLogger,
+            UiEventLogger uiEventLogger) {
         super(context);
         mContext = context;
         mMetricsLogger = metricsLogger;
+        mUiEventLogger = uiEventLogger;
     }
 
     public void onStart() {
@@ -392,6 +420,7 @@
             if (launched) {
                 mMetricsLogger.action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE,
                         (int) powerTapInterval);
+                mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER);
             }
         }
         mMetricsLogger.histogram("power_consecutive_short_tap_count", mPowerButtonConsecutiveTaps);
@@ -474,6 +503,7 @@
                 if (handleCameraGesture(true /* useWakelock */,
                         StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)) {
                     mMetricsLogger.action(MetricsEvent.ACTION_WIGGLE_CAMERA_GESTURE);
+                    mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_WIGGLE);
                     trackCameraLaunchEvent(event);
                 }
                 return;
@@ -558,6 +588,7 @@
                     if (handleCameraGesture(true /* useWakelock */,
                             StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER)) {
                         MetricsLogger.action(mContext, MetricsEvent.ACTION_CAMERA_LIFT_TRIGGER);
+                        mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_LIFT);
                     }
                 } else {
                     if (DBG_CAMERA_LIFT) Slog.d(TAG, "Ignoring lift event");
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 1b12dc7..4e194e2 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -75,6 +75,7 @@
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
 import android.app.AppGlobals;
@@ -89,6 +90,7 @@
 import android.app.AsyncNotedAppOp;
 import android.app.RuntimeAppOpAccessMessage;
 import android.app.SyncNotedAppOp;
+import android.app.admin.DevicePolicyManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -270,6 +272,8 @@
 
     private final AppOpsManagerInternalImpl mAppOpsManagerInternal
             = new AppOpsManagerInternalImpl();
+    @Nullable private final DevicePolicyManagerInternal dpmi =
+            LocalServices.getService(DevicePolicyManagerInternal.class);
 
     /**
      * Registered callbacks, called from {@link #collectAsyncNotedOp}.
@@ -2675,6 +2679,10 @@
                     Ops pkgOps = ent.getValue();
                     for (int j=pkgOps.size()-1; j>=0; j--) {
                         Op curOp = pkgOps.valueAt(j);
+                        if (shouldDeferResetOpToDpm(curOp.op)) {
+                            deferResetOpToDpm(curOp.op, reqPackageName, reqUserId);
+                            continue;
+                        }
                         if (AppOpsManager.opAllowsReset(curOp.op)
                                 && curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) {
                             int previousMode = curOp.mode;
@@ -2724,16 +2732,27 @@
             }
         }
 
-        if (allChanges != null) {
-            int numChanges = allChanges.size();
-            for (int i = 0; i < numChanges; i++) {
-                ChangeRec change = allChanges.get(i);
-                notifyOpChangedSync(change.op, change.uid, change.pkg,
-                        AppOpsManager.opToDefaultMode(change.op), change.previous_mode);
-            }
+        int numChanges = allChanges.size();
+        for (int i = 0; i < numChanges; i++) {
+            ChangeRec change = allChanges.get(i);
+            notifyOpChangedSync(change.op, change.uid, change.pkg,
+                    AppOpsManager.opToDefaultMode(change.op), change.previous_mode);
         }
     }
 
+    private boolean shouldDeferResetOpToDpm(int op) {
+        // TODO(b/174582385): avoid special-casing app-op resets by migrating app-op permission
+        //  pre-grants to a role-based mechanism or another general-purpose mechanism.
+        return dpmi != null && dpmi.supportsResetOp(op);
+    }
+
+    /** Assumes {@link #shouldDeferResetOpToDpm(int)} is true. */
+    private void deferResetOpToDpm(int op, String packageName, @UserIdInt int userId) {
+        // TODO(b/174582385): avoid special-casing app-op resets by migrating app-op permission
+        //  pre-grants to a role-based mechanism or another general-purpose mechanism.
+        dpmi.resetOp(op, packageName, userId);
+    }
+
     private void evalAllForegroundOpsLocked() {
         for (int uidi = mUidStates.size() - 1; uidi >= 0; uidi--) {
             final UidState uidState = mUidStates.valueAt(uidi);
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index 617f687..3e9e45e 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -14,14 +14,17 @@
  * limitations under the License.
  */
 package com.android.server.pm;
-
+import static android.Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES;
+import static android.Manifest.permission.INTERACT_ACROSS_PROFILES;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.MANAGE_APP_OPS_MODES;
 import static android.app.AppOpsManager.OP_INTERACT_ACROSS_PROFILES;
 import static android.content.Intent.FLAG_RECEIVER_REGISTERED_ONLY;
 import static android.content.pm.CrossProfileApps.ACTION_CAN_INTERACT_ACROSS_PROFILES_CHANGED;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 
-import android.Manifest;
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
@@ -31,7 +34,6 @@
 import android.app.AppOpsManager.Mode;
 import android.app.IApplicationThread;
 import android.app.admin.DevicePolicyEventLogger;
-import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.ComponentName;
 import android.content.Context;
@@ -154,15 +156,15 @@
             if (callerUserId != userId) {
                 final int permissionFlag =  PermissionChecker.checkPermissionForPreflight(
                         mContext,
-                        android.Manifest.permission.INTERACT_ACROSS_PROFILES,
+                        INTERACT_ACROSS_PROFILES,
                         callingPid,
                         callingUid,
                         callingPackage);
                 if (permissionFlag != PermissionChecker.PERMISSION_GRANTED
                         || !isSameProfileGroup(callerUserId, userId)) {
                     throw new SecurityException("Attempt to launch activity without required "
-                            + android.Manifest.permission.INTERACT_ACROSS_PROFILES + " permission"
-                            + " or target user is not in the same profile group.");
+                            + INTERACT_ACROSS_PROFILES
+                            + " permission or target user is not in the same profile group.");
                 }
             }
             launchIntent.setComponent(component);
@@ -217,8 +219,8 @@
         if (callerUserId != userId) {
             if (!hasCallerGotInteractAcrossProfilesPermission(callingPackage)) {
                 throw new SecurityException("Attempt to launch activity without required "
-                        + android.Manifest.permission.INTERACT_ACROSS_PROFILES + " permission"
-                        + " or target user is not in the same profile group.");
+                        + INTERACT_ACROSS_PROFILES
+                        + " permission or target user is not in the same profile group.");
             }
         }
 
@@ -294,13 +296,13 @@
                 callingPackage, mInjector.getCallingUid(), mInjector.getCallingPid());
     }
 
-    private boolean isCrossProfilePackageWhitelisted(String packageName) {
+    private boolean isCrossProfilePackageAllowlisted(String packageName) {
         return mInjector.withCleanCallingIdentity(() ->
                 mInjector.getDevicePolicyManagerInternal()
                         .getAllCrossProfilePackages().contains(packageName));
     }
 
-    private boolean isCrossProfilePackageWhitelistedByDefault(String packageName) {
+    private boolean isCrossProfilePackageAllowlistedByDefault(String packageName) {
         return mInjector.withCleanCallingIdentity(() ->
                 mInjector.getDevicePolicyManagerInternal()
                         .getDefaultCrossProfilePackages().contains(packageName));
@@ -388,32 +390,36 @@
     /**
      * See {@link android.content.pm.CrossProfileApps#setInteractAcrossProfilesAppOp(String, int)}.
      *
-     * <p>Logs metrics. Use {@link #setInteractAcrossProfilesAppOpUnchecked(String, int, boolean)}
-     * to avoid permission checks or to specify not to log metrics.
+     * <p>Use {@link #setInteractAcrossProfilesAppOpUnchecked(String, int, int)} to avoid permission
+     * checks.
      */
     @Override
     public void setInteractAcrossProfilesAppOp(String packageName, @Mode int newMode) {
+        setInteractAcrossProfilesAppOp(packageName, newMode, mInjector.getCallingUserId());
+    }
+
+    private void setInteractAcrossProfilesAppOp(
+            String packageName, @Mode int newMode, @UserIdInt int userId) {
         final int callingUid = mInjector.getCallingUid();
-        if (!isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingUid)
-                && !isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, callingUid)) {
+        if (!isPermissionGranted(INTERACT_ACROSS_USERS_FULL, callingUid)
+                && !isPermissionGranted(INTERACT_ACROSS_USERS, callingUid)) {
             throw new SecurityException(
                     "INTERACT_ACROSS_USERS or INTERACT_ACROSS_USERS_FULL is required to set the"
                             + " app-op for interacting across profiles.");
         }
-        if (!isPermissionGranted(Manifest.permission.MANAGE_APP_OPS_MODES, callingUid)
-                && !isPermissionGranted(
-                        Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES, callingUid)) {
+        if (!isPermissionGranted(MANAGE_APP_OPS_MODES, callingUid)
+                && !isPermissionGranted(CONFIGURE_INTERACT_ACROSS_PROFILES, callingUid)) {
             throw new SecurityException(
                     "MANAGE_APP_OPS_MODES or CONFIGURE_INTERACT_ACROSS_PROFILES is required to set"
                             + " the app-op for interacting across profiles.");
         }
-        setInteractAcrossProfilesAppOpUnchecked(packageName, newMode, /* logMetrics= */ true);
+        setInteractAcrossProfilesAppOpUnchecked(packageName, newMode, userId);
     }
 
     private void setInteractAcrossProfilesAppOpUnchecked(
-            String packageName, @Mode int newMode, boolean logMetrics) {
+            String packageName, @Mode int newMode, @UserIdInt int userId) {
         if (newMode == AppOpsManager.MODE_ALLOWED
-                && !canConfigureInteractAcrossProfiles(packageName)) {
+                && !canConfigureInteractAcrossProfiles(packageName, userId)) {
             // The user should not be prompted for apps that cannot request to interact across
             // profiles. However, we return early here if required to avoid race conditions.
             Slog.e(TAG, "Tried to turn on the appop for interacting across profiles for invalid"
@@ -421,56 +427,57 @@
             return;
         }
         final int[] profileIds =
-                mInjector.getUserManager()
-                        .getProfileIds(mInjector.getCallingUserId(), /* enabledOnly= */ false);
+                mInjector.getUserManager().getProfileIds(userId, /* enabledOnly= */ false);
         for (int profileId : profileIds) {
             if (!isPackageInstalled(packageName, profileId)) {
                 continue;
             }
-            setInteractAcrossProfilesAppOpForUser(packageName, newMode, profileId, logMetrics);
+            // Only log once per profile group by checking against the user ID.
+            setInteractAcrossProfilesAppOpForProfile(
+                    packageName, newMode, profileId, /* logMetrics= */ profileId == userId);
         }
     }
 
+    /**
+     * Returns whether the given package name is installed in the given user ID. The calling UID is
+     * used as the filter calling UID, as described at {@link PackageManagerInternal#getPackageInfo(
+     * String, int, int, int)}.
+     */
     private boolean isPackageInstalled(String packageName, @UserIdInt int userId) {
-        final int callingUid = mInjector.getCallingUid();
         return mInjector.withCleanCallingIdentity(() -> {
+            final int flags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
             final PackageInfo info =
                     mInjector.getPackageManagerInternal()
-                            .getPackageInfo(
-                                    packageName,
-                                    MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
-                                    callingUid,
-                                    userId);
+                            .getPackageInfo(packageName, flags, mInjector.getCallingUid(), userId);
             return info != null;
         });
     }
 
-    private void setInteractAcrossProfilesAppOpForUser(
-            String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics) {
+    private void setInteractAcrossProfilesAppOpForProfile(
+            String packageName, @Mode int newMode, @UserIdInt int profileId, boolean logMetrics) {
         try {
-            setInteractAcrossProfilesAppOpForUserOrThrow(packageName, newMode, userId, logMetrics);
+            setInteractAcrossProfilesAppOpForProfileOrThrow(
+                    packageName, newMode, profileId, logMetrics);
         } catch (PackageManager.NameNotFoundException e) {
-            Slog.e(TAG, "Missing package " + packageName + " on user ID " + userId, e);
+            Slog.e(TAG, "Missing package " + packageName + " on profile user ID " + profileId, e);
         }
     }
 
-    private void setInteractAcrossProfilesAppOpForUserOrThrow(
-            String packageName, @Mode int newMode, @UserIdInt int userId, boolean logMetrics)
+    private void setInteractAcrossProfilesAppOpForProfileOrThrow(
+            String packageName, @Mode int newMode, @UserIdInt int profileId, boolean logMetrics)
             throws PackageManager.NameNotFoundException {
         final int uid = mInjector.getPackageManager()
-                .getPackageUidAsUser(packageName, /* flags= */ 0, userId);
+                .getPackageUidAsUser(packageName, /* flags= */ 0, profileId);
         if (currentModeEquals(newMode, packageName, uid)) {
             Slog.i(TAG, "Attempt to set mode to existing value of " + newMode + " for "
-                    + packageName + " on user ID " + userId);
+                    + packageName + " on profile user ID " + profileId);
             return;
         }
 
         final boolean hadPermission = hasInteractAcrossProfilesPermission(
                 packageName, uid, PermissionChecker.PID_UNKNOWN);
 
-        final int callingUid = mInjector.getCallingUid();
-        if (isPermissionGranted(
-                Manifest.permission.CONFIGURE_INTERACT_ACROSS_PROFILES, callingUid)) {
+        if (isPermissionGranted(CONFIGURE_INTERACT_ACROSS_PROFILES, mInjector.getCallingUid())) {
             // Clear calling identity since the CONFIGURE_INTERACT_ACROSS_PROFILES permission allows
             // this particular app-op to be modified without the broader app-op permissions.
             mInjector.withCleanCallingIdentity(() ->
@@ -483,16 +490,15 @@
         // Kill the UID before sending the broadcast to ensure that apps can be informed when
         // their app-op has been revoked.
         maybeKillUid(packageName, uid, hadPermission);
-        sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(userId));
-        maybeLogSetInteractAcrossProfilesAppOp(packageName, newMode, userId, logMetrics, uid);
+        sendCanInteractAcrossProfilesChangedBroadcast(packageName, uid, UserHandle.of(profileId));
+        maybeLogSetInteractAcrossProfilesAppOp(packageName, newMode, logMetrics, uid);
     }
 
     /**
      * 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) {
+    private void maybeKillUid(String packageName, int uid, boolean hadPermission) {
         if (!hadPermission) {
             return;
         }
@@ -503,18 +509,10 @@
     }
 
     private void maybeLogSetInteractAcrossProfilesAppOp(
-            String packageName,
-            @Mode int newMode,
-            @UserIdInt int userId,
-            boolean logMetrics,
-            int uid) {
+            String packageName, @Mode int newMode, boolean logMetrics, int uid) {
         if (!logMetrics) {
             return;
         }
-        if (userId != mInjector.getCallingUserId()) {
-            // Only log once per profile group by checking for the calling user ID.
-            return;
-        }
         DevicePolicyEventLogger
                 .createEvent(DevicePolicyEnums.SET_INTERACT_ACROSS_PROFILES_APP_OP)
                 .setStrings(packageName)
@@ -529,8 +527,7 @@
      * any necessary permission checks.
      */
     private boolean currentModeEquals(@Mode int otherMode, String packageName, int uid) {
-        final String op =
-                AppOpsManager.permissionToOp(Manifest.permission.INTERACT_ACROSS_PROFILES);
+        final String op = AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES);
         return mInjector.withCleanCallingIdentity(() -> otherMode
                 == mInjector.getAppOpsManager().unsafeCheckOpNoThrow(op, uid, packageName));
     }
@@ -562,37 +559,49 @@
 
     @Override
     public boolean canConfigureInteractAcrossProfiles(String packageName) {
-        if (!canUserAttemptToConfigureInteractAcrossProfiles(packageName)) {
+        return canConfigureInteractAcrossProfiles(packageName, mInjector.getCallingUserId());
+    }
+
+    private boolean canConfigureInteractAcrossProfiles(String packageName, @UserIdInt int userId) {
+        if (!canUserAttemptToConfigureInteractAcrossProfiles(packageName, userId)) {
             return false;
         }
-        if (!hasOtherProfileWithPackageInstalled(packageName, mInjector.getCallingUserId())) {
+        if (!hasOtherProfileWithPackageInstalled(packageName, userId)) {
             return false;
         }
         if (!hasRequestedAppOpPermission(
                 AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName)) {
             return false;
         }
-        return isCrossProfilePackageWhitelisted(packageName);
+        return isCrossProfilePackageAllowlisted(packageName);
     }
 
     @Override
     public boolean canUserAttemptToConfigureInteractAcrossProfiles(String packageName) {
-        final int[] profileIds = mInjector.getUserManager().getProfileIds(
-                mInjector.getCallingUserId(), /* enabledOnly= */ false);
+        return canUserAttemptToConfigureInteractAcrossProfiles(
+                packageName, mInjector.getCallingUserId());
+    }
+
+    private boolean canUserAttemptToConfigureInteractAcrossProfiles(
+            String packageName, @UserIdInt int userId) {
+        final int[] profileIds =
+                mInjector.getUserManager().getProfileIds(userId, /* enabledOnly= */ false);
         if (profileIds.length < 2) {
             return false;
         }
         if (isProfileOwner(packageName, profileIds)) {
             return false;
         }
-        return hasRequestedAppOpPermission(
-                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName)
-                && !isPlatformSignedAppWithNonUserConfigurablePermission(packageName, profileIds);
+        if (!hasRequestedAppOpPermission(
+                AppOpsManager.opToPermission(OP_INTERACT_ACROSS_PROFILES), packageName)) {
+            return false;
+        }
+        return !isPlatformSignedAppWithNonUserConfigurablePermission(packageName, profileIds);
     }
 
     private boolean isPlatformSignedAppWithNonUserConfigurablePermission(
             String packageName, int[] profileIds) {
-        return !isCrossProfilePackageWhitelistedByDefault(packageName)
+        return !isCrossProfilePackageAllowlistedByDefault(packageName)
                 && isPlatformSignedAppWithAutomaticProfilesPermission(packageName, profileIds);
     }
 
@@ -610,7 +619,7 @@
             if (uid == -1) {
                 continue;
             }
-            if (isPermissionGranted(Manifest.permission.INTERACT_ACROSS_PROFILES, uid)) {
+            if (isPermissionGranted(INTERACT_ACROSS_PROFILES, uid)) {
                 return true;
             }
         }
@@ -642,7 +651,7 @@
             return;
         }
         final String op =
-                AppOpsManager.permissionToOp(Manifest.permission.INTERACT_ACROSS_PROFILES);
+                AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES);
         setInteractAcrossProfilesAppOp(packageName, AppOpsManager.opToDefaultMode(op));
     }
 
@@ -650,7 +659,7 @@
     public void clearInteractAcrossProfilesAppOps() {
         final int defaultMode =
                 AppOpsManager.opToDefaultMode(
-                        AppOpsManager.permissionToOp(Manifest.permission.INTERACT_ACROSS_PROFILES));
+                        AppOpsManager.permissionToOp(INTERACT_ACROSS_PROFILES));
         findAllPackageNames()
                 .forEach(packageName -> setInteractAcrossProfilesAppOp(packageName, defaultMode));
     }
@@ -695,17 +704,13 @@
     }
 
     private boolean hasInteractAcrossProfilesPermission(String packageName, int uid, int pid) {
-        if (isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid)
-                || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, uid)) {
+        if (isPermissionGranted(INTERACT_ACROSS_USERS_FULL, uid)
+                || isPermissionGranted(INTERACT_ACROSS_USERS, uid)) {
             return true;
         }
         return PermissionChecker.PERMISSION_GRANTED
                 == PermissionChecker.checkPermissionForPreflight(
-                        mContext,
-                        Manifest.permission.INTERACT_ACROSS_PROFILES,
-                        pid,
-                        uid,
-                        packageName);
+                        mContext, INTERACT_ACROSS_PROFILES, pid, uid, packageName);
     }
 
     private boolean isProfileOwner(String packageName, int[] userIds) {
@@ -898,5 +903,12 @@
         public List<UserHandle> getTargetUserProfiles(String packageName, int userId) {
             return getTargetUserProfilesUnchecked(packageName, userId);
         }
+
+        @Override
+        public void setInteractAcrossProfilesAppOp(
+                String packageName, int newMode, @UserIdInt int userId) {
+            CrossProfileAppsServiceImpl.this.setInteractAcrossProfilesAppOpUnchecked(
+                    packageName, newMode, userId);
+        }
     }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ce3cdea..b8a20ed 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -125,6 +125,7 @@
 import android.app.AlarmManager;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
+import android.app.AppOpsManager.Mode;
 import android.app.BroadcastOptions;
 import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
@@ -12816,6 +12817,28 @@
         public ComponentName getProfileOwnerAsUser(int userHandle) {
             return DevicePolicyManagerService.this.getProfileOwnerAsUser(userHandle);
         }
+
+        @Override
+        public boolean supportsResetOp(int op) {
+            return op == AppOpsManager.OP_INTERACT_ACROSS_PROFILES
+                    && LocalServices.getService(CrossProfileAppsInternal.class) != null;
+        }
+
+        @Override
+        public void resetOp(int op, String packageName, @UserIdInt int userId) {
+            if (op != AppOpsManager.OP_INTERACT_ACROSS_PROFILES) {
+                throw new IllegalArgumentException("Unsupported op for DPM reset: " + op);
+            }
+            LocalServices.getService(CrossProfileAppsInternal.class)
+                    .setInteractAcrossProfilesAppOp(
+                            packageName, findInteractAcrossProfilesResetMode(packageName), userId);
+        }
+
+        private @Mode int findInteractAcrossProfilesResetMode(String packageName) {
+            return getDefaultCrossProfilePackages().contains(packageName)
+                    ? AppOpsManager.MODE_ALLOWED
+                    : AppOpsManager.opToDefaultMode(AppOpsManager.OP_INTERACT_ACROSS_PROFILES);
+        }
     }
 
     private Intent createShowAdminSupportIntent(ComponentName admin, int userId) {
diff --git a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
index 4b25890..adf892a 100644
--- a/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
+++ b/services/robotests/src/com/android/server/pm/CrossProfileAppsServiceImplRoboTest.java
@@ -37,7 +37,6 @@
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.app.AppOpsManager.Mode;
-import android.app.admin.DevicePolicyManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.content.ComponentName;
 import android.content.ContextWrapper;
@@ -94,12 +93,15 @@
     private static final int CALLING_PID = 1000;
     private static final String CROSS_PROFILE_APP_PACKAGE_NAME =
             "com.android.server.pm.crossprofileappsserviceimplrobotest.crossprofileapp";
-    private static final int PERSONAL_PROFILE_USER_ID = 0;
+    @UserIdInt private static final int PERSONAL_PROFILE_USER_ID = 0;
     private static final int PERSONAL_PROFILE_UID = 2222;
-    private static final int WORK_PROFILE_USER_ID = 10;
+    @UserIdInt private static final int WORK_PROFILE_USER_ID = 10;
     private static final int WORK_PROFILE_UID = 3333;
     private static final int OTHER_PROFILE_WITHOUT_CROSS_PROFILE_APP_USER_ID = 20;
-    private static final int OUTSIDE_PROFILE_GROUP_USER_ID = 30;
+    @UserIdInt private static final int OTHER_PROFILE_GROUP_USER_ID = 30;
+    private static final int OTHER_PROFILE_GROUP_UID = 4444;
+    @UserIdInt private static final int OTHER_PROFILE_GROUP_2_USER_ID = 31;
+    private static final int OTHER_PROFILE_GROUP_2_UID = 5555;
 
     private final ContextWrapper mContext = ApplicationProvider.getApplicationContext();
     private final UserManager mUserManager = mContext.getSystemService(UserManager.class);
@@ -138,6 +140,10 @@
         mockCrossProfileAppInstalledOnProfile(
                 packageInfo, PERSONAL_PROFILE_USER_ID, PERSONAL_PROFILE_UID);
         mockCrossProfileAppInstalledOnProfile(packageInfo, WORK_PROFILE_USER_ID, WORK_PROFILE_UID);
+        mockCrossProfileAppInstalledOnProfile(
+                packageInfo, OTHER_PROFILE_GROUP_USER_ID, OTHER_PROFILE_GROUP_UID);
+        mockCrossProfileAppInstalledOnProfile(
+                packageInfo, OTHER_PROFILE_GROUP_2_USER_ID, OTHER_PROFILE_GROUP_2_UID);
     }
 
     private void mockCrossProfileAppInstalledOnProfile(
@@ -200,16 +206,22 @@
 
     @Before
     public void setUpCrossProfileAppUidsAndPackageNames() {
+        setUpCrossProfileAppUidAndPackageName(
+                PERSONAL_PROFILE_UID, PERSONAL_PROFILE_USER_ID);
+        setUpCrossProfileAppUidAndPackageName(
+                WORK_PROFILE_UID, WORK_PROFILE_USER_ID);
+        setUpCrossProfileAppUidAndPackageName(
+                OTHER_PROFILE_GROUP_UID, OTHER_PROFILE_GROUP_USER_ID);
+        setUpCrossProfileAppUidAndPackageName(
+                OTHER_PROFILE_GROUP_2_UID, OTHER_PROFILE_GROUP_2_USER_ID);
+    }
+
+    private void setUpCrossProfileAppUidAndPackageName(int uid, @UserIdInt int userId) {
         ShadowApplicationPackageManager.setPackageUidAsUser(
-                CROSS_PROFILE_APP_PACKAGE_NAME, PERSONAL_PROFILE_UID, PERSONAL_PROFILE_USER_ID);
-        ShadowApplicationPackageManager.setPackageUidAsUser(
-                CROSS_PROFILE_APP_PACKAGE_NAME, WORK_PROFILE_UID, WORK_PROFILE_USER_ID);
-        when(mPackageManagerInternal.getPackageUidInternal(
-                CROSS_PROFILE_APP_PACKAGE_NAME, /* flags= */ 0, PERSONAL_PROFILE_USER_ID))
-                .thenReturn(PERSONAL_PROFILE_UID);
-        when(mPackageManagerInternal.getPackageUidInternal(
-                CROSS_PROFILE_APP_PACKAGE_NAME, /* flags= */ 0, WORK_PROFILE_USER_ID))
-                .thenReturn(WORK_PROFILE_UID);
+                CROSS_PROFILE_APP_PACKAGE_NAME, uid, userId);
+        when(mPackageManagerInternal
+                .getPackageUid(CROSS_PROFILE_APP_PACKAGE_NAME, /* flags= */ 0, userId))
+                .thenReturn(uid);
     }
 
     @Before
@@ -229,7 +241,9 @@
                 PERSONAL_PROFILE_USER_ID,
                 WORK_PROFILE_USER_ID,
                 OTHER_PROFILE_WITHOUT_CROSS_PROFILE_APP_USER_ID);
-        shadowUserManager.addProfileIds(OUTSIDE_PROFILE_GROUP_USER_ID);
+        shadowUserManager.addProfileIds(
+                OTHER_PROFILE_GROUP_USER_ID,
+                OTHER_PROFILE_GROUP_2_USER_ID);
     }
 
     @Before
@@ -239,6 +253,8 @@
         final int defaultMode = AppOpsManager.opToDefaultMode(OP_INTERACT_ACROSS_PROFILES);
         explicitlySetInteractAcrossProfilesAppOp(PERSONAL_PROFILE_UID, defaultMode);
         explicitlySetInteractAcrossProfilesAppOp(WORK_PROFILE_UID, defaultMode);
+        explicitlySetInteractAcrossProfilesAppOp(OTHER_PROFILE_GROUP_UID, defaultMode);
+        explicitlySetInteractAcrossProfilesAppOp(OTHER_PROFILE_GROUP_2_UID, defaultMode);
     }
 
     @Test
@@ -422,6 +438,27 @@
     }
 
     @Test
+    public void setInteractAcrossProfilesAppOp_userToSetInDifferentProfileGroupToCaller_setsAppOp() {
+        mCrossProfileAppsServiceImpl.getLocalService().setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED, OTHER_PROFILE_GROUP_USER_ID);
+        assertThat(getCrossProfileAppOp(OTHER_PROFILE_GROUP_UID)).isEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_userToSetInDifferentProfileGroupToCaller_setsAppOpOnOtherProfile() {
+        mCrossProfileAppsServiceImpl.getLocalService().setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED, OTHER_PROFILE_GROUP_USER_ID);
+        assertThat(getCrossProfileAppOp(OTHER_PROFILE_GROUP_2_UID)).isEqualTo(MODE_ALLOWED);
+    }
+
+    @Test
+    public void setInteractAcrossProfilesAppOp_userToSetInDifferentProfileGroupToCaller_doesNotSetCallerAppOp() {
+        mCrossProfileAppsServiceImpl.getLocalService().setInteractAcrossProfilesAppOp(
+                CROSS_PROFILE_APP_PACKAGE_NAME, MODE_ALLOWED, OTHER_PROFILE_GROUP_USER_ID);
+        assertThat(getCrossProfileAppOp()).isEqualTo(MODE_DEFAULT);
+    }
+
+    @Test
     public void canConfigureInteractAcrossProfiles_packageNotInstalledInProfile_returnsFalse() {
         mockUninstallCrossProfileAppFromWorkProfile();
         assertThat(mCrossProfileAppsServiceImpl
@@ -530,7 +567,7 @@
 
     @Test
     public void canUserAttemptToConfigureInteractAcrossProfiles_profileOwnerOutsideProfileGroup_returnsTrue() {
-        when(mDevicePolicyManagerInternal.getProfileOwnerAsUser(OUTSIDE_PROFILE_GROUP_USER_ID))
+        when(mDevicePolicyManagerInternal.getProfileOwnerAsUser(OTHER_PROFILE_GROUP_USER_ID))
                 .thenReturn(buildCrossProfileComponentName());
         assertThat(mCrossProfileAppsServiceImpl
                 .canUserAttemptToConfigureInteractAcrossProfiles(CROSS_PROFILE_APP_PACKAGE_NAME))
@@ -601,8 +638,14 @@
     private void mockCrossProfileAndroidPackage(AndroidPackage androidPackage) {
         when(mPackageManagerInternal.getPackage(CROSS_PROFILE_APP_PACKAGE_NAME))
                 .thenReturn(androidPackage);
-        when(mPackageManagerInternal.getPackage(PERSONAL_PROFILE_UID)).thenReturn(androidPackage);
-        when(mPackageManagerInternal.getPackage(WORK_PROFILE_UID)).thenReturn(androidPackage);
+        when(mPackageManagerInternal.getPackage(PERSONAL_PROFILE_UID))
+                .thenReturn(androidPackage);
+        when(mPackageManagerInternal.getPackage(WORK_PROFILE_UID))
+                .thenReturn(androidPackage);
+        when(mPackageManagerInternal.getPackage(OTHER_PROFILE_GROUP_UID))
+                .thenReturn(androidPackage);
+        when(mPackageManagerInternal.getPackage(OTHER_PROFILE_GROUP_2_UID))
+                .thenReturn(androidPackage);
     }
 
     private void mockCrossProfileAppNotWhitelisted() {
diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
index 4fbc587..0cdc2c9 100644
--- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
@@ -19,6 +19,7 @@
 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.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.never;
@@ -34,6 +35,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 import android.test.mock.MockContentResolver;
+import android.testing.TestableLooper;
 import android.util.MutableBoolean;
 import android.view.KeyEvent;
 
@@ -42,6 +44,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.LocalServices;
@@ -64,6 +67,7 @@
 @Presubmit
 @SmallTest
 @RunWith(AndroidJUnit4.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class GestureLauncherServiceTest {
 
     private static final int FAKE_USER_ID = 1337;
@@ -81,6 +85,7 @@
     private @Mock Resources mResources;
     private @Mock StatusBarManagerInternal mStatusBarManagerInternal;
     private @Mock MetricsLogger mMetricsLogger;
+    @Mock private UiEventLogger mUiEventLogger;
     private MockContentResolver mContentResolver;
     private GestureLauncherService mGestureLauncherService;
 
@@ -105,7 +110,8 @@
         mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
         when(mContext.getContentResolver()).thenReturn(mContentResolver);
 
-        mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger);
+        mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger,
+                mUiEventLogger);
     }
 
     @Test
@@ -217,6 +223,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -261,6 +268,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -307,6 +315,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -355,6 +364,8 @@
                 StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
         verify(mMetricsLogger)
             .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval);
+        verify(mUiEventLogger, times(1))
+                .log(GestureLauncherService.GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER);
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -401,6 +412,7 @@
 
         verify(mMetricsLogger, never())
                 .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(1)).histogram(
@@ -445,6 +457,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -491,6 +504,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -537,6 +551,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -581,6 +596,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -624,6 +640,7 @@
         assertFalse(outLaunched.value);
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -669,6 +686,7 @@
         assertFalse(outLaunched.value);
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -716,6 +734,8 @@
                 StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
         verify(mMetricsLogger)
             .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval);
+        verify(mUiEventLogger, times(1))
+                .log(GestureLauncherService.GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER);
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -762,6 +782,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -806,6 +827,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
@@ -852,6 +874,7 @@
 
         verify(mMetricsLogger, never())
             .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+        verify(mUiEventLogger, never()).log(any());
 
         final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
         verify(mMetricsLogger, times(2)).histogram(
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 9621f68..0abab08 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -395,8 +395,9 @@
                         + interactorInfo + ")");
             }
 
-            // Initializing settings, look for an interactor first (but only on non-svelte).
-            if (curInteractorInfo == null && mEnableService) {
+            // Initializing settings. Look for an interactor first, but only on non-svelte and only
+            // if the user hasn't explicitly unset it.
+            if (curInteractorInfo == null && mEnableService && !"".equals(curInteractorStr)) {
                 curInteractorInfo = findAvailInteractor(userHandle, null);
             }
 
@@ -1692,8 +1693,13 @@
                 if (isPackageAppearing(pkgName) != PACKAGE_UNCHANGED) {
                     return;
                 }
+                final String curInteractorStr = Settings.Secure.getStringForUser(
+                        mContext.getContentResolver(),
+                        Settings.Secure.VOICE_INTERACTION_SERVICE, mCurUser);
                 final ComponentName curInteractor = getCurInteractor(mCurUser);
-                if (curInteractor == null) {
+                // If there's no interactor and the user hasn't explicitly unset it, check if the
+                // modified package offers one.
+                if (curInteractor == null && !"".equals(curInteractorStr)) {
                     final VoiceInteractionServiceInfo availInteractorInfo
                             = findAvailInteractor(mCurUser, pkgName);
                     if (availInteractorInfo != null) {