1 /* ownCloud Android client application 
   2  *   Copyright (C) 2011  Bartek Przybylski 
   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/>. 
  19 package com
.owncloud
.android
.ui
.activity
; 
  21 import android
.accounts
.Account
; 
  22 import android
.accounts
.AccountManager
; 
  23 import android
.accounts
.AccountManagerCallback
; 
  24 import android
.accounts
.AccountManagerFuture
; 
  25 import android
.accounts
.OperationCanceledException
; 
  26 import android
.content
.Intent
; 
  27 import android
.net
.Uri
; 
  28 import android
.os
.Bundle
; 
  29 import android
.webkit
.MimeTypeMap
; 
  31 import com
.actionbarsherlock
.app
.SherlockFragmentActivity
; 
  32 import com
.owncloud
.android
.AccountUtils
; 
  33 import com
.owncloud
.android
.Log_OC
; 
  34 import com
.owncloud
.android
.authentication
.AccountAuthenticator
; 
  35 import com
.owncloud
.android
.datamodel
.OCFile
; 
  36 import com
.owncloud
.android
.files
.FileHandler
; 
  38 import eu
.alefzero
.webdav
.WebdavUtils
; 
  41  * Activity with common behaviour for activities handling {@link OCFile}s in ownCloud {@link Account}s . 
  43  * @author David A. Velasco 
  45 public abstract class FileActivity 
extends SherlockFragmentActivity 
implements FileHandler 
{ 
  47     public static final String EXTRA_FILE 
= "com.owncloud.android.ui.activity.FILE"; 
  48     public static final String EXTRA_ACCOUNT 
= "com.owncloud.android.ui.activity.ACCOUNT"; 
  50     public static final String TAG 
= FileActivity
.class.getSimpleName();  
  53     /** OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located. */ 
  54     private Account mAccount
; 
  56     /** Main {@link OCFile} handled by the activity.*/ 
  59     /** Flag to signal that the activity will is finishing to enforce the creation of an ownCloud {@link Account} */ 
  60     private boolean mRedirectingToSetupAccount 
= false
; 
  62     private FileHandlerImpl mFileHandler
; 
  66     protected void onCreate(Bundle savedInstanceState
) { 
  67         super.onCreate(savedInstanceState
); 
  69         /// Load of saved instance state: keep this always before initDataFromCurrentAccount() 
  70         if(savedInstanceState 
!= null
) { 
  71             mFile 
= savedInstanceState
.getParcelable(FileActivity
.EXTRA_FILE
); 
  72             mAccount 
= savedInstanceState
.getParcelable(FileActivity
.EXTRA_ACCOUNT
); 
  74             mAccount 
= getIntent().getParcelableExtra(FileActivity
.EXTRA_ACCOUNT
); 
  75             mFile 
= getIntent().getParcelableExtra(FileActivity
.EXTRA_FILE
); 
  78         if (mAccount 
!= null 
&& AccountUtils
.setCurrentOwnCloudAccount(getApplicationContext(), mAccount
.name
)) { 
  82         mFileHandler 
= new FileHandlerImpl(); 
  87      * Validate the ownCloud {@link Account} associated to the Activity any time it is  
  88      * started, and if not valid tries to move to a different Account. 
  91     protected void onStart() { 
  92         Log_OC
.e(TAG
, "onStart en FileActivity"); 
  94         /// Validate account, and try to fix if wrong 
  95         if (mAccount 
== null 
|| !AccountUtils
.setCurrentOwnCloudAccount(getApplicationContext(), mAccount
.name
)) { 
  96             if (!AccountUtils
.accountsAreSetup(getApplicationContext())) { 
  97                 /// no account available: force account creation 
 100                 mRedirectingToSetupAccount 
= true
; 
 103                 /// get 'last current account' as default account 
 104                 mAccount 
= AccountUtils
.getCurrentOwnCloudAccount(getApplicationContext()); 
 112      * Launches the account creation activity. To use when no ownCloud account is available 
 114     private void createFirstAccount() { 
 115         AccountManager am 
= AccountManager
.get(getApplicationContext()); 
 116         am
.addAccount(AccountAuthenticator
.ACCOUNT_TYPE
,  
 117                         AccountAuthenticator
.AUTH_TOKEN_TYPE_PASSWORD
, 
 121                         new AccountCreationCallback(),                         
 130     protected void onSaveInstanceState(Bundle outState
) { 
 131         super.onSaveInstanceState(outState
); 
 132         outState
.putParcelable(FileActivity
.EXTRA_FILE
, mFile
); 
 133         outState
.putParcelable(FileActivity
.EXTRA_ACCOUNT
, mAccount
); 
 138      * Getter for the main {@link OCFile} handled by the activity. 
 140      * @return  Main {@link OCFile} handled by the activity. 
 142     public OCFile 
getFile() { 
 148      * Setter for the main {@link OCFile} handled by the activity. 
 150      * @param file  Main {@link OCFile} to be handled by the activity. 
 152     public void setFile(OCFile file
) { 
 158      * Getter for the ownCloud {@link Account} where the main {@link OCFile} handled by the activity is located. 
 160      * @return  OwnCloud {@link Account} where the main {@link OCFile} handled by the activity is located. 
 162     public Account 
getAccount() { 
 168      * @return  'True' when the Activity is finishing to enforce the setup of a new account. 
 170     protected boolean isRedirectingToSetupAccount() { 
 171         return mRedirectingToSetupAccount
; 
 176      * Helper class handling a callback from the {@link AccountManager} after the creation of 
 177      * a new ownCloud {@link Account} finished, successfully or not. 
 179      * At this moment, only called after the creation of the first account. 
 181      * @author David A. Velasco 
 183     public class AccountCreationCallback 
implements AccountManagerCallback
<Bundle
> { 
 186         public void run(AccountManagerFuture
<Bundle
> future
) { 
 187             FileActivity
.this.mRedirectingToSetupAccount 
= false
; 
 188             if (future 
!= null
) { 
 191                     result 
= future
.getResult(); 
 192                     String name 
= result
.getString(AccountManager
.KEY_ACCOUNT_NAME
); 
 193                     String type 
= result
.getString(AccountManager
.KEY_ACCOUNT_TYPE
); 
 194                     if (AccountUtils
.setCurrentOwnCloudAccount(getApplicationContext(), name
)) { 
 195                         FileActivity
.this.mAccount 
= new Account(name
, type
); 
 196                         FileActivity
.this.onAccountChanged(); 
 198                 } catch (OperationCanceledException e
) { 
 199                     Log_OC
.e(TAG
, "Account creation canceled"); 
 201                 } catch (Exception e
) { 
 202                     Log_OC
.e(TAG
, "Account creation finished in exception: ", e
); 
 206                 Log_OC
.e(TAG
, "Account creation callback with null bundle"); 
 208             if (mAccount 
== null
) { 
 216     public void openFile(OCFile file
) { 
 217         mFileHandler
.openFile(file
); 
 222      *  Called when the ownCloud {@link Account} associated to the Activity was just updated. 
 224      *  Child classes must grant that state depending on the {@link Account} is updated. 
 226     protected abstract void onAccountChanged(); 
 229     public class FileHandlerImpl 
implements FileHandler 
{ 
 231         public void openFile(OCFile file
) { 
 233                 String storagePath 
= file
.getStoragePath(); 
 234                 String encodedStoragePath 
= WebdavUtils
.encodePath(storagePath
); 
 236                 Intent intentForSavedMimeType 
= new Intent(Intent
.ACTION_VIEW
); 
 237                 intentForSavedMimeType
.setDataAndType(Uri
.parse("file://"+ encodedStoragePath
), file
.getMimetype()); 
 238                 intentForSavedMimeType
.setFlags(Intent
.FLAG_GRANT_READ_URI_PERMISSION 
| Intent
.FLAG_GRANT_WRITE_URI_PERMISSION
); 
 240                 Intent intentForGuessedMimeType 
= null
; 
 241                 if (storagePath
.lastIndexOf('.') >= 0) { 
 242                     String guessedMimeType 
= MimeTypeMap
.getSingleton().getMimeTypeFromExtension(storagePath
.substring(storagePath
.lastIndexOf('.') + 1)); 
 243                     if (guessedMimeType 
!= null 
&& !guessedMimeType
.equals(file
.getMimetype())) { 
 244                         intentForGuessedMimeType 
= new Intent(Intent
.ACTION_VIEW
); 
 245                         intentForGuessedMimeType
.setDataAndType(Uri
.parse("file://"+ encodedStoragePath
), guessedMimeType
); 
 246                         intentForGuessedMimeType
.setFlags(Intent
.FLAG_GRANT_READ_URI_PERMISSION 
| Intent
.FLAG_GRANT_WRITE_URI_PERMISSION
); 
 250                 Intent chooserIntent 
= null
; 
 251                 if (intentForGuessedMimeType 
!= null
) { 
 252                     chooserIntent 
= Intent
.createChooser(intentForGuessedMimeType
, null
); 
 254                     chooserIntent 
= Intent
.createChooser(intentForSavedMimeType
, null
); 
 257                 startActivity(chooserIntent
); 
 260                 Log_OC
.wtf(TAG
, "Trying to open a NULL OCFile");