Change usages of getQuantityString to icu MessageFormatter.

This cleans up all usages under frameworks/base/packages/SystemUI
Bug: 199230205
Fixes: 199230205
Test: atest passes for all the affected packages

Change-Id: I0c8dfbbd53901c3b34669a02447d2461869a90ea
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 64aa8ee..560cfe6 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -164,21 +164,21 @@
          Displayed in a dialog box.  -->
     <string name="kg_password_wrong_pin_code_pukked">Incorrect SIM PIN code you must now contact your carrier to unlock your device.</string>
     <!-- Instructions telling the user that they entered the wrong SIM PIN while trying
-         to unlock the keyguard.  Displayed in a dialog box.  -->
-    <plurals name="kg_password_wrong_pin_code">
-        <item quantity="one">Incorrect SIM PIN code, you have <xliff:g id="number">%d</xliff:g> remaining attempt before you must contact your carrier to unlock your device.</item>
-        <item quantity="other">Incorrect SIM PIN code, you have <xliff:g id="number">%d</xliff:g> remaining attempts.</item>
-    </plurals>
+         to unlock the keyguard.  Displayed in a dialog box.  [CHAR LIMIT=NONE] -->
+    <string name="kg_password_wrong_pin_code"> {count, plural,
+        =1 {Incorrect SIM PIN code, you have # remaining attempt before you must contact your carrier to unlock your device.}
+        other {Incorrect SIM PIN code, you have # remaining attempts. }
+    }</string>
 
     <!-- Instructions telling the user that they have exhausted SIM PUK retries and the SIM is now unusable.
          Displayed in a dialog box.  -->
     <string name="kg_password_wrong_puk_code_dead">SIM is unusable. Contact your carrier.</string>
     <!-- Instructions telling the user that they entered the wrong puk while trying
-         to unlock the keyguard.  Displayed in a dialog box.  -->
-    <plurals name="kg_password_wrong_puk_code">
-        <item quantity="one">Incorrect SIM PUK code, you have <xliff:g id="number">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item>
-        <item quantity="other">Incorrect SIM PUK code, you have <xliff:g id="number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item>
-    </plurals>
+         to unlock the keyguard.  Displayed in a dialog box.  [CHAR LIMIT=NONE] -->
+    <string name="kg_password_wrong_puk_code">{count, plural,
+        =1 {Incorrect SIM PUK code, you have # remaining attempt before SIM becomes permanently unusable.}
+        other {Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.}
+    }</string>
     <!-- Instructions telling the user that the operation to unlock the keyguard
          with SIM PIN failed. Displayed in one line in a large font.  -->
     <string name="kg_password_pin_failed">SIM PIN operation failed!</string>
@@ -223,21 +223,17 @@
      <!-- Error message indicating that the camera privacy sensor has been turned on [CHAR LIMIT=NONE] -->
     <string name="kg_face_sensor_privacy_enabled">To use Face Unlock, turn on <b>Camera access</b> in Settings > Privacy</string>
 
-    <!-- Instructions telling the user remaining times when enter SIM PIN view.  -->
-    <plurals name="kg_password_default_pin_message">
-        <item quantity="one">Enter SIM PIN. You have <xliff:g id="number">%d</xliff:g> remaining
-attempt before you must contact your carrier to unlock your device.</item>
-        <item quantity="other">Enter SIM PIN. You have <xliff:g id="number">%d</xliff:g> remaining
-attempts.</item>
-    </plurals>
+    <!-- Instructions telling the user remaining times when enter SIM PIN view.  [CHAR LIMIT=NONE] -->
+    <string name="kg_password_default_pin_message">{count, plural,
+        =1 {Enter SIM PIN. You have # remaining attempt before you must contact your carrier to unlock your device.}
+        other {Enter SIM PIN. You have # remaining attempts.}
+    }</string>
 
-    <!-- Instructions telling the user remaining times when enter SIM PUK view.  -->
-    <plurals name="kg_password_default_puk_message">
-        <item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="
-number">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact carrier for details.</item>
-        <item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id="
-number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item>
-    </plurals>
+    <!-- Instructions telling the user remaining times when enter SIM PUK view. [CHAR LIMIT=NONE] -->
+    <string name="kg_password_default_puk_message">{count, plural,
+        =1 {SIM is now disabled. Enter PUK code to continue. You have # remaining attempt before SIM becomes permanently unusable. Contact carrier for details.}
+        other {SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact carrier for details.}
+    }</string>
 
     <!-- Name of the "Default" clock face, which is the clock face that will be shown by default. [CHAR LIMIT=15]-->
     <string name="clock_title_default">Default</string>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 6f33986..f5381ff 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -505,10 +505,10 @@
     <string name="notification_group_overflow_indicator">+ <xliff:g id="number" example="3">%s</xliff:g></string>
 
     <!-- Content description describing how many more notifications are in a group [CHAR LIMIT=NONE] -->
-    <plurals name="notification_group_overflow_description">
-        <item quantity="one"><xliff:g id="number" example="1">%s</xliff:g> more notification inside.</item>
-        <item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> more notifications inside.</item>
-    </plurals>
+    <string name="notification_group_overflow_description">{count, plural,
+        =1 {# more notification inside.}
+        other {# more notifications inside.}
+    }</string>
 
     <!-- Format to use to summarize a message from a contact in a single line of text. For example: "Julia: How's it going?". [CHAR LIMIT=NONE] -->
 
@@ -654,10 +654,10 @@
          the user why they can't toggle the hotspot tile. [CHAR LIMIT=20] -->
     <string name="quick_settings_hotspot_secondary_label_data_saver_enabled">Data Saver is on</string>
     <!-- QuickSettings: Hotspot: Secondary label for how many devices are connected to the hotspot [CHAR LIMIT=NONE] -->
-    <plurals name="quick_settings_hotspot_secondary_label_num_devices">
-        <item quantity="one">%d device</item>
-        <item quantity="other">%d devices</item>
-    </plurals>
+    <string name="quick_settings_hotspot_secondary_label_num_devices">{count, plural,
+        =1 {# device}
+        other {# devices}
+    }</string>
     <!-- QuickSettings: Notifications [CHAR LIMIT=NONE] -->
     <!-- QuickSettings: Flashlight [CHAR LIMIT=NONE] -->
     <string name="quick_settings_flashlight_label">Flashlight</string>
@@ -928,10 +928,10 @@
     <string name="user_limit_reached_title">User limit reached</string>
 
     <!-- Message that tells people what's the maximum number of uses allowed on the device. [CHAR_LIMIT=NONE]-->
-    <plurals name="user_limit_reached_message">
-        <item quantity="one">Only one user can be created.</item>
-        <item quantity="other">You can add up to <xliff:g id="count" example="3">%d</xliff:g> users.</item>
-    </plurals>
+    <string name="user_limit_reached_message">{count, plural,
+        =1 {Only one user can be created.}
+        other {You can add up to # users.}
+    }</string>
 
     <!-- Title of the confirmation dialog for deleting a user [CHAR LIMIT=NONE] -->
     <string name="user_remove_user_title">Remove user?</string>
@@ -1486,20 +1486,20 @@
     <!-- Notification: Snooze panel: message indicating how long the notification was snoozed for. [CHAR LIMIT=100]-->
     <string name="snoozed_for_time">Snoozed for <xliff:g id="time_amount" example="15 minutes">%1$s</xliff:g></string>
 
-    <!-- Notification:Snooze panel: Snooze options for hours -->
-    <plurals name="snoozeHourOptions">
-        <item quantity="one">%d hour</item>
-        <item quantity="two">%d hours</item>
-        <item quantity="few">%d hours</item>
-        <item quantity="other">%d hours</item>
-    </plurals>
+    <!-- Notification:Snooze panel: Snooze options for hours [CHAR LIMIT=NONE]-->
+    <string name="snoozeHourOptions">{count, plural,
+        =1 {# hour}
+        =2 {# hours}
+        few {# hours}
+        other {# hours}
+    }</string>
 
-   <!--  Notification: Snooze panel: Snooze options for minutes -->
-   <plurals name="snoozeMinuteOptions">
-        <item quantity="one">%d minute</item>
-        <item quantity="few">%d minutes</item>
-        <item quantity="other">%d minutes</item>
-    </plurals>
+   <!--  Notification: Snooze panel: Snooze options for minutes [CHAR LIMIT=NONE]-->
+   <string name="snoozeMinuteOptions">{count, plural,
+        =1 {# minute}
+        few {# minutes}
+        other {# minutes}
+    }</string>
 
     <!-- Summary of battery saver not available [CHAR LIMIT=NONE] -->
 
@@ -2136,10 +2136,10 @@
     <!-- Controls management providers screen title [CHAR LIMIT=60]-->
     <string name="controls_providers_title">Choose app to add controls</string>
     <!-- Number of favorites for controls management screen [CHAR LIMIT=NONE]-->
-    <plurals name="controls_number_of_favorites">
-        <item quantity="one"><xliff:g id="number" example="1">%s</xliff:g> control added.</item>
-        <item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> controls added.</item>
-    </plurals>
+    <string name="controls_number_of_favorites">{count, plural,
+        =1 {# control added.}
+        other {# controls added.}
+    }</string>
 
     <!-- Removed control in management screen [CHAR LIMIT=20] -->
     <string name="controls_removed">Removed</string>
@@ -2495,10 +2495,10 @@
     <string name="qs_user_switch_dialog_title">Select user</string>
 
     <!-- Label for the entry point to open the dialog which shows currently running applications [CHAR LIMIT=NONE]-->
-    <plurals name="fgs_manager_footer_label">
-        <item quantity="one"><xliff:g id="count" example="1">%s</xliff:g> app is active</item>
-        <item quantity="other"><xliff:g id="count" example="2">%s</xliff:g> apps are active</item>
-    </plurals>
+    <string name="fgs_manager_footer_label">{count, plural,
+        =1 {# app is active}
+        other {# apps are active}
+    }</string>
     <!-- Content description for a dot indicator in the running application indicating that there
     is new information [CHAR LIMIT=NONE] -->
     <string name="fgs_dot_content_description">New information</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
index 47df70b..2f6fa14 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java
@@ -16,6 +16,8 @@
 
 package com.android.keyguard;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.annotation.NonNull;
 import android.app.AlertDialog;
 import android.app.AlertDialog.Builder;
@@ -241,10 +243,9 @@
             displayMessage = mView.getResources().getString(
                     R.string.kg_password_wrong_pin_code_pukked);
         } else if (attemptsRemaining > 0) {
-            msgId = isDefault ? R.plurals.kg_password_default_pin_message :
-                    R.plurals.kg_password_wrong_pin_code;
-            displayMessage = mView.getResources()
-                    .getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
+            msgId = isDefault ? R.string.kg_password_default_pin_message :
+                    R.string.kg_password_wrong_pin_code;
+            displayMessage = icuMessageFormat(mView.getResources(), msgId, attemptsRemaining);
         } else {
             msgId = isDefault ? R.string.kg_sim_pin_instructions : R.string.kg_password_pin_failed;
             displayMessage = mView.getResources().getString(msgId);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
index 760c2cc..c0971bf 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java
@@ -16,6 +16,8 @@
 
 package com.android.keyguard;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -57,10 +59,9 @@
         if (attemptsRemaining == 0) {
             displayMessage = getContext().getString(R.string.kg_password_wrong_puk_code_dead);
         } else if (attemptsRemaining > 0) {
-            int msgId = isDefault ? R.plurals.kg_password_default_puk_message :
-                    R.plurals.kg_password_wrong_puk_code;
-            displayMessage = getContext().getResources()
-                    .getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
+            int msgId = isDefault ? R.string.kg_password_default_puk_message :
+                    R.string.kg_password_wrong_puk_code;
+            displayMessage = icuMessageFormat(getResources(), msgId, attemptsRemaining);
         } else {
             int msgId = isDefault ? R.string.kg_puk_enter_puk_hint :
                     R.string.kg_password_puk_failed;
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
index 0bc6579..a174ed0 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
@@ -28,6 +28,7 @@
 import androidx.recyclerview.widget.RecyclerView
 import com.android.systemui.R
 import com.android.systemui.controls.ControlsServiceInfo
+import com.android.systemui.util.icuMessageFormat
 import java.text.Collator
 import java.util.concurrent.Executor
 
@@ -74,8 +75,10 @@
     }
 
     override fun onCreateViewHolder(parent: ViewGroup, i: Int): Holder {
-        return Holder(layoutInflater.inflate(R.layout.controls_app_item, parent, false),
-                favoritesRenderer)
+        return Holder(
+            layoutInflater.inflate(R.layout.controls_app_item, parent, false),
+            favoritesRenderer
+        )
     }
 
     override fun getItemCount() = listOfServices.size
@@ -116,10 +119,10 @@
 
     fun renderFavoritesForComponent(component: ComponentName): String? {
         val qty = favoriteFunction(component)
-        if (qty != 0) {
-            return resources.getQuantityString(R.plurals.controls_number_of_favorites, qty, qty)
+        return if (qty != 0) {
+            icuMessageFormat(resources, R.string.controls_number_of_favorites, qty)
         } else {
-            return null
+            null
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
index abebf3e..7eeedad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
@@ -17,6 +17,7 @@
 package com.android.systemui.qs;
 
 import static com.android.systemui.qs.dagger.QSFragmentModule.QS_FGS_MANAGER_FOOTER_VIEW;
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
 
 import android.content.Context;
 import android.view.View;
@@ -141,8 +142,8 @@
 
     public void handleRefreshState() {
         mMainExecutor.execute(() -> {
-            CharSequence text = mContext.getResources().getQuantityString(
-                    R.plurals.fgs_manager_footer_label, mNumPackages, mNumPackages);
+            CharSequence text = icuMessageFormat(mContext.getResources(),
+                    R.string.fgs_manager_footer_label, mNumPackages);
             mFooterText.setText(text);
             mNumberView.setText(Integer.toString(mNumPackages));
             mNumberView.setContentDescription(text);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index da5202b..9a0d0d9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.qs.tiles;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
@@ -182,10 +184,8 @@
         List<CachedBluetoothDevice> connectedDevices = mController.getConnectedDevices();
         if (enabled && connected && !connectedDevices.isEmpty()) {
             if (connectedDevices.size() > 1) {
-                // TODO(b/76102598): add a new string for "X connected devices" after P
-                return mContext.getResources().getQuantityString(
-                        R.plurals.quick_settings_hotspot_secondary_label_num_devices,
-                        connectedDevices.size(),
+                return icuMessageFormat(mContext.getResources(),
+                        R.string.quick_settings_hotspot_secondary_label_num_devices,
                         connectedDevices.size());
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
index 7c8e77b..b6f6e93 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.qs.tiles;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.content.Intent;
 import android.os.Handler;
 import android.os.Looper;
@@ -186,9 +188,8 @@
             return mContext.getString(
                     R.string.quick_settings_hotspot_secondary_label_data_saver_enabled);
         } else if (numConnectedDevices > 0 && isActive) {
-            return mContext.getResources().getQuantityString(
-                    R.plurals.quick_settings_hotspot_secondary_label_num_devices,
-                    numConnectedDevices,
+            return icuMessageFormat(mContext.getResources(),
+                    R.string.quick_settings_hotspot_secondary_label_num_devices,
                     numConnectedDevices);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
index 56f8e08..40a44ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/HybridGroupManager.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
@@ -136,8 +138,8 @@
         if (!text.equals(reusableView.getText())) {
             reusableView.setText(text);
         }
-        String contentDescription = String.format(mContext.getResources().getQuantityString(
-                R.plurals.notification_group_overflow_description, number), number);
+        String contentDescription = icuMessageFormat(mContext.getResources(),
+                R.string.notification_group_overflow_description, number);
 
         reusableView.setContentDescription(contentDescription);
         reusableView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mOverflowNumberSize);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
index 7269f55..512b049 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
@@ -243,11 +245,11 @@
     private SnoozeOption createOption(int minutes, int accessibilityActionId) {
         Resources res = getResources();
         boolean showInHours = minutes >= 60;
-        int pluralResId = showInHours
-                ? R.plurals.snoozeHourOptions
-                : R.plurals.snoozeMinuteOptions;
+        int stringResId = showInHours
+                ? R.string.snoozeHourOptions
+                : R.string.snoozeMinuteOptions;
         int count = showInHours ? (minutes / 60) : minutes;
-        String description = res.getQuantityString(pluralResId, count, count);
+        String description = icuMessageFormat(res, stringResId, count);
         String resultText = String.format(res.getString(R.string.snoozed_for_time), description);
         AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description);
         final int index = resultText.indexOf(description);
diff --git a/packages/SystemUI/src/com/android/systemui/util/PluralMessageFormater.kt b/packages/SystemUI/src/com/android/systemui/util/PluralMessageFormater.kt
new file mode 100644
index 0000000..83b471d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/PluralMessageFormater.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util
+
+import android.annotation.StringRes
+import android.content.res.Resources
+import android.util.PluralsMessageFormatter
+
+/**
+ * Utility method that provides the localized plural string for the given [messageId]
+ * using the [count] parameter.
+ */
+fun icuMessageFormat(res: Resources, @StringRes messageId: Int, count: Int): String {
+    return PluralsMessageFormatter.format(res, mapOf<String, Any>("count" to count), messageId)
+}