blob: 90a87ccfb7eec24aa27d52eecb91e9239963690c [file] [log] [blame]
/*
* Copyright (C) 2012 Google Inc.
* Licensed to The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.mail.browse;
import android.app.FragmentManager;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewParent;
import com.android.ex.photo.util.ImageUtils;
import com.android.mail.R;
import com.android.mail.analytics.Analytics;
import com.android.mail.photo.MailPhotoViewActivity;
import com.android.mail.providers.Attachment;
import com.android.mail.providers.UIProvider;
import com.android.mail.providers.UIProvider.AttachmentDestination;
import com.android.mail.providers.UIProvider.AttachmentRendition;
import com.android.mail.ui.AttachmentTile;
import com.android.mail.ui.AttachmentTileGrid;
import com.android.mail.utils.AttachmentUtils;
import com.android.mail.utils.LogTag;
import com.android.mail.utils.LogUtils;
import com.android.mail.utils.Utils;
import java.util.Comparator;
import java.util.PriorityQueue;
/**
* View for a single attachment in conversation view. Shows download status and allows launching
* intents to act on an attachment.
*
*/
public class MessageAttachmentTile extends AttachmentTile implements OnClickListener,
AttachmentViewInterface {
private int mPhotoIndex;
private Uri mAttachmentsListUri;
private View mTextContainer;
private final AttachmentActionHandler mActionHandler;
private static final String LOG_TAG = LogTag.getLogTag();
public MessageAttachmentTile(Context context) {
this(context, null);
}
public MessageAttachmentTile(Context context, AttributeSet attrs) {
super(context, attrs);
mActionHandler = new AttachmentActionHandler(context, this);
}
public void initialize(FragmentManager fragmentManager) {
mActionHandler.initialize(fragmentManager);
}
/**
* Render or update an attachment's view. This happens immediately upon instantiation, and
* repeatedly as status updates stream in, so only properties with new or changed values will
* cause sub-views to update.
*/
@Override
public void render(Attachment attachment, Uri attachmentsListUri, int index,
AttachmentPreviewCache attachmentPreviewCache, boolean loaderResult) {
super.render(attachment, attachmentsListUri, index, attachmentPreviewCache, loaderResult);
mAttachmentsListUri = attachmentsListUri;
mPhotoIndex = index;
mActionHandler.setAttachment(mAttachment);
mActionHandler.updateStatus(loaderResult);
}
public static MessageAttachmentTile inflate(LayoutInflater inflater, ViewGroup parent) {
MessageAttachmentTile view = (MessageAttachmentTile) inflater.inflate(
R.layout.conversation_message_attachment_tile, parent, false);
return view;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mTextContainer = findViewById(R.id.attachment_tile_text_container);
setOnClickListener(this);
}
@Override
public void onClick(View v) {
onClick();
}
private boolean onClick() {
showAndDownloadAttachments();
return true;
}
private void showAndDownloadAttachments() {
AttachmentTileGrid tileGrid = ((AttachmentTileGrid) getParent());
int childCount = tileGrid.getChildCount();
PriorityQueue<MessageAttachmentTile> queue = new PriorityQueue<MessageAttachmentTile>(
childCount, new ViewIndexDistanceComparator(mPhotoIndex));
for (int i = 0; i < childCount; i++) {
MessageAttachmentTile tile = (MessageAttachmentTile) tileGrid.getChildAt(i);
queue.add(tile);
}
// we want our downloads to have higher priority than the highest background downloads
int maxAdditionalPriority = childCount;
for (int i = 0; i < childCount; i++) {
// higher priority tiles are returned first
MessageAttachmentTile tile = queue.remove();
tile.downloadAttachment(maxAdditionalPriority - i, i != 0);
}
viewAttachment();
}
public void downloadAttachment(int additionalPriority, boolean delayDownload) {
if (!mAttachment.isPresentLocally()) {
mActionHandler.startDownloadingAttachment(AttachmentDestination.CACHE,
UIProvider.AttachmentRendition.BEST, additionalPriority, delayDownload);
}
}
@Override
public void viewAttachment() {
final String mime = Utils.normalizeMimeType(mAttachment.getContentType());
Analytics.getInstance()
.sendEvent("view_attachment", mime, "attachment_tile", mAttachment.size);
if (ImageUtils.isImageMimeType(mime)) {
MailPhotoViewActivity
.startMailPhotoViewActivity(getContext(), mAttachmentsListUri, mPhotoIndex);
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
Utils.setIntentDataAndTypeAndNormalize(
intent, mAttachment.contentUri, mime);
try {
getContext().startActivity(intent);
} catch (ActivityNotFoundException e) {
// couldn't find activity for View intent
LogUtils.e(LOG_TAG, "Couldn't find Activity for intent", e);
}
}
@Override
public void updateProgress(boolean showDeterminateProgress) {
// do not show progress for image tiles
}
@Override
public void onUpdateStatus() {
}
@Override
public void setThumbnailToDefault() {
super.setThumbnailToDefault();
mTextContainer.setVisibility(VISIBLE);
}
@Override
public void setThumbnail(Bitmap result) {
super.setThumbnail(result);
mTextContainer.setVisibility(GONE);
}
@Override
public void thumbnailLoadFailed() {
super.thumbnailLoadFailed();
if (AttachmentUtils.canDownloadAttachment(getContext(), null)) {
// Download if there is network. This check prevents the attachment
// download from failing and making the error toast show
mActionHandler.startDownloadingAttachment(
AttachmentDestination.CACHE, AttachmentRendition.SIMPLE, 0, false);
}
}
/**
* Given two child views, figure out whose index is closest to the specified
* index.
*/
public static class ViewIndexDistanceComparator implements Comparator<View>{
final private int mIndex;
/**
* @param index Compare based on each view's distance to this index
*/
public ViewIndexDistanceComparator(int index) {
mIndex = index;
}
@Override
public int compare(View lhs, View rhs) {
ViewParent parent = lhs.getParent();
if (parent == rhs.getParent()) {
if (parent instanceof ViewGroup) {
ViewGroup p = (ViewGroup) parent;
int lhsIndex = p.indexOfChild(lhs);
int rhsIndex = p.indexOfChild(rhs);
int lhsDistance = Math.abs(mIndex - lhsIndex);
int rhsDistance = Math.abs(mIndex - rhsIndex);
// prefer shorter distance since they are the next ones to be swiped to
int result = lhsDistance - rhsDistance;
if (result == 0) {
// prefer higher index since they are to the right in the photoviewer
return rhsIndex - lhsIndex;
}
return result;
}
}
return 0;
}
}
}