瀏覽代碼

Merge branch 'develop' into fix_instant_uploads_in_Samsung_4.x_devices

David A. Velasco 11 年之前
父節點
當前提交
01a4676beb

+ 0 - 1
src/com/owncloud/android/datamodel/FileDataStorageManager.java

@@ -676,7 +676,6 @@ public class FileDataStorageManager implements DataStorageManager {
 
         while (parentId != 0) {
             
-            Log_OC.d(TAG, "parent = " + parentId);
             // Update the size of the parent
             calculateFolderSize(parentId);
             

+ 7 - 5
src/com/owncloud/android/files/InstantUploadBroadcastReceiver.java

@@ -29,7 +29,7 @@ import android.accounts.Account;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
+//import android.content.IntentFilter;
 import android.database.Cursor;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo.State;
@@ -69,6 +69,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
 
     private void handleUploadFinished(Context context, Intent intent) {
         // remove successfull uploading, ignore rest for reupload on reconnect
+        /*
         if (intent.getBooleanExtra(FileUploader.EXTRA_UPLOAD_RESULT, false)) {
             DbHandler db = new DbHandler(context);
             String localPath = intent.getStringExtra(FileUploader.EXTRA_OLD_FILE_PATH);
@@ -77,6 +78,7 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
             }
             db.close();
         }
+        */
     }
 
     private void handleNewPhotoAction(Context context, Intent intent) {
@@ -122,8 +124,8 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
         // we can unregister from entire listenings but thats suck a bit.
         // On the other hand this might be only for dynamicly registered
         // broadcast receivers, needs investigation.
-        IntentFilter filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
-        context.getApplicationContext().registerReceiver(this, filter);
+        /*IntentFilter filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
+        context.getApplicationContext().registerReceiver(this, filter);*/
 
         Intent i = new Intent(context, FileUploader.class);
         i.putExtra(FileUploader.KEY_ACCOUNT, account);
@@ -148,8 +150,8 @@ public class InstantUploadBroadcastReceiver extends BroadcastReceiver {
             DbHandler db = new DbHandler(context);
             Cursor c = db.getAwaitingFiles();
             if (c.moveToFirst()) {
-                IntentFilter filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
-                context.getApplicationContext().registerReceiver(this, filter);
+                //IntentFilter filter = new IntentFilter(FileUploader.UPLOAD_FINISH_MESSAGE);
+                //context.getApplicationContext().registerReceiver(this, filter);
                 do {
                     String account_name = c.getString(c.getColumnIndex("account"));
                     String file_path = c.getString(c.getColumnIndex("path"));

+ 75 - 57
src/com/owncloud/android/files/services/FileUploader.java

@@ -38,6 +38,7 @@ import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.operations.ChunkedUploadFileOperation;
 import com.owncloud.android.operations.CreateFolderOperation;
+import com.owncloud.android.operations.ExistenceCheckOperation;
 import com.owncloud.android.operations.RemoteOperation;
 import com.owncloud.android.operations.RemoteOperationResult;
 import com.owncloud.android.operations.UploadFileOperation;
@@ -223,16 +224,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);
-        boolean fixed = false;
-        if (isInstant) {
-            fixed = checkAndFixInstantUploadDirectory(storageManager); // MUST
-                                                                       // be
-                                                                       // done
-                                                                       // BEFORE
-                                                                       // calling
-                                                                       // obtainNewOCFileToUpload
-        }
-
+        
         if (intent.hasExtra(KEY_FILE) && files == null) {
             Log_OC.e(TAG, "Incorrect array for OCFiles provided in upload intent");
             return Service.START_NOT_STICKY;
@@ -277,7 +269,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                 } else {
                     newUpload = new UploadFileOperation(account, files[i], isInstant, forceOverwrite, localAction);
                 }
-                if (fixed && i == 0) {
+                if (isInstant) {
                     newUpload.setRemoteFolderToBeCreated();
                 }
                 mPendingUploads.putIfAbsent(uploadKey, newUpload); // Grants that the file only upload once time
@@ -498,7 +490,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
 
             notifyUploadStart(mCurrentUpload);
 
-            RemoteOperationResult uploadResult = null;
+            RemoteOperationResult uploadResult = null, grantResult = null;
             
             try {
                 /// prepare client object to send requests to the ownCloud server
@@ -507,20 +499,22 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                     mStorageManager = new FileDataStorageManager(mLastAccount, getContentResolver());
                     mUploadClient = OwnCloudClientUtils.createOwnCloudClient(mLastAccount, getApplicationContext());
                 }
-            
-                /// create remote folder for instant uploads
-                if (mCurrentUpload.isRemoteFolderToBeCreated()) {
-                    RemoteOperation operation = new CreateFolderOperation(  FileStorageUtils.getInstantUploadFilePath(this, ""), 
-                                                                            mStorageManager.getFileByPath(OCFile.PATH_SEPARATOR).getFileId(), // TODO generalize this : INSTANT_UPLOAD_DIR could not be a child of root
-                                                                            mStorageManager);
-                    operation.execute(mUploadClient);      // ignoring result; fail could just mean that it already exists, but local database is not synchronized; the upload will be tried anyway
-                }
-
+                
+                /// 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
-                uploadResult = mCurrentUpload.execute(mUploadClient);
-                if (uploadResult.isSuccess()) {
-                    saveUploadedFile();
+                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) {
@@ -547,6 +541,58 @@ 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.
+     */
+    private RemoteOperationResult grantFolderExistence(String pathToGrant) {
+        RemoteOperation operation = new ExistenceCheckOperation(pathToGrant, this, false);
+        RemoteOperationResult result = operation.execute(mUploadClient);
+        if (!result.isSuccess() && result.getCode() == ResultCode.FILE_NOT_FOUND && mCurrentUpload.isRemoteFolderToBeCreated()) {
+            operation = new CreateFolderOperation(  pathToGrant,
+                                                    true,
+                                                    mStorageManager    );
+            result = operation.execute(mUploadClient);
+        }
+        if (result.isSuccess()) {
+            OCFile parentDir = mStorageManager.getFileByPath(pathToGrant);
+            if (parentDir == null) {
+                parentDir = createLocalFolder(pathToGrant);
+            }
+            if (parentDir != null) {
+                result = new RemoteOperationResult(ResultCode.OK);
+            } else {
+                result = new RemoteOperationResult(ResultCode.UNKNOWN_ERROR);
+            }
+        }
+        return result;
+    }
+
+    
+    private OCFile createLocalFolder(String remotePath) {
+        String parentPath = new File(remotePath).getParent();
+        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
+        OCFile parent = mStorageManager.getFileByPath(parentPath);
+        if (parent == null) {
+            parent = createLocalFolder(parentPath);
+        }
+        if (parent != null) {
+            OCFile createdFolder = new OCFile(remotePath);
+            createdFolder.setMimetype("DIR");
+            createdFolder.setParentId(parent.getFileId());
+            mStorageManager.saveFile(createdFolder);
+            return createdFolder;
+        }
+        return null;
+    }
+    
+
     /**
      * Saves a OC File after a successful upload.
      * 
@@ -619,28 +665,6 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         // file.setEtag(mCurrentUpload.getEtag());    // TODO Etag, where available
     }
 
-    private boolean checkAndFixInstantUploadDirectory(FileDataStorageManager storageManager) {
-        String instantUploadDirPath = FileStorageUtils.getInstantUploadFilePath(this, "");
-        OCFile instantUploadDir = storageManager.getFileByPath(instantUploadDirPath);
-        if (instantUploadDir == null) {
-            // first instant upload in the account. never account not
-            // synchronized after the remote InstantUpload folder was created
-            OCFile newDir = new OCFile(instantUploadDirPath);
-            newDir.setMimetype("DIR");
-            OCFile path = storageManager.getFileByPath(OCFile.PATH_SEPARATOR);
-
-            if (path != null) {
-                newDir.setParentId(path.getFileId());
-                storageManager.saveFile(newDir);
-                return true;
-            } else {    // this should not happen anymore
-                return false;
-            }
-
-        }
-        return false;
-    }
-
     private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType,
             FileDataStorageManager storageManager) {
         OCFile newFile = new OCFile(remotePath);
@@ -670,12 +694,6 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
         }
         newFile.setMimetype(mimeType);
 
-        // parent dir
-        String parentPath = new File(remotePath).getParent();
-        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
-        OCFile parentDir = storageManager.getFileByPath(parentPath);
-        long parentDirId = parentDir.getFileId();
-        newFile.setParentId(parentDirId);
         return newFile;
     }
 
@@ -782,7 +800,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
             mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification); // NOT
                                                                                                      // AN
             DbHandler db = new DbHandler(this.getBaseContext());
-            db.removeIUPendingFile(mCurrentUpload.getFile().getStoragePath());
+            db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
             db.close();
 
         } else {
@@ -852,10 +870,10 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
                         Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
                         if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
                             message = getString(R.string.failed_upload_quota_exceeded_text);
-                        }
-                        if (db.updateFileState(upload.getOriginalStoragePath(), DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
-                                message) == 0) {
-                            db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name, message);
+                            if (db.updateFileState(upload.getOriginalStoragePath(), DbHandler.UPLOAD_STATUS_UPLOAD_FAILED,
+                                    message) == 0) {
+                                db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name, message);
+                            }
                         }
                     } finally {
                         if (db != null) {

+ 30 - 8
src/com/owncloud/android/operations/CreateFolderOperation.java

@@ -17,6 +17,9 @@
 
 package com.owncloud.android.operations;
 
+import java.io.File;
+
+import org.apache.commons.httpclient.HttpStatus;
 import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
 
 import com.owncloud.android.Log_OC;
@@ -39,25 +42,25 @@ public class CreateFolderOperation extends RemoteOperation {
     private static final int CONNECTION_TIMEOUT = 5000;
     
     protected String mRemotePath;
-    protected long mParentDirId;
+    protected boolean mCreateFullPath;
     protected DataStorageManager mStorageManager;
     
     /**
      * Constructor
      * 
-     * @param remoetPath            Full path to the new directory to create in the remote server.
-     * @param parentDirId           Local database id for the parent folder.
+     * @param remotePath            Full path to the new directory to create in the remote server.
+     * @param createFullPath        'True' means that all the ancestor folders should be created if don't exist yet.
      * @param storageManager        Reference to the local database corresponding to the account where the file is contained. 
      */
-    public CreateFolderOperation(String remotePath, long parentDirId, DataStorageManager storageManager) {
+    public CreateFolderOperation(String remotePath, boolean createFullPath, DataStorageManager storageManager) {
         mRemotePath = remotePath;
-        mParentDirId = parentDirId;
+        mCreateFullPath = createFullPath;
         mStorageManager = storageManager;
     }
     
     
     /**
-     * Performs the remove operation
+     * Performs the operation
      * 
      * @param   client      Client object to communicate with the remote ownCloud server.
      */
@@ -68,15 +71,19 @@ public class CreateFolderOperation extends RemoteOperation {
         try {
             mkcol = new MkColMethod(client.getBaseUri() + WebdavUtils.encodePath(mRemotePath));
             int status =  client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);
+            if (!mkcol.succeeded() && mkcol.getStatusCode() == HttpStatus.SC_CONFLICT && mCreateFullPath) {
+                result = createParentFolder(getParentPath(), client);
+                status = client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);    // second (and last) try
+            }
             if (mkcol.succeeded()) {
                 // Save new directory in local database
                 OCFile newDir = new OCFile(mRemotePath);
                 newDir.setMimetype("DIR");
-                newDir.setParentId(mParentDirId);
+                long parentId = mStorageManager.getFileByPath(getParentPath()).getFileId();
+                newDir.setParentId(parentId);
                 newDir.setModificationTimestamp(System.currentTimeMillis());
                 mStorageManager.saveFile(newDir);
             }
-
             result = new RemoteOperationResult(mkcol.succeeded(), status, mkcol.getResponseHeaders());
             Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage());
             client.exhaustResponse(mkcol.getResponseBodyAsStream());
@@ -91,5 +98,20 @@ public class CreateFolderOperation extends RemoteOperation {
         }
         return result;
     }
+
+
+    private String getParentPath() {
+        String parentPath = new File(mRemotePath).getParent();
+        parentPath = parentPath.endsWith(OCFile.PATH_SEPARATOR) ? parentPath : parentPath + OCFile.PATH_SEPARATOR;
+        return parentPath;
+    }
+
     
+    private RemoteOperationResult createParentFolder(String parentPath, WebdavClient client) {
+        RemoteOperation operation = new CreateFolderOperation(  parentPath,
+                                                                mCreateFullPath,
+                                                                mStorageManager    );
+        return operation.execute(client);
+    }
+
 }

+ 1 - 1
src/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -1328,7 +1328,7 @@ OCFileListFragment.ContainerActivity, FileDetailFragment.ContainerActivity, OnNa
 
                 // Create directory
                 path += newDirectoryName + OCFile.PATH_SEPARATOR;
-                RemoteOperation operation = new CreateFolderOperation(path, getCurrentDir().getFileId(), mStorageManager);
+                RemoteOperation operation = new CreateFolderOperation(path, false, mStorageManager);
                 operation.execute(  getAccount(), 
                         FileDisplayActivity.this, 
                         FileDisplayActivity.this,