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