浏览代码

fix progress notifications
fix handling multiple uploads with same filepath key

Luke Owncloud 10 年之前
父节点
当前提交
4518da5d03

+ 83 - 44
src/com/owncloud/android/db/UploadDbHandler.java

@@ -50,13 +50,13 @@ public class UploadDbHandler extends Observable {
 
     // for testing only
     public void recreateDb() {
-//         getDB().beginTransaction();
-//         try {
-//         mHelper.onUpgrade(getDB(), 0, mDatabaseVersion);
-//         getDB().setTransactionSuccessful();
-//         } finally {
-//             getDB().endTransaction();
-//         }
+//        getDB().beginTransaction();
+//        try {
+//            mHelper.onUpgrade(getDB(), 0, mDatabaseVersion);
+//            getDB().setTransactionSuccessful();
+//        } finally {
+//            getDB().endTransaction();
+//        }
     }
 
     public enum UploadStatus {
@@ -93,6 +93,7 @@ public class UploadDbHandler extends Observable {
         private UploadStatus(int value) {
             this.value = value;
         }
+
         public int getValue() {
             return value;
         }
@@ -142,7 +143,6 @@ public class UploadDbHandler extends Observable {
         // return result != -1;
     }
 
-
     // ununsed until now. uncomment if needed.
     // public Cursor getFailedFiles() {
     // return mDB.query(TABLE_INSTANT_UPLOAD, null, "attempt>" +
@@ -191,47 +191,50 @@ public class UploadDbHandler extends Observable {
      * @return true on success.
      */
     public boolean storeUpload(UploadDbObject uploadObject) {
+        Log_OC.e(TAG, "Inserting "+uploadObject.getLocalPath()+" with uploadStatus="+uploadObject.getUploadStatus());
+        
         ContentValues cv = new ContentValues();
         cv.put("path", uploadObject.getLocalPath());
         cv.put("uploadStatus", uploadObject.getUploadStatus().value);
         cv.put("uploadObject", uploadObject.toString());
 
         long result = getDB().insert(TABLE_UPLOAD, null, cv);
+        
         Log_OC.d(TAG, "putFileForLater returns with: " + result + " for file: " + uploadObject.getLocalPath());
         if (result == 1) {
             notifyObserversNow();
         } else {
-            Log_OC.e(TAG, "Failed to insert item into upload db.");
+            Log_OC.e(TAG, "Failed to insert item "+uploadObject.getLocalPath()+" into upload db.");
         }
         return result != -1;
     }
 
     /**
      * Update upload status of file in DB.
+     * 
      * @return 1 if file status was updated, else 0.
      */
     public int updateUpload(UploadDbObject uploadDbObject) {
-        return updateUpload(uploadDbObject.getLocalPath(), uploadDbObject.getUploadStatus(), uploadDbObject.getLastResult());
+        return updateUpload(uploadDbObject.getLocalPath(), uploadDbObject.getUploadStatus(),
+                uploadDbObject.getLastResult());
     }
 
-    /**
-     * Update upload status of file.
-     * 
-     * @param filepath filepath local file path to file. used as identifier.
-     * @param status new status.
-     * @param result new result of upload operation
-     * @return 1 if file status was updated, else 0.
-     */
-    public int updateUpload(String filepath, UploadStatus status, RemoteOperationResult result) {
-        Cursor c = getDB().query(TABLE_UPLOAD, null, "path=?", new String[] { filepath }, null, null, null);
-        if (c.getCount() != 1) {
-            Log_OC.e(TAG, c.getCount() + " items for path=" + filepath + " available in UploadDb. Expected 1.");
-            return 0;
-        }
-        if (c.moveToFirst()) {
+    public int updateUploadInternal(Cursor c, UploadStatus status, RemoteOperationResult result) {
+        
+        while(c.moveToNext()) {
             // read upload object and update
+            
+            
             String uploadObjectString = c.getString(c.getColumnIndex("uploadObject"));
             UploadDbObject uploadObject = UploadDbObject.fromString(uploadObjectString);
+            
+            String path = c.getString(c.getColumnIndex("path"));
+            Log_OC.e(
+                    TAG,
+                    "Updating " + path + ": " + uploadObject.getLocalPath() + " with uploadStatus=" + status + "(old:"
+                            + uploadObject.getUploadStatus() + ") and result=" + result + "(old:"
+                            + uploadObject.getLastResult());
+            
             uploadObject.setUploadStatus(status);
             uploadObject.setLastResult(result);
             uploadObjectString = uploadObject.toString();
@@ -239,7 +242,10 @@ public class UploadDbHandler extends Observable {
             ContentValues cv = new ContentValues();
             cv.put("uploadStatus", status.value);
             cv.put("uploadObject", uploadObjectString);
-            int r = getDB().update(TABLE_UPLOAD, cv, "path=?", new String[] { filepath });
+            
+            
+            int r = getDB().update(TABLE_UPLOAD, cv, "path=?", new String[] { path });
+            
             if (r == 1) {
                 notifyObserversNow();
             } else {
@@ -249,7 +255,28 @@ public class UploadDbHandler extends Observable {
         }
         return 0;
     }
+    /**
+     * Update upload status of file uniquely referenced by filepath.
+     * 
+     * @param filepath filepath local file path to file. used as identifier.
+     * @param status new status.
+     * @param result new result of upload operation
+     * @return 1 if file status was updated, else 0.
+     */
+    public int updateUpload(String filepath, UploadStatus status, RemoteOperationResult result) {
+        
+//        Log_OC.e(TAG, "Updating "+filepath+" with uploadStatus="+status +" and result="+result);
+        
+        Cursor c = getDB().query(TABLE_UPLOAD, null, "path=?", new String[] { filepath }, null, null, null);
 
+        if (c.getCount() != 1) {
+            Log_OC.e(TAG, c.getCount() + " items for path=" + filepath
+                    + " available in UploadDb. Expected 1. Failed to update upload db.");
+            return 0;
+        }
+        return updateUploadInternal(c, status, result);
+    }
+    
     /**
      * Should be called when some value of this DB was changed. All observers
      * are informed.
@@ -267,10 +294,10 @@ public class UploadDbHandler extends Observable {
      * @param localPath
      * @return true when one or more upload entries were removed
      */
-    public boolean removeUpload(String localPath) {
-        long result = getDB().delete(TABLE_UPLOAD, "path = ?", new String[] { localPath });
+    public int removeUpload(String localPath) {
+        int result = getDB().delete(TABLE_UPLOAD, "path = ?", new String[] { localPath });
         Log_OC.d(TABLE_UPLOAD, "delete returns with: " + result + " for file: " + localPath);
-        return result != 0;
+        return result;
     }
 
     public UploadDbObject[] getAllStoredUploads() {
@@ -295,37 +322,42 @@ public class UploadDbHandler extends Observable {
     }
 
     /**
-     * Get all uploads which are pending, i.e., queued for upload but not currently being uploaded
+     * Get all uploads which are pending, i.e., queued for upload but not
+     * currently being uploaded
+     * 
      * @return
      */
     public UploadDbObject[] getPendingUploads() {
         return getUploads("uploadStatus==" + UploadStatus.UPLOAD_LATER.value + " OR uploadStatus=="
-                + UploadStatus.UPLOAD_FAILED_RETRY.value+ " OR uploadStatus=="
-                        + UploadStatus.UPLOAD_PAUSED.value, null);
+                + UploadStatus.UPLOAD_FAILED_RETRY.value, null);
     }
+
     /**
-     * Get all uploads which are currently being uploaded. There should only be one. No guarantee though.
+     * Get all uploads which are currently being uploaded. There should only be
+     * one. No guarantee though.
      */
     public UploadDbObject[] getCurrentUpload() {
         return getUploads("uploadStatus==" + UploadStatus.UPLOAD_IN_PROGRESS.value, null);
     }
-    
+
     /**
      * Get all current and pending uploads.
      */
     public UploadDbObject[] getCurrentAndPendingUploads() {
-        return getUploads("uploadStatus==" + UploadStatus.UPLOAD_IN_PROGRESS.value + " OR uploadStatus==" + UploadStatus.UPLOAD_LATER.value + " OR uploadStatus=="
-                + UploadStatus.UPLOAD_FAILED_RETRY.value+ " OR uploadStatus=="
-                        + UploadStatus.UPLOAD_PAUSED.value, null);
+        return getUploads("uploadStatus==" + UploadStatus.UPLOAD_IN_PROGRESS.value + " OR uploadStatus=="
+                + UploadStatus.UPLOAD_LATER.value + " OR uploadStatus==" + UploadStatus.UPLOAD_FAILED_RETRY.value
+                + " OR uploadStatus==" + UploadStatus.UPLOAD_PAUSED.value, null);
     }
-    
+
     /**
-     * Get all unrecoverably failed. Upload of these should/must/will not be retried.
+     * Get all unrecoverably failed. Upload of these should/must/will not be
+     * retried.
      */
     public UploadDbObject[] getFailedUploads() {
         return getUploads("uploadStatus==" + UploadStatus.UPLOAD_FAILED_GIVE_UP.value + " OR uploadStatus=="
                 + UploadStatus.UPLOAD_CANCELLED.value, null);
-    }    
+    }
+
     /**
      * Get all uploads which where successfully completed.
      */
@@ -346,15 +378,22 @@ public class UploadDbHandler extends Observable {
 
     public long cleanDoneUploads() {
         String[] where = new String[3];
-        where[0]  = String.valueOf(UploadStatus.UPLOAD_CANCELLED.value);
-        where[1]  = String.valueOf(UploadStatus.UPLOAD_FAILED_GIVE_UP.value);
-        where[2]  = String.valueOf(UploadStatus.UPLOAD_SUCCEEDED.value);
+        where[0] = String.valueOf(UploadStatus.UPLOAD_CANCELLED.value);
+        where[1] = String.valueOf(UploadStatus.UPLOAD_FAILED_GIVE_UP.value);
+        where[2] = String.valueOf(UploadStatus.UPLOAD_SUCCEEDED.value);
         long result = getDB().delete(TABLE_UPLOAD, "uploadStatus = ? OR uploadStatus = ? OR uploadStatus = ?", where);
         Log_OC.d(TABLE_UPLOAD, "delete all done uploads");
-        if(result>0) {
+        if (result > 0) {
             notifyObserversNow();
         }
         return result;
     }
 
+    public void setAllCurrentToUploadLater() {
+        
+        Cursor c = getDB().query(TABLE_UPLOAD, null, "uploadStatus==" + UploadStatus.UPLOAD_IN_PROGRESS.value, null, null, null, null);
+        
+        updateUploadInternal(c, UploadStatus.UPLOAD_LATER, null);
+    }
+
 }

+ 7 - 0
src/com/owncloud/android/db/UploadDbObject.java

@@ -302,4 +302,11 @@ public class UploadDbObject implements Serializable {
     public void setUploadTimestamp(long uploadTimestamp) {
         this.uploadTimestamp = uploadTimestamp;
     }
+    
+    /**
+     * For debugging purposes only.
+     */
+    public String toFormattedString() {
+        return getLocalPath() + " status:"+getUploadStatus() + " result:" + getLastResult();
+    }
 }

+ 1 - 1
src/com/owncloud/android/files/FileOperationsHelper.java

@@ -47,7 +47,7 @@ import com.owncloud.android.ui.dialog.ShareLinkToDialog;
  */
 public class FileOperationsHelper {
 
-    private static final String TAG = FileOperationsHelper.class.getName();
+    private static final String TAG = FileOperationsHelper.class.getSimpleName();
     
     private static final String FTAG_CHOOSER_DIALOG = "CHOOSER_DIALOG"; 
 

+ 81 - 33
src/com/owncloud/android/files/services/FileUploadService.java

@@ -67,6 +67,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation;
+import com.owncloud.android.lib.resources.files.FileUtils;
 import com.owncloud.android.lib.resources.files.ReadRemoteFileOperation;
 import com.owncloud.android.lib.resources.files.RemoteFile;
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;
@@ -98,7 +99,7 @@ import com.owncloud.android.utils.UriUtils;
  * 
  */
 @SuppressWarnings("unused")
-public class FileUploadService extends IntentService {
+public class FileUploadService extends IntentService implements OnDatatransferProgressListener {
 
     public FileUploadService() {
         super("FileUploadService");        
@@ -221,6 +222,7 @@ public class FileUploadService extends IntentService {
     
     private NotificationManager mNotificationManager;
     private NotificationCompat.Builder mNotificationBuilder;
+    private int mLastPercent;
 
     private static final String MIME_TYPE_PDF = "application/pdf";
     private static final String FILE_EXTENSION_PDF = ".pdf";
@@ -266,7 +268,7 @@ public class FileUploadService extends IntentService {
     @Override
     public void onCreate() {
         super.onCreate();
-        Log_OC.i(TAG, "mPendingUploads size:" + mPendingUploads.size());
+        Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.size());
         mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
         HandlerThread thread = new HandlerThread("FileUploaderThread", Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
@@ -276,11 +278,7 @@ public class FileUploadService extends IntentService {
         mDb.recreateDb(); //for testing only
         
         //when this service starts there is no upload in progress. if db says so, app probably crashed before.
-        UploadDbObject[] current = mDb.getCurrentUpload();
-        for (UploadDbObject uploadDbObject : current) {
-            uploadDbObject.setUploadStatus(UploadStatus.UPLOAD_LATER);
-            mDb.updateUpload(uploadDbObject);   
-        }
+        mDb.setAllCurrentToUploadLater();
         
         //TODO This service can be instantiated at any time. Better move this retry call to start of app.
         if(UploadUtils.isOnline(getApplicationContext())) {
@@ -312,26 +310,25 @@ public class FileUploadService extends IntentService {
 
     @Override
     protected void onHandleIntent(Intent intent) {
-        Log_OC.i(TAG, "onHandleIntent start");
-        Log_OC.i(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - before adding new uploads.");
+        Log_OC.d(TAG, "onHandleIntent start");
+        Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - before adding new uploads.");
         if (intent == null || intent.hasExtra(KEY_RETRY)) {
-            Log_OC.d(TAG, "Receive null intent.");
+            Log_OC.d(TAG, "Received null intent.");
             // service was restarted by OS or connectivity change was detected or
             // retry of pending upload was requested. 
             // ==> First check persistent uploads, then perform upload.
             int countAddedEntries = 0;
             UploadDbObject[] list = mDb.getPendingUploads();
             for (UploadDbObject uploadDbObject : list) {
-                // store locally.
+                Log_OC.d(TAG, "Retrieved from DB: " + uploadDbObject.toFormattedString());
+                
                 String uploadKey = buildRemoteName(uploadDbObject);
-                UploadDbObject previous = mPendingUploads.putIfAbsent(uploadKey, uploadDbObject);                
+                UploadDbObject previous = mPendingUploads.putIfAbsent(uploadKey, uploadDbObject);
                 if(previous == null) {
-                    // and store persistently.
-                    uploadDbObject.setUploadStatus(UploadStatus.UPLOAD_LATER);
-                    mDb.updateUpload(uploadDbObject);
+                    Log_OC.d(TAG, "mPendingUploads added: " + uploadDbObject.toFormattedString());
                     countAddedEntries++;
                 } else {
-                  //upload already pending. ignore.
+                    //already pending. ignore.
                 }
             }
             Log_OC.d(TAG, "added " + countAddedEntries
@@ -426,9 +423,21 @@ public class FileUploadService extends IntentService {
                 
                 if(previous == null)
                 {
+                    Log_OC.d(TAG, "mPendingUploads added: " + uploadObject.toFormattedString());
+
+                    // if upload was not queued before, we can add it to
+                    // database because the user wants the file to be uploaded.
+                    // however, it can happened that the user uploaded the same
+                    // file before in which case there is an old db entry.
+                    // delete that to be sure we have the latest one.
+                    if(mDb.removeUpload(uploadObject.getLocalPath())>0) {
+                        Log_OC.w(TAG, "There was an old DB entry " + uploadObject.getLocalPath()
+                                + " which had to be removed in order to add new one.");
+                    }
                     boolean success = mDb.storeUpload(uploadObject);
                     if(!success) {
-                        Log_OC.e(TAG, "Could not add upload to database. It might be a duplicate. Ignore.");
+                        Log_OC.e(TAG, "Could not add upload " + uploadObject.getLocalPath()
+                                + " to database. This should not happen.");
                     } 
                 } else {
                     Log_OC.w(TAG, "FileUploadService got upload intent for file which is already queued: "
@@ -437,10 +446,9 @@ public class FileUploadService extends IntentService {
                 }
             }
         }
-
         // at this point mPendingUploads is filled.
 
-        Log_OC.i(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - before uploading.");
+        Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - before uploading.");
 
         Iterator<String> it = mPendingUploads.keySet().iterator();
         while (it.hasNext()) {
@@ -459,7 +467,8 @@ public class FileUploadService extends IntentService {
                     Log_OC.d(TAG, "Upload with result " + uploadResult.getCode() + ": " + uploadResult.getLogMessage()
                             + " will be abandoned.");                    
                     mPendingUploads.remove(buildRemoteName(uploadDbObject));
-                }                
+                }
+                Log_OC.d(TAG, "mCurrentUpload = null");
                 mCurrentUpload = null;
                 break;
             case LATER:
@@ -479,8 +488,8 @@ public class FileUploadService extends IntentService {
             }
         }
 
-        Log_OC.i(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - after uploading.");
-        Log_OC.i(TAG, "onHandleIntent end");
+        Log_OC.d(TAG, "mPendingUploads size:" + mPendingUploads.size() + " - after uploading.");
+        Log_OC.d(TAG, "onHandleIntent end");
     }
 
     /**
@@ -525,14 +534,23 @@ public class FileUploadService extends IntentService {
          * @param file A file in the queue of pending uploads
          */
         public void cancel(Account account, OCFile file) {
-            UploadDbObject upload = null;
-            //remove is atomic operation. no need for synchronize.
-            upload = mPendingUploads.remove(buildRemoteName(account, file));
-            upload.setUploadStatus(UploadStatus.UPLOAD_CANCELLED);
-            mDb.updateUpload(upload);            
-            if(mCurrentUpload != null) {
+            // updating current references (i.e., uploadStatus of current
+            // upload) is handled by updateDataseUploadResult() which is called
+            // after upload finishes. Following cancel call makes sure that is
+            // does finish right now.
+            if (mCurrentUpload != null) {
                 mCurrentUpload.cancel();
-                mCurrentUpload = null;
+            } else {
+                Log_OC.e(TAG, "mCurrentUpload == null. Cannot cancel upload. Fix that!");
+
+                // in this case we have to update the db here. this should never
+                // happen though!
+                UploadDbObject upload = mPendingUploads.remove(buildRemoteName(account, file));
+                upload.setUploadStatus(UploadStatus.UPLOAD_CANCELLED);
+                // storagePath inside upload is the temporary path. file
+                // contains the correct path used as db reference.
+                upload.getOCFile().setStoragePath(file.getStoragePath());
+                mDb.updateUpload(upload);
             }
         }
 
@@ -547,6 +565,10 @@ public class FileUploadService extends IntentService {
          * If 'file' is a directory, returns 'true' if some of its descendant
          * files is uploading or waiting to upload.
          * 
+         * Warning: If remote file exists and !forceOverwrite the original file
+         * is being returned here. That is, it seems as if the original file is
+         * being updated when actually a new file is being uploaded.
+         * 
          * @param account Owncloud account where the remote file will be stored.
          * @param file A file that could be in the queue of pending uploads
          */
@@ -702,18 +724,20 @@ public class FileUploadService extends IntentService {
 
         uploadKey = buildRemoteName(account, uploadDbObject.getRemotePath());
         OCFile file = uploadDbObject.getOCFile();
+        Log_OC.d(TAG, "mCurrentUpload = new UploadFileOperation");
         mCurrentUpload = new UploadFileOperation(account, file, chunked, uploadDbObject.isForceOverwrite(),
                 uploadDbObject.getLocalAction(), getApplicationContext());
         if (uploadDbObject.isCreateRemoteFolder()) {
             mCurrentUpload.setRemoteFolderToBeCreated();
         }
         mCurrentUpload.addDatatransferProgressListener((FileUploaderBinder) mBinder);
-
+        mCurrentUpload.addDatatransferProgressListener(this);
+        
         notifyUploadStart(mCurrentUpload);        
 
         RemoteOperationResult uploadResult = null, grantResult = null;
         try {
-            // / prepare client object to send requests to the ownCloud
+            // prepare client object to send requests to the ownCloud
             // server
             if (mUploadClient == null || !mLastAccount.equals(mCurrentUpload.getAccount())) {
                 mLastAccount = mCurrentUpload.getAccount();
@@ -722,7 +746,7 @@ public class FileUploadService extends IntentService {
                 mUploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, this);
             }
 
-            // / check the existence of the parent folder for the file to
+            // 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
@@ -733,6 +757,11 @@ public class FileUploadService extends IntentService {
             if (grantResult.isSuccess()) {
                 OCFile parent = mStorageManager.getFileByPath(remoteParentPath);
                 mCurrentUpload.getFile().setParentId(parent.getFileId());
+                // inside this call the remote path may be changed (if remote
+                // file exists and !forceOverwrite) in this case the map from
+                // mPendingUploads is wrong. This results in an upload
+                // indication in the GUI showing that the original file is being
+                // uploaded (instead that a new one is created)
                 uploadResult = mCurrentUpload.execute(mUploadClient);
                 if (uploadResult.isSuccess()) {
                     saveUploadedFile(mCurrentUpload);
@@ -750,7 +779,7 @@ public class FileUploadService extends IntentService {
             uploadResult = new RemoteOperationResult(e);
 
         } finally {
-            Log_OC.i(TAG, "Remove CurrentUploadItem from pending upload Item Map.");
+            Log_OC.d(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
@@ -911,6 +940,7 @@ public class FileUploadService extends IntentService {
      */
     private void notifyUploadStart(UploadFileOperation upload) {
         // / create status notification with a progress bar
+        mLastPercent = 0; 
         mNotificationBuilder = NotificationBuilderWithProgressBar.newNotificationBuilderWithProgressBar(this);
         mNotificationBuilder
                 .setOngoing(true)
@@ -942,6 +972,22 @@ public class FileUploadService extends IntentService {
         mDb.updateUpload(upload.getOriginalStoragePath(), UploadStatus.UPLOAD_IN_PROGRESS, null);    
     }
 
+    /**
+     * Callback method to update the progress bar in the status notification
+     */
+    @Override
+    public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filePath) {
+        int percent = (int) (100.0 * ((double) totalTransferredSoFar) / ((double) totalToTransfer));
+        if (percent != mLastPercent) {
+            mNotificationBuilder.setProgress(100, percent, false);
+            String fileName = filePath.substring(filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1);
+            String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, fileName);
+            mNotificationBuilder.setContentText(text);
+            mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build());
+        }
+        mLastPercent = percent;
+    } 
+    
     /**
      * Updates the status notification with the result of an upload operation.
      * 
@@ -1015,6 +1061,7 @@ public class FileUploadService extends IntentService {
      */
     private void updateDataseUploadResult(RemoteOperationResult uploadResult, UploadFileOperation upload) {
         // result: success or fail notification
+        Log_OC.d(TAG, "updateDataseUploadResult uploadResult: " + uploadResult + " upload: " + upload);
         if (uploadResult.isCancelled()) {
             mDb.updateUpload(upload.getOriginalStoragePath(), UploadStatus.UPLOAD_CANCELLED, uploadResult);
         } else {
@@ -1096,4 +1143,5 @@ public class FileUploadService extends IntentService {
         context.startService(i);        
     }
 
+
 }

+ 5 - 1
src/com/owncloud/android/operations/UploadFileOperation.java

@@ -380,7 +380,11 @@ public class UploadFileOperation extends RemoteOperation {
                         complement = " (while copying local file to " + FileStorageUtils.getSavePath(mAccount.name)
                                 + ")";
                     }
-                    Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage() + complement, result.getException());
+                    if(result.isCancelled()){
+                        Log_OC.w(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
+                    } else {
+                        Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage() + complement, result.getException());    
+                    }                    
                 } else {
                     Log_OC.e(TAG, "Upload of " + mOriginalStoragePath + " to " + mRemotePath + ": " + result.getLogMessage());
                 }

+ 9 - 1
src/com/owncloud/android/ui/adapter/ExpandableUploadListAdapter.java

@@ -22,6 +22,7 @@ import com.owncloud.android.R;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.db.UploadDbHandler;
 import com.owncloud.android.db.UploadDbObject;
+import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.utils.DisplayUtils;
 
@@ -30,7 +31,7 @@ import com.owncloud.android.utils.DisplayUtils;
  * active, completed. Filtering possible.
  * 
  */
-public class ExpandableUploadListAdapter extends BaseExpandableListAdapter implements Observer {
+public class ExpandableUploadListAdapter extends BaseExpandableListAdapter implements Observer, OnDatatransferProgressListener {
 
     private static final String TAG = "ExpandableUploadListAdapter";
     private Activity mActivity;
@@ -293,4 +294,11 @@ public class ExpandableUploadListAdapter extends BaseExpandableListAdapter imple
     public boolean isChildSelectable(int groupPosition, int childPosition) {
         return true;
     }
+
+    @Override
+    public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer,
+            String fileAbsoluteName) {
+        // TODO Auto-generated method stub
+        
+    }
 }

+ 8 - 0
src/com/owncloud/android/ui/fragment/FileDetailFragment.java

@@ -509,11 +509,19 @@ public class FileDetailFragment extends FileFragment implements OnClickListener
     public void listenForTransferProgress() {
         if (mProgressListener != null) {
             if (mContainerActivity.getFileDownloaderBinder() != null) {
+                Log_OC.d(TAG, "registering download progress listener");
                 mContainerActivity.getFileDownloaderBinder().addDatatransferProgressListener(mProgressListener, mAccount, getFile());
+            }else {
+                Log_OC.d(TAG, "mContainerActivity.getFileDownloaderBinder() == null");
             }
             if (mContainerActivity.getFileUploaderBinder() != null) {
+                Log_OC.d(TAG, "registering upload progress listener");
                 mContainerActivity.getFileUploaderBinder().addDatatransferProgressListener(mProgressListener, mAccount, getFile());
+            }else {
+                Log_OC.d(TAG, "mContainerActivity.getFileUploaderBinder() == null");
             }
+        } else {
+            Log_OC.d(TAG, "mProgressListener == null");
         }
     }