Support audio attachments through GalleryMediaChooser am: 2716c26c23 am: 3359f4dee2 am: b330155fea

Change-Id: I17b954c754e53aab4338d67be00171def7c6f9c6
This commit is contained in:
Automerger Merge Worker
2020-02-20 00:50:28 +00:00
9 changed files with 188 additions and 71 deletions

View File

@@ -21,12 +21,67 @@
android:background="@color/gallery_image_default_background"
android:clickable="true">
<!-- Thumbnail for image and video contents. -->
<com.android.messaging.ui.AsyncImageView
android:id="@+id/image"
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<!-- Additional info such as icon, name and etc. -->
<RelativeLayout
android:id="@+id/additional_info"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical"
android:visibility="gone" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/file_info" >
<ImageView
android:id="@+id/icon"
android:layout_width="@dimen/gallery_icon_size"
android:layout_height="@dimen/gallery_icon_size"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:background="@color/background_item_transparent"
android:visibility="gone" />
</FrameLayout>
<!-- File info for audio contents only -->
<LinearLayout
android:id="@+id/file_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="4dp"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:orientation="vertical"
android:visibility="gone" >
<TextView
android:id="@+id/file_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
android:textAppearance="@android:style/TextAppearance.Material.Subhead" />
<TextView
android:id="@+id/file_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
android:gravity="right"
android:textAppearance="@android:style/TextAppearance.Material.Caption" />
</LinearLayout>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -44,13 +99,4 @@
android:visibility="gone"
android:contentDescription="@string/gallery_checkbox_content_description" />
<!-- Play button image for video contents only -->
<ImageView
android:id="@+id/video_thumbnail_play_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@color/background_item_transparent"
android:src="@drawable/ic_video_play_light"
android:visibility="gone" />
</com.android.messaging.ui.mediapicker.GalleryGridItemView>

View File

@@ -85,6 +85,7 @@
<!-- Flings faster than this length / sec will go from fullscreen straight to closed -->
<dimen name="mediapicker_big_fling_threshold">1000dp</dimen>
<dimen name="gallery_image_cell_size">110dp</dimen>
<dimen name="gallery_icon_size">40dp</dimen>
<dimen name="single_attachment_min_dimen">50dp</dimen>
<dimen name="single_attachment_max_height">150dp</dimen>
<dimen name="multiple_attachment_preview_height">130dp</dimen>

View File

@@ -35,7 +35,11 @@ public class GalleryBoundCursorLoader extends BoundCursorLoader {
private static final String SORT_ORDER = MediaColumns.DATE_MODIFIED + " DESC";
private static final String SELECTION = createSelection(
MessagePartData.ACCEPTABLE_GALLERY_MEDIA_TYPES,
new Integer[] {FileColumns.MEDIA_TYPE_IMAGE, FileColumns.MEDIA_TYPE_VIDEO});
new Integer[] {
FileColumns.MEDIA_TYPE_IMAGE,
FileColumns.MEDIA_TYPE_VIDEO,
FileColumns.MEDIA_TYPE_AUDIO
});
public GalleryBoundCursorLoader(final String bindingId, final Context context) {
super(bindingId, context, STORAGE_URI, GalleryGridItemData.MEDIA_PROJECTION, SELECTION,

View File

@@ -29,6 +29,7 @@ import com.android.messaging.datamodel.media.UriImageRequestDescriptor;
import com.android.messaging.datamodel.media.VideoThumbnailRequestDescriptor;
import com.android.messaging.util.Assert;
import com.android.messaging.util.ContentType;
import com.android.messaging.util.UriUtil;
/**
* Provides data for GalleryGridItemView
@@ -40,7 +41,8 @@ public class GalleryGridItemData {
MediaColumns.WIDTH,
MediaColumns.HEIGHT,
MediaColumns.MIME_TYPE,
MediaColumns.DATE_MODIFIED};
MediaColumns.DATE_MODIFIED,
MediaColumns.DISPLAY_NAME};
public static final String[] SPECIAL_ITEM_COLUMNS = new String[] {
BaseColumns._ID
@@ -54,6 +56,7 @@ public class GalleryGridItemData {
private static final int INDEX_HEIGHT = 3;
private static final int INDEX_MIME_TYPE = 4;
private static final int INDEX_DATE_MODIFIED = 5;
private static final int INDEX_DISPLAY_NAME = 6;
/** A special item's id for picking a media from document picker */
public static final String ID_DOCUMENT_PICKER_ITEM = "-1";
@@ -62,6 +65,8 @@ public class GalleryGridItemData {
private String mContentType;
private boolean mIsDocumentPickerItem;
private long mDateSeconds;
private String mFileName;
private Uri mAudioUri;
public GalleryGridItemData() {
}
@@ -73,37 +78,44 @@ public class GalleryGridItemData {
mImageData = null;
mContentType = null;
} else {
int sourceWidth = cursor.getInt(INDEX_WIDTH);
int sourceHeight = cursor.getInt(INDEX_HEIGHT);
// Guard against bad data
if (sourceWidth <= 0) {
sourceWidth = ImageRequest.UNSPECIFIED_SIZE;
}
if (sourceHeight <= 0) {
sourceHeight = ImageRequest.UNSPECIFIED_SIZE;
}
mContentType = cursor.getString(INDEX_MIME_TYPE);
final String filePath = cursor.getString(INDEX_DATA_PATH);
final String dateModified = cursor.getString(INDEX_DATE_MODIFIED);
mDateSeconds = !TextUtils.isEmpty(dateModified) ? Long.parseLong(dateModified) : -1;
if (ContentType.isVideoType(mContentType)) {
mImageData = new VideoThumbnailRequestDescriptor(
cursor.getLong(INDEX_ID),
desiredWidth,
desiredHeight,
sourceWidth,
sourceHeight);
} else {
mImageData = new FileImageRequestDescriptor(
cursor.getString(INDEX_DATA_PATH),
desiredWidth,
desiredHeight,
sourceWidth,
sourceHeight,
true /* canUseThumbnail */,
true /* allowCompression */,
true /* isStatic */);
if (ContentType.isAudioType(mContentType)) {
mImageData = null;
mAudioUri = UriUtil.getUriForResourceFile(filePath);
mFileName = cursor.getString(INDEX_DISPLAY_NAME);
} else { // For image and video types
int sourceWidth = cursor.getInt(INDEX_WIDTH);
int sourceHeight = cursor.getInt(INDEX_HEIGHT);
// Guard against bad data
if (sourceWidth <= 0) {
sourceWidth = ImageRequest.UNSPECIFIED_SIZE;
}
if (sourceHeight <= 0) {
sourceHeight = ImageRequest.UNSPECIFIED_SIZE;
}
if (ContentType.isVideoType(mContentType)) {
mImageData = new VideoThumbnailRequestDescriptor(
cursor.getLong(INDEX_ID),
desiredWidth,
desiredHeight,
sourceWidth,
sourceHeight);
} else {
mImageData = new FileImageRequestDescriptor(
filePath,
desiredWidth,
desiredHeight,
sourceWidth,
sourceHeight,
true /* canUseThumbnail */,
true /* allowCompression */,
true /* isStatic */);
}
}
}
}
@@ -113,7 +125,7 @@ public class GalleryGridItemData {
}
public Uri getImageUri() {
return mImageData.uri;
return ContentType.isAudioType(mContentType) ? mAudioUri : mImageData.uri;
}
public UriImageRequestDescriptor getImageRequestDescriptor() {
@@ -122,8 +134,10 @@ public class GalleryGridItemData {
public MessagePartData constructMessagePartData(final Rect startRect) {
Assert.isTrue(!mIsDocumentPickerItem);
return new MediaPickerMessagePartData(startRect, mContentType,
mImageData.uri, mImageData.sourceWidth, mImageData.sourceHeight);
return ContentType.isAudioType(mContentType)
? new MediaPickerMessagePartData(startRect, mContentType, mAudioUri, 0, 0)
: new MediaPickerMessagePartData(startRect, mContentType, mImageData.uri,
mImageData.sourceWidth, mImageData.sourceHeight);
}
/**
@@ -136,4 +150,8 @@ public class GalleryGridItemData {
public String getContentType() {
return mContentType;
}
public String getFileName() {
return mFileName;
}
}

View File

@@ -61,7 +61,12 @@ public class MessagePartData implements Parcelable {
// Acceptable video types
ContentType.VIDEO_3GP, ContentType.VIDEO_3GPP, ContentType.VIDEO_3G2,
ContentType.VIDEO_H263, ContentType.VIDEO_M4V, ContentType.VIDEO_MP4,
ContentType.VIDEO_MPEG, ContentType.VIDEO_MPEG4, ContentType.VIDEO_WEBM
ContentType.VIDEO_MPEG, ContentType.VIDEO_MPEG4, ContentType.VIDEO_WEBM,
// Acceptable audio types
ContentType.AUDIO_MP3, ContentType.AUDIO_MP4, ContentType.AUDIO_MIDI,
ContentType.AUDIO_MID, ContentType.AUDIO_AMR, ContentType.AUDIO_X_WAV,
ContentType.AUDIO_AAC, ContentType.AUDIO_X_MIDI, ContentType.AUDIO_X_MID,
ContentType.AUDIO_X_MP3
};
private static final String[] sProjection = {

View File

@@ -30,7 +30,7 @@ import com.android.messaging.util.ImageUtils;
import com.android.messaging.util.SafeAsyncTask;
/**
* Wraps around the functionalities to allow the user to pick an image/video from the document
* Wraps around the functionalities to allow the user to pick an image/video/audio from the document
* picker. Instances of this class must be tied to a Fragment which is able to delegate activity
* result callbacks.
*/

View File

@@ -17,6 +17,7 @@ package com.android.messaging.ui.mediapicker;
import android.content.Context;
import android.database.Cursor;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -25,6 +26,9 @@ import android.view.View;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.messaging.R;
import com.android.messaging.datamodel.DataModel;
@@ -54,6 +58,11 @@ public class GalleryGridItemView extends FrameLayout {
GalleryGridItemData mData;
private AsyncImageView mImageView;
private CheckBox mCheckBox;
private RelativeLayout mAdditionalInfo;
private ImageView mIcon;
private LinearLayout mFileInfo;
private TextView mFileName;
private TextView mFileType;
private HostInterface mHostInterface;
private final OnClickListener mOnClickListener = new OnClickListener() {
@Override
@@ -70,9 +79,14 @@ public class GalleryGridItemView extends FrameLayout {
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mImageView = (AsyncImageView) findViewById(R.id.image);
mImageView = (AsyncImageView) findViewById(R.id.thumbnail);
mCheckBox = (CheckBox) findViewById(R.id.checkbox);
mCheckBox.setOnClickListener(mOnClickListener);
mAdditionalInfo = (RelativeLayout) findViewById(R.id.additional_info);
mIcon = (ImageView) findViewById(R.id.icon);
mFileInfo = (LinearLayout) findViewById(R.id.file_info);
mFileName = (TextView) findViewById(R.id.file_name);
mFileType = (TextView) findViewById(R.id.file_type);
setOnClickListener(mOnClickListener);
final OnLongClickListener longClickListener = new OnLongClickListener() {
@Override
@@ -136,32 +150,59 @@ public class GalleryGridItemView extends FrameLayout {
}
private void updateImageView() {
ImageView playButton = (ImageView) findViewById(R.id.video_thumbnail_play_button);
if (mData.isDocumentPickerItem()) {
mImageView.setScaleType(ImageView.ScaleType.CENTER);
setBackgroundColor(ConversationDrawables.get().getConversationThemeColor());
mImageView.setImageResourceId(null);
mImageView.setImageResource(R.drawable.ic_photo_library_light);
playButton.setVisibility(GONE);
mImageView.setContentDescription(getResources().getString(
R.string.pick_image_from_document_library_content_description));
mIcon.setImageResource(R.drawable.ic_photo_library_light);
mIcon.clearColorFilter();
mImageView.setVisibility(GONE);
mIcon.setVisibility(VISIBLE);
mFileInfo.setVisibility(GONE);
mAdditionalInfo.setVisibility(VISIBLE);
} else {
mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
setBackgroundColor(getResources().getColor(R.color.gallery_image_default_background));
mImageView.setImageResourceId(mData.getImageRequestDescriptor());
if (ContentType.isVideoType(mData.getContentType())) {
playButton.setVisibility(VISIBLE);
} else {
playButton.setVisibility(GONE);
final String contentType = mData.getContentType();
if (ContentType.isAudioType(contentType)) {
final Context context = getContext();
setBackgroundColor(
getResources().getColor(R.color.gallery_image_default_background));
mIcon.setImageDrawable(
context.getContentResolver()
.getTypeInfo(contentType)
.getIcon()
.loadDrawable(context));
mIcon.setColorFilter(
ConversationDrawables.get().getConversationThemeColor(),
PorterDuff.Mode.SRC_IN);
mFileName.setText(mData.getFileName());
String[] type = contentType.split("/");
mFileType.setText(type[1].toUpperCase() + " " + type[0]);
mImageView.setVisibility(GONE);
mIcon.setVisibility(VISIBLE);
mFileInfo.setVisibility(VISIBLE);
mAdditionalInfo.setVisibility(VISIBLE);
} else { // For image and video types
mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
setBackgroundColor(
getResources().getColor(R.color.gallery_image_default_background));
mImageView.setImageResourceId(mData.getImageRequestDescriptor());
mImageView.setVisibility(VISIBLE);
if (ContentType.isVideoType(mData.getContentType())) {
mIcon.setImageResource(R.drawable.ic_video_play_light);
mIcon.clearColorFilter();
mIcon.setVisibility(VISIBLE);
} else {
mIcon.setVisibility(GONE);
}
mFileInfo.setVisibility(GONE);
mAdditionalInfo.setVisibility(VISIBLE);
final long dateSeconds = mData.getDateSeconds();
final boolean isValidDate = (dateSeconds > 0);
final int templateId = isValidDate ?
R.string.mediapicker_gallery_image_item_description :
R.string.mediapicker_gallery_image_item_description_no_date;
String contentDescription = String.format(getResources().getString(templateId),
dateSeconds * TimeUnit.SECONDS.toMillis(1));
mImageView.setContentDescription(contentDescription);
}
final long dateSeconds = mData.getDateSeconds();
final boolean isValidDate = (dateSeconds > 0);
final int templateId = isValidDate ?
R.string.mediapicker_gallery_image_item_description :
R.string.mediapicker_gallery_image_item_description_no_date;
String contentDescription = String.format(getResources().getString(templateId),
dateSeconds * TimeUnit.SECONDS.toMillis(1));
mImageView.setContentDescription(contentDescription);
}
}
}

View File

@@ -39,7 +39,7 @@ import com.android.messaging.util.Assert;
import com.android.messaging.util.OsUtil;
/**
* Chooser which allows the user to select one or more existing images or videos
* Chooser which allows the user to select one or more existing images or videos or audios.
*/
class GalleryMediaChooser extends MediaChooser implements
GalleryGridView.GalleryGridViewListener, MediaPickerDataListener {
@@ -54,7 +54,9 @@ class GalleryMediaChooser extends MediaChooser implements
@Override
public int getSupportedMediaTypes() {
return MediaPicker.MEDIA_TYPE_IMAGE | MediaPicker.MEDIA_TYPE_VIDEO;
return (MediaPicker.MEDIA_TYPE_IMAGE
| MediaPicker.MEDIA_TYPE_VIDEO
| MediaPicker.MEDIA_TYPE_AUDIO);
}
@Override

View File

@@ -55,7 +55,7 @@ public class GalleryGridItemViewTest extends ViewTest<GalleryGridItemView> {
final String imageUrl,
final boolean showCheckbox,
final boolean isSelected) {
final AsyncImageView imageView = (AsyncImageView) view.findViewById(R.id.image);
final AsyncImageView imageView = (AsyncImageView) view.findViewById(R.id.thumbnail);
final CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkbox);
assertNotNull(imageView);