Support GIF badge and video badge in PhotoPicker

Test: manual. screenshot on the bug
Bug: 188885093
Change-Id: I9eace2fd687c8d0c496ac883d556c252ccddf5b3
Merged-In: I9eace2fd687c8d0c496ac883d556c252ccddf5b3
(cherry picked from commit 10319359c76c9096326171efc4819f78099d374a)
diff --git a/res/drawable/ic_gif.xml b/res/drawable/ic_gif.xml
new file mode 100644
index 0000000..f0d1c98
--- /dev/null
+++ b/res/drawable/ic_gif.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M11.5,9L13,9v6h-1.5L11.5,9zM9,9L6,9c-0.6,0 -1,0.5 -1,1v4c0,0.5 0.4,1 1,1h3c0.6,0 1,-0.5 1,-1v-2L8.5,12v1.5h-2v-3L10,10.5L10,10c0,-0.5 -0.4,-1 -1,-1zM19,10.5L19,9h-4.5v6L16,15v-2h2v-1.5h-2v-1h3z"/>
+</vector>
diff --git a/res/drawable/ic_play_circle_filled.xml b/res/drawable/ic_play_circle_filled.xml
new file mode 100644
index 0000000..e7509a2
--- /dev/null
+++ b/res/drawable/ic_play_circle_filled.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="18dp"
+        android:height="18dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,16.5v-9l6,4.5 -6,4.5z"/>
+</vector>
diff --git a/res/layout/item_photo_grid.xml b/res/layout/item_photo_grid.xml
index 5065d6e..f9ced81 100644
--- a/res/layout/item_photo_grid.xml
+++ b/res/layout/item_photo_grid.xml
@@ -31,12 +31,56 @@
         app:cardElevation="0dp"
         app:cardCornerRadius="0dp">
 
-        <com.android.providers.media.photopicker.ui.SquareImageView
-            android:id="@+id/icon_thumbnail"
+        <FrameLayout
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:scaleType="centerCrop"
-            android:contentDescription="@null"/>
+            android:layout_height="wrap_content">
+
+            <com.android.providers.media.photopicker.ui.SquareImageView
+                android:id="@+id/icon_thumbnail"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:scaleType="centerCrop"
+                android:contentDescription="@null"/>
+
+            <ImageView
+                android:id="@+id/icon_gif"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right|top"
+                android:layout_marginEnd="@dimen/picker_item_badge_margin"
+                android:layout_marginTop="@dimen/picker_item_badge_margin"
+                android:scaleType="fitCenter"
+                android:src="@drawable/ic_gif"
+                android:contentDescription="@null"/>
+
+            <LinearLayout
+                android:id="@+id/video_container"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="right|top"
+                android:layout_marginEnd="@dimen/picker_item_badge_margin"
+                android:layout_marginTop="@dimen/picker_item_badge_margin"
+                android:orientation="horizontal"
+                android:contentDescription="@null">
+
+                <TextView
+                    android:id="@+id/video_duration"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_marginEnd="@dimen/picker_item_badge_text_margin"
+                    android:layout_gravity="center_vertical"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/picker_item_badge_text_size"/>
+
+                <ImageView
+                    android:id="@+id/icon_video"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:scaleType="fitCenter"
+                    android:src="@drawable/ic_play_circle_filled"
+                    android:contentDescription="@null"/>
+            </LinearLayout>
+        </FrameLayout>
 
     </com.google.android.material.card.MaterialCardView>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 782259d..fc3c5cd 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -28,6 +28,9 @@
     <dimen name="picker_bottom_bar_elevation">8dp</dimen>
     <dimen name="picker_item_check_size">24dp</dimen>
     <dimen name="picker_item_check_margin">6dp</dimen>
+    <dimen name="picker_item_badge_margin">5dp</dimen>
+    <dimen name="picker_item_badge_text_margin">3dp</dimen>
+    <dimen name="picker_item_badge_text_size">10dp</dimen>
 
     <!-- PhotoPicker Preview -->
     <dimen name="preview_buttons_margin_horizontal">16dp</dimen>
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 b0a94a3..c73c30e 100644
--- a/src/com/android/providers/media/photopicker/data/model/Item.java
+++ b/src/com/android/providers/media/photopicker/data/model/Item.java
@@ -54,13 +54,18 @@
                 Arrays.asList(ALL_COLUMNS));
     }
 
+    private static final String MIME_TYPE_GIF = "image/gif";
+
     private long mId;
     private long mDateTaken;
+    private long mDuration;
     private String mDisplayName;
-    private int mDuration;
     private String mMimeType;
     private String mVolumeName;
     private Uri mUri;
+    private boolean mIsImage;
+    private boolean mIsVideo;
+    private boolean mIsGif;
 
     private Item() {}
 
@@ -72,8 +77,16 @@
         return mId;
     }
 
-    public boolean isPhoto() {
-        return MimeUtils.isImageMimeType(mMimeType);
+    public boolean isImage() {
+        return mIsImage;
+    }
+
+    public boolean isVideo() {
+        return mIsVideo;
+    }
+
+    public boolean isGif() {
+        return mIsGif;
     }
 
     public Uri getContentUri() {
@@ -84,7 +97,7 @@
         return mDisplayName;
     }
 
-    public int getDuration() {
+    public long getDuration() {
         return mDuration;
     }
 
@@ -116,11 +129,23 @@
         mDisplayName = getCursorString(cursor, ItemColumns.DISPLAY_NAME);
         mDateTaken = getCursorLong(cursor, ItemColumns.DATE_TAKEN);
         mVolumeName = getCursorString(cursor, ItemColumns.VOLUME_NAME);
-        mDuration = getCursorInt(cursor, ItemColumns.DURATION);
+        mDuration = getCursorLong(cursor, ItemColumns.DURATION);
 
         // TODO (b/188867567): Currently, we only has local data source,
         //  get the uri from provider
         mUri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL, mId);
+
+        parseMimeType();
+    }
+
+    private void parseMimeType() {
+        if (MIME_TYPE_GIF.equalsIgnoreCase(mMimeType)) {
+            mIsGif = true;
+        } else if (MimeUtils.isImageMimeType(mMimeType)) {
+            mIsImage = true;
+        } else if (MimeUtils.isVideoMimeType(mMimeType)) {
+            mIsVideo = true;
+        }
     }
 
     @Nullable
diff --git a/src/com/android/providers/media/photopicker/ui/PhotoGridHolder.java b/src/com/android/providers/media/photopicker/ui/PhotoGridHolder.java
index 0f683d7..4484aeb 100644
--- a/src/com/android/providers/media/photopicker/ui/PhotoGridHolder.java
+++ b/src/com/android/providers/media/photopicker/ui/PhotoGridHolder.java
@@ -17,9 +17,12 @@
 package com.android.providers.media.photopicker.ui;
 
 import android.content.Context;
+
+import android.text.format.DateUtils;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ImageView;
+import android.widget.TextView;
 
 import com.android.providers.media.R;
 import com.android.providers.media.photopicker.data.model.Item;
@@ -32,12 +35,20 @@
     private final Context mContext;
     private final IconHelper mIconHelper;
     private final ImageView mIconThumb;
+    private final ImageView mIconGif;
+    private final ImageView mIconVideo;
+    private final View mVideoBadgeContainer;
+    private final TextView mVideoDuration;
 
     public PhotoGridHolder(Context context, ViewGroup parent, IconHelper iconHelper,
             boolean canSelectMultiple) {
         super(context, parent, R.layout.item_photo_grid);
 
         mIconThumb = itemView.findViewById(R.id.icon_thumbnail);
+        mIconGif = itemView.findViewById(R.id.icon_gif);
+        mVideoBadgeContainer = itemView.findViewById(R.id.video_container);
+        mIconVideo = mVideoBadgeContainer.findViewById(R.id.icon_video);
+        mVideoDuration = mVideoBadgeContainer.findViewById(R.id.video_duration);
         mContext = context;
         mIconHelper = iconHelper;
         final ImageView iconCheck = itemView.findViewById(R.id.icon_check);
@@ -52,5 +63,18 @@
     public void bind() {
         final Item item = (Item) itemView.getTag();
         mIconHelper.load(item, mIconThumb);
+
+        if (item.isGif()) {
+            mIconGif.setVisibility(View.VISIBLE);
+        } else {
+            mIconGif.setVisibility(View.GONE);
+        }
+
+        if (item.isVideo()) {
+            mVideoBadgeContainer.setVisibility(View.VISIBLE);
+            mVideoDuration.setText(DateUtils.formatElapsedTime(item.getDuration() / 1000));
+        } else {
+            mVideoBadgeContainer.setVisibility(View.GONE);
+        }
     }
 }
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 f94aa67..3c5a86b 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
@@ -38,7 +38,7 @@
         final String mimeType = "image/png";
         final String displayName = "123.png";
         final String volumeName = "primary";
-        final int duration = 1000;
+        final long duration = 1000;
 
         final Cursor cursor = generateCursorForItem(id, mimeType, displayName, volumeName,
                 dateTaken, duration);
@@ -55,7 +55,7 @@
     }
 
     private static Cursor generateCursorForItem(long id, String mimeType,
-            String displayName, String volumeName, long dateTaken, int duration) {
+            String displayName, String volumeName, long dateTaken, long duration) {
         final MatrixCursor cursor = new MatrixCursor(
                 ItemColumns.ALL_COLUMNS_LIST.toArray(new String[0]));
         cursor.addRow(new Object[] {id, mimeType, displayName, volumeName, dateTaken, duration});