Home | History | Annotate | Download | only in browse
      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 
     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 
     67     public void initialize(FragmentManager fragmentManager) {
     68         mFragmentManager = fragmentManager;
     69     }
     70 
     71     public void setAttachment(Attachment attachment) {
     72         mAttachment = attachment;
     73     }
     74 
     75     public void setViewOnFinish(boolean viewOnFinish) {
     76         mViewOnFinish = viewOnFinish;
     77     }
     78 
     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      */
    100     public void startDownloadingAttachment(int destination) {
    101         startDownloadingAttachment(destination, UIProvider.AttachmentRendition.BEST, 0, false);
    102     }
    103 
    104     public void startDownloadingAttachment(
    105             int destination, int rendition, int additionalPriority, boolean delayDownload) {
    106         startDownloadingAttachment(
    107                 mAttachment, destination, rendition, additionalPriority, delayDownload);
    108     }
    109 
    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 
    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 
    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      */
    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      */
    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 
    197     public boolean isProgressDialogVisible() {
    198         final Fragment dialog = mFragmentManager.findFragmentByTag(PROGRESS_FRAGMENT_TAG);
    199         return dialog != null && dialog.isVisible();
    200     }
    201 
    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 
    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