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