AttachmentActionHandler.java revision 9e2d407fdafeb874e640eb84017feaf784309075
1/* 2 * Copyright (C) 2012 Google Inc. 3 * Licensed to The Android Open Source Project. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package com.android.mail.browse; 19 20 21import android.app.DialogFragment; 22import android.app.Fragment; 23import android.app.FragmentManager; 24import android.app.FragmentTransaction; 25import android.content.ActivityNotFoundException; 26import android.content.ContentValues; 27import android.content.Context; 28import android.content.Intent; 29import android.net.Uri; 30import android.os.Handler; 31import android.os.Parcelable; 32 33import com.android.mail.providers.Attachment; 34import com.android.mail.providers.UIProvider; 35import com.android.mail.providers.UIProvider.AttachmentColumns; 36import com.android.mail.providers.UIProvider.AttachmentContentValueKeys; 37import com.android.mail.providers.UIProvider.AttachmentDestination; 38import com.android.mail.providers.UIProvider.AttachmentState; 39import com.android.mail.utils.LogTag; 40import com.android.mail.utils.LogUtils; 41import com.android.mail.utils.Utils; 42 43import java.util.ArrayList; 44 45public class AttachmentActionHandler { 46 private static final String PROGRESS_FRAGMENT_TAG = "attachment-progress"; 47 48 private Attachment mAttachment; 49 50 private final AttachmentCommandHandler mCommandHandler; 51 private final AttachmentViewInterface mView; 52 private final Context mContext; 53 private final Handler mHandler; 54 private FragmentManager mFragmentManager; 55 56 private static final String LOG_TAG = LogTag.getLogTag(); 57 58 public AttachmentActionHandler(Context context, AttachmentViewInterface view) { 59 mCommandHandler = new AttachmentCommandHandler(context); 60 mView = view; 61 mContext = context; 62 mHandler = new Handler(); 63 } 64 65 public void initialize(FragmentManager fragmentManager) { 66 mFragmentManager = fragmentManager; 67 } 68 69 public void setAttachment(Attachment attachment) { 70 mAttachment = attachment; 71 } 72 73 public void showAttachment(int destination) { 74 if (mView == null) { 75 return; 76 } 77 78 // If the caller requested that this attachments be saved to the external storage, we should 79 // verify that the it was saved there. 80 if (mAttachment.isPresentLocally() && 81 (destination == AttachmentDestination.CACHE || 82 mAttachment.destination == destination)) { 83 mView.viewAttachment(); 84 } else { 85 showDownloadingDialog(); 86 startDownloadingAttachment(destination); 87 } 88 } 89 90 /** 91 * Start downloading the full size attachment set with 92 * {@link #setAttachment(Attachment)} immediately. 93 */ 94 public void startDownloadingAttachment(int destination) { 95 startDownloadingAttachment(destination, UIProvider.AttachmentRendition.BEST, 0, false); 96 } 97 98 public void startDownloadingAttachment( 99 int destination, int rendition, int additionalPriority, boolean delayDownload) { 100 startDownloadingAttachment( 101 mAttachment, destination, rendition, additionalPriority, delayDownload); 102 } 103 104 private void startDownloadingAttachment( 105 Attachment attachment, int destination, int rendition, int additionalPriority, 106 boolean delayDownload) { 107 final ContentValues params = new ContentValues(2); 108 params.put(AttachmentColumns.STATE, AttachmentState.DOWNLOADING); 109 params.put(AttachmentColumns.DESTINATION, destination); 110 params.put(AttachmentContentValueKeys.RENDITION, rendition); 111 params.put(AttachmentContentValueKeys.ADDITIONAL_PRIORITY, additionalPriority); 112 params.put(AttachmentContentValueKeys.DELAY_DOWNLOAD, delayDownload); 113 114 mCommandHandler.sendCommand(attachment.uri, params); 115 } 116 117 public void cancelAttachment() { 118 final ContentValues params = new ContentValues(1); 119 params.put(AttachmentColumns.STATE, AttachmentState.NOT_SAVED); 120 121 mCommandHandler.sendCommand(mAttachment.uri, params); 122 } 123 124 public void startRedownloadingAttachment(Attachment attachment) { 125 showDownloadingDialog(); 126 final ContentValues params = new ContentValues(2); 127 params.put(AttachmentColumns.STATE, AttachmentState.REDOWNLOADING); 128 params.put(AttachmentColumns.DESTINATION, attachment.destination); 129 130 mCommandHandler.sendCommand(attachment.uri, params); 131 } 132 133 /** 134 * Displays a loading dialog to be used for downloading attachments. 135 * Must be called on the UI thread. 136 */ 137 private void showDownloadingDialog() { 138 final FragmentTransaction ft = mFragmentManager.beginTransaction(); 139 final Fragment prev = mFragmentManager.findFragmentByTag(PROGRESS_FRAGMENT_TAG); 140 if (prev != null) { 141 ft.remove(prev); 142 } 143 ft.addToBackStack(null); 144 145 // Create and show the dialog. 146 final DialogFragment newFragment = AttachmentProgressDialogFragment.newInstance( 147 mAttachment); 148 newFragment.show(ft, PROGRESS_FRAGMENT_TAG); 149 } 150 151 /** 152 * Update progress-related views. Will also trigger a view intent if a progress dialog was 153 * previously brought up (by tapping 'View') and the download has now finished. 154 */ 155 public void updateStatus(boolean loaderResult) { 156 if (mView == null) { 157 return; 158 } 159 160 final boolean showProgress = mAttachment.shouldShowProgress(); 161 162 final AttachmentProgressDialogFragment dialog = (AttachmentProgressDialogFragment) 163 mFragmentManager.findFragmentByTag(PROGRESS_FRAGMENT_TAG); 164 if (dialog != null && dialog.isShowingDialogForAttachment(mAttachment)) { 165 dialog.setProgress(mAttachment.downloadedSize); 166 167 // We don't want the progress bar to switch back to indeterminate mode after 168 // have been in determinate progress mode. 169 final boolean indeterminate = !showProgress && dialog.isIndeterminate(); 170 dialog.setIndeterminate(indeterminate); 171 172 if (loaderResult && mAttachment.isDownloadFinishedOrFailed()) { 173 mHandler.post(new Runnable() { 174 @Override 175 public void run() { 176 dialog.dismiss(); 177 } 178 }); 179 } 180 181 if (mAttachment.state == AttachmentState.SAVED) { 182 mView.viewAttachment(); 183 } 184 } else { 185 mView.updateProgress(showProgress); 186 } 187 188 // Call on update status for the view so that it can do some specific things. 189 mView.onUpdateStatus(); 190 } 191 192 public boolean isProgressDialogVisible() { 193 final Fragment dialog = mFragmentManager.findFragmentByTag(PROGRESS_FRAGMENT_TAG); 194 return dialog != null && dialog.isVisible(); 195 } 196 197 public void shareAttachment() { 198 if (mAttachment.contentUri == null) { 199 return; 200 } 201 202 Intent intent = new Intent(Intent.ACTION_SEND); 203 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION 204 | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 205 206 final Uri uri = Utils.normalizeUri(mAttachment.contentUri); 207 intent.putExtra(Intent.EXTRA_STREAM, uri); 208 intent.setType(Utils.normalizeMimeType(mAttachment.getContentType())); 209 210 try { 211 mContext.startActivity(intent); 212 } catch (ActivityNotFoundException e) { 213 // couldn't find activity for SEND intent 214 LogUtils.e(LOG_TAG, "Couldn't find Activity for intent", e); 215 } 216 } 217 218 public void shareAttachments(ArrayList<Parcelable> uris) { 219 Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE); 220 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION 221 | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 222 223 intent.setType("image/*"); 224 intent.putParcelableArrayListExtra( 225 Intent.EXTRA_STREAM, uris); 226 227 try { 228 mContext.startActivity(intent); 229 } catch (ActivityNotFoundException e) { 230 // couldn't find activity for SEND_MULTIPLE intent 231 LogUtils.e(LOG_TAG, "Couldn't find Activity for intent", e); 232 } 233 } 234} 235