Merge "Change usages of getQuantityString to icu MessageFormatter." into tm-qpr-dev am: 48bab40d62

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

Change-Id: I2e460a6dc5ecab4c62059e4e4581ee287dfa9dc3
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2022-06-02 18:18:15 +00:00
committed by Automerger Merge Worker
11 changed files with 121 additions and 85 deletions

View File

@@ -164,21 +164,21 @@
Displayed in a dialog box. --> 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> <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 <!-- Instructions telling the user that they entered the wrong SIM PIN while trying
to unlock the keyguard. Displayed in a dialog box. --> to unlock the keyguard. Displayed in a dialog box. [CHAR LIMIT=NONE] -->
<plurals name="kg_password_wrong_pin_code"> <string name="kg_password_wrong_pin_code"> {count, plural,
<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> =1 {Incorrect SIM PIN code, you have # remaining attempt before you must contact your carrier to unlock your device.}
<item quantity="other">Incorrect SIM PIN code, you have <xliff:g id="number">%d</xliff:g> remaining attempts.</item> other {Incorrect SIM PIN code, you have # remaining attempts. }
</plurals> }</string>
<!-- Instructions telling the user that they have exhausted SIM PUK retries and the SIM is now unusable. <!-- Instructions telling the user that they have exhausted SIM PUK retries and the SIM is now unusable.
Displayed in a dialog box. --> Displayed in a dialog box. -->
<string name="kg_password_wrong_puk_code_dead">SIM is unusable. Contact your carrier.</string> <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 <!-- Instructions telling the user that they entered the wrong puk while trying
to unlock the keyguard. Displayed in a dialog box. --> to unlock the keyguard. Displayed in a dialog box. [CHAR LIMIT=NONE] -->
<plurals name="kg_password_wrong_puk_code"> <string name="kg_password_wrong_puk_code">{count, plural,
<item quantity="one">Incorrect SIM PUK code, you have <xliff:g id="number">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.</item> =1 {Incorrect SIM PUK code, you have # remaining attempt before SIM becomes permanently unusable.}
<item quantity="other">Incorrect SIM PUK code, you have <xliff:g id="number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.</item> other {Incorrect SIM PUK code, you have # remaining attempts before SIM becomes permanently unusable.}
</plurals> }</string>
<!-- Instructions telling the user that the operation to unlock the keyguard <!-- Instructions telling the user that the operation to unlock the keyguard
with SIM PIN failed. Displayed in one line in a large font. --> with SIM PIN failed. Displayed in one line in a large font. -->
<string name="kg_password_pin_failed">SIM PIN operation failed!</string> <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] --> <!-- 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> <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. --> <!-- Instructions telling the user remaining times when enter SIM PIN view. [CHAR LIMIT=NONE] -->
<plurals name="kg_password_default_pin_message"> <string name="kg_password_default_pin_message">{count, plural,
<item quantity="one">Enter SIM PIN. You have <xliff:g id="number">%d</xliff:g> remaining =1 {Enter SIM PIN. You have # remaining attempt before you must contact your carrier to unlock your device.}
attempt before you must contact your carrier to unlock your device.</item> other {Enter SIM PIN. You have # remaining attempts.}
<item quantity="other">Enter SIM PIN. You have <xliff:g id="number">%d</xliff:g> remaining }</string>
attempts.</item>
</plurals>
<!-- Instructions telling the user remaining times when enter SIM PUK view. --> <!-- Instructions telling the user remaining times when enter SIM PUK view. [CHAR LIMIT=NONE] -->
<plurals name="kg_password_default_puk_message"> <string name="kg_password_default_puk_message">{count, plural,
<item quantity="one">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id=" =1 {SIM is now disabled. Enter PUK code to continue. You have # remaining attempt before SIM becomes permanently unusable. Contact carrier for details.}
number">%d</xliff:g> remaining attempt before SIM becomes permanently unusable. Contact carrier for details.</item> other {SIM is now disabled. Enter PUK code to continue. You have # remaining attempts before SIM becomes permanently unusable. Contact carrier for details.}
<item quantity="other">SIM is now disabled. Enter PUK code to continue. You have <xliff:g id=" }</string>
number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item>
</plurals>
<!-- Name of the "Default" clock face, which is the clock face that will be shown by default. [CHAR LIMIT=15]--> <!-- 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> <string name="clock_title_default">Default</string>

View File

@@ -505,10 +505,10 @@
<string name="notification_group_overflow_indicator">+ <xliff:g id="number" example="3">%s</xliff:g></string> <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] --> <!-- Content description describing how many more notifications are in a group [CHAR LIMIT=NONE] -->
<plurals name="notification_group_overflow_description"> <string name="notification_group_overflow_description">{count, plural,
<item quantity="one"><xliff:g id="number" example="1">%s</xliff:g> more notification inside.</item> =1 {# more notification inside.}
<item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> more notifications inside.</item> other {# more notifications inside.}
</plurals> }</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] --> <!-- 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] --> 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> <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] --> <!-- 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"> <string name="quick_settings_hotspot_secondary_label_num_devices">{count, plural,
<item quantity="one">%d device</item> =1 {# device}
<item quantity="other">%d devices</item> other {# devices}
</plurals> }</string>
<!-- QuickSettings: Notifications [CHAR LIMIT=NONE] --> <!-- QuickSettings: Notifications [CHAR LIMIT=NONE] -->
<!-- QuickSettings: Flashlight [CHAR LIMIT=NONE] --> <!-- QuickSettings: Flashlight [CHAR LIMIT=NONE] -->
<string name="quick_settings_flashlight_label">Flashlight</string> <string name="quick_settings_flashlight_label">Flashlight</string>
@@ -928,10 +928,10 @@
<string name="user_limit_reached_title">User limit reached</string> <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]--> <!-- Message that tells people what's the maximum number of uses allowed on the device. [CHAR_LIMIT=NONE]-->
<plurals name="user_limit_reached_message"> <string name="user_limit_reached_message">{count, plural,
<item quantity="one">Only one user can be created.</item> =1 {Only one user can be created.}
<item quantity="other">You can add up to <xliff:g id="count" example="3">%d</xliff:g> users.</item> other {You can add up to # users.}
</plurals> }</string>
<!-- Title of the confirmation dialog for deleting a user [CHAR LIMIT=NONE] --> <!-- Title of the confirmation dialog for deleting a user [CHAR LIMIT=NONE] -->
<string name="user_remove_user_title">Remove user?</string> <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]--> <!-- 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> <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 --> <!-- Notification:Snooze panel: Snooze options for hours [CHAR LIMIT=NONE]-->
<plurals name="snoozeHourOptions"> <string name="snoozeHourOptions">{count, plural,
<item quantity="one">%d hour</item> =1 {# hour}
<item quantity="two">%d hours</item> =2 {# hours}
<item quantity="few">%d hours</item> few {# hours}
<item quantity="other">%d hours</item> other {# hours}
</plurals> }</string>
<!-- Notification: Snooze panel: Snooze options for minutes --> <!-- Notification: Snooze panel: Snooze options for minutes [CHAR LIMIT=NONE]-->
<plurals name="snoozeMinuteOptions"> <string name="snoozeMinuteOptions">{count, plural,
<item quantity="one">%d minute</item> =1 {# minute}
<item quantity="few">%d minutes</item> few {# minutes}
<item quantity="other">%d minutes</item> other {# minutes}
</plurals> }</string>
<!-- Summary of battery saver not available [CHAR LIMIT=NONE] --> <!-- Summary of battery saver not available [CHAR LIMIT=NONE] -->
@@ -2136,10 +2136,10 @@
<!-- Controls management providers screen title [CHAR LIMIT=60]--> <!-- Controls management providers screen title [CHAR LIMIT=60]-->
<string name="controls_providers_title">Choose app to add controls</string> <string name="controls_providers_title">Choose app to add controls</string>
<!-- Number of favorites for controls management screen [CHAR LIMIT=NONE]--> <!-- Number of favorites for controls management screen [CHAR LIMIT=NONE]-->
<plurals name="controls_number_of_favorites"> <string name="controls_number_of_favorites">{count, plural,
<item quantity="one"><xliff:g id="number" example="1">%s</xliff:g> control added.</item> =1 {# control added.}
<item quantity="other"><xliff:g id="number" example="3">%s</xliff:g> controls added.</item> other {# controls added.}
</plurals> }</string>
<!-- Removed control in management screen [CHAR LIMIT=20] --> <!-- Removed control in management screen [CHAR LIMIT=20] -->
<string name="controls_removed">Removed</string> <string name="controls_removed">Removed</string>
@@ -2495,10 +2495,10 @@
<string name="qs_user_switch_dialog_title">Select user</string> <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]--> <!-- Label for the entry point to open the dialog which shows currently running applications [CHAR LIMIT=NONE]-->
<plurals name="fgs_manager_footer_label"> <string name="fgs_manager_footer_label">{count, plural,
<item quantity="one"><xliff:g id="count" example="1">%s</xliff:g> app is active</item> =1 {# app is active}
<item quantity="other"><xliff:g id="count" example="2">%s</xliff:g> apps are active</item> other {# apps are active}
</plurals> }</string>
<!-- Content description for a dot indicator in the running application indicating that there <!-- Content description for a dot indicator in the running application indicating that there
is new information [CHAR LIMIT=NONE] --> is new information [CHAR LIMIT=NONE] -->
<string name="fgs_dot_content_description">New information</string> <string name="fgs_dot_content_description">New information</string>

View File

@@ -16,6 +16,8 @@
package com.android.keyguard; package com.android.keyguard;
import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.AlertDialog.Builder; import android.app.AlertDialog.Builder;
@@ -241,10 +243,9 @@ public class KeyguardSimPinViewController
displayMessage = mView.getResources().getString( displayMessage = mView.getResources().getString(
R.string.kg_password_wrong_pin_code_pukked); R.string.kg_password_wrong_pin_code_pukked);
} else if (attemptsRemaining > 0) { } else if (attemptsRemaining > 0) {
msgId = isDefault ? R.plurals.kg_password_default_pin_message : msgId = isDefault ? R.string.kg_password_default_pin_message :
R.plurals.kg_password_wrong_pin_code; R.string.kg_password_wrong_pin_code;
displayMessage = mView.getResources() displayMessage = icuMessageFormat(mView.getResources(), msgId, attemptsRemaining);
.getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
} else { } else {
msgId = isDefault ? R.string.kg_sim_pin_instructions : R.string.kg_password_pin_failed; msgId = isDefault ? R.string.kg_sim_pin_instructions : R.string.kg_password_pin_failed;
displayMessage = mView.getResources().getString(msgId); displayMessage = mView.getResources().getString(msgId);

View File

@@ -16,6 +16,8 @@
package com.android.keyguard; package com.android.keyguard;
import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@@ -57,10 +59,9 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView {
if (attemptsRemaining == 0) { if (attemptsRemaining == 0) {
displayMessage = getContext().getString(R.string.kg_password_wrong_puk_code_dead); displayMessage = getContext().getString(R.string.kg_password_wrong_puk_code_dead);
} else if (attemptsRemaining > 0) { } else if (attemptsRemaining > 0) {
int msgId = isDefault ? R.plurals.kg_password_default_puk_message : int msgId = isDefault ? R.string.kg_password_default_puk_message :
R.plurals.kg_password_wrong_puk_code; R.string.kg_password_wrong_puk_code;
displayMessage = getContext().getResources() displayMessage = icuMessageFormat(getResources(), msgId, attemptsRemaining);
.getQuantityString(msgId, attemptsRemaining, attemptsRemaining);
} else { } else {
int msgId = isDefault ? R.string.kg_puk_enter_puk_hint : int msgId = isDefault ? R.string.kg_puk_enter_puk_hint :
R.string.kg_password_puk_failed; R.string.kg_password_puk_failed;

View File

@@ -28,6 +28,7 @@ import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.android.systemui.R import com.android.systemui.R
import com.android.systemui.controls.ControlsServiceInfo import com.android.systemui.controls.ControlsServiceInfo
import com.android.systemui.util.icuMessageFormat
import java.text.Collator import java.text.Collator
import java.util.concurrent.Executor import java.util.concurrent.Executor
@@ -74,8 +75,10 @@ class AppAdapter(
} }
override fun onCreateViewHolder(parent: ViewGroup, i: Int): Holder { override fun onCreateViewHolder(parent: ViewGroup, i: Int): Holder {
return Holder(layoutInflater.inflate(R.layout.controls_app_item, parent, false), return Holder(
favoritesRenderer) layoutInflater.inflate(R.layout.controls_app_item, parent, false),
favoritesRenderer
)
} }
override fun getItemCount() = listOfServices.size override fun getItemCount() = listOfServices.size
@@ -116,10 +119,10 @@ class FavoritesRenderer(
fun renderFavoritesForComponent(component: ComponentName): String? { fun renderFavoritesForComponent(component: ComponentName): String? {
val qty = favoriteFunction(component) val qty = favoriteFunction(component)
if (qty != 0) { return if (qty != 0) {
return resources.getQuantityString(R.plurals.controls_number_of_favorites, qty, qty) icuMessageFormat(resources, R.string.controls_number_of_favorites, qty)
} else { } else {
return null null
} }
} }
} }

View File

@@ -17,6 +17,7 @@
package com.android.systemui.qs; package com.android.systemui.qs;
import static com.android.systemui.qs.dagger.QSFragmentModule.QS_FGS_MANAGER_FOOTER_VIEW; 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.content.Context;
import android.view.View; import android.view.View;
@@ -141,8 +142,8 @@ public class QSFgsManagerFooter implements View.OnClickListener,
public void handleRefreshState() { public void handleRefreshState() {
mMainExecutor.execute(() -> { mMainExecutor.execute(() -> {
CharSequence text = mContext.getResources().getQuantityString( CharSequence text = icuMessageFormat(mContext.getResources(),
R.plurals.fgs_manager_footer_label, mNumPackages, mNumPackages); R.string.fgs_manager_footer_label, mNumPackages);
mFooterText.setText(text); mFooterText.setText(text);
mNumberView.setText(Integer.toString(mNumPackages)); mNumberView.setText(Integer.toString(mNumPackages));
mNumberView.setContentDescription(text); mNumberView.setContentDescription(text);

View File

@@ -16,6 +16,8 @@
package com.android.systemui.qs.tiles; package com.android.systemui.qs.tiles;
import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
@@ -182,10 +184,8 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
List<CachedBluetoothDevice> connectedDevices = mController.getConnectedDevices(); List<CachedBluetoothDevice> connectedDevices = mController.getConnectedDevices();
if (enabled && connected && !connectedDevices.isEmpty()) { if (enabled && connected && !connectedDevices.isEmpty()) {
if (connectedDevices.size() > 1) { if (connectedDevices.size() > 1) {
// TODO(b/76102598): add a new string for "X connected devices" after P return icuMessageFormat(mContext.getResources(),
return mContext.getResources().getQuantityString( R.string.quick_settings_hotspot_secondary_label_num_devices,
R.plurals.quick_settings_hotspot_secondary_label_num_devices,
connectedDevices.size(),
connectedDevices.size()); connectedDevices.size());
} }

View File

@@ -16,6 +16,8 @@
package com.android.systemui.qs.tiles; package com.android.systemui.qs.tiles;
import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
import android.content.Intent; import android.content.Intent;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
@@ -186,9 +188,8 @@ public class HotspotTile extends QSTileImpl<BooleanState> {
return mContext.getString( return mContext.getString(
R.string.quick_settings_hotspot_secondary_label_data_saver_enabled); R.string.quick_settings_hotspot_secondary_label_data_saver_enabled);
} else if (numConnectedDevices > 0 && isActive) { } else if (numConnectedDevices > 0 && isActive) {
return mContext.getResources().getQuantityString( return icuMessageFormat(mContext.getResources(),
R.plurals.quick_settings_hotspot_secondary_label_num_devices, R.string.quick_settings_hotspot_secondary_label_num_devices,
numConnectedDevices,
numConnectedDevices); numConnectedDevices);
} }

View File

@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.row; package com.android.systemui.statusbar.notification.row;
import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.Notification; import android.app.Notification;
import android.content.Context; import android.content.Context;
@@ -136,8 +138,8 @@ public class HybridGroupManager {
if (!text.equals(reusableView.getText())) { if (!text.equals(reusableView.getText())) {
reusableView.setText(text); reusableView.setText(text);
} }
String contentDescription = String.format(mContext.getResources().getQuantityString( String contentDescription = icuMessageFormat(mContext.getResources(),
R.plurals.notification_group_overflow_description, number), number); R.string.notification_group_overflow_description, number);
reusableView.setContentDescription(contentDescription); reusableView.setContentDescription(contentDescription);
reusableView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mOverflowNumberSize); reusableView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mOverflowNumberSize);

View File

@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.row; package com.android.systemui.statusbar.notification.row;
import static com.android.systemui.util.PluralMessageFormaterKt.icuMessageFormat;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
@@ -243,11 +245,11 @@ public class NotificationSnooze extends LinearLayout
private SnoozeOption createOption(int minutes, int accessibilityActionId) { private SnoozeOption createOption(int minutes, int accessibilityActionId) {
Resources res = getResources(); Resources res = getResources();
boolean showInHours = minutes >= 60; boolean showInHours = minutes >= 60;
int pluralResId = showInHours int stringResId = showInHours
? R.plurals.snoozeHourOptions ? R.string.snoozeHourOptions
: R.plurals.snoozeMinuteOptions; : R.string.snoozeMinuteOptions;
int count = showInHours ? (minutes / 60) : minutes; 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); String resultText = String.format(res.getString(R.string.snoozed_for_time), description);
AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description); AccessibilityAction action = new AccessibilityAction(accessibilityActionId, description);
final int index = resultText.indexOf(description); final int index = resultText.indexOf(description);

View File

@@ -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)
}