Refactor album names out of Category class

Category had a lot of assumptions about local-only items. With
cloud-only and merged local and cloud albums, these assumptions break
down. Made the following changes:

1. Removed the 'category type' concept and replaced it with 'category
id' synonymous with 'album_id' received from cloud providers.
2. Plumbed the 'album authority' from the MediaProvider (queryAlbums)
to the UI and back to the MediaProvider (queryMedia for albums)
3. Removed some redundant code especially from the Category class to
keep it simpler

Test: presubmit
Bug: 202139341
Change-Id: I50af917a79a0b11b671d9f5ad3f1c1e739aef380
Merged-In: I50af917a79a0b11b671d9f5ad3f1c1e739aef380
diff --git a/apex/framework/java/android/provider/CloudMediaProviderContract.java b/apex/framework/java/android/provider/CloudMediaProviderContract.java
index 4eff3ac..bc19561 100644
--- a/apex/framework/java/android/provider/CloudMediaProviderContract.java
+++ b/apex/framework/java/android/provider/CloudMediaProviderContract.java
@@ -208,6 +208,25 @@
          * @hide
          */
         public static final String DATA = "data";
+
+        /**
+         * Array of all {@link MediaColumn} fields.
+         *
+         * @hide
+         */
+        public static final String[] ALL_PROJECTION = new String[] {
+            ID,
+            DATE_TAKEN_MILLIS,
+            SYNC_GENERATION,
+            MIME_TYPE,
+            STANDARD_MIME_TYPE_EXTENSION,
+            SIZE_BYTES,
+            MEDIA_STORE_URI,
+            DURATION_MILLIS,
+            IS_FAVORITE,
+            DATA,
+            AUTHORITY,
+        };
     }
 
     /** Constants related to an album item, including {@link Cursor} column names */
@@ -272,42 +291,73 @@
         public static final String MEDIA_COUNT = "album_media_count";
 
         /**
-         * Type of album: {@link #TYPE_LOCAL}, {@link TYPE_CLOUD}, {@link TYPE_FAVORITES},
-         * {@link TYPE_UNRELIABLE_VOLUME}
+         * Authority of the album item
          * <p>
          * Type: STRING
          *
          * @hide
          */
-        public static final String TYPE = "type";
+        public static final String AUTHORITY = "authority";
 
         /**
-         * Constant representing a type of album from a local provider except favorites
+         * Whether the album item was generated locally
+         * <p>
+         * Type: STRING
          *
          * @hide
          */
-        public static final String TYPE_LOCAL = "LOCAL";
+        public static final String IS_LOCAL = "is_local";
 
         /**
-         * Constant representing a type of album from a cloud provider
+         * Array of all {@link AlbumColumn} fields.
          *
          * @hide
          */
-        public static final String TYPE_CLOUD = null;
+        public static final String[] ALL_PROJECTION = new String[] {
+            ID,
+            DATE_TAKEN_MILLIS,
+            DISPLAY_NAME,
+            MEDIA_COVER_ID,
+            MEDIA_COUNT,
+            AUTHORITY,
+        };
 
         /**
-         * Constant representing a type of album from merged favorites of a local and cloud provider
+         * Includes local media present in any directory containing
+         * {@link Environment#DIRECTORY_SCREENSHOTS} in relative path
          *
          * @hide
          */
-        public static final String TYPE_FAVORITES = "FAVORITES";
+        public static final String ALBUM_ID_SCREENSHOTS = "Screenshots";
 
         /**
-         * Constant representing a type of album from an unreliable volume
+         * Includes local images/videos that are present in the
+         * {@link Environment#DIRECTORY_DCIM}/Camera directory.
          *
          * @hide
          */
-        public static final String TYPE_UNRELIABLE_VOLUME = "UNRELIABLE_VOLUME";
+        public static final String ALBUM_ID_CAMERA = "Camera";
+
+        /**
+         * Includes local and cloud videos only.
+         *
+         * @hide
+         */
+        public static final String ALBUM_ID_VIDEOS = "Videos";
+
+        /**
+         * Includes local images/videos that have {@link MediaStore.MediaColumns#IS_DOWNLOAD} set.
+         *
+         * @hide
+         */
+        public static final String ALBUM_ID_DOWNLOADS = "Downloads";
+
+        /**
+         * Includes local and cloud images/videos that have been favorited by the user.
+         *
+         * @hide
+         */
+        public static final String ALBUM_ID_FAVORITES = "Favorites";
     }
 
     /** Constants related to a media collection */
diff --git a/apex/framework/java/android/provider/MediaStore.java b/apex/framework/java/android/provider/MediaStore.java
index 61022df..47ef4ec 100644
--- a/apex/framework/java/android/provider/MediaStore.java
+++ b/apex/framework/java/android/provider/MediaStore.java
@@ -269,7 +269,7 @@
     /** {@hide} */
     public static final String QUERY_ARG_ALBUM_ID = "android:query-arg-album_id";
     /** {@hide} */
-    public static final String QUERY_ARG_ALBUM_TYPE = "android:query-arg-album_type";
+    public static final String QUERY_ARG_ALBUM_AUTHORITY = "android:query-arg-album_authority";
 
     /**
      * This is for internal use by the media scanner only.
diff --git a/src/com/android/providers/media/photopicker/PickerDataLayer.java b/src/com/android/providers/media/photopicker/PickerDataLayer.java
index 2b3ee00..5eaf634 100644
--- a/src/com/android/providers/media/photopicker/PickerDataLayer.java
+++ b/src/com/android/providers/media/photopicker/PickerDataLayer.java
@@ -67,24 +67,25 @@
 
     public Cursor fetchMedia(Bundle queryArgs) {
         final CloudProviderQueryExtras queryExtras
-                = CloudProviderQueryExtras.fromMediaStoreBundle(queryArgs);
+                = CloudProviderQueryExtras.fromMediaStoreBundle(queryArgs, mLocalProvider);
         final String albumId = queryExtras.getAlbumId();
+        final String authority = queryExtras.getAlbumAuthority();
+        final boolean isFavorite = queryExtras.isFavorite();
 
-        if (TextUtils.isEmpty(albumId)) {
+        if (TextUtils.isEmpty(albumId) || isFavorite) {
             // Refresh the 'media' table
             mSyncController.syncAllMedia();
 
             // Fetch all merged and deduped cloud and local media from 'media' table
+            // This also matches 'merged' albums like Favorites because |authority| will
+            // be null, hence we have to fetch the data from the picker db
             return mDbFacade.queryMediaForUi(queryExtras.toQueryFilter());
         } else {
             // The album type here can only be local or cloud because other album types
-            // like Favorites don't have albumIds hence would hit the first condition
-            final boolean isLocal = AlbumColumns.TYPE_LOCAL.equals(queryExtras.getAlbumType());
-            final String authority = isLocal ? mDbFacade.getLocalProvider()
-                    : queryExtras.getCloudProvider();
+            // like Favorites don't have album authorities hence would hit the first condition
 
             // Refresh the 'album_media' table
-            mSyncController.syncAlbumMedia(albumId, isLocal);
+            mSyncController.syncAlbumMedia(albumId, isLocal(authority));
 
             // Fetch album specific media for local or cloud from 'album_media' table
             return mDbFacade.queryAlbumMediaForUi(queryExtras.toQueryFilter(), authority);
@@ -97,7 +98,7 @@
 
         final String cloudProvider = mDbFacade.getCloudProvider();
         final CloudProviderQueryExtras queryExtras
-                = CloudProviderQueryExtras.fromMediaStoreBundle(queryArgs);
+                = CloudProviderQueryExtras.fromMediaStoreBundle(queryArgs, mLocalProvider);
         final Bundle cloudMediaArgs = queryExtras.toCloudMediaBundle();
         final List<Cursor> cursors = new ArrayList<>();
         final Bundle cursorExtra = new Bundle();
@@ -169,6 +170,10 @@
                 /* cancellationSignal */ null);
     }
 
+    private boolean isLocal(String authority) {
+        return mLocalProvider.equals(authority);
+    }
+
     public static class AccountInfo {
         public final String accountName;
         public final Intent accountConfigurationIntent;
diff --git a/src/com/android/providers/media/photopicker/data/CloudProviderQueryExtras.java b/src/com/android/providers/media/photopicker/data/CloudProviderQueryExtras.java
index 800b9e1..8ad5343 100644
--- a/src/com/android/providers/media/photopicker/data/CloudProviderQueryExtras.java
+++ b/src/com/android/providers/media/photopicker/data/CloudProviderQueryExtras.java
@@ -30,9 +30,8 @@
  */
 public class CloudProviderQueryExtras {
     private final String mAlbumId;
-    private final String mAlbumType;
+    private final String mAlbumAuthority;
     private final String mMimeType;
-    private final String mCloudProvider;
     private final long mSizeBytes;
     private final long mGeneration;
     private final int mLimit;
@@ -40,45 +39,44 @@
 
     private CloudProviderQueryExtras() {
         mAlbumId = STRING_DEFAULT;
-        mAlbumType = STRING_DEFAULT;
+        mAlbumAuthority = STRING_DEFAULT;
         mMimeType = STRING_DEFAULT;
-        mCloudProvider = STRING_DEFAULT;
         mSizeBytes = LONG_DEFAULT;
         mGeneration = LONG_DEFAULT;
         mLimit = LIMIT_DEFAULT;
         mIsFavorite = BOOLEAN_DEFAULT;
     }
 
-    private CloudProviderQueryExtras (String albumId, String albumType, String mimeType,
-            String cloudProvider, long sizeBytes, long generation, int limit, boolean isFavorite) {
+    private CloudProviderQueryExtras (String albumId, String albumAuthority, String mimeType,
+            long sizeBytes, long generation, int limit, boolean isFavorite) {
         mAlbumId = albumId;
-        mAlbumType = albumType;
+        mAlbumAuthority = albumAuthority;
         mMimeType = mimeType;
-        mCloudProvider = cloudProvider;
         mSizeBytes = sizeBytes;
         mGeneration = generation;
         mLimit = limit;
         mIsFavorite = isFavorite;
     }
 
-    public static CloudProviderQueryExtras fromMediaStoreBundle(Bundle bundle) {
+    public static CloudProviderQueryExtras fromMediaStoreBundle(Bundle bundle,
+            String localProvider) {
         if (bundle == null) {
             return new CloudProviderQueryExtras();
         }
 
         final String albumId = bundle.getString(MediaStore.QUERY_ARG_ALBUM_ID, STRING_DEFAULT);
-        final String albumType = bundle.getString(MediaStore.QUERY_ARG_ALBUM_TYPE, STRING_DEFAULT);
-        final String mimeType = bundle.getString(MediaStore.QUERY_ARG_MIME_TYPE, STRING_DEFAULT);
-        final String cloudProvider = bundle.getString(MediaStore.EXTRA_CLOUD_PROVIDER,
+        final String albumAuthority = bundle.getString(MediaStore.QUERY_ARG_ALBUM_AUTHORITY,
                 STRING_DEFAULT);
+        final String mimeType = bundle.getString(MediaStore.QUERY_ARG_MIME_TYPE, STRING_DEFAULT);
 
         final long sizeBytes = bundle.getLong(MediaStore.QUERY_ARG_SIZE_BYTES, LONG_DEFAULT);
         final long generation = LONG_DEFAULT;
         final int limit = bundle.getInt(MediaStore.QUERY_ARG_LIMIT, LIMIT_DEFAULT);
 
-        final boolean isFavorite = AlbumColumns.TYPE_FAVORITES.equals(albumType);
+        final boolean isFavorite = localProvider.equals(albumAuthority)
+                && AlbumColumns.ALBUM_ID_FAVORITES.equals(albumId);
 
-        return new CloudProviderQueryExtras(albumId, albumType, mimeType, cloudProvider, sizeBytes,
+        return new CloudProviderQueryExtras(albumId, albumAuthority, mimeType, sizeBytes,
                 generation, limit, isFavorite);
     }
 
@@ -89,11 +87,9 @@
 
         final String albumId = bundle.getString(CloudMediaProviderContract.EXTRA_ALBUM_ID,
                 STRING_DEFAULT);
-        final String albumType = STRING_DEFAULT;
+        final String albumAuthority = STRING_DEFAULT;
         final String mimeType = bundle.getString(CloudMediaProviderContract.EXTRA_MIME_TYPE,
                 STRING_DEFAULT);
-        final String cloudProvider = STRING_DEFAULT;
-
         final long sizeBytes = bundle.getLong(CloudMediaProviderContract.EXTRA_SIZE_LIMIT_BYTES,
                 LONG_DEFAULT);
         final long generation = bundle.getLong(CloudMediaProviderContract.EXTRA_SYNC_GENERATION,
@@ -102,7 +98,7 @@
 
         final boolean isFavorite = BOOLEAN_DEFAULT;
 
-        return new CloudProviderQueryExtras(albumId, albumType, mimeType, cloudProvider, sizeBytes,
+        return new CloudProviderQueryExtras(albumId, albumAuthority, mimeType, sizeBytes,
                 generation, limit, isFavorite);
     }
 
@@ -128,18 +124,14 @@
         return mAlbumId;
     }
 
-    public String getAlbumType() {
-        return mAlbumType;
+    public String getAlbumAuthority() {
+        return mAlbumAuthority;
     }
 
     public String getMimeType() {
         return mMimeType;
     }
 
-    public String getCloudProvider() {
-        return mCloudProvider;
-    }
-
     public long getSizeBytes() {
         return mSizeBytes;
     }
@@ -147,4 +139,8 @@
     public long getGeneration() {
         return mGeneration;
     }
+
+    public boolean isFavorite() {
+        return mIsFavorite;
+    }
 }
diff --git a/src/com/android/providers/media/photopicker/data/ExternalDbFacade.java b/src/com/android/providers/media/photopicker/data/ExternalDbFacade.java
index d985f01..b30fced 100644
--- a/src/com/android/providers/media/photopicker/data/ExternalDbFacade.java
+++ b/src/com/android/providers/media/photopicker/data/ExternalDbFacade.java
@@ -16,6 +16,11 @@
 
 package com.android.providers.media.photopicker.data;
 
+import static android.provider.CloudMediaProviderContract.AlbumColumns;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_VIDEOS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_SCREENSHOTS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_CAMERA;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_DOWNLOADS;
 import static android.provider.CloudMediaProviderContract.MediaCollectionInfo;
 import static com.android.providers.media.photopicker.util.CursorUtils.getCursorLong;
 import static com.android.providers.media.photopicker.util.CursorUtils.getCursorString;
@@ -38,7 +43,8 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.providers.media.DatabaseHelper;
-import com.android.providers.media.photopicker.data.model.Category;
+import com.android.providers.media.R;
+import com.android.providers.media.photopicker.PickerSyncController;
 import com.android.providers.media.util.MimeUtils;
 
 import java.util.ArrayList;
@@ -86,15 +92,6 @@
         MediaColumns._ID + " AS " + CloudMediaProviderContract.AlbumColumns.MEDIA_COVER_ID,
     };
 
-    private static final String[] PROJECTION_ALBUM_CURSOR = new String[] {
-            CloudMediaProviderContract.AlbumColumns.ID,
-            CloudMediaProviderContract.AlbumColumns.DATE_TAKEN_MILLIS,
-            CloudMediaProviderContract.AlbumColumns.DISPLAY_NAME,
-            CloudMediaProviderContract.AlbumColumns.MEDIA_COUNT,
-            CloudMediaProviderContract.AlbumColumns.MEDIA_COVER_ID,
-            CloudMediaProviderContract.AlbumColumns.TYPE,
-    };
-
     private static final String WHERE_IMAGE_TYPE = FileColumns.MEDIA_TYPE + " = "
             + FileColumns.MEDIA_TYPE_IMAGE;
     private static final String WHERE_VIDEO_TYPE = FileColumns.MEDIA_TYPE + " = "
@@ -117,6 +114,14 @@
 
     public static final String RELATIVE_PATH_CAMERA = Environment.DIRECTORY_DCIM + "/Camera/%";
 
+    @VisibleForTesting
+    static String[] LOCAL_ALBUM_IDS = {
+        ALBUM_ID_CAMERA,
+        ALBUM_ID_VIDEOS,
+        ALBUM_ID_SCREENSHOTS,
+        ALBUM_ID_DOWNLOADS
+    };
+
     private final DatabaseHelper mDatabaseHelper;
     private final Context mContext;
 
@@ -330,22 +335,17 @@
 
     /**
      * Returns the media item categories from the files table.
-     * Categories are determined with the {@link Category#CATEGORIES_LIST}.
-     * If there are no media items under a category, the category is skipped from the results.
+     * Categories are determined with the {@link #LOCAL_ALBUM_IDS}.
+     * If there are no media items under an albumId, the album is skipped from the results.
      */
     public Cursor queryAlbums(String mimeType) {
-        final MatrixCursor c = new MatrixCursor(PROJECTION_ALBUM_CURSOR);
+        final MatrixCursor c = new MatrixCursor(AlbumColumns.ALL_PROJECTION);
 
-        for (String category: Category.CATEGORIES_LIST) {
-            if (Category.CATEGORY_FAVORITES.equals(category)) {
-                // TODO(b/196071169): Remove after removing favorites from CATEGORIES_LIST
-                continue;
-            }
-
+        for (String albumId: LOCAL_ALBUM_IDS) {
             Cursor cursor = mDatabaseHelper.runWithTransaction(db -> {
                 final SQLiteQueryBuilder qb = createMediaQueryBuilder();
                 final List<String> selectionArgs = new ArrayList<>();
-                selectionArgs.addAll(appendWhere(qb, category, mimeType));
+                selectionArgs.addAll(appendWhere(qb, albumId, mimeType));
 
                 return qb.query(db, PROJECTION_ALBUM_DB, /* selection */ null,
                         selectionArgs.toArray(new String[selectionArgs.size()]), /* groupBy */ null,
@@ -362,12 +362,12 @@
             }
 
             final String[] projectionValue = new String[] {
-                category,
-                getCursorString(cursor, CloudMediaProviderContract.AlbumColumns.DATE_TAKEN_MILLIS),
-                Category.getCategoryName(mContext, category),
+                /* albumId */ albumId,
+                getCursorString(cursor, AlbumColumns.DATE_TAKEN_MILLIS),
+                /* displayName */ albumId,
+                getCursorString(cursor, AlbumColumns.MEDIA_COVER_ID),
                 String.valueOf(count),
-                getCursorString(cursor, CloudMediaProviderContract.AlbumColumns.MEDIA_COVER_ID),
-                CloudMediaProviderContract.AlbumColumns.TYPE_LOCAL
+                PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY
             };
 
             c.addRow(projectionValue);
@@ -376,11 +376,11 @@
         return c;
     }
 
-        private static Cursor query(SQLiteQueryBuilder qb, SQLiteDatabase db, String[] projection,
-                String[] selectionArgs) {
-            return qb.query(db, PROJECTION_MEDIA_INFO, /* select */ null, selectionArgs,
-                    /* groupBy */ null, /* having */ null, /* orderBy */ null);
-        }
+    private static Cursor query(SQLiteQueryBuilder qb, SQLiteDatabase db, String[] projection,
+            String[] selectionArgs) {
+        return qb.query(db, projection, /* select */ null, selectionArgs,
+                /* groupBy */ null, /* having */ null, /* orderBy */ null);
+    }
 
     private static List<String> appendWhere(SQLiteQueryBuilder qb, String albumId,
             String mimeType) {
@@ -396,18 +396,18 @@
         }
 
         switch (albumId) {
-            case Category.CATEGORY_VIDEOS:
+            case ALBUM_ID_VIDEOS:
                 qb.appendWhereStandalone(WHERE_VIDEO_TYPE);
                 break;
-            case Category.CATEGORY_CAMERA:
+            case ALBUM_ID_CAMERA:
                 qb.appendWhereStandalone(WHERE_RELATIVE_PATH);
                 selectionArgs.add(RELATIVE_PATH_CAMERA);
                 break;
-            case Category.CATEGORY_SCREENSHOTS:
+            case ALBUM_ID_SCREENSHOTS:
                 qb.appendWhereStandalone(WHERE_RELATIVE_PATH);
                 selectionArgs.add(RELATIVE_PATH_SCREENSHOTS);
                 break;
-            case Category.CATEGORY_DOWNLOADS:
+            case ALBUM_ID_DOWNLOADS:
                 qb.appendWhereStandalone(WHERE_IS_DOWNLOAD);
                 break;
             default:
diff --git a/src/com/android/providers/media/photopicker/data/ItemsProvider.java b/src/com/android/providers/media/photopicker/data/ItemsProvider.java
index 5112403..fb32872 100644
--- a/src/com/android/providers/media/photopicker/data/ItemsProvider.java
+++ b/src/com/android/providers/media/photopicker/data/ItemsProvider.java
@@ -16,6 +16,8 @@
 
 package com.android.providers.media.photopicker.data;
 
+import static com.android.providers.media.photopicker.util.CursorUtils.getCursorString;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentProvider;
@@ -28,6 +30,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.provider.CloudMediaProviderContract;
 import android.provider.CloudMediaProviderContract.AlbumColumns;
 import android.provider.MediaStore;
 import android.text.TextUtils;
@@ -35,9 +38,8 @@
 
 import com.android.modules.utils.build.SdkLevel;
 import com.android.providers.media.PickerUriResolver;
+import com.android.providers.media.photopicker.data.PickerDbFacade;
 import com.android.providers.media.photopicker.data.model.Category;
-import com.android.providers.media.photopicker.data.model.Category.CategoryColumns;
-import com.android.providers.media.photopicker.data.model.Item.ItemColumns;
 import com.android.providers.media.photopicker.data.model.UserId;
 
 /**
@@ -60,9 +62,8 @@
      * <p>
      * By default the returned {@link Cursor} sorts by latest date taken.
      *
-     * @param category the category of items to return, {@link Category.CategoryType} are supported.
-     *                 {@code null} defaults to {@link Category#CATEGORY_DEFAULT} which returns
-     *                 items from all categories.
+     * @param category the category of items to return. May be cloud, local or merged albums like
+     * favorites or videos.
      * @param offset the offset after which to return items.
      * @param limit the limit of number of items to return.
      * @param mimeType the mime type of item. {@code null} returns all images/videos that are
@@ -73,22 +74,14 @@
      * @return {@link Cursor} to images/videos on external storage that are scanned by
      * {@link MediaStore}. The returned cursor is filtered based on params passed, it {@code null}
      * if there are no such images/videos. The Cursor for each item contains {@link ItemColumns}
-     *
-     * @throws IllegalArgumentException thrown if unsupported values for {@code category} is passed.
-     *
      */
     @Nullable
-    public Cursor getItems(@Nullable @Category.CategoryType String category, int offset,
+    public Cursor getItems(Category category, int offset,
             int limit, @Nullable String mimeType, @Nullable UserId userId) throws
             IllegalArgumentException {
         if (userId == null) {
             userId = UserId.CURRENT_USER;
         }
-        // Validate incoming params
-        if (category != null && !Category.isValidCategory(category)) {
-            throw new IllegalArgumentException("ItemsProvider does not support the given "
-                    + "category: " + category);
-        }
 
         return queryMedia(limit, mimeType, category, userId);
     }
@@ -123,7 +116,7 @@
     }
 
     private Cursor queryMedia(int limit, @Nullable String mimeType,
-            @NonNull String category, @NonNull UserId userId)
+            @NonNull Category category, @NonNull UserId userId)
             throws IllegalStateException {
         final Bundle extras = new Bundle();
         try (ContentProviderClient client = userId.getContentResolver(mContext)
@@ -135,14 +128,8 @@
             }
             extras.putInt(MediaStore.QUERY_ARG_LIMIT, limit);
             extras.putString(MediaStore.QUERY_ARG_MIME_TYPE, mimeType);
-            if (category != null) {
-                if (!Category.CATEGORY_FAVORITES.equals(category)) {
-                    extras.putString(MediaStore.QUERY_ARG_ALBUM_ID, category);
-                }
-                extras.putString(MediaStore.QUERY_ARG_ALBUM_TYPE,
-                        Category.CATEGORY_FAVORITES.equals(category)
-                        ? AlbumColumns.TYPE_FAVORITES : AlbumColumns.TYPE_LOCAL);
-            }
+            extras.putString(MediaStore.QUERY_ARG_ALBUM_ID, category.getId());
+            extras.putString(MediaStore.QUERY_ARG_ALBUM_AUTHORITY, category.getAuthority());
 
             final Uri uri = PickerUriResolver.PICKER_INTERNAL_URI.buildUpon()
                     .appendPath(PickerUriResolver.MEDIA_PATH).build();
@@ -181,15 +168,8 @@
     }
 
     public static Uri getItemsUri(String id, String authority, UserId userId) {
-        final Uri uri;
-        if (authority == null) {
-            uri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL,
-                    Long.parseLong(id));
-        } else {
-            // We only have authority after querying the picker db
-            uri = PickerUriResolver.getMediaUri(authority).buildUpon()
-                    .appendPath(id).build();
-        }
+        final Uri uri = PickerUriResolver.getMediaUri(authority).buildUpon()
+                .appendPath(id).build();
 
         if (userId.equals(UserId.CURRENT_USER)) {
             return uri;
diff --git a/src/com/android/providers/media/photopicker/data/PickerDbFacade.java b/src/com/android/providers/media/photopicker/data/PickerDbFacade.java
index 5f38522..14bbc3c 100644
--- a/src/com/android/providers/media/photopicker/data/PickerDbFacade.java
+++ b/src/com/android/providers/media/photopicker/data/PickerDbFacade.java
@@ -16,6 +16,8 @@
 
 package com.android.providers.media.photopicker.data;
 
+import static android.provider.CloudMediaProviderContract.AlbumColumns;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_FAVORITES;
 import static android.provider.CloudMediaProviderContract.MediaColumns;
 import static android.provider.MediaStore.PickerMediaColumns;
 import static com.android.providers.media.PickerUriResolver.getMediaUri;
@@ -44,7 +46,6 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.providers.media.photopicker.PickerSyncController;
-import com.android.providers.media.photopicker.data.model.Category;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -142,15 +143,6 @@
                     KEY_DATE_TAKEN_MS, KEY_DATE_TAKEN_MS, KEY_ID);
     private static final String WHERE_ALBUM_ID = KEY_ALBUM_ID  + " = ?";
 
-    private static final String[] PROJECTION_ALBUM_CURSOR = new String[] {
-        CloudMediaProviderContract.AlbumColumns.ID,
-        CloudMediaProviderContract.AlbumColumns.DATE_TAKEN_MILLIS,
-        CloudMediaProviderContract.AlbumColumns.DISPLAY_NAME,
-        CloudMediaProviderContract.AlbumColumns.MEDIA_COUNT,
-        CloudMediaProviderContract.AlbumColumns.MEDIA_COVER_ID,
-        CloudMediaProviderContract.AlbumColumns.TYPE
-    };
-
     private static final String[] PROJECTION_ALBUM_DB = new String[] {
         "COUNT(" + KEY_ID + ") AS " + CloudMediaProviderContract.AlbumColumns.MEDIA_COUNT,
         "MAX(" + KEY_DATE_TAKEN_MS + ") AS "
@@ -738,14 +730,14 @@
             return null;
         }
 
-        final MatrixCursor c = new MatrixCursor(PROJECTION_ALBUM_CURSOR);
+        final MatrixCursor c = new MatrixCursor(AlbumColumns.ALL_PROJECTION);
         final String[] projectionValue = new String[] {
-            Category.CATEGORY_FAVORITES,
-            getCursorString(cursor, CloudMediaProviderContract.AlbumColumns.DATE_TAKEN_MILLIS),
-            Category.getCategoryName(mContext, Category.CATEGORY_FAVORITES),
+            /* albumId */ ALBUM_ID_FAVORITES,
+            getCursorString(cursor, AlbumColumns.DATE_TAKEN_MILLIS),
+            /* displayName */ ALBUM_ID_FAVORITES,
+            getCursorString(cursor, AlbumColumns.MEDIA_COVER_ID),
             String.valueOf(count),
-            getCursorString(cursor, CloudMediaProviderContract.AlbumColumns.MEDIA_COVER_ID),
-            CloudMediaProviderContract.AlbumColumns.TYPE_FAVORITES
+            mLocalProvider,
         };
         c.addRow(projectionValue);
         return c;
@@ -996,17 +988,9 @@
             selectArgs.add(replaceMatchAnyChar(query.mimeType));
         }
 
-        if (query.isFavorite && !TextUtils.isEmpty(query.albumId)) {
-            throw new IllegalStateException(
-                    "If albumId is present, the media cannot be marked as isFavorite as it "
-                            + "represents media for another album.");
-        }
-
         if (query.isFavorite) {
             qb.appendWhereStandalone(WHERE_IS_FAVORITE);
-        }
-
-        if(!TextUtils.isEmpty(query.albumId)) {
+        } else if (!TextUtils.isEmpty(query.albumId)) {
             qb.appendWhereStandalone(WHERE_ALBUM_ID);
             selectArgs.add(query.albumId);
         }
@@ -1133,5 +1117,4 @@
             return counter;
         }
     }
-
 }
diff --git a/src/com/android/providers/media/photopicker/data/model/Category.java b/src/com/android/providers/media/photopicker/data/model/Category.java
index 473aad7..6166d4a 100644
--- a/src/com/android/providers/media/photopicker/data/model/Category.java
+++ b/src/com/android/providers/media/photopicker/data/model/Category.java
@@ -16,6 +16,12 @@
 
 package com.android.providers.media.photopicker.data.model;
 
+import static android.provider.CloudMediaProviderContract.AlbumColumns;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_VIDEOS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_SCREENSHOTS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_CAMERA;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_DOWNLOADS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_FAVORITES;
 import static com.android.providers.media.photopicker.util.CursorUtils.getCursorInt;
 import static com.android.providers.media.photopicker.util.CursorUtils.getCursorString;
 
@@ -23,10 +29,12 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.Bundle;
 import android.os.Environment;
 import android.provider.CloudMediaProviderContract;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Files.FileColumns;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 
 import androidx.annotation.NonNull;
@@ -35,188 +43,66 @@
 
 import com.android.providers.media.R;
 import com.android.providers.media.photopicker.data.ItemsProvider;
-import com.android.providers.media.photopicker.data.model.Item.ItemColumns;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Defines each category (which is group of items) for the photo picker.
  */
 public class Category {
+    public static final Category DEFAULT = new Category();
 
-    /**
-     * Photo Picker categorises images/videos into pre-defined buckets based on various criteria
-     * (for example based on file path location items may be in {@link #CATEGORY_SCREENSHOTS} or
-     * {@link #CATEGORY_CAMERA}, based on {@link FileColumns#MEDIA_TYPE}) items may be in
-     * {@link #CATEGORY_VIDEOS}). This list is predefined for v0.
-     *
-     * TODO (b/187919236): Add Downloads/SDCard categories.
-     */
-    @StringDef(prefix = { "CATEGORY_" }, value = {
-            CATEGORY_DEFAULT,
-            CATEGORY_SCREENSHOTS,
-            CATEGORY_CAMERA,
-            CATEGORY_VIDEOS,
-            CATEGORY_FAVORITES,
-            CATEGORY_DOWNLOADS,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CategoryType {}
+    private final String mId;
+    private final String mAuthority;
+    private final String mDisplayName;
+    private final boolean mIsLocal;
+    private final Uri mCoverUri;
+    private final int mItemCount;
 
-    /**
-     * Includes all images/videos on device that are scanned by {@link MediaStore}.
-     */
-    public static final String CATEGORY_DEFAULT = "default";
-
-    /**
-     * Includes media present in any directory containing
-     * {@link Environment#DIRECTORY_SCREENSHOTS} in relative path
-     */
-    public static final String CATEGORY_SCREENSHOTS = "Screenshots";
-    private static final String SCREENSHOTS_WHERE_CLAUSE =
-            "(" + MediaStore.MediaColumns.RELATIVE_PATH + " LIKE '" +
-                    "%/" + Environment.DIRECTORY_SCREENSHOTS + "/%')";
-
-    /**
-     * Includes images/videos that are present in the {@link Environment#DIRECTORY_DCIM}/Camera
-     * directory.
-     */
-    public static final String CATEGORY_CAMERA = "Camera";
-    private static final String CAMERA_WHERE_CLAUSE =
-            "(" + MediaStore.MediaColumns.RELATIVE_PATH + " LIKE '" +
-                    Environment.DIRECTORY_DCIM + "/Camera/%')";
-
-    /**
-     * Includes videos only.
-     */
-    public static final String CATEGORY_VIDEOS = "Videos";
-    private static final String VIDEOS_WHERE_CLAUSE =
-            "(" + MediaStore.Files.FileColumns.MEDIA_TYPE +
-            " = " + MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO + ")";
-
-    /**
-     * Includes images/videos that have {@link MediaStore.MediaColumns#IS_FAVORITE} set.
-     */
-    public static final String CATEGORY_FAVORITES = "Favorites";
-    // TODO (b/188053832): Do not reveal implementation detail for is_favorite,
-    // use MATCH_INCLUDE in queryArgs.
-    private static final String FAVORITES_WHERE_CLAUSE =
-            "(" + MediaStore.MediaColumns.IS_FAVORITE + " =1)";
-
-    /**
-     * Includes images/videos that have {@link MediaStore.MediaColumns#IS_DOWNLOAD} set.
-     */
-    public static final String CATEGORY_DOWNLOADS = "Downloads";
-    private static final String DOWNLOADS_WHERE_CLAUSE =
-            "(" + MediaStore.MediaColumns.IS_DOWNLOAD + " =1)";
-
-    /**
-     * Set of {@link Cursor} columns that refer to raw filesystem paths.
-     */
-    private static final ArrayMap<String, String> sCategoryWhereClause = new ArrayMap<>();
-
-    static {
-        sCategoryWhereClause.put(CATEGORY_SCREENSHOTS, SCREENSHOTS_WHERE_CLAUSE);
-        sCategoryWhereClause.put(CATEGORY_CAMERA, CAMERA_WHERE_CLAUSE);
-        sCategoryWhereClause.put(CATEGORY_VIDEOS, VIDEOS_WHERE_CLAUSE);
-        sCategoryWhereClause.put(CATEGORY_FAVORITES, FAVORITES_WHERE_CLAUSE);
-        sCategoryWhereClause.put(CATEGORY_DOWNLOADS, DOWNLOADS_WHERE_CLAUSE);
+    private Category() {
+        this(null, null, null, null, 0, false);
     }
 
-    public static String getWhereClauseForCategory(@CategoryType String category) {
-        return sCategoryWhereClause.get(category);
-    }
-
-    private static String[] CATEGORIES = {
-            CATEGORY_FAVORITES,
-            CATEGORY_CAMERA,
-            CATEGORY_VIDEOS,
-            CATEGORY_SCREENSHOTS,
-            CATEGORY_DOWNLOADS,
-    };
-
-    public static List<String> CATEGORIES_LIST = Collections.unmodifiableList(
-            Arrays.asList(CATEGORIES));
-
-    public static boolean isValidCategory(String category) {
-        return CATEGORIES_LIST.contains(category);
-    }
-
-    @CategoryType
-    private String mCategoryType;
-    private String mCategoryName;
-    private Uri mCoverUri;
-    private int mItemCount;
-
-    private Category() {}
-
     @VisibleForTesting
-    Category(@NonNull Cursor cursor, @NonNull UserId userId) {
-        updateFromCursor(cursor, userId);
+    public Category(String id, String authority, String displayName, Uri coverUri, int itemCount,
+            boolean isLocal) {
+        mId = id;
+        mAuthority = authority;
+        mDisplayName = displayName;
+        mIsLocal = isLocal;
+        mCoverUri = coverUri;
+        mItemCount = itemCount;
     }
 
-    /**
-     * Defines category columns for each category
-     */
-    public static class CategoryColumns {
-        public static String NAME = CloudMediaProviderContract.AlbumColumns.DISPLAY_NAME;
-        public static String COVER_ID = CloudMediaProviderContract.AlbumColumns.MEDIA_COVER_ID;
-        public static String NUMBER_OF_ITEMS = CloudMediaProviderContract.AlbumColumns.MEDIA_COUNT;
-        public static String CATEGORY_TYPE = CloudMediaProviderContract.AlbumColumns.ID;
+    @Override
+    public String toString() {
+        return String.format(Locale.ROOT, "Category: {mId: %s, mAuthority: %s, mDisplayName: %s, " +
+                "mCoverUri: %s, mItemCount: %d, mIsLocal: %b",
+                mId, mAuthority, mDisplayName, mCoverUri, mItemCount, mIsLocal);
+    }
 
-        public static String[] getAllColumns() {
-            return new String[] {
-                    NAME,
-                    COVER_ID,
-                    NUMBER_OF_ITEMS,
-                    CATEGORY_TYPE,
-            };
+    public String getId() {
+        return mId;
+    }
+
+    public String getAuthority() {
+        return mAuthority;
+    }
+
+    public String getDisplayName(Context context) {
+        if (mIsLocal) {
+            return getLocalizedDisplayName(context, mId);
         }
+        return mDisplayName;
     }
 
-    /**
-     * @return localized category name if {@code context} is not null and {@link #mCategoryType} is
-     * in {@link #CATEGORIES}, {@link #mCategoryName} otherwise.
-     */
-    public String getCategoryName(@Nullable Context context) {
-        if (context != null) {
-            final String categoryName = getCategoryName(context, mCategoryType);
-            if (categoryName != null) {
-                return categoryName;
-            }
-        }
-        return mCategoryName;
-    }
-
-    /**
-     * @return localized category name if {@link #mCategoryType} is in {@link #CATEGORIES},
-     * {@code null} otherwise.
-     */
-    public static String getCategoryName(@NonNull Context context,
-            @NonNull @CategoryType String categoryType) {
-        switch (categoryType) {
-            case CATEGORY_FAVORITES:
-                return context.getString(R.string.picker_category_favorites);
-            case CATEGORY_VIDEOS:
-                return context.getString(R.string.picker_category_videos);
-            case CATEGORY_CAMERA:
-                return context.getString(R.string.picker_category_camera);
-            case CATEGORY_SCREENSHOTS:
-                return context.getString(R.string.picker_category_screenshots);
-            case CATEGORY_DOWNLOADS:
-                return context.getString(R.string.picker_category_downloads);
-            default:
-                return null;
-        }
-    }
-
-    @CategoryType
-    public String getCategoryType() {
-        return mCategoryType;
+    public boolean isLocal() {
+        return mIsLocal;
     }
 
     public Uri getCoverUri() {
@@ -227,37 +113,73 @@
         return mItemCount;
     }
 
-    /**
-     * Get the category instance with the {@link #mCategoryType} is {@link #CATEGORY_DEFAULT}
-     *
-     * @return the default category
-     */
-    public static Category getDefaultCategory() {
-        final Category category = new Category();
-        category.mCategoryType = CATEGORY_DEFAULT;
-        return category;
+    public boolean isDefault() {
+        return TextUtils.isEmpty(mId);
     }
 
     /**
-     * @return {@link Category} from the given {@code cursor}
+     * Write the {@link Category} to the given {@code bundle}.
+     */
+    public void toBundle(@NonNull Bundle bundle) {
+        bundle.putString(AlbumColumns.ID, mId);
+        bundle.putString(AlbumColumns.AUTHORITY, mAuthority);
+        bundle.putString(AlbumColumns.DISPLAY_NAME, mDisplayName);
+        // Re-using the 'media_cover_id' to store the media_cover_uri for lack of
+        // a different constant
+        bundle.putParcelable(AlbumColumns.MEDIA_COVER_ID, mCoverUri);
+        bundle.putInt(AlbumColumns.MEDIA_COUNT, mItemCount);
+        bundle.putBoolean(AlbumColumns.IS_LOCAL, mIsLocal);
+    }
+
+    /**
+     * Create a {@link Category} from the {@code bundle}.
+     */
+    public static Category fromBundle(@NonNull Bundle bundle) {
+        return new Category(bundle.getString(AlbumColumns.ID),
+                bundle.getString(AlbumColumns.AUTHORITY),
+                bundle.getString(AlbumColumns.DISPLAY_NAME),
+                bundle.getParcelable(AlbumColumns.MEDIA_COVER_ID),
+                bundle.getInt(AlbumColumns.MEDIA_COUNT),
+                bundle.getBoolean(AlbumColumns.IS_LOCAL));
+    }
+
+    /**
+     * Create a {@link Category} from the {@code cursor}.
      */
     public static Category fromCursor(@NonNull Cursor cursor, @NonNull UserId userId) {
-        final Category category = new Category(cursor, userId);
-        return category;
+        final boolean isLocal;
+        String authority = getCursorString(cursor, AlbumColumns.AUTHORITY);
+        if (authority != null) {
+            isLocal = true;
+        } else {
+            isLocal = false;
+            authority = cursor.getExtras().getString(MediaStore.EXTRA_CLOUD_PROVIDER);
+        }
+        final Uri coverUri = ItemsProvider.getItemsUri(
+                getCursorString(cursor, AlbumColumns.MEDIA_COVER_ID), authority, userId);
+
+        return new Category(getCursorString(cursor, AlbumColumns.ID),
+                authority,
+                getCursorString(cursor, AlbumColumns.DISPLAY_NAME),
+                coverUri,
+                getCursorInt(cursor, AlbumColumns.MEDIA_COUNT),
+                isLocal);
     }
 
-    /**
-     * Update the category based on the {@code cursor}
-     *
-     * @param cursor the cursor to update the data
-     */
-    public void updateFromCursor(@NonNull Cursor cursor, @NonNull UserId userId) {
-        final String authority = getCursorString(cursor, ItemColumns.AUTHORITY);
-
-        mCategoryName = getCursorString(cursor, CategoryColumns.NAME);
-        mCoverUri = ItemsProvider.getItemsUri(getCursorString(cursor, CategoryColumns.COVER_ID),
-                authority, userId);
-        mItemCount = getCursorInt(cursor, CategoryColumns.NUMBER_OF_ITEMS);
-        mCategoryType = getCursorString(cursor, CategoryColumns.CATEGORY_TYPE);
+    private static String getLocalizedDisplayName(Context context, String albumId) {
+        switch (albumId) {
+            case ALBUM_ID_VIDEOS:
+                return context.getString(R.string.picker_category_videos);
+            case ALBUM_ID_CAMERA:
+                return context.getString(R.string.picker_category_camera);
+            case ALBUM_ID_SCREENSHOTS:
+                return context.getString(R.string.picker_category_screenshots);
+            case ALBUM_ID_DOWNLOADS:
+                return context.getString(R.string.picker_category_downloads);
+            case ALBUM_ID_FAVORITES:
+                return context.getString(R.string.picker_category_favorites);
+            default:
+                return albumId;
+        }
     }
 }
diff --git a/src/com/android/providers/media/photopicker/data/model/Item.java b/src/com/android/providers/media/photopicker/data/model/Item.java
index b47369d..7983555 100644
--- a/src/com/android/providers/media/photopicker/data/model/Item.java
+++ b/src/com/android/providers/media/photopicker/data/model/Item.java
@@ -16,6 +16,7 @@
 
 package com.android.providers.media.photopicker.data.model;
 
+import static android.provider.CloudMediaProviderContract.MediaColumns;
 import static android.provider.MediaStore.Files.FileColumns._SPECIAL_FORMAT_ANIMATED_WEBP;
 import static android.provider.MediaStore.Files.FileColumns._SPECIAL_FORMAT_GIF;
 import static android.provider.MediaStore.Files.FileColumns._SPECIAL_FORMAT_MOTION_PHOTO;
@@ -44,43 +45,6 @@
  * Base class representing one single entity/item in the PhotoPicker.
  */
 public class Item {
-
-    public static class ItemColumns {
-        public static String ID = CloudMediaProviderContract.MediaColumns.ID;
-        public static String MIME_TYPE = CloudMediaProviderContract.MediaColumns.MIME_TYPE;
-        public static String DATE_TAKEN = CloudMediaProviderContract.MediaColumns.DATE_TAKEN_MILLIS;
-        // TODO(b/195009139): Remove after fully switching to picker db
-        public static String DATE_MODIFIED = MediaStore.MediaColumns.DATE_MODIFIED;
-        public static String GENERATION_MODIFIED =
-                CloudMediaProviderContract.MediaColumns.SYNC_GENERATION;
-        public static String DURATION = CloudMediaProviderContract.MediaColumns.DURATION_MILLIS;
-        public static String SIZE = CloudMediaProviderContract.MediaColumns.SIZE_BYTES;
-        public static String AUTHORITY = CloudMediaProviderContract.MediaColumns.AUTHORITY;
-        public static String SPECIAL_FORMAT =
-                CloudMediaProviderContract.MediaColumns.STANDARD_MIME_TYPE_EXTENSION;
-
-        public static final String[] ALL_COLUMNS = {
-                ID,
-                MIME_TYPE,
-                DATE_TAKEN,
-                DATE_MODIFIED,
-                GENERATION_MODIFIED,
-                DURATION,
-                SPECIAL_FORMAT
-        };
-
-        // TODO(b/195009139): Remove after fully switching to picker db
-        public static final String[] PROJECTION = {
-            MediaStore.MediaColumns._ID + " AS " + ID,
-            MediaStore.MediaColumns.MIME_TYPE + " AS " + MIME_TYPE,
-            MediaStore.MediaColumns.DATE_TAKEN + " AS " + DATE_TAKEN,
-            MediaStore.MediaColumns.DATE_MODIFIED + " AS " + DATE_MODIFIED,
-            MediaStore.MediaColumns.GENERATION_MODIFIED + " AS " + GENERATION_MODIFIED,
-            MediaStore.MediaColumns.DURATION +  " AS " + DURATION,
-            MediaStore.Files.FileColumns._SPECIAL_FORMAT +  " AS " + SPECIAL_FORMAT,
-        };
-    }
-
     private String mId;
     private long mDateTaken;
     private long mGenerationModified;
@@ -194,17 +158,13 @@
      * @param userId the user id to create an {@link Item} for
      */
     public void updateFromCursor(@NonNull Cursor cursor, @NonNull UserId userId) {
-        final String authority = extractAuthority(cursor);
-        mId = getCursorString(cursor, ItemColumns.ID);
-        mMimeType = getCursorString(cursor, ItemColumns.MIME_TYPE);
-        mDateTaken = getCursorLong(cursor, ItemColumns.DATE_TAKEN);
-        if (mDateTaken < 0) {
-            // Convert DATE_MODIFIED to millis
-            mDateTaken = getCursorLong(cursor, ItemColumns.DATE_MODIFIED) * 1000;
-        }
-        mGenerationModified = getCursorLong(cursor, ItemColumns.GENERATION_MODIFIED);
-        mDuration = getCursorLong(cursor, ItemColumns.DURATION);
-        mSpecialFormat = getCursorInt(cursor, ItemColumns.SPECIAL_FORMAT);
+        final String authority = getCursorString(cursor, MediaColumns.AUTHORITY);
+        mId = getCursorString(cursor, MediaColumns.ID);
+        mMimeType = getCursorString(cursor, MediaColumns.MIME_TYPE);
+        mDateTaken = getCursorLong(cursor, MediaColumns.DATE_TAKEN_MILLIS);
+        mGenerationModified = getCursorLong(cursor, MediaColumns.SYNC_GENERATION);
+        mDuration = getCursorLong(cursor, MediaColumns.DURATION_MILLIS);
+        mSpecialFormat = getCursorInt(cursor, MediaColumns.STANDARD_MIME_TYPE_EXTENSION);
         mUri = ItemsProvider.getItemsUri(mId, authority, userId);
 
         parseMimeType();
@@ -259,13 +219,4 @@
             return mId.compareTo(anotherItem.getId());
         }
     }
-
-    private String extractAuthority(Cursor cursor) {
-        final String authority = getCursorString(cursor, ItemColumns.AUTHORITY);
-        if (authority == null) {
-            final Bundle bundle = cursor.getExtras();
-            return bundle.getString(ItemColumns.AUTHORITY);
-        }
-        return authority;
-    }
 }
diff --git a/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java b/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java
index 1585d3b..d84395c 100644
--- a/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java
+++ b/src/com/android/providers/media/photopicker/ui/AlbumGridHolder.java
@@ -61,7 +61,7 @@
     public void bind() {
         final Category category = (Category) itemView.getTag();
         mImageLoader.loadAlbumThumbnail(category, mIconThumb);
-        mAlbumName.setText(category.getCategoryName(itemView.getContext()));
+        mAlbumName.setText(category.getDisplayName(itemView.getContext()));
 
         // Check whether there is a mime type filter or not. If yes, hide the item count. Otherwise,
         // show the item count and update the count.
diff --git a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
index 8e87ae7..ffd3743 100644
--- a/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
+++ b/src/com/android/providers/media/photopicker/ui/PhotosTabFragment.java
@@ -18,6 +18,7 @@
 import static com.android.providers.media.photopicker.ui.PhotosTabAdapter.COLUMN_COUNT;
 
 import android.os.Bundle;
+import android.provider.CloudMediaProviderContract;
 import android.text.TextUtils;
 import android.view.View;
 
@@ -32,7 +33,6 @@
 
 import com.android.providers.media.photopicker.PhotoPickerActivity;
 import com.android.providers.media.photopicker.data.model.Category;
-import com.android.providers.media.photopicker.data.model.Category.CategoryType;
 import com.android.providers.media.photopicker.data.model.Item;
 import com.android.providers.media.photopicker.util.LayoutModeUtils;
 import com.android.providers.media.util.StringUtils;
@@ -49,13 +49,8 @@
 
     private static final int MINIMUM_SPAN_COUNT = 3;
     private static final String FRAGMENT_TAG = "PhotosTabFragment";
-    private static final String EXTRA_CATEGORY_TYPE = "category_type";
-    private static final String EXTRA_CATEGORY_NAME = "category_name";
 
-    private boolean mIsDefaultCategory;
-    @CategoryType
-    private String mCategoryType = Category.CATEGORY_DEFAULT;
-    private String mCategoryName = "";
+    private Category mCategory = Category.DEFAULT;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -64,10 +59,7 @@
         // be triggered. We need to restore the savedInstanceState in onCreate.
         // E.g. Click the albums -> preview one item -> rotate the device
         if (savedInstanceState != null) {
-            mCategoryType = savedInstanceState.getString(EXTRA_CATEGORY_TYPE,
-                    Category.CATEGORY_DEFAULT);
-            mCategoryName = savedInstanceState.getString(EXTRA_CATEGORY_NAME,
-                    /* defaultValue= */ "");
+            mCategory = Category.fromBundle(savedInstanceState);
         }
     }
 
@@ -78,8 +70,8 @@
         final PhotosTabAdapter adapter = new PhotosTabAdapter(mSelection, mImageLoader,
                 this::onItemClick, this::onItemLongClick);
         setEmptyMessage(R.string.picker_photos_empty_message);
-        mIsDefaultCategory = TextUtils.equals(Category.CATEGORY_DEFAULT, mCategoryType);
-        if (mIsDefaultCategory) {
+
+        if (mCategory.isDefault()) {
             // Set the pane title for A11y
             view.setAccessibilityPaneTitle(getString(R.string.picker_photos));
             mPickerViewModel.getItems().observe(this, itemList -> {
@@ -89,8 +81,8 @@
             });
         } else {
             // Set the pane title for A11y
-            view.setAccessibilityPaneTitle(Category.getCategoryName(getContext(), mCategoryType));
-            mPickerViewModel.getCategoryItems(mCategoryType).observe(this, itemList -> {
+            view.setAccessibilityPaneTitle(mCategory.getDisplayName(getContext()));
+            mPickerViewModel.getCategoryItems(mCategory).observe(this, itemList -> {
                 // If the item count of the albums is zero, albums are not shown on the Albums tab.
                 // The user can't launch the album items page when the album has zero items. So, we
                 // don't need to show emptyView in the case.
@@ -124,27 +116,21 @@
      */
     public void onSaveInstanceState(Bundle state) {
         super.onSaveInstanceState(state);
-        state.putString(EXTRA_CATEGORY_TYPE, mCategoryType);
-        state.putString(EXTRA_CATEGORY_NAME, mCategoryName);
+        mCategory.toBundle(state);
     }
 
     @Override
     public void onResume() {
         super.onResume();
 
-        if (mIsDefaultCategory) {
+        if (mCategory.isDefault()) {
             ((PhotoPickerActivity) getActivity()).updateCommonLayouts(
                     LayoutModeUtils.MODE_PHOTOS_TAB, /* title */ "");
             hideProfileButton(/* hide */ false);
         } else {
             hideProfileButton(/* hide */ true);
-            String categoryName = Category.getCategoryName(getContext(), mCategoryType);
-
-            if (TextUtils.isEmpty(categoryName)) {
-                categoryName = mCategoryName;
-            }
             ((PhotoPickerActivity) getActivity()).updateCommonLayouts(
-                    LayoutModeUtils.MODE_ALBUM_PHOTOS_TAB, categoryName);
+                    LayoutModeUtils.MODE_ALBUM_PHOTOS_TAB, mCategory.getDisplayName(getContext()));
         }
     }
 
@@ -204,10 +190,9 @@
     public static void show(FragmentManager fm, Category category) {
         final FragmentTransaction ft = fm.beginTransaction();
         final PhotosTabFragment fragment = new PhotosTabFragment();
-        fragment.mCategoryType = category.getCategoryType();
-        fragment.mCategoryName = category.getCategoryName(/* context= */ null);
+        fragment.mCategory = category;
         ft.replace(R.id.fragment_container, fragment, FRAGMENT_TAG);
-        if (!TextUtils.equals(category.getCategoryType(), Category.CATEGORY_DEFAULT)) {
+        if (!fragment.mCategory.isDefault()) {
             ft.addToBackStack(FRAGMENT_TAG);
         }
         ft.commitAllowingStateLoss();
diff --git a/src/com/android/providers/media/photopicker/viewmodel/PickerViewModel.java b/src/com/android/providers/media/photopicker/viewmodel/PickerViewModel.java
index b5f708a..7f97f4c 100644
--- a/src/com/android/providers/media/photopicker/viewmodel/PickerViewModel.java
+++ b/src/com/android/providers/media/photopicker/viewmodel/PickerViewModel.java
@@ -38,7 +38,6 @@
 import com.android.providers.media.photopicker.data.Selection;
 import com.android.providers.media.photopicker.data.UserIdManager;
 import com.android.providers.media.photopicker.data.model.Category;
-import com.android.providers.media.photopicker.data.model.Category.CategoryType;
 import com.android.providers.media.photopicker.data.model.Item;
 import com.android.providers.media.photopicker.data.model.UserId;
 import com.android.providers.media.photopicker.util.DateTimeUtils;
@@ -137,7 +136,7 @@
         return mItemList;
     }
 
-    private List<Item> loadItems(@Nullable @CategoryType String category, UserId userId) {
+    private List<Item> loadItems(Category category, UserId userId) {
         final List<Item> items = new ArrayList<>();
 
         try (Cursor cursor = mItemsProvider.getItems(category, /* offset */ 0,
@@ -151,7 +150,7 @@
             // We only add the RECENT header on the PhotosTabFragment with CATEGORY_DEFAULT. In this
             // case, we call this method {loadItems} with null category. When the category is not
             // empty, we don't show the RECENT header.
-            final boolean showRecent = TextUtils.isEmpty(category);
+            final boolean showRecent = category.isDefault();
 
             int recentSize = 0;
             long currentDateTaken = 0;
@@ -181,19 +180,15 @@
             }
         }
 
-        if (TextUtils.isEmpty(category)) {
-            Log.d(TAG, "Loaded " + items.size() + " items for user " + userId.toString());
-        } else {
-            Log.d(TAG, "Loaded " + items.size() + " items in " + category + " for user "
-                    + userId.toString());
-        }
+        Log.d(TAG, "Loaded " + items.size() + " items in " + category + " for user "
+                + userId.toString());
         return items;
     }
 
     private void loadItemsAsync() {
         final UserId userId = mUserIdManager.getCurrentUserProfileId();
         ForegroundThread.getExecutor().execute(() -> {
-            mItemList.postValue(loadItems(/* category= */ null, userId));
+                    mItemList.postValue(loadItems(Category.DEFAULT, userId));
         });
     }
 
@@ -214,12 +209,12 @@
      * @return the list of all photos and videos with the specific {@code category}
      *         {@link #mCategoryItemList}
      */
-    public LiveData<List<Item>> getCategoryItems(@NonNull @CategoryType String category) {
+    public LiveData<List<Item>> getCategoryItems(@NonNull Category category) {
         updateCategoryItems(category);
         return mCategoryItemList;
     }
 
-    private void loadCategoryItemsAsync(@NonNull @CategoryType String category) {
+    private void loadCategoryItemsAsync(@NonNull Category category) {
         final UserId userId = mUserIdManager.getCurrentUserProfileId();
         ForegroundThread.getExecutor().execute(() -> {
             mCategoryItemList.postValue(loadItems(category, userId));
@@ -229,7 +224,7 @@
     /**
      * Update the item List with the {@code category} {@link #mCategoryItemList}
      */
-    public void updateCategoryItems(@NonNull @CategoryType String category) {
+    public void updateCategoryItems(@NonNull Category category) {
         if (mCategoryItemList == null) {
             mCategoryItemList = new MutableLiveData<>();
         }
@@ -321,4 +316,4 @@
     public int getBottomSheetState() {
         return mBottomSheetState;
     }
-}
\ No newline at end of file
+}
diff --git a/tests/src/com/android/providers/media/PickerProviderMediaGenerator.java b/tests/src/com/android/providers/media/PickerProviderMediaGenerator.java
index 0f1f202..11a8e4b 100644
--- a/tests/src/com/android/providers/media/PickerProviderMediaGenerator.java
+++ b/tests/src/com/android/providers/media/PickerProviderMediaGenerator.java
@@ -31,6 +31,8 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import com.android.providers.media.photopicker.LocalProvider;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -72,18 +74,11 @@
         AlbumColumns.DATE_TAKEN_MILLIS,
         AlbumColumns.MEDIA_COVER_ID,
         AlbumColumns.MEDIA_COUNT,
-        AlbumColumns.TYPE,
+        AlbumColumns.AUTHORITY
     };
 
     private static final String[] DELETED_MEDIA_PROJECTION = new String[] { MediaColumns.ID };
 
-    // TODO(b/195009148): Investigate how to expose as TestApi and avoid hard-coding
-    // Copied from CloudMediaProviderContract#AlbumColumns
-    public static final String ALBUM_COLUMN_TYPE_LOCAL = "LOCAL";
-    public static final String ALBUM_COLUMN_TYPE_CLOUD = null;
-    public static final String ALBUM_COLUMN_TYPE_FAVORITES = "FAVORITES";
-    public static final String ALBUM_COLUMN_TYPE_UNRELIABLE_VOLUME = "UNRELIABLE_VOLUME";
-
     public static class MediaGenerator {
         private final List<TestMedia> mMedia = new ArrayList<>();
         private final List<TestMedia> mDeletedMedia = new ArrayList<>();
@@ -357,7 +352,7 @@
                 /* displayName */ id,
                 String.valueOf(dateTakenMs),
                 String.valueOf(mediaCount),
-                isLocal ? ALBUM_COLUMN_TYPE_LOCAL : ALBUM_COLUMN_TYPE_CLOUD
+                isLocal ? LocalProvider.AUTHORITY : null
             };
         }
 
diff --git a/tests/src/com/android/providers/media/photopicker/ItemsProviderTest.java b/tests/src/com/android/providers/media/photopicker/ItemsProviderTest.java
index a9eb6bf..2047419 100644
--- a/tests/src/com/android/providers/media/photopicker/ItemsProviderTest.java
+++ b/tests/src/com/android/providers/media/photopicker/ItemsProviderTest.java
@@ -16,6 +16,13 @@
 
 package com.android.providers.media.photopicker;
 
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_FAVORITES;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_VIDEOS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_SCREENSHOTS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_CAMERA;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_DOWNLOADS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns;
+import static android.provider.CloudMediaProviderContract.MediaColumns;
 import static android.provider.MediaStore.VOLUME_EXTERNAL;
 
 import static com.android.providers.media.photopicker.data.PickerDbFacade.PROP_DEFAULT_SYNC_DELAY_MS;
@@ -39,6 +46,7 @@
 
 import androidx.test.InstrumentationRegistry;
 
+import com.android.providers.media.photopicker.data.ExternalDbFacade;
 import com.android.providers.media.photopicker.data.ItemsProvider;
 import com.android.providers.media.photopicker.data.model.Category;
 import com.android.providers.media.photopicker.data.model.Item;
@@ -96,7 +104,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_CAMERA}.
+     * {@link #ALBUM_ID_CAMERA}.
      */
     @Test
     public void testGetCategories_camera() throws Exception {
@@ -108,7 +116,7 @@
         final File cameraDir = getCameraDir();
         File imageFile = assertCreateNewImage(cameraDir);
         try {
-            assertGetCategoriesMatchSingle(Category.CATEGORY_CAMERA, /* numberOfItems */ 1);
+            assertGetCategoriesMatchSingle(ALBUM_ID_CAMERA, /* numberOfItems */ 1);
         } finally {
             imageFile.delete();
         }
@@ -116,7 +124,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_CAMERA}.
+     * {@link #ALBUM_ID_CAMERA}.
      */
     @Test
     public void testGetCategories_not_camera() throws Exception {
@@ -127,7 +135,7 @@
         final File picturesDir = getPicturesDir();
         File nonCameraImageFile = assertCreateNewImage(picturesDir);
         try {
-            assertGetCategoriesMatchSingle(Category.CATEGORY_CAMERA, /* numberOfItems */ 0);
+            assertGetCategoriesMatchSingle(ALBUM_ID_CAMERA, /* numberOfItems */ 0);
         } finally {
             nonCameraImageFile.delete();
         }
@@ -135,7 +143,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_VIDEOS}.
+     * {@link #ALBUM_ID_VIDEOS}.
      */
     @Test
     public void testGetCategories_videos() throws Exception {
@@ -147,7 +155,7 @@
         final File moviesDir = getMoviesDir();
         File videoFile = assertCreateNewVideo(moviesDir);
         try {
-           assertGetCategoriesMatchSingle(Category.CATEGORY_VIDEOS, /* numberOfItems */ 1);
+            assertGetCategoriesMatchSingle(ALBUM_ID_VIDEOS, /* numberOfItems */ 1);
         } finally {
             videoFile.delete();
         }
@@ -155,7 +163,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_VIDEOS}.
+     * {@link #ALBUM_ID_VIDEOS}.
      */
     @Test
     public void testGetCategories_not_videos() throws Exception {
@@ -166,7 +174,7 @@
         final File picturesDir = getPicturesDir();
         File imageFile = assertCreateNewImage(picturesDir);
         try {
-            assertGetCategoriesMatchSingle(Category.CATEGORY_VIDEOS, /* numberOfItems */ 0);
+            assertGetCategoriesMatchSingle(ALBUM_ID_VIDEOS, /* numberOfItems */ 0);
         } finally {
             imageFile.delete();
         }
@@ -174,7 +182,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_SCREENSHOTS}.
+     * {@link #ALBUM_ID_SCREENSHOTS}.
      */
     @Test
     public void testGetCategories_screenshots() throws Exception {
@@ -191,8 +199,8 @@
         File imageFileInScreenshotDirInDownloads =
                 assertCreateNewImage(screenshotsDirInDownloadsDir);
         try {
-            assertGetCategoriesMatchMultiple(Category.CATEGORY_SCREENSHOTS,
-                    Category.CATEGORY_DOWNLOADS, /* numberOfItemsInScreenshots */ 2,
+            assertGetCategoriesMatchMultiple(ALBUM_ID_SCREENSHOTS,
+                    ALBUM_ID_DOWNLOADS, /* numberOfItemsInScreenshots */ 2,
                                              /* numberOfItemsInDownloads */ 1);
         } finally {
             imageFile.delete();
@@ -202,7 +210,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_SCREENSHOTS}.
+     * {@link #ALBUM_ID_SCREENSHOTS}.
      */
     @Test
     public void testGetCategories_not_screenshots() throws Exception {
@@ -213,7 +221,7 @@
         final File cameraDir = getCameraDir();
         File imageFile = assertCreateNewImage(cameraDir);
         try {
-            assertGetCategoriesMatchSingle(Category.CATEGORY_SCREENSHOTS, /* numberOfItems */ 0);
+            assertGetCategoriesMatchSingle(ALBUM_ID_SCREENSHOTS, /* numberOfItems */ 0);
         } finally {
             imageFile.delete();
         }
@@ -221,7 +229,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_FAVORITES}.
+     * {@link AlbumColumns#ALBUM_ID_FAVORITES}.
      */
     @Test
     public void testGetCategories_favorites() throws Exception {
@@ -233,7 +241,7 @@
         final File imageFile = assertCreateNewImage(picturesDir);
         setIsFavorite(imageFile);
         try {
-            assertGetCategoriesMatchSingle(Category.CATEGORY_FAVORITES, /* numberOfItems */1);
+            assertGetCategoriesMatchSingle(ALBUM_ID_FAVORITES, /* numberOfItems */1);
         } finally {
             imageFile.delete();
         }
@@ -241,7 +249,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_FAVORITES}.
+     * {@link AlbumColumns#ALBUM_ID_FAVORITES}.
      */
     @Test
     public void testGetCategories_not_favorites() throws Exception {
@@ -252,7 +260,7 @@
         final File picturesDir = getPicturesDir();
         final File nonFavImageFile = assertCreateNewImage(picturesDir);
         try {
-            assertGetCategoriesMatchSingle(Category.CATEGORY_FAVORITES, /* numberOfItems */ 0);
+            assertGetCategoriesMatchSingle(ALBUM_ID_FAVORITES, /* numberOfItems */ 0);
         } finally {
             nonFavImageFile.delete();
         }
@@ -260,7 +268,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_DOWNLOADS}.
+     * {@link #ALBUM_ID_DOWNLOADS}.
      */
     @Test
     public void testGetCategories_downloads() throws Exception {
@@ -272,7 +280,7 @@
         final File downloadsDir = getDownloadsDir();
         final File imageFile = assertCreateNewImage(downloadsDir);
         try {
-            assertGetCategoriesMatchSingle(Category.CATEGORY_DOWNLOADS, /* numberOfItems */ 1);
+            assertGetCategoriesMatchSingle(ALBUM_ID_DOWNLOADS, /* numberOfItems */ 1);
         } finally {
             imageFile.delete();
         }
@@ -280,7 +288,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_DOWNLOADS}.
+     * {@link #ALBUM_ID_DOWNLOADS}.
      */
     @Test
     public void testGetCategories_not_downloads() throws Exception {
@@ -291,7 +299,7 @@
         final File picturesDir = getPicturesDir();
         final File nonDownloadsImageFile = assertCreateNewImage(picturesDir);
         try {
-            assertGetCategoriesMatchSingle(Category.CATEGORY_DOWNLOADS, /* numberOfItems */ 0);
+            assertGetCategoriesMatchSingle(ALBUM_ID_DOWNLOADS, /* numberOfItems */ 0);
         } finally {
             nonDownloadsImageFile.delete();
         }
@@ -299,7 +307,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_CAMERA} and {@link Category#CATEGORY_VIDEOS}.
+     * {@link #ALBUM_ID_CAMERA} and {@link #ALBUM_ID_VIDEOS}.
      */
     @Test
     public void testGetCategories_camera_and_videos() throws Exception {
@@ -311,7 +319,7 @@
         final File cameraDir = getCameraDir();
         File videoFile = assertCreateNewVideo(cameraDir);
         try {
-            assertGetCategoriesMatchMultiple(Category.CATEGORY_CAMERA, Category.CATEGORY_VIDEOS,
+            assertGetCategoriesMatchMultiple(ALBUM_ID_CAMERA, ALBUM_ID_VIDEOS,
                     /* numberOfItemsInCamera */ 1,
                     /* numberOfItemsInVideos */ 1);
         } finally {
@@ -321,7 +329,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_SCREENSHOTS} and {@link Category#CATEGORY_FAVORITES}.
+     * {@link AlbumColumns#ALBUM_ID_SCREENSHOTS} and {@link AlbumColumns#ALBUM_ID_FAVORITES}.
      */
     @Test
     public void testGetCategories_screenshots_and_favorites() throws Exception {
@@ -334,8 +342,8 @@
         File imageFile = assertCreateNewImage(screenshotsDir);
         setIsFavorite(imageFile);
         try {
-            assertGetCategoriesMatchMultiple(Category.CATEGORY_SCREENSHOTS,
-                    Category.CATEGORY_FAVORITES,
+            assertGetCategoriesMatchMultiple(ALBUM_ID_SCREENSHOTS,
+                    ALBUM_ID_FAVORITES,
                     /* numberOfItemsInScreenshots */ 1,
                     /* numberOfItemsInFavorites */ 1);
         } finally {
@@ -345,7 +353,7 @@
 
     /**
      * Tests {@link ItemsProvider#getCategories(String, UserId)} to return correct info about
-     * {@link Category#CATEGORY_DOWNLOADS} and {@link Category#CATEGORY_FAVORITES}.
+     * {@link AlbumColumns#ALBUM_ID_DOWNLOADS} and {@link AlbumColumns#ALBUM_ID_FAVORITES}.
      */
     @Test
     public void testGetCategories_downloads_and_favorites() throws Exception {
@@ -358,8 +366,8 @@
         File imageFile = assertCreateNewImage(downloadsDir);
         setIsFavorite(imageFile);
         try {
-            assertGetCategoriesMatchMultiple(Category.CATEGORY_DOWNLOADS,
-                    Category.CATEGORY_FAVORITES,
+            assertGetCategoriesMatchMultiple(ALBUM_ID_DOWNLOADS,
+                    ALBUM_ID_FAVORITES,
                     /* numberOfItemsInScreenshots */ 1,
                     /* numberOfItemsInFavorites */ 1);
         } finally {
@@ -379,7 +387,7 @@
         File imageFile = assertCreateNewImage();
         File videoFile = assertCreateNewVideo();
         try {
-            final Cursor res = mItemsProvider.getItems(/* category */ null, /* offset */ 0,
+            final Cursor res = mItemsProvider.getItems(Category.DEFAULT, /* offset */ 0,
                     /* limit */ -1, /* mimeType */ null, /* userId */ null);
             assertThat(res).isNotNull();
             assertThat(res.getCount()).isEqualTo(2);
@@ -415,7 +423,7 @@
             uris.add(videoFileDateNowUri);
             uris.add(imageFileDateNowUri);
 
-            try (Cursor cursor = mItemsProvider.getItems(/* category */ null, /* offset */ 0,
+            try (Cursor cursor = mItemsProvider.getItems(Category.DEFAULT, /* offset */ 0,
                     /* limit */ -1, /* mimeType */ null, /* userId */ null)) {
                 assertThat(cursor).isNotNull();
 
@@ -424,7 +432,7 @@
 
                 int rowNum = 0;
                 assertThat(cursor.moveToFirst()).isTrue();
-                final int idColumnIndex = cursor.getColumnIndexOrThrow(Item.ItemColumns.ID);
+                final int idColumnIndex = cursor.getColumnIndexOrThrow(MediaColumns.ID);
                 while (rowNum < expectedCount) {
                     assertWithMessage("id at row:" + rowNum + " is expected to be"
                             + " same as id in " + uris.get(rowNum))
@@ -452,7 +460,7 @@
         File imageFileHidden = assertCreateNewImage(hiddenDir);
         File videoFileHidden = assertCreateNewVideo(hiddenDir);
         try {
-            final Cursor res = mItemsProvider.getItems(/* category */ null, /* offset */ 0,
+            final Cursor res = mItemsProvider.getItems(Category.DEFAULT, /* offset */ 0,
                     /* limit */ -1, /* mimeType */ null, /* userId */ null);
             assertThat(res).isNotNull();
             assertThat(res.getCount()).isEqualTo(0);
@@ -475,7 +483,7 @@
         File imageFile = assertCreateNewImage();
         File videoFile = assertCreateNewVideo();
         try {
-            final Cursor res = mItemsProvider.getItems(/* category */ null, /* offset */ 0,
+            final Cursor res = mItemsProvider.getItems(Category.DEFAULT, /* offset */ 0,
                     /* limit */ -1, /* mimeType */ "image/*", /* userId */ null);
             assertThat(res).isNotNull();
             assertThat(res.getCount()).isEqualTo(1);
@@ -497,7 +505,7 @@
         // Create a jpg file image. Tests negative use case, this should not be returned below.
         File imageFile = assertCreateNewImage();
         try {
-            final Cursor res = mItemsProvider.getItems(/* category */ null, /* offset */ 0,
+            final Cursor res = mItemsProvider.getItems(Category.DEFAULT, /* offset */ 0,
                     /* limit */ -1, /* mimeType */ "image/png", /* userId */ null);
             assertThat(res).isNotNull();
             assertThat(res.getCount()).isEqualTo(0);
@@ -519,7 +527,7 @@
         File imageFileHidden = assertCreateNewImage(hiddenDir);
         File videoFileHidden = assertCreateNewVideo(hiddenDir);
         try {
-            final Cursor res = mItemsProvider.getItems(/* category */ null, /* offset */ 0,
+            final Cursor res = mItemsProvider.getItems(Category.DEFAULT, /* offset */ 0,
                     /* limit */ -1, /* mimeType */ "image/*", /* userId */ null);
             assertThat(res).isNotNull();
             assertThat(res.getCount()).isEqualTo(0);
@@ -542,7 +550,7 @@
         File imageFile = assertCreateNewImage();
         File videoFile = assertCreateNewVideo();
         try {
-            final Cursor res = mItemsProvider.getItems(/* category */ null, /* offset */ 0,
+            final Cursor res = mItemsProvider.getItems(Category.DEFAULT, /* offset */ 0,
                     /* limit */ -1, /* mimeType */ "video/*", /* userId */ null);
             assertThat(res).isNotNull();
             assertThat(res.getCount()).isEqualTo(1);
@@ -564,7 +572,7 @@
         // Create a mp4 video file. Tests positive use case, this should be returned below.
         File videoFile = assertCreateNewVideo();
         try {
-            final Cursor res = mItemsProvider.getItems(/* category */ null, /* offset */ 0,
+            final Cursor res = mItemsProvider.getItems(Category.DEFAULT, /* offset */ 0,
                     /* limit */ -1, /* mimeType */ "video/mp4", /* userId */ null);
             assertThat(res).isNotNull();
             assertThat(res.getCount()).isEqualTo(1);
@@ -585,7 +593,7 @@
         File imageFileHidden = assertCreateNewImage(hiddenDir);
         File videoFileHidden = assertCreateNewVideo(hiddenDir);
         try {
-            final Cursor res = mItemsProvider.getItems(/* category */ null, /* offset */ 0,
+            final Cursor res = mItemsProvider.getItems(Category.DEFAULT, /* offset */ 0,
                     /* limit */ -1, /* mimeType */ "video/*", /* userId */ null);
             assertThat(res).isNotNull();
             assertThat(res.getCount()).isEqualTo(0);
@@ -609,15 +617,14 @@
 
         // Assert that only expected category is returned and has expectedNumberOfItems items in it
         assertThat(c.moveToFirst()).isTrue();
-        final int nameColumnIndex = c.getColumnIndexOrThrow(Category.CategoryColumns.NAME);
-        final int numOfItemsColumnIndex = c.getColumnIndexOrThrow(
-                Category.CategoryColumns.NUMBER_OF_ITEMS);
-        final int coverIdIndex = c.getColumnIndexOrThrow(Category.CategoryColumns.COVER_ID);
+        final int nameColumnIndex = c.getColumnIndexOrThrow(AlbumColumns.DISPLAY_NAME);
+        final int numOfItemsColumnIndex = c.getColumnIndexOrThrow(AlbumColumns.MEDIA_COUNT);
+        final int coverIdIndex = c.getColumnIndexOrThrow(AlbumColumns.MEDIA_COVER_ID);
 
         final String categoryName = c.getString(nameColumnIndex);
         final int numOfItems = c.getInt(numOfItemsColumnIndex);
         final Uri coverUri = ItemsProvider.getItemsUri(c.getString(coverIdIndex),
-                /* authority */ null, UserId.CURRENT_USER);
+                PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY, UserId.CURRENT_USER);
 
         assertThat(categoryName).isEqualTo(expectedCategoryName);
         assertThat(numOfItems).isEqualTo(expectedNumberOfItems);
@@ -635,7 +642,7 @@
     private void assertCategoriesNoMatch(String expectedCategoryName) {
         Cursor c = mItemsProvider.getCategories(/* mimeType */ null, /* userId */ null);
         while (c != null && c.moveToNext()) {
-            final int nameColumnIndex = c.getColumnIndexOrThrow(Category.CategoryColumns.NAME);
+            final int nameColumnIndex = c.getColumnIndexOrThrow(AlbumColumns.DISPLAY_NAME);
             final String categoryName = c.getString(nameColumnIndex);
             assertThat(categoryName).isNotEqualTo(expectedCategoryName);
         }
@@ -652,9 +659,9 @@
         boolean isCategory1Returned = false;
         boolean isCategory2Returned = false;
         while (c.moveToNext()) {
-            final int nameColumnIndex = c.getColumnIndexOrThrow(Category.CategoryColumns.NAME);
+            final int nameColumnIndex = c.getColumnIndexOrThrow(AlbumColumns.DISPLAY_NAME);
             final int numOfItemsColumnIndex = c.getColumnIndexOrThrow(
-                    Category.CategoryColumns.NUMBER_OF_ITEMS);
+                    AlbumColumns.MEDIA_COUNT);
 
             final String categoryName = c.getString(nameColumnIndex);
             final int numOfItems = c.getInt(numOfItemsColumnIndex);
@@ -842,6 +849,5 @@
                         c.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)))).delete();
             }
         }
-
     }
 }
diff --git a/tests/src/com/android/providers/media/photopicker/LocalProvider.java b/tests/src/com/android/providers/media/photopicker/LocalProvider.java
index 40eb092..f674872 100644
--- a/tests/src/com/android/providers/media/photopicker/LocalProvider.java
+++ b/tests/src/com/android/providers/media/photopicker/LocalProvider.java
@@ -37,7 +37,7 @@
  * {@link MediaGenerator}
  */
 public class LocalProvider extends CloudMediaProvider {
-    private static final String AUTHORITY = "com.android.providers.media.photopicker.tests.local";
+    public static final String AUTHORITY = "com.android.providers.media.photopicker.tests.local";
 
     private final MediaGenerator mMediaGenerator =
             PickerProviderMediaGenerator.getMediaGenerator(AUTHORITY);
diff --git a/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java b/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java
index e572900..ade855a 100644
--- a/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java
+++ b/tests/src/com/android/providers/media/photopicker/PickerDataLayerTest.java
@@ -16,9 +16,7 @@
 
 package com.android.providers.media.photopicker;
 
-import static com.android.providers.media.PickerProviderMediaGenerator.ALBUM_COLUMN_TYPE_CLOUD;
-import static com.android.providers.media.PickerProviderMediaGenerator.ALBUM_COLUMN_TYPE_FAVORITES;
-import static com.android.providers.media.PickerProviderMediaGenerator.ALBUM_COLUMN_TYPE_LOCAL;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_FAVORITES;
 import static com.android.providers.media.PickerProviderMediaGenerator.MediaGenerator;
 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.LONG_DEFAULT;
 import static com.android.providers.media.photopicker.data.PickerDbFacade.QueryFilterBuilder.STRING_DEFAULT;
@@ -29,6 +27,7 @@
 import android.content.Intent;
 import android.database.Cursor;
 import android.os.Bundle;
+import android.provider.CloudMediaProviderContract;
 import android.provider.CloudMediaProviderContract.AlbumColumns;
 import android.provider.CloudMediaProviderContract.MediaColumns;
 import android.provider.MediaStore;
@@ -163,8 +162,8 @@
             assertThat(cr.getCount()).isEqualTo(4);
         }
 
-        final Bundle favoriteQueryArgs = buildQueryArgs(STRING_DEFAULT,
-                ALBUM_COLUMN_TYPE_FAVORITES, MIME_TYPE_DEFAULT, SIZE_BYTES_DEFAULT);
+        final Bundle favoriteQueryArgs = buildQueryArgs(ALBUM_ID_FAVORITES,
+                LOCAL_PROVIDER_AUTHORITY, MIME_TYPE_DEFAULT, SIZE_BYTES_DEFAULT);
 
         try (Cursor cr = mDataLayer.fetchMedia(favoriteQueryArgs)) {
             assertThat(cr.getCount()).isEqualTo(2);
@@ -194,8 +193,8 @@
             assertThat(cr.getCount()).isEqualTo(4);
         }
 
-        final Bundle favoriteMimeTypeQueryArgs = buildQueryArgs(STRING_DEFAULT,
-                ALBUM_COLUMN_TYPE_FAVORITES, VIDEO_MIME_TYPE, SIZE_BYTES_DEFAULT);
+        final Bundle favoriteMimeTypeQueryArgs = buildQueryArgs(ALBUM_ID_FAVORITES,
+                LOCAL_PROVIDER_AUTHORITY, VIDEO_MIME_TYPE, SIZE_BYTES_DEFAULT);
 
         try (Cursor cr = mDataLayer.fetchMedia(favoriteMimeTypeQueryArgs)) {
             assertThat(cr.getCount()).isEqualTo(1);
@@ -224,8 +223,8 @@
             assertThat(cr.getCount()).isEqualTo(4);
         }
 
-        final Bundle favoriteSizeQueryArgs = buildQueryArgs(STRING_DEFAULT,
-                ALBUM_COLUMN_TYPE_FAVORITES, MIME_TYPE_DEFAULT, SIZE_BYTES - 1);
+        final Bundle favoriteSizeQueryArgs = buildQueryArgs(ALBUM_ID_FAVORITES,
+                LOCAL_PROVIDER_AUTHORITY, MIME_TYPE_DEFAULT, SIZE_BYTES - 1);
 
         try (Cursor cr = mDataLayer.fetchMedia(favoriteSizeQueryArgs)) {
             assertThat(cr.getCount()).isEqualTo(1);
@@ -254,8 +253,8 @@
             assertThat(cr.getCount()).isEqualTo(4);
         }
 
-        final Bundle favoriteSizeAndMimeTypeQueryArgs = buildQueryArgs(STRING_DEFAULT,
-                ALBUM_COLUMN_TYPE_FAVORITES, VIDEO_MIME_TYPE, SIZE_BYTES - 1);
+        final Bundle favoriteSizeAndMimeTypeQueryArgs = buildQueryArgs(ALBUM_ID_FAVORITES,
+                LOCAL_PROVIDER_AUTHORITY, VIDEO_MIME_TYPE, SIZE_BYTES - 1);
 
         try (Cursor cr = mDataLayer.fetchMedia(favoriteSizeAndMimeTypeQueryArgs)) {
             assertThat(cr.getCount()).isEqualTo(0);
@@ -342,9 +341,9 @@
         try (Cursor cr = mDataLayer.fetchAlbums(defaultQueryArgs)) {
             assertThat(cr.getCount()).isEqualTo(3);
 
-            assertAlbumCursor(cr, ALBUM_ID_1, ALBUM_COLUMN_TYPE_LOCAL);
-            assertAlbumCursor(cr, Category.CATEGORY_FAVORITES, ALBUM_COLUMN_TYPE_FAVORITES);
-            assertAlbumCursor(cr, ALBUM_ID_2, ALBUM_COLUMN_TYPE_CLOUD);
+            assertAlbumCursor(cr, ALBUM_ID_1, LOCAL_PROVIDER_AUTHORITY);
+            assertAlbumCursor(cr, ALBUM_ID_FAVORITES, LOCAL_PROVIDER_AUTHORITY);
+            assertAlbumCursor(cr, ALBUM_ID_2, CLOUD_PRIMARY_PROVIDER_AUTHORITY);
         }
 
         try (Cursor cr = mDataLayer.fetchMedia(defaultQueryArgs)) {
@@ -357,13 +356,13 @@
         }
 
         final Bundle localAlbumQueryArgs = buildQueryArgs(ALBUM_ID_1,
-                ALBUM_COLUMN_TYPE_LOCAL, MIME_TYPE_DEFAULT, SIZE_BYTES_DEFAULT);
+                LOCAL_PROVIDER_AUTHORITY, MIME_TYPE_DEFAULT, SIZE_BYTES_DEFAULT);
 
         final Bundle cloudAlbumQueryArgs = buildQueryArgs(ALBUM_ID_2,
-                ALBUM_COLUMN_TYPE_CLOUD, MIME_TYPE_DEFAULT, SIZE_BYTES_DEFAULT);
+                CLOUD_PRIMARY_PROVIDER_AUTHORITY, MIME_TYPE_DEFAULT, SIZE_BYTES_DEFAULT);
 
-        final Bundle favoriteAlbumQueryArgs = buildQueryArgs(STRING_DEFAULT,
-                ALBUM_COLUMN_TYPE_FAVORITES, MIME_TYPE_DEFAULT, SIZE_BYTES_DEFAULT);
+        final Bundle favoriteAlbumQueryArgs = buildQueryArgs(ALBUM_ID_FAVORITES,
+                LOCAL_PROVIDER_AUTHORITY, MIME_TYPE_DEFAULT, SIZE_BYTES_DEFAULT);
 
         try (Cursor cr = mDataLayer.fetchMedia(localAlbumQueryArgs)) {
             assertWithMessage("Local album count").that(cr.getCount()).isEqualTo(1);
@@ -406,15 +405,15 @@
         try (Cursor cr = mDataLayer.fetchAlbums(mimeTypeQueryArgs)) {
             assertThat(cr.getCount()).isEqualTo(2);
 
-            assertAlbumCursor(cr, ALBUM_ID_1, ALBUM_COLUMN_TYPE_LOCAL);
-            assertAlbumCursor(cr, ALBUM_ID_2, ALBUM_COLUMN_TYPE_CLOUD);
+            assertAlbumCursor(cr, ALBUM_ID_1, LOCAL_PROVIDER_AUTHORITY);
+            assertAlbumCursor(cr, ALBUM_ID_2, CLOUD_PRIMARY_PROVIDER_AUTHORITY);
         }
 
         final Bundle localAlbumAndMimeTypeQueryArgs = buildQueryArgs(ALBUM_ID_1,
-                ALBUM_COLUMN_TYPE_LOCAL, IMAGE_MIME_TYPE, SIZE_BYTES_DEFAULT);
+                LOCAL_PROVIDER_AUTHORITY, IMAGE_MIME_TYPE, SIZE_BYTES_DEFAULT);
 
         final Bundle cloudAlbumAndMimeTypeQueryArgs = buildQueryArgs(ALBUM_ID_2,
-                ALBUM_COLUMN_TYPE_CLOUD, IMAGE_MIME_TYPE, SIZE_BYTES_DEFAULT);
+                CLOUD_PRIMARY_PROVIDER_AUTHORITY, IMAGE_MIME_TYPE, SIZE_BYTES_DEFAULT);
 
         try (Cursor cr = mDataLayer.fetchMedia(localAlbumAndMimeTypeQueryArgs)) {
             assertWithMessage("Local album count").that(cr.getCount()).isEqualTo(1);
@@ -452,15 +451,15 @@
         try (Cursor cr = mDataLayer.fetchAlbums(sizeQueryArgs)) {
             assertThat(cr.getCount()).isEqualTo(2);
 
-            assertAlbumCursor(cr, ALBUM_ID_1, ALBUM_COLUMN_TYPE_LOCAL);
-            assertAlbumCursor(cr, ALBUM_ID_2, ALBUM_COLUMN_TYPE_CLOUD);
+            assertAlbumCursor(cr, ALBUM_ID_1, LOCAL_PROVIDER_AUTHORITY);
+            assertAlbumCursor(cr, ALBUM_ID_2, CLOUD_PRIMARY_PROVIDER_AUTHORITY);
         }
 
         final Bundle localAlbumAndSizeQueryArgs = buildQueryArgs(ALBUM_ID_1,
-                ALBUM_COLUMN_TYPE_LOCAL, MIME_TYPE_DEFAULT, SIZE_BYTES -1);
+                LOCAL_PROVIDER_AUTHORITY, MIME_TYPE_DEFAULT, SIZE_BYTES -1);
 
         final Bundle cloudAlbumAndSizeQueryArgs = buildQueryArgs(ALBUM_ID_2,
-                ALBUM_COLUMN_TYPE_CLOUD, MIME_TYPE_DEFAULT, SIZE_BYTES -1);
+                CLOUD_PRIMARY_PROVIDER_AUTHORITY, MIME_TYPE_DEFAULT, SIZE_BYTES -1);
 
         try (Cursor cr = mDataLayer.fetchMedia(localAlbumAndSizeQueryArgs)) {
             assertWithMessage("Local album count").that(cr.getCount()).isEqualTo(1);
@@ -496,13 +495,13 @@
         final Bundle mimeTypeAndSizeQueryArgs = buildQueryArgs(VIDEO_MIME_TYPE, SIZE_BYTES -1);
 
         final Bundle cloudAlbumAndMimeTypeQueryArgs = buildQueryArgs(ALBUM_ID_2,
-                ALBUM_COLUMN_TYPE_CLOUD, VIDEO_MIME_TYPE, SIZE_BYTES - 1);
+                CLOUD_PRIMARY_PROVIDER_AUTHORITY, VIDEO_MIME_TYPE, SIZE_BYTES - 1);
 
         try (Cursor cr = mDataLayer.fetchAlbums(mimeTypeAndSizeQueryArgs)) {
             assertWithMessage("Local album count").that(cr.getCount()).isEqualTo(2);
 
-            assertAlbumCursor(cr, ALBUM_ID_1, ALBUM_COLUMN_TYPE_LOCAL);
-            assertAlbumCursor(cr, ALBUM_ID_2, ALBUM_COLUMN_TYPE_CLOUD);
+            assertAlbumCursor(cr, ALBUM_ID_1, LOCAL_PROVIDER_AUTHORITY);
+            assertAlbumCursor(cr, ALBUM_ID_2, CLOUD_PRIMARY_PROVIDER_AUTHORITY);
         }
 
         try (Cursor cr = mDataLayer.fetchMedia(cloudAlbumAndMimeTypeQueryArgs)) {
@@ -561,17 +560,12 @@
         return queryArgs;
     }
 
-    private static Bundle buildQueryArgs(String albumId, String albumType, String mimeType,
+    private static Bundle buildQueryArgs(String albumId, String albumAuthority, String mimeType,
             long sizeBytes) {
         final Bundle queryArgs = buildQueryArgs(mimeType, sizeBytes);
 
         queryArgs.putString(MediaStore.QUERY_ARG_ALBUM_ID, albumId);
-        queryArgs.putString(MediaStore.QUERY_ARG_ALBUM_TYPE, albumType);
-
-        if (Objects.equals(albumType, ALBUM_COLUMN_TYPE_CLOUD)) {
-            queryArgs.putString(MediaStore.EXTRA_CLOUD_PROVIDER,
-                    CLOUD_PRIMARY_PROVIDER_AUTHORITY);
-        }
+        queryArgs.putString(MediaStore.QUERY_ARG_ALBUM_AUTHORITY, albumAuthority);
 
         return queryArgs;
     }
@@ -602,30 +596,31 @@
         }
     }
 
-    private static void assertAlbumCursor(Cursor cursor, String id, String type) {
+    private static void assertAlbumCursor(Cursor cursor, String id, String expectedAuthority) {
         cursor.moveToNext();
         assertThat(cursor.getString(cursor.getColumnIndex(AlbumColumns.ID)))
                 .isEqualTo(id);
-        assertThat(cursor.getString(cursor.getColumnIndex(AlbumColumns.TYPE)))
-                .isEqualTo(type);
+        final int authorityIdx = cursor.getColumnIndex(AlbumColumns.AUTHORITY);
+        String authority = null;
+        if (authorityIdx >= 0) {
+            // Cursor from picker db has authority as a column
+            authority = cursor.getString(authorityIdx);
+        }
+        if (authority == null) {
+            // Cursor from provider directly doesn't have an authority column but will
+            // have the authority set as an extra
+            final Bundle bundle = cursor.getExtras();
+            authority = bundle.getString(MediaStore.EXTRA_CLOUD_PROVIDER);
+        }
+
+        assertThat(authority).isEqualTo(expectedAuthority);
     }
 
     private static void assertCursor(Cursor cursor, String id, String expectedAuthority) {
         cursor.moveToNext();
         assertThat(cursor.getString(cursor.getColumnIndex(MediaColumns.ID)))
                 .isEqualTo(id);
-
-        final int authorityIdx = cursor.getColumnIndex(MediaColumns.AUTHORITY);
-        final String authority;
-        if (authorityIdx >= 0) {
-            // Cursor from picker db has authority as a column
-            authority = cursor.getString(authorityIdx);
-        } else {
-            // Cursor from provider directly doesn't have an authority column but will
-            // have the authority set as an extra
-            final Bundle bundle = cursor.getExtras();
-            authority = bundle.getString(MediaColumns.AUTHORITY);
-        }
-        assertThat(authority).isEqualTo(expectedAuthority);
+        assertThat(cursor.getString(cursor.getColumnIndex(MediaColumns.AUTHORITY)))
+                .isEqualTo(expectedAuthority);
     }
 }
diff --git a/tests/src/com/android/providers/media/photopicker/PickerSyncControllerTest.java b/tests/src/com/android/providers/media/photopicker/PickerSyncControllerTest.java
index faeb430..d8bc5f5 100644
--- a/tests/src/com/android/providers/media/photopicker/PickerSyncControllerTest.java
+++ b/tests/src/com/android/providers/media/photopicker/PickerSyncControllerTest.java
@@ -16,7 +16,6 @@
 
 package com.android.providers.media.photopicker;
 
-import static com.android.providers.media.PickerProviderMediaGenerator.ALBUM_COLUMN_TYPE_CLOUD;
 import static com.android.providers.media.PickerProviderMediaGenerator.MediaGenerator;
 import static com.android.providers.media.photopicker.PickerSyncController.CloudProviderInfo;
 import static com.google.common.truth.Truth.assertThat;
@@ -26,6 +25,7 @@
 import android.os.Bundle;
 import android.os.Process;
 import android.os.SystemClock;
+import android.provider.CloudMediaProviderContract;
 import android.provider.CloudMediaProviderContract.MediaColumns;
 import android.provider.MediaStore;
 import android.util.Pair;
@@ -815,17 +815,12 @@
         return queryArgs;
     }
 
-    private static Bundle buildQueryArgs(String albumId, String albumType, String mimeType,
+    private static Bundle buildQueryArgs(String albumId, String albumAuthority, String mimeType,
             long sizeBytes) {
         final Bundle queryArgs = buildQueryArgs(mimeType, sizeBytes);
 
         queryArgs.putString(MediaStore.QUERY_ARG_ALBUM_ID, albumId);
-        queryArgs.putString(MediaStore.QUERY_ARG_ALBUM_TYPE, albumType);
-
-        if (Objects.equals(albumType, ALBUM_COLUMN_TYPE_CLOUD)) {
-            queryArgs.putString(MediaStore.EXTRA_CLOUD_PROVIDER,
-                    CLOUD_PRIMARY_PROVIDER_AUTHORITY);
-        }
+        queryArgs.putString(MediaStore.QUERY_ARG_ALBUM_AUTHORITY, albumAuthority);
 
         return queryArgs;
     }
@@ -890,18 +885,7 @@
         cursor.moveToNext();
         assertThat(cursor.getString(cursor.getColumnIndex(MediaColumns.ID)))
                 .isEqualTo(id);
-
-        final int authorityIdx = cursor.getColumnIndex(MediaColumns.AUTHORITY);
-        final String authority;
-        if (authorityIdx >= 0) {
-            // Cursor from picker db has authority as a column
-            authority = cursor.getString(authorityIdx);
-        } else {
-            // Cursor from provider directly doesn't have an authority column but will
-            // have the authority set as an extra
-            final Bundle bundle = cursor.getExtras();
-            authority = bundle.getString(MediaColumns.AUTHORITY);
-        }
-        assertThat(authority).isEqualTo(expectedAuthority);
+        assertThat(cursor.getString(cursor.getColumnIndex( MediaColumns.AUTHORITY)))
+                .isEqualTo(expectedAuthority);
     }
 }
diff --git a/tests/src/com/android/providers/media/photopicker/data/ExternalDbFacadeTest.java b/tests/src/com/android/providers/media/photopicker/data/ExternalDbFacadeTest.java
index d24dcab..e900239 100644
--- a/tests/src/com/android/providers/media/photopicker/data/ExternalDbFacadeTest.java
+++ b/tests/src/com/android/providers/media/photopicker/data/ExternalDbFacadeTest.java
@@ -16,6 +16,11 @@
 
 package com.android.providers.media.photopicker.data;
 
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_VIDEOS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_SCREENSHOTS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_CAMERA;
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_DOWNLOADS;
+
 import static android.provider.MediaStore.Files.FileColumns._SPECIAL_FORMAT_NONE;
 import static android.provider.MediaStore.Files.FileColumns._SPECIAL_FORMAT_GIF;
 
@@ -536,7 +541,7 @@
             }
 
             try (Cursor cursor = facade.queryMediaGeneration(/* generation */ 0,
-                            Category.CATEGORY_CAMERA, /* mimeType */ null)) {
+                            ALBUM_ID_CAMERA, /* mimeType */ null)) {
                 assertThat(cursor.getCount()).isEqualTo(1);
 
                 cursor.moveToFirst();
@@ -544,7 +549,7 @@
             }
 
             try (Cursor cursor = facade.queryMediaGeneration(/* generation */ 0,
-                            Category.CATEGORY_SCREENSHOTS, /* mimeType */ null)) {
+                            ALBUM_ID_SCREENSHOTS, /* mimeType */ null)) {
                 assertThat(cursor.getCount()).isEqualTo(1);
 
                 cursor.moveToFirst();
@@ -552,7 +557,7 @@
             }
 
             try (Cursor cursor = facade.queryMediaGeneration(/* generation */ 0,
-                            Category.CATEGORY_DOWNLOADS, /* mimeType */ null)) {
+                            ALBUM_ID_DOWNLOADS, /* mimeType */ null)) {
                 assertThat(cursor.getCount()).isEqualTo(1);
 
                 cursor.moveToFirst();
@@ -560,7 +565,7 @@
             }
 
             try (Cursor cursor = facade.queryMediaGeneration(/* generation */ 0,
-                            Category.CATEGORY_VIDEOS, /* mimeType */ null)) {
+                            ALBUM_ID_VIDEOS, /* mimeType */ null)) {
                 assertThat(cursor.getCount()).isEqualTo(2);
 
                 cursor.moveToFirst();
@@ -592,17 +597,17 @@
             }
 
             try (Cursor cursor = facade.queryMediaGeneration(/* generation */ 0,
-                            Category.CATEGORY_SCREENSHOTS, IMAGE_MIME_TYPE)) {
+                            ALBUM_ID_SCREENSHOTS, IMAGE_MIME_TYPE)) {
                 assertThat(cursor.getCount()).isEqualTo(0);
             }
 
             try (Cursor cursor = facade.queryMediaGeneration(/* generation */ 0,
-                            Category.CATEGORY_CAMERA, VIDEO_MIME_TYPE)) {
+                            ALBUM_ID_CAMERA, VIDEO_MIME_TYPE)) {
                 assertThat(cursor.getCount()).isEqualTo(0);
             }
 
             try (Cursor cursor = facade.queryMediaGeneration(/* generation */ 0,
-                            Category.CATEGORY_CAMERA, IMAGE_MIME_TYPE)) {
+                            ALBUM_ID_CAMERA, IMAGE_MIME_TYPE)) {
                 assertThat(cursor.getCount()).isEqualTo(1);
 
                 cursor.moveToFirst();
@@ -783,7 +788,7 @@
                 cursor.moveToNext();
                 assertAlbumColumns(facade,
                         cursor,
-                        Category.getCategoryName(sIsolatedContext, Category.CATEGORY_CAMERA),
+                        ALBUM_ID_CAMERA,
                         /* mediaCoverId */ "1",
                         DATE_TAKEN_MS1,
                         /* count */ 1);
@@ -791,7 +796,7 @@
                 cursor.moveToNext();
                 assertAlbumColumns(facade,
                         cursor,
-                        Category.getCategoryName(sIsolatedContext, Category.CATEGORY_VIDEOS),
+                        ALBUM_ID_VIDEOS,
                         /* mediaCoverId */ "5",
                         DATE_TAKEN_MS5,
                         /* count */ 2);
@@ -799,7 +804,7 @@
                 cursor.moveToNext();
                 assertAlbumColumns(facade,
                         cursor,
-                        Category.getCategoryName(sIsolatedContext, Category.CATEGORY_SCREENSHOTS),
+                        ALBUM_ID_SCREENSHOTS,
                         /* mediaCoverId */ "2",
                         DATE_TAKEN_MS2,
                         /* count */ 1);
@@ -807,7 +812,7 @@
                 cursor.moveToNext();
                 assertAlbumColumns(facade,
                         cursor,
-                        Category.getCategoryName(sIsolatedContext, Category.CATEGORY_DOWNLOADS),
+                        ALBUM_ID_DOWNLOADS,
                         /* mediaCoverId */ "3",
                         DATE_TAKEN_MS3,
                         /* count */ 1);
@@ -848,7 +853,7 @@
                 cursor.moveToNext();
                 assertAlbumColumns(facade,
                         cursor,
-                        Category.getCategoryName(sIsolatedContext, Category.CATEGORY_CAMERA),
+                        ALBUM_ID_CAMERA,
                         /* mediaCoverId */ "1",
                         DATE_TAKEN_MS1,
                         /* count */ 1);
@@ -856,6 +861,17 @@
         }
     }
 
+    @Test
+    public void testOrderOfLocalAlbumIds() {
+        // Camera, Videos, ScreenShots, Downloads
+        assertThat(ExternalDbFacade.LOCAL_ALBUM_IDS[0]).isEqualTo(ALBUM_ID_CAMERA);
+        assertThat(ExternalDbFacade.LOCAL_ALBUM_IDS[1]).isEqualTo(ALBUM_ID_VIDEOS);
+        assertThat(ExternalDbFacade.LOCAL_ALBUM_IDS[2])
+                .isEqualTo(ALBUM_ID_SCREENSHOTS);
+        assertThat(ExternalDbFacade.LOCAL_ALBUM_IDS[3])
+                .isEqualTo(ALBUM_ID_DOWNLOADS);
+    }
+
     private static void initMediaInAllAlbums(DatabaseHelper helper) {
         // Insert in camera album
         ContentValues cv1 = getContentValues(DATE_TAKEN_MS1, GENERATION_MODIFIED1);
diff --git a/tests/src/com/android/providers/media/photopicker/data/PickerDbFacadeTest.java b/tests/src/com/android/providers/media/photopicker/data/PickerDbFacadeTest.java
index e650ff0..4cb1dcb 100644
--- a/tests/src/com/android/providers/media/photopicker/data/PickerDbFacadeTest.java
+++ b/tests/src/com/android/providers/media/photopicker/data/PickerDbFacadeTest.java
@@ -16,6 +16,7 @@
 
 package com.android.providers.media.photopicker.data;
 
+import static android.provider.CloudMediaProviderContract.AlbumColumns.ALBUM_ID_FAVORITES;
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.junit.Assert.assertThrows;
@@ -23,6 +24,7 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.database.MatrixCursor;
+import android.provider.CloudMediaProviderContract;
 import android.provider.CloudMediaProviderContract.AlbumColumns;
 import android.provider.CloudMediaProviderContract.MediaColumns;
 import android.provider.MediaStore.PickerMediaColumns;
@@ -30,7 +32,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.providers.media.photopicker.data.model.Category;
+
 
 import java.io.File;
 
@@ -865,8 +867,8 @@
             assertThat(cr.getCount()).isEqualTo(1);
             cr.moveToFirst();
             assertCloudAlbumCursor(cr,
-                    Category.CATEGORY_FAVORITES,
-                    Category.getCategoryName(mContext, Category.CATEGORY_FAVORITES),
+                    ALBUM_ID_FAVORITES,
+                    ALBUM_ID_FAVORITES,
                     LOCAL_ID + "1",
                     DATE_TAKEN_MS,
                     /* count */ 2);
@@ -911,8 +913,8 @@
             assertThat(cr.getCount()).isEqualTo(1);
             cr.moveToFirst();
             assertCloudAlbumCursor(cr,
-                    Category.CATEGORY_FAVORITES,
-                    Category.getCategoryName(mContext, Category.CATEGORY_FAVORITES),
+                    ALBUM_ID_FAVORITES,
+                    ALBUM_ID_FAVORITES,
                     LOCAL_ID + "1",
                     DATE_TAKEN_MS,
                     /* count */ 2);
@@ -923,8 +925,8 @@
             assertThat(cr.getCount()).isEqualTo(1);
             cr.moveToFirst();
             assertCloudAlbumCursor(cr,
-                    Category.CATEGORY_FAVORITES,
-                    Category.getCategoryName(mContext, Category.CATEGORY_FAVORITES),
+                    ALBUM_ID_FAVORITES,
+                    ALBUM_ID_FAVORITES,
                     CLOUD_ID + "1",
                     DATE_TAKEN_MS,
                     /* count */ 1);
@@ -935,8 +937,8 @@
             assertThat(cr.getCount()).isEqualTo(1);
             cr.moveToFirst();
             assertCloudAlbumCursor(cr,
-                    Category.CATEGORY_FAVORITES,
-                    Category.getCategoryName(mContext, Category.CATEGORY_FAVORITES),
+                    ALBUM_ID_FAVORITES,
+                    ALBUM_ID_FAVORITES,
                     LOCAL_ID + "1",
                     DATE_TAKEN_MS,
                     /* count */ 1);
diff --git a/tests/src/com/android/providers/media/photopicker/data/model/CategoryTest.java b/tests/src/com/android/providers/media/photopicker/data/model/CategoryTest.java
index 80132a8..808f70b 100644
--- a/tests/src/com/android/providers/media/photopicker/data/model/CategoryTest.java
+++ b/tests/src/com/android/providers/media/photopicker/data/model/CategoryTest.java
@@ -16,14 +16,7 @@
 
 package com.android.providers.media.photopicker.data.model;
 
-import static com.android.providers.media.photopicker.data.model.Category.CATEGORY_CAMERA;
-import static com.android.providers.media.photopicker.data.model.Category.CATEGORY_DEFAULT;
-import static com.android.providers.media.photopicker.data.model.Category.CATEGORY_DOWNLOADS;
-import static com.android.providers.media.photopicker.data.model.Category.CATEGORY_FAVORITES;
-import static com.android.providers.media.photopicker.data.model.Category.CATEGORY_SCREENSHOTS;
-import static com.android.providers.media.photopicker.data.model.Category.CATEGORY_VIDEOS;
-import static com.android.providers.media.photopicker.data.model.Category.CategoryColumns;
-import static com.android.providers.media.photopicker.data.model.Category.CategoryType;
+import static android.provider.CloudMediaProviderContract.AlbumColumns;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -31,6 +24,7 @@
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.net.Uri;
+import android.provider.CloudMediaProviderContract;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
@@ -47,97 +41,31 @@
 
     @Test
     public void testConstructor() {
+        final Context context = InstrumentationRegistry.getTargetContext();
         final int itemCount = 10;
         final String categoryName = "Album";
         final String coverId = "52";
-        final String categoryType = CATEGORY_SCREENSHOTS;
-        final Cursor cursor = generateCursorForCategory(categoryName, coverId, itemCount,
-                categoryType);
+        final String categoryId = "Album";
+        final boolean categoryIsLocal = true;
+        final Cursor cursor = generateCursorForCategory(categoryId, categoryName,
+                coverId, itemCount, categoryIsLocal);
         cursor.moveToFirst();
 
-        final Category category = new Category(cursor, UserId.CURRENT_USER);
+        final Category category = Category.fromCursor(cursor, UserId.CURRENT_USER);
 
-        assertThat(category.getCategoryName(/* context= */ null)).isEqualTo(categoryName);
+        assertThat(category.getDisplayName(context)).isEqualTo(categoryName);
+        assertThat(category.isLocal()).isEqualTo(categoryIsLocal);
         assertThat(category.getItemCount()).isEqualTo(itemCount);
         assertThat(category.getCoverUri()).isEqualTo(ItemsProvider.getItemsUri(coverId,
-                        /* authority */ null, UserId.CURRENT_USER));
-        assertThat(category.getCategoryType()).isEqualTo(categoryType);
+                        /* authority */ "foo", UserId.CURRENT_USER));
+        assertThat(category.getId()).isEqualTo(categoryId);
     }
 
-    /**
-     * If the {@code category} is not in {@link Category#CATEGORIES}, return {@code null}.
-     */
-    @Test
-    public void testGetCategoryName_notInList_returnNull() {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        final String categoryName = Category.getCategoryName(context, CATEGORY_DEFAULT);
-
-        assertThat(categoryName).isNull();
-    }
-
-    @Test
-    public void testGetCategoryName_camera() {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        final String categoryName = Category.getCategoryName(context, CATEGORY_CAMERA);
-
-        assertThat(categoryName).isEqualTo("Camera");
-    }
-
-    @Test
-    public void testGetCategoryName_downloads() {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        final String categoryName = Category.getCategoryName(context, CATEGORY_DOWNLOADS);
-
-        assertThat(categoryName).isEqualTo("Downloads");
-    }
-
-    @Test
-    public void testGetCategoryName_favorites() {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        final String categoryName = Category.getCategoryName(context, CATEGORY_FAVORITES);
-
-        assertThat(categoryName).isEqualTo("Favorites");
-    }
-
-    @Test
-    public void testGetCategoryName_screenshots() {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        final String categoryName = Category.getCategoryName(context, CATEGORY_SCREENSHOTS);
-
-        assertThat(categoryName).isEqualTo("Screenshots");
-    }
-
-    @Test
-    public void testGetCategoryName_videos() {
-        final Context context = InstrumentationRegistry.getTargetContext();
-        final String categoryName = Category.getCategoryName(context, CATEGORY_VIDEOS);
-
-        assertThat(categoryName).isEqualTo("Videos");
-    }
-
-    @Test
-    public void testGetDefaultCategory() {
-        final Category category = Category.getDefaultCategory();
-
-        assertThat(category.getCategoryType()).isEqualTo(CATEGORY_DEFAULT);
-    }
-
-    @Test
-    public void testOrderOfCategories() {
-        final List<String> categoryList = Category.CATEGORIES_LIST;
-
-        // Favorites, Camera, Videos, ScreenShots, Downloads
-        assertThat(categoryList.get(0)).isEqualTo(CATEGORY_FAVORITES);
-        assertThat(categoryList.get(1)).isEqualTo(CATEGORY_CAMERA);
-        assertThat(categoryList.get(2)).isEqualTo(CATEGORY_VIDEOS);
-        assertThat(categoryList.get(3)).isEqualTo(CATEGORY_SCREENSHOTS);
-        assertThat(categoryList.get(4)).isEqualTo(CATEGORY_DOWNLOADS);
-    }
-
-    private static Cursor generateCursorForCategory(String categoryName, String coverId,
-            int itemCount, @CategoryType String categoryType) {
-        final MatrixCursor cursor = new MatrixCursor(CategoryColumns.getAllColumns());
-        cursor.addRow(new Object[] {categoryName, coverId, itemCount, categoryType});
+    private static Cursor generateCursorForCategory(String categoryId, String categoryName,
+            String coverId, int itemCount, boolean isLocal) {
+        final MatrixCursor cursor = new MatrixCursor(AlbumColumns.ALL_PROJECTION);
+        cursor.addRow(new Object[] {categoryId, 1, categoryName, coverId, itemCount,
+                                    "foo"});
         return cursor;
     }
 }
diff --git a/tests/src/com/android/providers/media/photopicker/data/model/ItemTest.java b/tests/src/com/android/providers/media/photopicker/data/model/ItemTest.java
index 1f940e8..a78bbef 100644
--- a/tests/src/com/android/providers/media/photopicker/data/model/ItemTest.java
+++ b/tests/src/com/android/providers/media/photopicker/data/model/ItemTest.java
@@ -16,13 +16,12 @@
 
 package com.android.providers.media.photopicker.data.model;
 
+import static android.provider.CloudMediaProviderContract.MediaColumns;
 import static android.provider.MediaStore.Files.FileColumns._SPECIAL_FORMAT_ANIMATED_WEBP;
 import static android.provider.MediaStore.Files.FileColumns._SPECIAL_FORMAT_GIF;
 import static android.provider.MediaStore.Files.FileColumns._SPECIAL_FORMAT_MOTION_PHOTO;
 import static android.provider.MediaStore.Files.FileColumns._SPECIAL_FORMAT_NONE;
 
-import static com.android.providers.media.photopicker.data.model.Item.ItemColumns;
-
 import static com.google.common.truth.Truth.assertThat;
 
 import android.content.Context;
@@ -35,6 +34,8 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.providers.media.photopicker.PickerSyncController;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -62,7 +63,8 @@
         assertThat(item.getGenerationModified()).isEqualTo(generationModified);
         assertThat(item.getMimeType()).isEqualTo(mimeType);
         assertThat(item.getDuration()).isEqualTo(duration);
-        assertThat(item.getContentUri()).isEqualTo(Uri.parse("content://media/external/file/1"));
+        assertThat(item.getContentUri()).isEqualTo(
+                Uri.parse("content://com.android.providers.media.photopicker/media/1"));
 
         assertThat(item.isDate()).isFalse();
         assertThat(item.isImage()).isTrue();
@@ -90,7 +92,8 @@
         assertThat(item.getGenerationModified()).isEqualTo(generationModified);
         assertThat(item.getMimeType()).isEqualTo(mimeType);
         assertThat(item.getDuration()).isEqualTo(duration);
-        assertThat(item.getContentUri()).isEqualTo(Uri.parse("content://10@media/external/file/1"));
+        assertThat(item.getContentUri()).isEqualTo(
+                Uri.parse("content://10@com.android.providers.media.photopicker/media/1"));
 
         assertThat(item.isImage()).isTrue();
 
@@ -312,9 +315,19 @@
 
     private static Cursor generateCursorForItem(String id, String mimeType, long dateTaken,
             long generationModified, long duration, int specialFormat) {
-        final MatrixCursor cursor = new MatrixCursor(ItemColumns.ALL_COLUMNS);
-        cursor.addRow(new Object[] {id, mimeType, dateTaken, dateTaken /* dateModified */,
-                generationModified, duration, specialFormat});
+        final MatrixCursor cursor = new MatrixCursor(MediaColumns.ALL_PROJECTION);
+        cursor.addRow(new Object[] {
+                    id,
+                    dateTaken,
+                    generationModified,
+                    mimeType,
+                    specialFormat,
+                    "1", // size_bytes
+                    null, // media_store_uri
+                    duration,
+                    "0", // is_favorite
+                    "/storage/emulated/0/foo", // data
+                    PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY});
         return cursor;
     }
 
diff --git a/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelTest.java b/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelTest.java
index fc5c5a5..458725b 100644
--- a/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelTest.java
+++ b/tests/src/com/android/providers/media/photopicker/viewmodel/PickerViewModelTest.java
@@ -16,7 +16,8 @@
 
 package com.android.providers.media.photopicker.viewmodel;
 
-import static com.android.providers.media.photopicker.data.model.Category.CATEGORY_DOWNLOADS;
+import static android.provider.CloudMediaProviderContract.AlbumColumns;
+import static android.provider.CloudMediaProviderContract.MediaColumns;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -28,6 +29,8 @@
 import android.content.Intent;
 import android.database.Cursor;
 import android.database.MatrixCursor;
+import android.net.Uri;
+import android.provider.CloudMediaProviderContract;
 import android.text.format.DateUtils;
 
 import androidx.annotation.NonNull;
@@ -35,6 +38,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.providers.media.photopicker.PickerSyncController;
 import com.android.providers.media.photopicker.data.ItemsProvider;
 import com.android.providers.media.photopicker.data.UserIdManager;
 import com.android.providers.media.photopicker.data.model.Category;
@@ -60,6 +64,10 @@
     private static final String FAKE_CATEGORY_NAME = "testCategoryName";
     private static final String FAKE_ID = "5";
 
+    private static final Category FAKE_CATEGORY =
+            new Category(FAKE_ID, PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY,
+                    FAKE_CATEGORY_NAME, Uri.parse("content://media/foo"), 0, true);
+
     @Rule
     public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule();
 
@@ -179,13 +187,12 @@
     public void testGetCategoryItems() throws Exception {
         final int itemCount = 3;
         mItemsProvider.setItems(generateFakeImageItemList(itemCount));
-        mPickerViewModel.updateCategoryItems(CATEGORY_DOWNLOADS);
+        mPickerViewModel.updateCategoryItems(FAKE_CATEGORY);
         // We use ForegroundThread to execute the loadItems in updateCategoryItems(), wait for the
         // thread idle
         ForegroundThread.waitForIdle();
 
-        final List<Item> itemList = mPickerViewModel.getCategoryItems(
-                CATEGORY_DOWNLOADS).getValue();
+        final List<Item> itemList = mPickerViewModel.getCategoryItems(FAKE_CATEGORY).getValue();
 
         // Original item count + 3 date items
         assertThat(itemList.size()).isEqualTo(itemCount + 3);
@@ -207,13 +214,12 @@
     public void testGetCategoryItems_dataIsUpdated() throws Exception {
         final int itemCount = 3;
         mItemsProvider.setItems(generateFakeImageItemList(itemCount));
-        mPickerViewModel.updateCategoryItems(CATEGORY_DOWNLOADS);
+        mPickerViewModel.updateCategoryItems(FAKE_CATEGORY);
         // We use ForegroundThread to execute the loadItems in updateCategoryItems(), wait for the
         // thread idle
         ForegroundThread.waitForIdle();
 
-        final List<Item> itemList = mPickerViewModel.getCategoryItems(
-                CATEGORY_DOWNLOADS).getValue();
+        final List<Item> itemList = mPickerViewModel.getCategoryItems(FAKE_CATEGORY).getValue();
 
         // Original item count + 3 date items
         assertThat(itemList.size()).isEqualTo(itemCount + 3);
@@ -222,15 +228,15 @@
         mItemsProvider.setItems(generateFakeImageItemList(updatedItemCount));
 
         // trigger updateCategoryItems in getCategoryItems first and wait the idle
-        mPickerViewModel.getCategoryItems(CATEGORY_DOWNLOADS).getValue();
+        mPickerViewModel.getCategoryItems(FAKE_CATEGORY).getValue();
 
         // We use ForegroundThread to execute the loadItems in updateCategoryItems(), wait for the
         // thread idle
         ForegroundThread.waitForIdle();
 
         // Get the result again to check the result is as expected
-        final List<Item> updatedItemList = mPickerViewModel.getCategoryItems(
-                CATEGORY_DOWNLOADS).getValue();
+        final List<Item> updatedItemList =
+                mPickerViewModel.getCategoryItems(FAKE_CATEGORY).getValue();
 
         // Original item count + 5 date items
         assertThat(updatedItemList.size()).isEqualTo(updatedItemCount + 5);
@@ -238,6 +244,7 @@
 
     @Test
     public void testGetCategories() throws Exception {
+        final Context context = InstrumentationRegistry.getTargetContext();
         final int categoryCount = 2;
         try (final Cursor fakeCursor = generateCursorForFakeCategories(categoryCount)) {
             fakeCursor.moveToFirst();
@@ -258,18 +265,14 @@
             assertThat(categoryList.size()).isEqualTo(categoryCount);
             // Verify the first category
             final Category firstCategory = categoryList.get(0);
-            assertThat(firstCategory.getCategoryType()).isEqualTo(
-                    fakeFirstCategory.getCategoryType());
-            assertThat(firstCategory.getCategoryName(/* context= */ null)).isEqualTo(
-                    fakeFirstCategory.getCategoryName(/* context= */ null));
+            assertThat(firstCategory.getDisplayName(context)).isEqualTo(
+                    fakeFirstCategory.getDisplayName(context));
             assertThat(firstCategory.getItemCount()).isEqualTo(fakeFirstCategory.getItemCount());
             assertThat(firstCategory.getCoverUri()).isEqualTo(fakeFirstCategory.getCoverUri());
             // Verify the second category
             final Category secondCategory = categoryList.get(1);
-            assertThat(secondCategory.getCategoryType()).isEqualTo(
-                    fakeSecondCategory.getCategoryType());
-            assertThat(secondCategory.getCategoryName(/* context= */ null)).isEqualTo(
-                    fakeSecondCategory.getCategoryName(/* context= */ null));
+            assertThat(secondCategory.getDisplayName(context)).isEqualTo(
+                    fakeSecondCategory.getDisplayName(context));
             assertThat(secondCategory.getItemCount()).isEqualTo(fakeSecondCategory.getItemCount());
             assertThat(secondCategory.getCoverUri()).isEqualTo(fakeSecondCategory.getCoverUri());
         }
@@ -294,14 +297,17 @@
     }
 
     private static Cursor generateCursorForFakeCategories(int num) {
-        final MatrixCursor cursor = new MatrixCursor(Category.CategoryColumns.getAllColumns());
+        final MatrixCursor cursor = new MatrixCursor(AlbumColumns.ALL_PROJECTION);
         final int itemCount = 5;
         for (int i = 0; i < num; i++) {
             cursor.addRow(new Object[]{
+                    FAKE_ID + String.valueOf(i),
+                    System.currentTimeMillis(),
                     FAKE_CATEGORY_NAME + i,
                     FAKE_ID + String.valueOf(i),
                     itemCount + i,
-                    CATEGORY_DOWNLOADS});
+                    PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY
+                    });
         }
         return cursor;
     }
@@ -316,21 +322,24 @@
         }
 
         @Override
-        public Cursor getItems(@Nullable @Category.CategoryType String category, int offset,
+        public Cursor getItems(Category category, int offset,
                 int limit, @Nullable String mimeType, @Nullable UserId userId) throws
                 IllegalArgumentException, IllegalStateException {
-            final String[] columns = Item.ItemColumns.ALL_COLUMNS;
-            final MatrixCursor c = new MatrixCursor(columns);
+            final MatrixCursor c = new MatrixCursor(MediaColumns.ALL_PROJECTION);
 
             for (Item item : mItemList) {
                 c.addRow(new String[] {
                         item.getId(),
-                        item.getMimeType(),
-                        String.valueOf(item.getDateTaken()),
                         String.valueOf(item.getDateTaken()),
                         String.valueOf(item.getGenerationModified()),
-                        String.valueOf(item.getDuration()),
+                        item.getMimeType(),
                         String.valueOf(item.getSpecialFormat()),
+                        "1", // size_bytes
+                        null, // media_store_uri
+                        String.valueOf(item.getDuration()),
+                        "0", // is_favorite
+                        "/storage/emulated/0/foo",
+                        PickerSyncController.LOCAL_PICKER_PROVIDER_AUTHORITY
                 });
             }
 
@@ -343,7 +352,7 @@
                 return mCategoriesCursor;
             }
 
-            final MatrixCursor c = new MatrixCursor(Category.CategoryColumns.getAllColumns());
+            final MatrixCursor c = new MatrixCursor(AlbumColumns.ALL_PROJECTION);
             return c;
         }