1 /* ownCloud Android client application 
   3  *   Copyright (C) 2012-2013  ownCloud Inc. 
   5  *   This program is free software: you can redistribute it and/or modify 
   6  *   it under the terms of the GNU General Public License version 2, 
   7  *   as published by the Free Software Foundation. 
   9  *   This program is distributed in the hope that it will be useful, 
  10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  12  *   GNU General Public License for more details. 
  14  *   You should have received a copy of the GNU General Public License 
  15  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  18 package com
.owncloud
.android
.ui
.preview
; 
  20 import java
.lang
.ref
.WeakReference
; 
  22 import com
.owncloud
.android
.R
; 
  23 import com
.owncloud
.android
.datamodel
.OCFile
; 
  24 import com
.owncloud
.android
.files
.services
.FileDownloader
.FileDownloaderBinder
; 
  25 import com
.owncloud
.android
.ui
.fragment
.FileFragment
; 
  26 import com
.owncloud
.android
.utils
.Log_OC
; 
  28 import android
.accounts
.Account
; 
  29 import android
.app
.Activity
; 
  30 import android
.os
.Bundle
; 
  31 import android
.support
.v4
.app
.FragmentStatePagerAdapter
; 
  32 import android
.view
.LayoutInflater
; 
  33 import android
.view
.View
; 
  34 import android
.view
.View
.OnClickListener
; 
  35 import android
.view
.ViewGroup
; 
  36 import android
.widget
.ImageButton
; 
  37 import android
.widget
.ProgressBar
; 
  38 import android
.widget
.TextView
; 
  40 import com
.owncloud
.android
.lib
.network
.OnDatatransferProgressListener
; 
  44  * This Fragment is used to monitor the progress of a file downloading. 
  46  * @author David A. Velasco 
  48 public class FileDownloadFragment 
extends FileFragment 
implements OnClickListener 
{ 
  50     public static final String EXTRA_FILE 
= "FILE"; 
  51     public static final String EXTRA_ACCOUNT 
= "ACCOUNT"; 
  52     private static final String EXTRA_ERROR 
= "ERROR"; 
  54     private FileFragment
.ContainerActivity mContainerActivity
; 
  57     private Account mAccount
; 
  59     public ProgressListener mProgressListener
; 
  60     private boolean mListening
; 
  62     private static final String TAG 
= FileDownloadFragment
.class.getSimpleName(); 
  64     private boolean mIgnoreFirstSavedState
; 
  65     private boolean mError
; 
  69      * Creates an empty details fragment. 
  71      * It's necessary to keep a public constructor without parameters; the system uses it when tries to reinstantiate a fragment automatically.  
  73     public FileDownloadFragment() { 
  76         mProgressListener 
= null
; 
  78         mIgnoreFirstSavedState 
= false
; 
  84      * Creates a details fragment. 
  86      * When 'fileToDetail' or 'ocAccount' are null, creates a dummy layout (to use when a file wasn't tapped before). 
  88      * @param fileToDetail      An {@link OCFile} to show in the fragment 
  89      * @param ocAccount         An ownCloud account; needed to start downloads 
  90      * @param ignoreFirstSavedState     Flag to work around an unexpected behaviour of {@link FragmentStatePagerAdapter}; TODO better solution  
  92     public FileDownloadFragment(OCFile fileToDetail
, Account ocAccount
, boolean ignoreFirstSavedState
) { 
  95         mProgressListener 
= null
; 
  97         mIgnoreFirstSavedState 
= ignoreFirstSavedState
; 
 103     public void onCreate(Bundle savedInstanceState
) { 
 104         super.onCreate(savedInstanceState
); 
 109     public View 
onCreateView(LayoutInflater inflater
, ViewGroup container
, 
 110             Bundle savedInstanceState
) { 
 111         super.onCreateView(inflater
, container
, savedInstanceState
); 
 113         if (savedInstanceState 
!= null
) { 
 114             if (!mIgnoreFirstSavedState
) { 
 115                 setFile((OCFile
)savedInstanceState
.getParcelable(FileDownloadFragment
.EXTRA_FILE
)); 
 116                 mAccount 
= savedInstanceState
.getParcelable(FileDownloadFragment
.EXTRA_ACCOUNT
); 
 117                 mError 
= savedInstanceState
.getBoolean(FileDownloadFragment
.EXTRA_ERROR
); 
 119                 mIgnoreFirstSavedState 
= false
; 
 124         view 
= inflater
.inflate(R
.layout
.file_download_fragment
, container
, false
); 
 127         ProgressBar progressBar 
= (ProgressBar
)mView
.findViewById(R
.id
.progressBar
); 
 128         mProgressListener 
= new ProgressListener(progressBar
); 
 130         ((ImageButton
)mView
.findViewById(R
.id
.cancelBtn
)).setOnClickListener(this); 
 133             setButtonsForRemote(); 
 135             setButtonsForTransferring(); 
 146     public void onAttach(Activity activity
) { 
 147         super.onAttach(activity
); 
 149             mContainerActivity 
= (ContainerActivity
) activity
; 
 151         } catch (ClassCastException e
) { 
 152             throw new ClassCastException(activity
.toString() + " must implement " + FileFragment
.ContainerActivity
.class.getSimpleName()); 
 161     public void onActivityCreated(Bundle savedInstanceState
) { 
 162         super.onActivityCreated(savedInstanceState
); 
 163         if (mAccount 
!= null
) { 
 164             //mStorageManager = new FileDataStorageManager(mAccount, getActivity().getApplicationContext().getContentResolver());; 
 170     public void onSaveInstanceState(Bundle outState
) { 
 171         super.onSaveInstanceState(outState
); 
 172         outState
.putParcelable(FileDownloadFragment
.EXTRA_FILE
, getFile()); 
 173         outState
.putParcelable(FileDownloadFragment
.EXTRA_ACCOUNT
, mAccount
); 
 174         outState
.putBoolean(FileDownloadFragment
.EXTRA_ERROR
, mError
); 
 178     public void onStart() { 
 180         listenForTransferProgress(); 
 184     public void onResume() { 
 190     public void onPause() { 
 196     public void onStop() { 
 198         leaveTransferProgress(); 
 202     public void onDestroy() { 
 208     public View 
getView() { 
 210             listenForTransferProgress(); 
 212         return super.getView() == null ? mView 
: super.getView(); 
 217     public void onClick(View v
) { 
 219             case R
.id
.cancelBtn
: { 
 220                 FileDownloaderBinder downloaderBinder 
= mContainerActivity
.getFileDownloaderBinder(); 
 221                 if (downloaderBinder 
!= null 
&& downloaderBinder
.isDownloading(mAccount
, getFile())) { 
 222                     downloaderBinder
.cancel(mAccount
, getFile()); 
 223                     getActivity().finish(); // :) 
 225                     leaveTransferProgress(); 
 226                     if (mFile.isDown()) { 
 229                         setButtonsForRemote(); 
 236                 Log_OC
.e(TAG
, "Incorrect view clicked!"); 
 242      * Updates the view depending upon the state of the downloading file. 
 244      * @param   transferring    When true, the view must be updated assuming that the holded file is  
 245      *                          downloading, no matter what the downloaderBinder says. 
 247     public void updateView(boolean transferring
) { 
 248         // configure UI for depending upon local state of the file 
 249         FileDownloaderBinder downloaderBinder 
= (mContainerActivity 
== null
) ? null 
: mContainerActivity
.getFileDownloaderBinder(); 
 250         if (transferring 
|| (downloaderBinder 
!= null 
&& downloaderBinder
.isDownloading(mAccount
, getFile()))) { 
 251             setButtonsForTransferring(); 
 253         } else if (getFile().isDown()) { 
 258             setButtonsForRemote(); 
 260         getView().invalidate(); 
 266      * Enables or disables buttons for a file being downloaded 
 268     private void setButtonsForTransferring() { 
 269         getView().findViewById(R
.id
.cancelBtn
).setVisibility(View
.VISIBLE
); 
 271         // show the progress bar for the transfer 
 272         getView().findViewById(R
.id
.progressBar
).setVisibility(View
.VISIBLE
); 
 273         TextView progressText 
= (TextView
)getView().findViewById(R
.id
.progressText
); 
 274         progressText
.setText(R
.string
.downloader_download_in_progress_ticker
); 
 275         progressText
.setVisibility(View
.VISIBLE
); 
 277         // hides the error icon 
 278         getView().findViewById(R
.id
.errorText
).setVisibility(View
.GONE
); 
 279         getView().findViewById(R
.id
.error_image
).setVisibility(View
.GONE
); 
 284      * Enables or disables buttons for a file locally available  
 286     private void setButtonsForDown() { 
 287         getView().findViewById(R
.id
.cancelBtn
).setVisibility(View
.GONE
); 
 289         // hides the progress bar 
 290         getView().findViewById(R
.id
.progressBar
).setVisibility(View
.GONE
); 
 292         // updates the text message 
 293         TextView progressText 
= (TextView
)getView().findViewById(R
.id
.progressText
); 
 294         progressText
.setText(R
.string
.common_loading
); 
 295         progressText
.setVisibility(View
.VISIBLE
); 
 297         // hides the error icon 
 298         getView().findViewById(R
.id
.errorText
).setVisibility(View
.GONE
); 
 299         getView().findViewById(R
.id
.error_image
).setVisibility(View
.GONE
); 
 304      * Enables or disables buttons for a file not locally available  
 306      * Currently, this is only used when a download was failed 
 308     private void setButtonsForRemote() { 
 309         getView().findViewById(R
.id
.cancelBtn
).setVisibility(View
.GONE
); 
 311         // hides the progress bar and message 
 312         getView().findViewById(R
.id
.progressBar
).setVisibility(View
.GONE
); 
 313         getView().findViewById(R
.id
.progressText
).setVisibility(View
.GONE
); 
 315         // shows the error icon and message 
 316         getView().findViewById(R
.id
.errorText
).setVisibility(View
.VISIBLE
); 
 317         getView().findViewById(R
.id
.error_image
).setVisibility(View
.VISIBLE
); 
 321     public void listenForTransferProgress() { 
 322         if (mProgressListener 
!= null 
&& !mListening
) { 
 323             if (mContainerActivity
.getFileDownloaderBinder() != null
) { 
 324                 mContainerActivity
.getFileDownloaderBinder().addDatatransferProgressListener(mProgressListener
, mAccount
, getFile()); 
 326                 setButtonsForTransferring(); 
 332     public void leaveTransferProgress() { 
 333         if (mProgressListener 
!= null
) { 
 334             if (mContainerActivity
.getFileDownloaderBinder() != null
) { 
 335                 mContainerActivity
.getFileDownloaderBinder().removeDatatransferProgressListener(mProgressListener
, mAccount
, getFile()); 
 343      * Helper class responsible for updating the progress bar shown for file uploading or downloading   
 345      * @author David A. Velasco 
 347     private class ProgressListener 
implements OnDatatransferProgressListener 
{ 
 348         int mLastPercent 
= 0; 
 349         WeakReference
<ProgressBar
> mProgressBar 
= null
; 
 351         ProgressListener(ProgressBar progressBar
) { 
 352             mProgressBar 
= new WeakReference
<ProgressBar
>(progressBar
); 
 356         public void onTransferProgress(long progressRate
, long totalTransferredSoFar
, long totalToTransfer
, String filename
) { 
 357             int percent 
= (int)(100.0*((double)totalTransferredSoFar
)/((double)totalToTransfer
)); 
 358             if (percent 
!= mLastPercent
) { 
 359                 ProgressBar pb 
= mProgressBar
.get(); 
 361                     pb
.setProgress(percent
); 
 365             mLastPercent 
= percent
; 
 371     public void setError(boolean error
) {