Merge "Update the font style to use device default style" into sc-mainline-prod
diff --git a/apex/framework/api/current.txt b/apex/framework/api/current.txt
index 187da31..0a53fb5 100644
--- a/apex/framework/api/current.txt
+++ b/apex/framework/api/current.txt
@@ -8,7 +8,6 @@
     method @NonNull public static android.app.PendingIntent createFavoriteRequest(@NonNull android.content.ContentResolver, @NonNull java.util.Collection<android.net.Uri>, boolean);
     method @NonNull public static android.app.PendingIntent createTrashRequest(@NonNull android.content.ContentResolver, @NonNull java.util.Collection<android.net.Uri>, boolean);
     method @NonNull public static android.app.PendingIntent createWriteRequest(@NonNull android.content.ContentResolver, @NonNull java.util.Collection<android.net.Uri>);
-    method @Nullable public static String getCloudProvider(@NonNull android.content.ContentResolver);
     method @Nullable public static android.net.Uri getDocumentUri(@NonNull android.content.Context, @NonNull android.net.Uri);
     method @NonNull public static java.util.Set<java.lang.String> getExternalVolumeNames(@NonNull android.content.Context);
     method public static long getGeneration(@NonNull android.content.Context, @NonNull String);
@@ -23,7 +22,6 @@
     method @NonNull public static String getVersion(@NonNull android.content.Context, @NonNull String);
     method @NonNull public static String getVolumeName(@NonNull android.net.Uri);
     method public static boolean isCurrentSystemGallery(@NonNull android.content.ContentResolver, int, @NonNull String);
-    method public static boolean notifyCloudEvent(@NonNull android.content.ContentResolver);
     method @Deprecated @NonNull public static android.net.Uri setIncludePending(@NonNull android.net.Uri);
     method @NonNull public static android.net.Uri setRequireOriginal(@NonNull android.net.Uri);
     field public static final String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
diff --git a/apex/framework/api/module-lib-current.txt b/apex/framework/api/module-lib-current.txt
index eae8f7a..d802177 100644
--- a/apex/framework/api/module-lib-current.txt
+++ b/apex/framework/api/module-lib-current.txt
@@ -1,41 +1 @@
 // Signature format: 2.0
-package android.provider {
-
-  public final class CloudMediaProviderContract {
-    field public static final String EXTRA_FILTER_ALBUM = "android.provider.extra.FILTER_ALBUM";
-    field public static final String EXTRA_FILTER_MIMETYPE = "android.provider.extra.FILTER_MIMETYPE";
-    field public static final String EXTRA_FILTER_SIZE_BYTES = "android.provider.extra.FILTER_SIZE_BYTES";
-    field public static final String EXTRA_GENERATION = "android.provider.extra.GENERATION";
-    field public static final String EXTRA_PAGE_TOKEN = "android.provider.extra.PAGE_TOKEN";
-    field public static final String MANAGE_CLOUD_MEDIA_PROVIDERS_PERMISSION = "com.android.providers.media.permission.MANAGE_CLOUD_MEDIA_PROVIDERS";
-    field public static final String METHOD_GET_MEDIA_INFO = "android:getMediaInfo";
-    field public static final String PROVIDER_INTERFACE = "android.content.action.CLOUD_MEDIA_PROVIDER";
-  }
-
-  public static final class CloudMediaProviderContract.AlbumColumns {
-    field public static final String DATE_TAKEN_MS = "date_taken_ms";
-    field public static final String DISPLAY_NAME = "display_name";
-    field public static final String ID = "id";
-    field public static final String MEDIA_COUNT = "album_media_count";
-    field public static final String MEDIA_COVER_ID = "album_media_cover_id";
-  }
-
-  public static final class CloudMediaProviderContract.MediaColumns {
-    field public static final String DATE_TAKEN_MS = "date_taken_ms";
-    field public static final String DURATION_MS = "duration_ms";
-    field public static final String GENERATION_MODIFIED = "generation_modified";
-    field public static final String ID = "id";
-    field public static final String IS_FAVORITE = "is_favorite";
-    field public static final String MEDIA_STORE_URI = "media_store_uri";
-    field public static final String MIME_TYPE = "mime_type";
-    field public static final String SIZE_BYTES = "size_bytes";
-  }
-
-  public static final class CloudMediaProviderContract.MediaInfo {
-    field public static final String MEDIA_COUNT = "media_count";
-    field public static final String MEDIA_GENERATION = "media_generation";
-    field public static final String MEDIA_VERSION = "media_version";
-  }
-
-}
-
diff --git a/apex/framework/java/android/provider/CloudMediaProvider.java b/apex/framework/java/android/provider/CloudMediaProvider.java
index 3ef174f..ae96fb1 100644
--- a/apex/framework/java/android/provider/CloudMediaProvider.java
+++ b/apex/framework/java/android/provider/CloudMediaProvider.java
@@ -16,6 +16,7 @@
 
 package android.provider;
 
+import static android.provider.CloudMediaProviderContract.METHOD_GET_ACCOUNT_INFO;
 import static android.provider.CloudMediaProviderContract.METHOD_GET_MEDIA_INFO;
 import static android.provider.CloudMediaProviderContract.URI_PATH_ALBUM;
 import static android.provider.CloudMediaProviderContract.URI_PATH_DELETED_MEDIA;
@@ -116,6 +117,25 @@
     }
 
     /**
+     * Returns account related information for the media collection.
+     * <p>
+     * This is useful for the OS to populate a settings page with account information and allow
+     * users configure their media collection account.
+     *
+     * @param extras containing keys to filter result:
+     * <ul>
+     * <li> {@link CloudMediaProviderContract.AccountInfo#ACTIVE_ACCOUNT_NAME}
+     * <li> {@link CloudMediaProviderContract.AccountInfo#ACCOUNT_CONFIGURATION_INTENT}
+     * </ul>
+     *
+     * @return {@link Bundle} containing {@link CloudMediaProviderContract.AccountInfo}
+     */
+    @NonNull
+    public Bundle onGetAccountInfo(@Nullable Bundle extras) {
+        throw new UnsupportedOperationException("getAccountInfo not supported");
+    }
+
+        /**
      * Returns metadata about the media collection itself.
      * <p>
      * This is useful for the OS to determine if its cache of media items in the collection is
@@ -281,6 +301,8 @@
             throws FileNotFoundException {
         if (METHOD_GET_MEDIA_INFO.equals(method)) {
             return onGetMediaInfo(extras);
+        } else if (METHOD_GET_ACCOUNT_INFO.equals(method)) {
+            return onGetAccountInfo(extras);
         } else {
             throw new UnsupportedOperationException("Method not supported " + method);
         }
diff --git a/apex/framework/java/android/provider/CloudMediaProviderContract.java b/apex/framework/java/android/provider/CloudMediaProviderContract.java
index f8a2811..840f009 100644
--- a/apex/framework/java/android/provider/CloudMediaProviderContract.java
+++ b/apex/framework/java/android/provider/CloudMediaProviderContract.java
@@ -17,6 +17,7 @@
 package android.provider;
 
 import android.annotation.SystemApi;
+import android.app.Activity;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.database.Cursor;
@@ -34,7 +35,6 @@
  *
  * @hide
  */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
 public final class CloudMediaProviderContract {
     private static final String TAG = "CloudMediaProviderContract";
 
@@ -325,6 +325,30 @@
         public static final String MEDIA_COUNT = "media_count";
     }
 
+    /** Constants related to the account information */
+    public static final class AccountInfo {
+        private AccountInfo() {}
+
+        /**
+         * Name of the account owning the media collection synced from the cloud provider.
+         * <p>
+         * Type: STRING
+         *
+         * @see CloudMediaProvider#onGetAccountInfo
+         */
+        public static final String ACTIVE_ACCOUNT_NAME = "active_account_name";
+
+        /**
+         * {@link Intent} Intent to launch an {@link Activity} to allow users configure their media
+         * collection account information like the active account.
+         * <p>
+         * Type: PARCELABLE
+         *
+         * @see CloudMediaProvider#onGetAccountInfo
+         */
+        public static final String ACCOUNT_CONFIGURATION_INTENT = "account_configuration_intent";
+    }
+
     /**
      * Opaque pagination token to retrieve the next page (cursor) from a media or album query.
      * <p>
@@ -433,10 +457,17 @@
      *
      * {@hide}
      */
-    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final String METHOD_GET_MEDIA_INFO = "android:getMediaInfo";
 
     /**
+     * Constant used to execute {@link CloudMediaProvider#onGetAccountInfo} via
+     * {@link ContentProvider#call}.
+     *
+     * {@hide}
+     */
+    public static final String METHOD_GET_ACCOUNT_INFO = "android:getAccountInfo";
+
+    /**
      * URI path for {@link CloudMediaProvider#onQueryMedia}
      *
      * {@hide}
@@ -470,4 +501,11 @@
      * {@hide}
      */
     public static final String URI_PATH_MEDIA_INFO = "media_info";
+
+    /**
+     * URI path for {@link CloudMediaProvider#onGetAccountInfo}
+     *
+     * {@hide}
+     */
+    public static final String URI_PATH_ACCOUNT_INFO = "account_info";
 }
diff --git a/apex/framework/java/android/provider/MediaStore.java b/apex/framework/java/android/provider/MediaStore.java
index 8a8a811..39df119 100644
--- a/apex/framework/java/android/provider/MediaStore.java
+++ b/apex/framework/java/android/provider/MediaStore.java
@@ -4579,6 +4579,8 @@
      * enabled.
      *
      * See android.provider.CloudMediaProvider
+     *
+     * @hide
      */
     // TODO(b/202733511): Convert See to @see tag after CloudMediaProvider API is unhidden
     @Nullable
@@ -4600,6 +4602,8 @@
      * {@link #getCloudProvider(ContentResolver)}, the request will be unsuccessful.
      *
      * @return {@code true} if the notification was successful, {@code false} otherwise
+     *
+     * @hide
      */
     public static boolean notifyCloudEvent(@NonNull ContentResolver resolver) {
         Objects.requireNonNull(resolver);
diff --git a/res/layout/item_album_grid.xml b/res/layout/item_album_grid.xml
index 323f3be..e40891e 100644
--- a/res/layout/item_album_grid.xml
+++ b/res/layout/item_album_grid.xml
@@ -42,14 +42,16 @@
     <TextView
         android:id="@+id/album_name"
         android:layout_width="wrap_content"
-        android:layout_height="@dimen/picker_album_name_min_height"
+        android:layout_height="wrap_content"
+        android:minHeight="@dimen/picker_album_name_min_height"
         android:layout_marginTop="@dimen/picker_album_name_margin"
         android:textAppearance="@style/PickerHeaderTextAppearance"/>
 
     <TextView
         android:id="@+id/item_count"
         android:layout_width="wrap_content"
-        android:layout_height="@dimen/picker_album_item_count_height"
+        android:layout_height="wrap_content"
+        android:minHeight="@dimen/picker_album_item_count_height"
         android:layout_marginTop="@dimen/picker_album_item_count_margin"
         android:textAppearance="@android:style/TextAppearance.DeviceDefault.Small"/>
 
diff --git a/res/layout/item_date_header.xml b/res/layout/item_date_header.xml
index bbd4b3d..d3a931a 100644
--- a/res/layout/item_date_header.xml
+++ b/res/layout/item_date_header.xml
@@ -17,6 +17,7 @@
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
           android:id="@+id/date_header_title"
           android:layout_width="match_parent"
-          android:layout_height="@dimen/picker_date_header_height"
+          android:layout_height="wrap_content"
+          android:minHeight="@dimen/picker_date_header_height"
           android:padding="@dimen/picker_date_header_padding"
           android:textAppearance="@style/PickerHeaderTextAppearance"/>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 26dbbbb..9258e71 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -50,16 +50,16 @@
     <string name="grant_dialog_button_deny">Deny</string>
 
     <!-- Text placed over a visual thumbnail indicating that there are more items beyond the number currently displayed on the screen. [CHAR LIMIT=6] -->
-    <plurals name="permission_more_thumb">
-        <item quantity="one">+<xliff:g id="count" example="1">^1</xliff:g></item>
-        <item quantity="other">+<xliff:g id="count" example="42">^1</xliff:g></item>
-    </plurals>
+    <string name="permission_more_thumb"> {count, plural,
+        =1    {+<xliff:g id="count" example="1">^1</xliff:g>}
+        other {+<xliff:g id="count" example="42">^1</xliff:g>}
+    }</string>
 
     <!-- Text shown at the end of a list indicating that there are more items beyond the number currently displayed on the screen. [CHAR LIMIT=32]  -->
-    <plurals name="permission_more_text">
-        <item quantity="one">Plus <xliff:g id="count" example="1">^1</xliff:g> additional item</item>
-        <item quantity="other">Plus <xliff:g id="count" example="42">^1</xliff:g> additional items</item>
-    </plurals>
+    <string name="permission_more_text"> {count, plural,
+        =1    {Plus <xliff:g id="count" example="1">^1</xliff:g> additional item}
+        other {Plus <xliff:g id="count" example="42">^1</xliff:g> additional items}
+    }</string>
 
     <!-- Cache clearing permission dialog warning title. [CHAR LIMIT=NONE] -->
     <string name="cache_clearing_dialog_title">Clear temporary app files</string>
@@ -89,10 +89,10 @@
     <string name="select">Select</string>
 
     <!-- Select up to max label message for PhotoPicker. [CHAR LIMIT=30] -->
-    <plurals name="select_up_to">
-        <item quantity="one">Select up to <xliff:g id="count" example="1">^1</xliff:g> item</item>
-        <item quantity="other">Select up to <xliff:g id="count" example="42">^1</xliff:g> items</item>
-    </plurals>
+    <string name="select_up_to"> {count, plural,
+        =1    {Select up to <xliff:g id="count" example="1">^1</xliff:g> item}
+        other {Select up to <xliff:g id="count" example="42">^1</xliff:g> items}
+    }</string>
 
     <!-- Recent header for PhotoPicker. [CHAR LIMIT=50] -->
     <string name="recent">Recent</string>
@@ -127,10 +127,10 @@
     <string name="picker_profile_work_paused_msg">To open work photos, turn on your work apps then try again</string>
 
     <!-- Text shown on the album item in PhotoPicker. [CHAR LIMIT=30]  -->
-    <plurals name="picker_album_item_count">
-        <item quantity="one"><xliff:g id="count" example="1">^1</xliff:g> item</item>
-        <item quantity="other"><xliff:g id="count" example="42">^1</xliff:g> items</item>
-    </plurals>
+    <string name="picker_album_item_count"> {count, plural,
+        =1    {<xliff:g id="count" example="1">^1</xliff:g> item}
+        other {<xliff:g id="count" example="42">^1</xliff:g> items}
+    }</string>
 
     <!-- Text shown on the add button for multi-select in PhotoPicker. [CHAR LIMIT=30]  -->
     <string name="picker_add_button_multi_select">Add (<xliff:g id="count" example="42">^1</xliff:g>)</string>
@@ -154,174 +154,174 @@
     <!-- ========================= WRITE STRINGS ========================= -->
 
     <!-- Dialog title asking if user will allow write permission to the audio item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_write_audio">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify this audio file?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify <xliff:g id="count" example="42">^2</xliff:g> audio files?</item>
-    </plurals>
+    <string name="permission_write_audio"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify this audio file?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify <xliff:g id="count" example="42">^2</xliff:g> audio files?}
+    }</string>
     <!-- Progress dialog message after user allows write permission to the audio item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_write_audio">
-        <item quantity="one">Modifying audio file&#8230;</item>
-        <item quantity="other">Modifying <xliff:g id="count" example="42">^1</xliff:g> audio files&#8230;</item>
-    </plurals>
+    <string name="permission_progress_write_audio"> {count, plural,
+        =1    {Modifying audio file&#8230;}
+        other {Modifying <xliff:g id="count" example="42">^1</xliff:g> audio files&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow write permission to the video item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_write_video">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify this video?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify <xliff:g id="count" example="42">^2</xliff:g> videos?</item>
-    </plurals>
+    <string name="permission_write_video"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify this video?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify <xliff:g id="count" example="42">^2</xliff:g> videos?}
+    }</string>
     <!-- Progress dialog message after user allows write permission to the video item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_write_video">
-        <item quantity="one">Modifying video&#8230;</item>
-        <item quantity="other">Modifying <xliff:g id="count" example="42">^1</xliff:g> videos&#8230;</item>
-    </plurals>
+    <string name="permission_progress_write_video"> {count, plural,
+        =1    {Modifying video&#8230;}
+        other {Modifying <xliff:g id="count" example="42">^1</xliff:g> videos&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow write permission to the image item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_write_image">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify this photo?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify <xliff:g id="count" example="42">^2</xliff:g> photos?</item>
-    </plurals>
+    <string name="permission_write_image"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify this photo?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify <xliff:g id="count" example="42">^2</xliff:g> photos?}
+    }</string>
     <!-- Progress dialog message after user allows write permission to the image item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_write_image">
-        <item quantity="one">Modifying photo&#8230;</item>
-        <item quantity="other">Modifying <xliff:g id="count" example="42">^1</xliff:g> photos&#8230;</item>
-    </plurals>
+    <string name="permission_progress_write_image"> {count, plural,
+        =1    {Modifying photo&#8230;}
+        other {Modifying <xliff:g id="count" example="42">^1</xliff:g> photos&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow write permission to the generic item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_write_generic">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify this item?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify <xliff:g id="count" example="42">^2</xliff:g> items?</item>
-    </plurals>
+    <string name="permission_write_generic"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify this item?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to modify <xliff:g id="count" example="42">^2</xliff:g> items?}
+    }</string>
     <!-- Progress dialog message after user allows write permission to the generic item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_write_generic">
-        <item quantity="one">Modifying item&#8230;</item>
-        <item quantity="other">Modifying <xliff:g id="count" example="42">^1</xliff:g> items&#8230;</item>
-    </plurals>
+    <string name="permission_progress_write_generic"> {count, plural,
+        =1    {Modifying item&#8230;}
+        other {Modifying <xliff:g id="count" example="42">^1</xliff:g> items&#8230;}
+    }</string>
 
     <!-- ========================= TRASH STRINGS ========================= -->
 
     <!-- Dialog title asking if user will allow trash permission to the audio item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_trash_audio">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this audio file to trash?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> audio files to trash?</item>
-    </plurals>
+    <string name="permission_trash_audio"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this audio file to trash?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> audio files to trash?}
+    }</string>
     <!-- Progress dialog message after user allows trash permission to the audio item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_trash_audio">
-        <item quantity="one">Moving audio file to trash&#8230;</item>
-        <item quantity="other">Moving <xliff:g id="count" example="42">^1</xliff:g> audio files to trash&#8230;</item>
-    </plurals>
+    <string name="permission_progress_trash_audio"> {count, plural,
+        =1    {Moving audio file to trash&#8230;}
+        other {Moving <xliff:g id="count" example="42">^1</xliff:g> audio files to trash&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow trash permission to the video item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_trash_video">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this video to trash?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> videos to trash?</item>
-    </plurals>
+    <string name="permission_trash_video"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this video to trash?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> videos to trash?}
+    }</string>
     <!-- Progress dialog message after user allows trash permission to the video item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_trash_video">
-        <item quantity="one">Moving video to trash&#8230;</item>
-        <item quantity="other">Moving <xliff:g id="count" example="42">^1</xliff:g> videos to trash&#8230;</item>
-    </plurals>
+    <string name="permission_progress_trash_video"> {count, plural,
+        =1    {Moving video to trash&#8230;}
+        other {Moving <xliff:g id="count" example="42">^1</xliff:g> videos to trash&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow trash permission to the image item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_trash_image">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this photo to trash?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> photos to trash?</item>
-    </plurals>
+    <string name="permission_trash_image"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this photo to trash?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> photos to trash?}
+    }</string>
     <!-- Progress dialog message after user allows trash permission to the image item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_trash_image">
-        <item quantity="one">Moving photo to trash&#8230;</item>
-        <item quantity="other">Moving <xliff:g id="count" example="42">^1</xliff:g> photos to trash&#8230;</item>
-    </plurals>
+    <string name="permission_progress_trash_image"> {count, plural,
+        =1    {Moving photo to trash&#8230;}
+        other {Moving <xliff:g id="count" example="42">^1</xliff:g> photos to trash&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow trash permission to the generic item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_trash_generic">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this item to trash?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> items to trash?</item>
-    </plurals>
+    <string name="permission_trash_generic"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this item to trash?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> items to trash?}
+    }</string>
     <!-- Progress dialog message after user allows trash permission to the generic item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_trash_generic">
-        <item quantity="one">Moving item to trash&#8230;</item>
-        <item quantity="other">Moving <xliff:g id="count" example="42">^1</xliff:g> items to trash&#8230;</item>
-    </plurals>
+    <string name="permission_progress_trash_generic"> {count, plural,
+        =1    {Moving item to trash&#8230;}
+        other {Moving <xliff:g id="count" example="42">^1</xliff:g> items to trash&#8230;}
+    }</string>
 
     <!-- ========================= UNTRASH STRINGS ========================= -->
 
     <!-- Dialog title asking if user will allow untrash permission to the audio item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_untrash_audio">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this audio file out of trash?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> audio files out of trash?</item>
-    </plurals>
+    <string name="permission_untrash_audio"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this audio file out of trash?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> audio files out of trash?}
+    }</string>
     <!-- Progress dialog message after user allows untrash permission to the audio item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_untrash_audio">
-        <item quantity="one">Moving audio file out of trash&#8230;</item>
-        <item quantity="other">Moving <xliff:g id="count" example="42">^1</xliff:g> audio files out of trash&#8230;</item>
-    </plurals>
+    <string name="permission_progress_untrash_audio"> {count, plural,
+        =1    {Moving audio file out of trash&#8230;}
+        other {Moving <xliff:g id="count" example="42">^1</xliff:g> audio files out of trash&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow untrash permission to the video item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_untrash_video">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this video out of trash?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> videos out of trash?</item>
-    </plurals>
+    <string name="permission_untrash_video"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this video out of trash?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> videos out of trash?}
+    }</string>
     <!-- Progress dialog message after user allows untrash permission to the video item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_untrash_video">
-        <item quantity="one">Moving video out of trash&#8230;</item>
-        <item quantity="other">Moving <xliff:g id="count" example="42">^1</xliff:g> videos out of trash&#8230;</item>
-    </plurals>
+    <string name="permission_progress_untrash_video"> {count, plural,
+        =1    {Moving video out of trash&#8230;}
+        other {Moving <xliff:g id="count" example="42">^1</xliff:g> videos out of trash&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow untrash permission to the image item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_untrash_image">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this photo out of trash?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> photos out of trash?</item>
-    </plurals>
+    <string name="permission_untrash_image"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this photo out of trash?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> photos out of trash?}
+    }</string>
     <!-- Progress dialog message after user allows untrash permission to the image item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_untrash_image">
-        <item quantity="one">Moving photo out of trash&#8230;</item>
-        <item quantity="other">Moving <xliff:g id="count" example="42">^1</xliff:g> photos out of trash&#8230;</item>
-    </plurals>
+    <string name="permission_progress_untrash_image"> {count, plural,
+        =1    {Moving photo out of trash&#8230;}
+        other {Moving <xliff:g id="count" example="42">^1</xliff:g> photos out of trash&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow untrash permission to the generic item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_untrash_generic">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this item out of trash?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> items out of trash?</item>
-    </plurals>
+    <string name="permission_untrash_generic"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move this item out of trash?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to move <xliff:g id="count" example="42">^2</xliff:g> items out of trash?}
+    }</string>
     <!-- Progress dialog message after user allows untrash permission to the generic item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_untrash_generic">
-        <item quantity="one">Moving item out of trash&#8230;</item>
-        <item quantity="other">Moving <xliff:g id="count" example="42">^1</xliff:g> items out of trash&#8230;</item>
-    </plurals>
+    <string name="permission_progress_untrash_generic"> {count, plural,
+        =1    {Moving item out of trash&#8230;}
+        other {Moving <xliff:g id="count" example="42">^1</xliff:g> items out of trash&#8230;}
+    }</string>
 
     <!-- ========================= DELETE STRINGS ========================= -->
 
     <!-- Dialog title asking if user will allow delete permission to the audio item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_delete_audio">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete this audio file?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete <xliff:g id="count" example="42">^2</xliff:g> audio files?</item>
-    </plurals>
+    <string name="permission_delete_audio"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete this audio file?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete <xliff:g id="count" example="42">^2</xliff:g> audio files?}
+    }</string>
     <!-- Progress dialog message after user allows delete permission to the audio item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_delete_audio">
-        <item quantity="one">Deleting audio file&#8230;</item>
-        <item quantity="other">Deleting <xliff:g id="count" example="42">^1</xliff:g> audio files&#8230;</item>
-    </plurals>
+    <string name="permission_progress_delete_audio"> {count, plural,
+        =1    {Deleting audio file&#8230;}
+        other {Deleting <xliff:g id="count" example="42">^1</xliff:g> audio files&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow delete permission to the video item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_delete_video">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete this video?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete <xliff:g id="count" example="42">^2</xliff:g> videos?</item>
-    </plurals>
+    <string name="permission_delete_video"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete this video?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete <xliff:g id="count" example="42">^2</xliff:g> videos?}
+    }</string>
     <!-- Progress dialog message after user allows delete permission to the video item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_delete_video">
-        <item quantity="one">Deleting video&#8230;</item>
-        <item quantity="other">Deleting <xliff:g id="count" example="42">^1</xliff:g> videos&#8230;</item>
-    </plurals>
+    <string name="permission_progress_delete_video"> {count, plural,
+        =1    {Deleting video&#8230;}
+        other {Deleting <xliff:g id="count" example="42">^1</xliff:g> videos&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow delete permission to the image item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_delete_image">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete this photo?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete <xliff:g id="count" example="42">^2</xliff:g> photos?</item>
-    </plurals>
+    <string name="permission_delete_image"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete this photo?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete <xliff:g id="count" example="42">^2</xliff:g> photos?}
+    }</string>
     <!-- Progress dialog message after user allows delete permission to the image item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_delete_image">
-        <item quantity="one">Deleting photo&#8230;</item>
-        <item quantity="other">Deleting <xliff:g id="count" example="42">^1</xliff:g> photos&#8230;</item>
-    </plurals>
+    <string name="permission_progress_delete_image"> {count, plural,
+        =1    {Deleting photo&#8230;}
+        other {Deleting <xliff:g id="count" example="42">^1</xliff:g> photos&#8230;}
+    }</string>
     <!-- Dialog title asking if user will allow delete permission to the generic item displayed below this string. [CHAR LIMIT=128] -->
-    <plurals name="permission_delete_generic">
-        <item quantity="one">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete this item?</item>
-        <item quantity="other">Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete <xliff:g id="count" example="42">^2</xliff:g> items?</item>
-    </plurals>
+    <string name="permission_delete_generic"> {count, plural,
+        =1    {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete this item?}
+        other {Allow <xliff:g id="app_name" example="Gmail">^1</xliff:g> to delete <xliff:g id="count" example="42">^2</xliff:g> items?}
+    }</string>
     <!-- Progress dialog message after user allows delete permission to the generic item [CHAR LIMIT=128] -->
-    <plurals name="permission_progress_delete_generic">
-        <item quantity="one">Deleting item&#8230;</item>
-        <item quantity="other">Deleting <xliff:g id="count" example="42">^1</xliff:g> items&#8230;</item>
-    </plurals>
+    <string name="permission_progress_delete_generic"> {count, plural,
+        =1    {Deleting item&#8230;}
+        other {Deleting <xliff:g id="count" example="42">^1</xliff:g> items&#8230;}
+    }</string>
 
     <!-- ========================= END AUTO-GENERATED BY gen_strings.py ========================= -->
 
diff --git a/src/com/android/providers/media/PermissionActivity.java b/src/com/android/providers/media/PermissionActivity.java
index 0bf8f24..5b53e7d 100644
--- a/src/com/android/providers/media/PermissionActivity.java
+++ b/src/com/android/providers/media/PermissionActivity.java
@@ -47,6 +47,7 @@
 import android.graphics.ImageDecoder.Source;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Icon;
+import android.icu.text.MessageFormat;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
@@ -76,11 +77,15 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
+import java.util.Map;
 import java.util.Objects;
 import java.util.function.Predicate;
 import java.util.function.ToIntFunction;
 import java.util.stream.Collectors;
+import src.com.android.providers.media.util.StringUtils;
 
 /**
  * Permission dialog that asks for user confirmation before performing a
@@ -506,11 +511,11 @@
      */
     private @Nullable CharSequence resolveTitleText() {
         final String resName = "permission_" + verb + "_" + data;
-        final int resId = getResources().getIdentifier(resName, "plurals",
+        final int resId = getResources().getIdentifier(resName, "string",
                 getResources().getResourcePackageName(R.string.app_label));
         if (resId != 0) {
             final int count = uris.size();
-            final CharSequence text = getResources().getQuantityText(resId, count);
+            final CharSequence text = StringUtils.getICUFormatString(getResources(), count, resId);
             return TextUtils.expandTemplate(text, label, String.valueOf(count));
         } else {
             // We always need a string to prompt the user with
@@ -524,11 +529,11 @@
      */
     private @Nullable CharSequence resolveProgressMessageText() {
         final String resName = "permission_progress_" + verb + "_" + data;
-        final int resId = getResources().getIdentifier(resName, "plurals",
+        final int resId = getResources().getIdentifier(resName, "string",
                 getResources().getResourcePackageName(R.string.app_label));
         if (resId != 0) {
             final int count = uris.size();
-            final CharSequence text = getResources().getQuantityText(resId, count);
+            final CharSequence text = StringUtils.getICUFormatString(getResources(), count, resId);
             return TextUtils.expandTemplate(text, String.valueOf(count));
         } else {
             // Only some actions have a progress message string; it's okay if
@@ -693,9 +698,11 @@
 
                 final int shownCount = Math.min(visualResults.size(), MAX_THUMBS - 1);
                 final int moreCount = results.size() - shownCount;
-                final CharSequence moreText = TextUtils.expandTemplate(res.getQuantityText(
-                        R.plurals.permission_more_thumb, moreCount), String.valueOf(moreCount));
-
+                final CharSequence moreText =
+                    TextUtils.expandTemplate(
+                        StringUtils.getICUFormatString(
+                            res, moreCount, R.string.permission_more_thumb),
+                        String.valueOf(moreCount));
                 thumbMoreText.setText(moreText);
                 thumbMoreContainer.setVisibility(View.VISIBLE);
                 gradientView.setVisibility(View.VISIBLE);
@@ -733,8 +740,11 @@
 
                 if (list.size() >= MAX_THUMBS && results.size() > list.size()) {
                     final int moreCount = results.size() - list.size();
-                    final CharSequence moreText = TextUtils.expandTemplate(res.getQuantityText(
-                            R.plurals.permission_more_text, moreCount), String.valueOf(moreCount));
+                    final CharSequence moreText =
+                        TextUtils.expandTemplate(
+                            StringUtils.getICUFormatString(
+                                res, moreCount, R.string.permission_more_text),
+                            String.valueOf(moreCount));
                     list.add(moreText);
                     break;
                 }
diff --git a/src/com/android/providers/media/PickerUriResolver.java b/src/com/android/providers/media/PickerUriResolver.java
index 1b4d9fb..d39071d 100644
--- a/src/com/android/providers/media/PickerUriResolver.java
+++ b/src/com/android/providers/media/PickerUriResolver.java
@@ -167,6 +167,11 @@
                 + CloudMediaProviderContract.URI_PATH_MEDIA_INFO);
     }
 
+    public static Uri getAccountInfoUri(String authority) {
+        return Uri.parse("content://" + authority + "/"
+                + CloudMediaProviderContract.URI_PATH_ACCOUNT_INFO);
+    }
+
     public static Uri getAlbumUri(String authority) {
         return Uri.parse("content://" + authority + "/"
                 + CloudMediaProviderContract.URI_PATH_ALBUM);
diff --git a/src/com/android/providers/media/photopicker/PickerDataLayer.java b/src/com/android/providers/media/photopicker/PickerDataLayer.java
index 11d9338..b343c81 100644
--- a/src/com/android/providers/media/photopicker/PickerDataLayer.java
+++ b/src/com/android/providers/media/photopicker/PickerDataLayer.java
@@ -17,8 +17,10 @@
 package com.android.providers.media.photopicker;
 
 import static android.provider.CloudMediaProviderContract.EXTRA_GENERATION;
+import static android.provider.CloudMediaProviderContract.METHOD_GET_ACCOUNT_INFO;
 import static android.provider.CloudMediaProviderContract.MediaColumns;
 import static android.provider.CloudMediaProviderContract.MediaInfo;
+import static com.android.providers.media.PickerUriResolver.getAccountInfoUri;
 import static com.android.providers.media.PickerUriResolver.getAlbumUri;
 import static com.android.providers.media.PickerUriResolver.getMediaUri;
 import static com.android.providers.media.PickerUriResolver.getDeletedMediaUri;
@@ -28,11 +30,13 @@
 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.STRING_DEFAULT;
 
 import android.content.Context;
+import android.content.Intent;
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.database.MergeCursor;
 import android.net.Uri;
 import android.os.Bundle;
+import android.provider.CloudMediaProviderContract;
 import android.provider.CloudMediaProviderContract.AlbumColumns;
 import android.provider.MediaStore;
 import android.util.Log;
@@ -118,6 +122,32 @@
         return mergeCursor;
     }
 
+    public AccountInfo fetchCloudAccountInfo() {
+        final String cloudProvider = mDbFacade.getCloudProvider();
+        if (cloudProvider == null) {
+            return null;
+        }
+
+        try {
+            final Bundle accountBundle = mContext.getContentResolver().call(
+                    getAccountInfoUri(cloudProvider), METHOD_GET_ACCOUNT_INFO, /* arg */ null,
+                    /* extras */ null);
+            final String accountName = accountBundle.getString(
+                    CloudMediaProviderContract.AccountInfo.ACTIVE_ACCOUNT_NAME);
+            final Intent configIntent = (Intent) accountBundle.getParcelable(
+                    CloudMediaProviderContract.AccountInfo.ACCOUNT_CONFIGURATION_INTENT);
+
+            if (accountName == null) {
+                return null;
+            }
+
+            return new AccountInfo(accountName, configIntent);
+        } catch (Exception e) {
+            Log.w(TAG, "Failed to fetch account info from cloud provider: " + cloudProvider, e);
+            return null;
+        }
+    }
+
     private Cursor queryProviderAlbums(String authority, Bundle queryArgs) {
         if (authority == null) {
             // Can happen if there is no cloud provider
@@ -152,4 +182,14 @@
         // Cloud provider has switched since last query, so no longer valid
         return null;
     }
+
+    public static class AccountInfo {
+        public final String accountName;
+        public final Intent accountConfigurationIntent;
+
+        public AccountInfo(String accountName, Intent accountConfigurationIntent) {
+            this.accountName = accountName;
+            this.accountConfigurationIntent = accountConfigurationIntent;
+        }
+    }
 }
diff --git a/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java b/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java
index 9533b48..67fed45 100644
--- a/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java
+++ b/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java
@@ -17,6 +17,7 @@
 package com.android.providers.media.photopicker.ui;
 
 import android.content.Context;
+import android.icu.text.MessageFormat;
 import android.text.TextUtils;
 import android.view.View;
 import android.view.ViewGroup;
@@ -29,7 +30,10 @@
 import com.android.providers.media.photopicker.data.model.Category;
 
 import java.text.NumberFormat;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
+import src.com.android.providers.media.util.StringUtils;
 
 /**
  * ViewHolder of a album item within a RecyclerView.
@@ -66,9 +70,9 @@
         } else {
             mItemCount.setVisibility(View.VISIBLE);
             final int itemCount = category.getItemCount();
-            final String quantityText = itemView.getResources().getQuantityString(
-                    R.plurals.picker_album_item_count, itemCount);
-
+            final String quantityText =
+                    StringUtils.getICUFormatString(
+                        itemView.getResources(), itemCount, R.string.picker_album_item_count);
             final String itemCountString = NumberFormat.getInstance(Locale.getDefault()).format(
                     itemCount);
             mItemCount.setText(TextUtils.expandTemplate(quantityText, itemCountString));
diff --git a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
index 51e3052..de45fe9 100644
--- a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
@@ -17,6 +17,7 @@
 
 import static com.android.providers.media.photopicker.ui.PhotosTabAdapter.COLUMN_COUNT;
 
+import android.icu.text.MessageFormat;
 import android.os.Bundle;
 import android.text.TextUtils;
 import android.view.View;
@@ -39,7 +40,10 @@
 import com.google.android.material.snackbar.Snackbar;
 
 import java.text.NumberFormat;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
+import src.com.android.providers.media.util.StringUtils;
 
 /**
  * Photos tab fragment for showing the photos
@@ -146,11 +150,12 @@
                 if (!mSelection.isSelectionAllowed()) {
                     final int maxCount = mSelection.getMaxSelectionLimit();
                     final CharSequence quantityText =
-                            getResources().getQuantityString(R.plurals.select_up_to, maxCount);
+                        StringUtils.getICUFormatString(
+                            getResources(), maxCount, R.string.select_up_to);
                     final String itemCountString = NumberFormat.getInstance(Locale.getDefault())
-                            .format(maxCount);
+                        .format(maxCount);
                     final CharSequence message = TextUtils.expandTemplate(quantityText,
-                            itemCountString);
+                        itemCountString);
                     Snackbar.make(view, message, Snackbar.LENGTH_SHORT).show();
                     return;
                 } else {
diff --git a/src/com/android/providers/media/util/StringUtils.java b/src/com/android/providers/media/util/StringUtils.java
new file mode 100644
index 0000000..f73a58a
--- /dev/null
+++ b/src/com/android/providers/media/util/StringUtils.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package src.com.android.providers.media.util;
+
+import android.icu.text.MessageFormat;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import android.content.res.Resources;
+
+public class StringUtils {
+
+  /**
+   * Returns the formatted ICU format string corresponding to the provided resource ID and count
+   * number of entities in the plural string.
+   */
+  public static String getICUFormatString(Resources resources, int count, int resourceID) {
+    MessageFormat msgFormat = new MessageFormat(
+        resources.getString(resourceID),
+        Locale.getDefault());
+    Map<String, Object> arguments = new HashMap<>();
+    arguments.put("count", count);
+    return msgFormat.format(arguments);
+  }
+}
diff --git a/tests/src/com/android/providers/media/PickerProviderMediaGenerator.java b/tests/src/com/android/providers/media/PickerProviderMediaGenerator.java
index 60fedab..909f28c 100644
--- a/tests/src/com/android/providers/media/PickerProviderMediaGenerator.java
+++ b/tests/src/com/android/providers/media/PickerProviderMediaGenerator.java
@@ -16,13 +16,16 @@
 
 package com.android.providers.media;
 
+import static android.provider.CloudMediaProviderContract.AccountInfo;
 import static android.provider.CloudMediaProviderContract.AlbumColumns;
 import static android.provider.CloudMediaProviderContract.MediaColumns;
 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LONG_DEFAULT;
 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.STRING_DEFAULT;
 
+import android.content.Intent;
 import android.database.Cursor;
 import android.database.MatrixCursor;
+import android.os.Bundle;
 import android.os.SystemClock;
 import android.provider.CloudMediaProvider;
 
@@ -73,6 +76,8 @@
         private final List<TestAlbum> mAlbums = new ArrayList<>();
         private String mVersion;
         private long mGeneration;
+        private String mAccountName;
+        private Intent mAccountConfigurationIntent;
 
         public Cursor getMedia(long generation, String albumdId, String mimeType, long sizeBytes) {
             return getCursor(mMedia, generation, albumdId, mimeType, sizeBytes,
@@ -89,6 +94,20 @@
                     /* isDeleted */ true);
         }
 
+        public Bundle getAccountInfo() {
+            Bundle bundle = new Bundle();
+            bundle.putString(AccountInfo.ACTIVE_ACCOUNT_NAME, mAccountName);
+            bundle.putParcelable(AccountInfo.ACCOUNT_CONFIGURATION_INTENT,
+                    mAccountConfigurationIntent);
+
+            return bundle;
+        }
+
+        public void setAccountInfo(String accountName, Intent configIntent) {
+            mAccountName = accountName;
+            mAccountConfigurationIntent = configIntent;
+        }
+
         public void addMedia(String localId, String cloudId) {
             mDeletedMedia.remove(createPlaceholderMedia(localId, cloudId));
             mMedia.add(0, createTestMedia(localId, cloudId));
diff --git a/tests/src/com/android/providers/media/cloudproviders/CloudProviderPrimary.java b/tests/src/com/android/providers/media/cloudproviders/CloudProviderPrimary.java
index 93ff18a..7d661e1 100644
--- a/tests/src/com/android/providers/media/cloudproviders/CloudProviderPrimary.java
+++ b/tests/src/com/android/providers/media/cloudproviders/CloudProviderPrimary.java
@@ -101,4 +101,9 @@
 
         return bundle;
     }
+
+    @Override
+    public Bundle onGetAccountInfo(Bundle extras) {
+        return mMediaGenerator.getAccountInfo();
+    }
 }
diff --git a/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java b/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java
index b003c70..a0e69fc 100644
--- a/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java
+++ b/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java
@@ -29,6 +29,7 @@
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import android.content.Context;
+import android.content.Intent;
 import android.database.Cursor;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -518,6 +519,29 @@
         }
     }
 
+    @Test
+    public void testFetchCloudAccountInfo() {
+        // Cloud provider is not set so cloud account info is null
+        assertThat(mDataLayer.fetchCloudAccountInfo()).isNull();
+
+        // Set cloud provider
+        mFacade.setCloudProvider(CLOUD_PRIMARY_PROVIDER_AUTHORITY);
+
+        // Still null since cloud provider doesn't return account info yet
+        assertThat(mDataLayer.fetchCloudAccountInfo()).isNull();
+
+        // Fake cloud provider cloud account info
+        final String expectedName = "bar";
+        final Intent expectedIntent = new Intent("foo");
+        mCloudPrimaryMediaGenerator.setAccountInfo(expectedName, expectedIntent);
+
+        // Verify account info
+        final PickerDataLayer.AccountInfo info = mDataLayer.fetchCloudAccountInfo();
+        assertThat(info).isNotNull();
+        assertThat(info.accountName).isEqualTo(expectedName);
+        assertThat(info.accountConfigurationIntent).isEqualTo(expectedIntent);
+    }
+
     private static void waitForIdle() {
         final CountDownLatch latch = new CountDownLatch(1);
         BackgroundThread.getExecutor().execute(() -> {
diff --git a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java
index bb97c4d..14a4881 100644
--- a/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java
+++ b/tests/src/com/android/providers/media/photopicker/espresso/PhotoPickerBaseTest.java
@@ -176,9 +176,9 @@
         // Create files and change dateModified so that we can predict the recyclerView item
         // position. Set modified date ahead of time, so that even if other files are created,
         // the below files always have positions 1, 2 and 3.
-        createFile(IMAGE_1_FILE, timeNow + 3000);
-        createFile(IMAGE_2_FILE, timeNow + 2000);
-        createFile(VIDEO_FILE, timeNow + 1000);
+        createFile(IMAGE_1_FILE, timeNow + 30000);
+        createFile(IMAGE_2_FILE, timeNow + 20000);
+        createFile(VIDEO_FILE, timeNow + 10000);
     }
 
     private static void pollForCondition(Supplier<Boolean> condition, String errorMessage)