Эх сурвалжийг харах

Detect if the account exists before the tranfer starts

masensio 10 жил өмнө
parent
commit
ab8bf56a15

+ 151 - 144
src/com/owncloud/android/files/services/FileUploader.java

@@ -124,14 +124,14 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     private static final String MIME_TYPE_PDF = "application/pdf";
     private static final String FILE_EXTENSION_PDF = ".pdf";
 
-    
+
     public static String getUploadFinishMessage() {
         return FileUploader.class.getName().toString() + UPLOAD_FINISH_MESSAGE;
     }
-    
+
     /**
      * Builds a key for mPendingUploads from the account and file to upload
-     * 
+     *
      * @param account   Account where the file to upload is stored
      * @param file      File to upload
      */
@@ -145,7 +145,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     /**
      * Checks if an ownCloud server version should support chunked uploads.
-     * 
+     *
      * @param version OwnCloud version instance corresponding to an ownCloud
      *            server.
      * @return 'True' if the ownCloud server with version supports chunked
@@ -172,7 +172,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     /**
      * Entry point to add one or several files to the queue of uploads.
-     * 
+     *
      * New uploads are added calling to startService(), resulting in a call to
      * this method. This ensures the service will keep on working although the
      * caller activity goes away.
@@ -211,11 +211,11 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
             if (intent.hasExtra(KEY_FILE)) {
                 files = (OCFile[]) intent.getParcelableArrayExtra(KEY_FILE); // TODO
-                                                                             // will
-                                                                             // this
-                                                                             // casting
-                                                                             // work
-                                                                             // fine?
+                // will
+                // this
+                // casting
+                // work
+                // fine?
 
             } else {
                 localPaths = intent.getStringArrayExtra(KEY_LOCAL_FILE);
@@ -229,7 +229,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         boolean forceOverwrite = intent.getBooleanExtra(KEY_FORCE_OVERWRITE, false);
         boolean isInstant = intent.getBooleanExtra(KEY_INSTANT_UPLOAD, false);
         int localAction = intent.getIntExtra(KEY_LOCAL_BEHAVIOUR, LOCAL_BEHAVIOUR_COPY);
-        
+
         if (intent.hasExtra(KEY_FILE) && files == null) {
             Log_OC.e(TAG, "Incorrect array for OCFiles provided in upload intent");
             return Service.START_NOT_STICKY;
@@ -262,7 +262,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         AccountManager aMgr = AccountManager.get(this);
         String version = aMgr.getUserData(account, Constants.KEY_OC_VERSION);
         OwnCloudVersion ocv = new OwnCloudVersion(version);
-        
+
         boolean chunked = FileUploader.chunkedUploadIsSupported(ocv);
         AbstractList<String> requestedUploads = new Vector<String>();
         String uploadKey = null;
@@ -270,7 +270,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         try {
             for (int i = 0; i < files.length; i++) {
                 uploadKey = buildRemoteName(account, files[i].getRemotePath());
-                newUpload = new UploadFileOperation(account, files[i], chunked, isInstant, forceOverwrite, localAction, 
+                newUpload = new UploadFileOperation(account, files[i], chunked, isInstant, forceOverwrite, localAction,
                         getApplicationContext());
                 if (isInstant) {
                     newUpload.setRemoteFolderToBeCreated();
@@ -309,7 +309,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     /**
      * Provides a binder object that clients can use to perform operations on
      * the queue of uploads, excepting the addition of new files.
-     * 
+     *
      * Implemented to perform cancellation, pause and resume of existing
      * uploads.
      */
@@ -317,7 +317,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     public IBinder onBind(Intent arg0) {
         return mBinder;
     }
-    
+
     /**
      * Called when ALL the bound clients were onbound.
      */
@@ -326,24 +326,24 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         ((FileUploaderBinder)mBinder).clearListeners();
         return false;   // not accepting rebinding (default behaviour)
     }
-    
+
 
     /**
      * Binder to let client components to perform operations on the queue of
      * uploads.
-     * 
+     *
      * It provides by itself the available operations.
      */
     public class FileUploaderBinder extends Binder implements OnDatatransferProgressListener {
-        
-        /** 
+
+        /**
          * Map of listeners that will be reported about progress of uploads from a {@link FileUploaderBinder} instance 
          */
         private Map<String, OnDatatransferProgressListener> mBoundListeners = new HashMap<String, OnDatatransferProgressListener>();
-        
+
         /**
          * Cancels a pending or current upload of a remote file.
-         * 
+         *
          * @param account Owncloud account where the remote file will be stored.
          * @param file A file in the queue of pending uploads
          */
@@ -356,22 +356,22 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 upload.cancel();
             }
         }
-        
-        
-        
+
+
+
         public void clearListeners() {
             mBoundListeners.clear();
         }
 
 
-        
-        
+
+
         /**
          * Returns True when the file described by 'file' is being uploaded to
          * the ownCloud account 'account' or waiting for it
-         * 
+         *
          * If 'file' is a directory, returns 'true' if some of its descendant files is uploading or waiting to upload. 
-         * 
+         *
          * @param account   ownCloud account where the remote file will be stored.
          * @param file      A file that could be in the queue of pending uploads
          */
@@ -397,7 +397,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
         /**
          * Adds a listener interested in the progress of the upload for a concrete file.
-         * 
+         *
          * @param listener      Object to notify about progress of transfer.    
          * @param account       ownCloud account holding the file of interest.
          * @param file          {@link OCFile} of interest for listener.
@@ -407,12 +407,12 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             String targetKey = buildRemoteName(account, file);
             mBoundListeners.put(targetKey, listener);
         }
-        
-        
-        
+
+
+
         /**
          * Removes a listener interested in the progress of the upload for a concrete file.
-         * 
+         *
          * @param listener      Object to notify about progress of transfer.    
          * @param account       ownCloud account holding the file of interest.
          * @param file          {@link OCFile} of interest for listener.
@@ -428,20 +428,20 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
         @Override
         public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer,
-                String fileName) {
+                                       String fileName) {
             String key = buildRemoteName(mCurrentUpload.getAccount(), mCurrentUpload.getFile());
             OnDatatransferProgressListener boundListener = mBoundListeners.get(key);
             if (boundListener != null) {
                 boundListener.onTransferProgress(progressRate, totalTransferredSoFar, totalToTransfer, fileName);
             }
         }
-        
+
     }
 
     /**
      * Upload worker. Performs the pending uploads in the order they were
      * requested.
-     * 
+     *
      * Created with the Looper of a new thread, started in
      * {@link FileUploader#onCreate()}.
      */
@@ -473,7 +473,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     /**
      * Core upload method: sends the file(s) to upload
-     * 
+     *
      * @param uploadKey Key to access the upload to perform, contained in
      *            mPendingUploads
      */
@@ -485,63 +485,70 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
         if (mCurrentUpload != null) {
 
-            notifyUploadStart(mCurrentUpload);
+            // Detect if the account exists
+            if (AccountUtils.exists(mCurrentUpload.getAccount(), getApplicationContext())) {
+                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().toString() + " exists");
 
-            RemoteOperationResult uploadResult = null, grantResult = null;
-            
-            try {
-                /// prepare client object to send requests to the ownCloud server
-                if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
-                    mLastAccount = mCurrentUpload.getAccount();
-                    mStorageManager = 
-                            new FileDataStorageManager(mLastAccount, getContentResolver());
-                    OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this);
-                    mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
-                            getClientFor(ocAccount, this);
-                }
-                
-                /// check the existence of the parent folder for the file to upload
-                String remoteParentPath = new File(mCurrentUpload.getRemotePath()).getParent();
-                remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ? remoteParentPath : remoteParentPath + OCFile.PATH_SEPARATOR;
-                grantResult = grantFolderExistence(remoteParentPath);
-            
-                /// perform the upload
-                if (grantResult.isSuccess()) {
-                    OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
-                    mCurrentUpload.getFile().setParentId(parent.getFileId());
-                    uploadResult = mCurrentUpload.execute(mUploadClient);
-                    if (uploadResult.isSuccess()) {
-                        saveUploadedFile();
+                notifyUploadStart(mCurrentUpload);
+
+                RemoteOperationResult uploadResult = null, grantResult = null;
+
+                try {
+                    /// prepare client object to send requests to the ownCloud server
+                    if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
+                        mLastAccount = mCurrentUpload.getAccount();
+                        mStorageManager =
+                                new FileDataStorageManager(mLastAccount, getContentResolver());
+                        OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this);
+                        mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
+                                getClientFor(ocAccount, this);
+                    }
+
+                    /// check the existence of the parent folder for the file to upload
+                    String remoteParentPath = new File(mCurrentUpload.getRemotePath()).getParent();
+                    remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ? remoteParentPath : remoteParentPath + OCFile.PATH_SEPARATOR;
+                    grantResult = grantFolderExistence(remoteParentPath);
+
+                    /// perform the upload
+                    if (grantResult.isSuccess()) {
+                        OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
+                        mCurrentUpload.getFile().setParentId(parent.getFileId());
+                        uploadResult = mCurrentUpload.execute(mUploadClient);
+                        if (uploadResult.isSuccess()) {
+                            saveUploadedFile();
+                        }
+                    } else {
+                        uploadResult = grantResult;
+                    }
+
+                } catch (AccountsException e) {
+                    Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
+                    uploadResult = new RemoteOperationResult(e);
+
+                } catch (IOException e) {
+                    Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
+                    uploadResult = new RemoteOperationResult(e);
+
+                } finally {
+                    synchronized (mPendingUploads) {
+                        mPendingUploads.remove(uploadKey);
+                        Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
+                    }
+                    if (uploadResult.isException()) {
+                        // enforce the creation of a new client object for next uploads; this grant that a new socket will
+                        // be created in the future if the current exception is due to an abrupt lose of network connection
+                        mUploadClient = null;
                     }
-                } else {
-                    uploadResult = grantResult;
-                }
-                
-            } catch (AccountsException e) {
-                Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
-                uploadResult = new RemoteOperationResult(e);
-                
-            } catch (IOException e) {
-                Log_OC.e(TAG, "Error while trying to get autorization for " + mLastAccount.name, e);
-                uploadResult = new RemoteOperationResult(e);
-                
-            } finally {
-                synchronized (mPendingUploads) {
-                    mPendingUploads.remove(uploadKey);
-                    Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
-                }
-                if (uploadResult.isException()) {
-                    // enforce the creation of a new client object for next uploads; this grant that a new socket will 
-                    // be created in the future if the current exception is due to an abrupt lose of network connection
-                    mUploadClient = null;
                 }
-            }
-            
-            /// notify result
-            
-            notifyUploadResult(uploadResult, mCurrentUpload);
-            sendFinalBroadcast(mCurrentUpload, uploadResult);
 
+                /// notify result
+                notifyUploadResult(uploadResult, mCurrentUpload);
+                sendFinalBroadcast(mCurrentUpload, uploadResult);
+
+            } else {
+                // Cancel the transfer
+                Log_OC.d(TAG, "Account " + mCurrentUpload.getAccount().toString() + " doesn't exist");
+            }
         }
 
     }
@@ -549,10 +556,10 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     /**
      * Checks the existence of the folder where the current file will be uploaded both in the remote server 
      * and in the local database.
-     * 
+     *
      * If the upload is set to enforce the creation of the folder, the method tries to create it both remote
      * and locally.
-     *  
+     *
      *  @param  pathToGrant     Full remote path whose existence will be granted.
      *  @return  An {@link OCFile} instance corresponding to the folder where the file will be uploaded.
      */
@@ -577,7 +584,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         return result;
     }
 
-    
+
     private OCFile createLocalFolder(String remotePath) {
         String parentPath = new File(remotePath).getParent();
         parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
@@ -594,15 +601,15 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         }
         return null;
     }
-    
+
 
     /**
      * Saves a OC File after a successful upload.
-     * 
+     *
      * A PROPFIND is necessary to keep the props in the local database
      * synchronized with the server, specially the modification time and Etag
      * (where available)
-     * 
+     *
      * TODO refactor this ugly thing
      */
     private void saveUploadedFile() {
@@ -621,7 +628,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             updateOCFile(file, (RemoteFile) result.getData().get(0));
             file.setLastSyncDateForProperties(syncDate);
         }
-        
+
         // / maybe this would be better as part of UploadFileOperation... or
         // maybe all this method
         if (mCurrentUpload.wasRenamed()) {
@@ -631,8 +638,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 mStorageManager.saveFile(oldFile);
 
             } // else: it was just an automatic renaming due to a name
-              // coincidence; nothing else is needed, the storagePath is right
-              // in the instance returned by mCurrentUpload.getFile()
+            // coincidence; nothing else is needed, the storagePath is right
+            // in the instance returned by mCurrentUpload.getFile()
         }
         file.setNeedsUpdateThumbnail(true);
         mStorageManager.saveFile(file);
@@ -649,7 +656,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     }
 
     private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType,
-            FileDataStorageManager storageManager) {
+                                           FileDataStorageManager storageManager) {
 
         // MIME type
         if (mimeType == null || mimeType.length() <= 0) {
@@ -679,7 +686,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             newFile.setFileLength(localFile.length());
             newFile.setLastSyncDateForData(localFile.lastModified());
         } // don't worry about not assigning size, the problems with localPath
-          // are checked when the UploadFileOperation instance is created
+        // are checked when the UploadFileOperation instance is created
 
 
         newFile.setMimetype(mimeType);
@@ -689,13 +696,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     /**
      * Creates a status notification to show the upload progress
-     * 
+     *
      * @param upload Upload operation starting.
      */
     private void notifyUploadStart(UploadFileOperation upload) {
         // / create status notification with a progress bar
         mLastPercent = 0;
-        mNotificationBuilder = 
+        mNotificationBuilder =
                 NotificationBuilderWithProgressBar.newNotificationBuilderWithProgressBar(this);
         mNotificationBuilder
                 .setOngoing(true)
@@ -712,7 +719,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount());
         showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         mNotificationBuilder.setContentIntent(PendingIntent.getActivity(
-            this, (int) System.currentTimeMillis(), showDetailsIntent, 0
+                this, (int) System.currentTimeMillis(), showDetailsIntent, 0
         ));
 
         mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
@@ -736,7 +743,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
     /**
      * Updates the status notification with the result of an upload operation.
-     * 
+     *
      * @param uploadResult Result of the upload operation.
      * @param upload Finished upload operation
      */
@@ -745,33 +752,33 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         Log_OC.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
         // / cancelled operation or success -> silent removal of progress notification
         mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);
-        
+
         // Show the result: success or fail notification
         if (!uploadResult.isCancelled()) {
-            int tickerId = (uploadResult.isSuccess()) ? R.string.uploader_upload_succeeded_ticker : 
-                R.string.uploader_upload_failed_ticker;
-            
+            int tickerId = (uploadResult.isSuccess()) ? R.string.uploader_upload_succeeded_ticker :
+                    R.string.uploader_upload_failed_ticker;
+
             String content = null;
 
             // check credentials error
             boolean needsToUpdateCredentials = (
-                    uploadResult.getCode() == ResultCode.UNAUTHORIZED || 
-                    uploadResult.isIdPRedirection()
+                    uploadResult.getCode() == ResultCode.UNAUTHORIZED ||
+                            uploadResult.isIdPRedirection()
             );
-            tickerId = (needsToUpdateCredentials) ? 
+            tickerId = (needsToUpdateCredentials) ?
                     R.string.uploader_upload_failed_credentials_error : tickerId;
 
             mNotificationBuilder
-            .setTicker(getString(tickerId))
-            .setContentTitle(getString(tickerId))
-            .setAutoCancel(true)
-            .setOngoing(false)
-            .setProgress(0, 0, false);
-            
+                    .setTicker(getString(tickerId))
+                    .setContentTitle(getString(tickerId))
+                    .setAutoCancel(true)
+                    .setOngoing(false)
+                    .setProgress(0, 0, false);
+
             content =  ErrorMessageAdapter.getErrorCauseMessage(
                     uploadResult, upload, getResources()
             );
-            
+
             if (needsToUpdateCredentials) {
                 // let the user update credentials with one click
                 Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
@@ -779,24 +786,24 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                         AuthenticatorActivity.EXTRA_ACCOUNT, upload.getAccount()
                 );
                 updateAccountCredentials.putExtra(
-                        AuthenticatorActivity.EXTRA_ACTION, 
+                        AuthenticatorActivity.EXTRA_ACTION,
                         AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN
                 );
                 updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                 updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
                 mNotificationBuilder.setContentIntent(PendingIntent.getActivity(
-                    this, 
-                    (int) System.currentTimeMillis(), 
-                    updateAccountCredentials, 
-                    PendingIntent.FLAG_ONE_SHOT
+                        this,
+                        (int) System.currentTimeMillis(),
+                        updateAccountCredentials,
+                        PendingIntent.FLAG_ONE_SHOT
                 ));
-                
-                mUploadClient = null;   
-                    // grant that future retries on the same account will get the fresh credentials
+
+                mUploadClient = null;
+                // grant that future retries on the same account will get the fresh credentials
             } else {
                 mNotificationBuilder.setContentText(content);
-    
+
                 if (upload.isInstant()) {
                     DbHandler db = null;
                     try {
@@ -807,12 +814,12 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                         if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
                             //message = getString(R.string.failed_upload_quota_exceeded_text);
                             if (db.updateFileState(
-                                    upload.getOriginalStoragePath(), 
+                                    upload.getOriginalStoragePath(),
                                     DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
                                     message) == 0) {
                                 db.putFileForLater(
-                                        upload.getOriginalStoragePath(), 
-                                        upload.getAccount().name, 
+                                        upload.getOriginalStoragePath(),
+                                        upload.getAccount().name,
                                         message
                                 );
                             }
@@ -824,22 +831,22 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                     }
                 }
             }
-            
+
             mNotificationBuilder.setContentText(content);
             mNotificationManager.notify(tickerId, mNotificationBuilder.build());
-            
+
             if (uploadResult.isSuccess()) {
-                
+
                 DbHandler db = new DbHandler(this.getBaseContext());
                 db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
                 db.close();
 
                 // remove success notification, with a delay of 2 seconds
                 NotificationDelayer.cancelWithDelay(
-                        mNotificationManager, 
-                        R.string.uploader_upload_succeeded_ticker, 
+                        mNotificationManager,
+                        R.string.uploader_upload_succeeded_ticker,
                         2000);
-                
+
             }
         }
     }
@@ -847,17 +854,17 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
     /**
      * Sends a broadcast in order to the interested activities can update their
      * view
-     * 
+     *
      * @param upload Finished upload operation
      * @param uploadResult Result of the upload operation
      */
     private void sendFinalBroadcast(UploadFileOperation upload, RemoteOperationResult uploadResult) {
         Intent end = new Intent(getUploadFinishMessage());
         end.putExtra(EXTRA_REMOTE_PATH, upload.getRemotePath()); // real remote
-                                                                 // path, after
-                                                                 // possible
-                                                                 // automatic
-                                                                 // renaming
+        // path, after
+        // possible
+        // automatic
+        // renaming
         if (upload.wasRenamed()) {
             end.putExtra(EXTRA_OLD_REMOTE_PATH, upload.getOldFile().getRemotePath());
         }
@@ -875,8 +882,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
      * @return true if is needed to add the pdf file extension to the file
      */
     private boolean isPdfFileFromContentProviderWithoutExtension(String localPath, String mimeType) {
-        return localPath.startsWith(UriUtils.URI_CONTENT_SCHEME) && 
-                mimeType.equals(MIME_TYPE_PDF) && 
+        return localPath.startsWith(UriUtils.URI_CONTENT_SCHEME) &&
+                mimeType.equals(MIME_TYPE_PDF) &&
                 !localPath.endsWith(FILE_EXTENSION_PDF);
     }