소스 검색

Minimize refresh of list of files on reception of events from FileDownloader

David A. Velasco 10 년 전
부모
커밋
a07937cb6f

+ 39 - 21
src/com/owncloud/android/files/services/FileDownloader.java

@@ -63,6 +63,7 @@ import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
 import android.support.v4.app.NotificationCompat;
+import android.util.Pair;
 
 public class FileDownloader extends Service implements OnDatatransferProgressListener {
     
@@ -76,6 +77,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     public static final String EXTRA_DOWNLOAD_RESULT = "RESULT";    
     public static final String EXTRA_FILE_PATH = "FILE_PATH";
     public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";
+    public static final String EXTRA_LINKED_TO_PATH = "LINKED_TO";
     public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
     
     private static final String TAG = "FileDownloader";
@@ -97,11 +99,11 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
 
     
     public static String getDownloadAddedMessage() {
-        return FileDownloader.class.getName().toString() + DOWNLOAD_ADDED_MESSAGE;
+        return FileDownloader.class.getName() + DOWNLOAD_ADDED_MESSAGE;
     }
     
     public static String getDownloadFinishMessage() {
-        return FileDownloader.class.getName().toString() + DOWNLOAD_FINISH_MESSAGE;
+        return FileDownloader.class.getName() + DOWNLOAD_FINISH_MESSAGE;
     }
     
     /**
@@ -136,6 +138,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
             final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
             final OCFile file = intent.getParcelableExtra(EXTRA_FILE);
 
+            /*
             if (ACTION_CANCEL_FILE_DOWNLOAD.equals(intent.getAction())) {
 
                 new Thread(new Runnable() {
@@ -146,11 +149,15 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                 }).start();
 
             } else {
+            */
 
                 AbstractList<String> requestedDownloads = new Vector<String>();
                 try {
                     DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
-                    String downloadKey = mPendingDownloads.putIfAbsent(account, file.getRemotePath(), newDownload);
+                    Pair<String, String> putResult = mPendingDownloads.putIfAbsent(
+                        account, file.getRemotePath(), newDownload
+                    );
+                    String downloadKey = putResult.first;
                     newDownload.addDatatransferProgressListener(this);
                     newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
                     requestedDownloads.add(downloadKey);
@@ -163,7 +170,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                     storageManager.saveFile(file);
                     */
 
-                    sendBroadcastNewDownload(newDownload);
+                    sendBroadcastNewDownload(newDownload, putResult.second);
 
                 } catch (IllegalArgumentException e) {
                     Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
@@ -176,7 +183,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                     msg.obj = requestedDownloads;
                     mServiceHandler.sendMessage(msg);
                 }
-            }
+            //}
         }
 
         return START_NOT_STICKY;
@@ -227,14 +234,14 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
          * @param file          A file in the queue of pending downloads
          */
         public void cancel(Account account, OCFile file) {
-            DownloadFileOperation download = null;
-            download = mPendingDownloads.remove(account, file.getRemotePath());
+            Pair<DownloadFileOperation, String> removeResult = mPendingDownloads.remove(account, file.getRemotePath());
+            DownloadFileOperation download = removeResult.first;
             if (download != null) {
                 download.cancel();
             } else {
                 // TODO synchronize
                 if (mCurrentDownload.getRemotePath().startsWith(file.getRemotePath()) &&
-                        account.name.equals(mLastAccount)) {
+                        account.name.equals(mLastAccount.name)) {
                     mCurrentDownload.cancel();
                 }
             }
@@ -381,14 +388,15 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                 downloadResult = new RemoteOperationResult(e);
                 
             } finally {
-                mPendingDownloads.remove(mLastAccount, mCurrentDownload.getRemotePath());
+                Pair<DownloadFileOperation, String> removeResult =
+                        mPendingDownloads.remove(mLastAccount, mCurrentDownload.getRemotePath());
+
+                /// notify result
+                notifyDownloadResult(mCurrentDownload, downloadResult);
+
+                sendBroadcastDownloadFinished(mCurrentDownload, downloadResult, removeResult.second);
             }
 
-            
-            /// notify result
-            notifyDownloadResult(mCurrentDownload, downloadResult);
-            
-            sendBroadcastDownloadFinished(mCurrentDownload, downloadResult);
         }
     }
 
@@ -554,15 +562,22 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     /**
      * Sends a broadcast when a download finishes in order to the interested activities can update their view
      * 
-     * @param download          Finished download operation
-     * @param downloadResult    Result of the download operation
+     * @param download                  Finished download operation
+     * @param downloadResult            Result of the download operation
+     * @param unlinkedFromRemotePath    Path in the downloads tree where the download was unlinked from
      */
-    private void sendBroadcastDownloadFinished(DownloadFileOperation download, RemoteOperationResult downloadResult) {
+    private void sendBroadcastDownloadFinished(
+            DownloadFileOperation download,
+            RemoteOperationResult downloadResult,
+            String unlinkedFromRemotePath) {
         Intent end = new Intent(getDownloadFinishMessage());
         end.putExtra(EXTRA_DOWNLOAD_RESULT, downloadResult.isSuccess());
         end.putExtra(ACCOUNT_NAME, download.getAccount().name);
         end.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
         end.putExtra(EXTRA_FILE_PATH, download.getSavePath());
+        if (unlinkedFromRemotePath != null) {
+            end.putExtra(EXTRA_LINKED_TO_PATH, unlinkedFromRemotePath);
+        }
         sendStickyBroadcast(end);
     }
     
@@ -570,13 +585,15 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     /**
      * Sends a broadcast when a new download is added to the queue.
      * 
-     * @param download          Added download operation
+     * @param download              Added download operation
+     * @param linkedToRemotePath    Path in the downloads tree where the download was linked to
      */
-    private void sendBroadcastNewDownload(DownloadFileOperation download) {
+    private void sendBroadcastNewDownload(DownloadFileOperation download, String linkedToRemotePath) {
         Intent added = new Intent(getDownloadAddedMessage());
         added.putExtra(ACCOUNT_NAME, download.getAccount().name);
         added.putExtra(EXTRA_REMOTE_PATH, download.getRemotePath());
         added.putExtra(EXTRA_FILE_PATH, download.getSavePath());
+        added.putExtra(EXTRA_LINKED_TO_PATH, linkedToRemotePath);
         sendStickyBroadcast(added);
     }
 
@@ -584,7 +601,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
      * Cancel operation
      * @param account       ownCloud account where the remote file is stored.
      * @param file          File OCFile
-     */
+     *-/
     public void cancel(Account account, OCFile file){
         DownloadFileOperation download = null;
         //String targetKey = buildKey(account, file.getRemotePath());
@@ -613,7 +630,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                 }
             }
 
-            */
+            *-/
 
         } else {
             // this is not really expected...
@@ -624,5 +641,6 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
             }
         }
     }
+    */
 
 }

+ 17 - 6
src/com/owncloud/android/files/services/IndexedForest.java

@@ -18,6 +18,7 @@
 package com.owncloud.android.files.services;
 
 import android.accounts.Account;
+import android.util.Pair;
 
 import com.owncloud.android.datamodel.OCFile;
 
@@ -91,7 +92,7 @@ public class IndexedForest<V> {
     }
 
 
-    public /* synchronized */ String putIfAbsent(Account account, String remotePath, V value) {
+    public /* synchronized */ Pair<String, String> putIfAbsent(Account account, String remotePath, V value) {
         String targetKey = buildKey(account, remotePath);
         Node<V> valuedNode = new Node(targetKey, value);
         mMap.putIfAbsent(
@@ -121,12 +122,17 @@ public class IndexedForest<V> {
             currentNode = parentNode;
         }
 
-        return targetKey;
+        String linkedTo = OCFile.ROOT_PATH;
+        if (linked) {
+            linkedTo = parentNode.getKey().substring(account.name.length());
+        }
+        return new Pair<String, String>(targetKey, linkedTo);
     };
 
-    public /* synchronized */ V remove(Account account, String remotePath) {
+    public /* synchronized */ Pair<V, String> remove(Account account, String remotePath) {
         String targetKey = buildKey(account, remotePath);
         Node<V> firstRemoved = mMap.remove(targetKey);
+        String unlinkedFrom = null;
 
         if (firstRemoved != null) {
             /// remove children
@@ -135,21 +141,26 @@ public class IndexedForest<V> {
             /// remove ancestors if only here due to firstRemoved
             Node<V> removed = firstRemoved;
             Node<V> parent = removed.getParent();
+            boolean unlinked = false;
             while (parent != null) {
                 parent.removeChild(removed);
                 if (!parent.hasChildren()) {
                     removed = mMap.remove(parent.getKey());
                     parent = removed.getParent();
                 } else {
-                    parent = null;
+                    break;
                 }
             }
+
+            if (parent != null) {
+                unlinkedFrom = parent.getKey().substring(account.name.length());
+            }
         }
 
         if (firstRemoved != null) {
-            return firstRemoved.getPayload();
+            return new Pair<V, String>(firstRemoved.getPayload(), unlinkedFrom);
         } else {
-            return null;
+            return new Pair<V, String>(null, unlinkedFrom);
         }
 
     }

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

@@ -1261,20 +1261,30 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
      * current folder.
      */
     private class DownloadFinishReceiver extends BroadcastReceiver {
+
+        int refreshCounter = 0;
         @Override
         public void onReceive(Context context, Intent intent) {
             try {
                 boolean sameAccount = isSameAccount(context, intent);
                 String downloadedRemotePath = intent.getStringExtra(FileDownloader.EXTRA_REMOTE_PATH);
                 boolean isDescendant = isDescendant(downloadedRemotePath);
-    
+
                 if (sameAccount && isDescendant) {
-                    refreshListOfFilesFragment();
-                    refreshSecondFragment(intent.getAction(), downloadedRemotePath, intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false));
+                    String linkedToRemotePath = intent.getStringExtra(FileDownloader.EXTRA_LINKED_TO_PATH);
+                    if (linkedToRemotePath == null || isAscendant(linkedToRemotePath)) {
+                        Log_OC.v(TAG, "NOW: refresh #" + ++refreshCounter);
+                        refreshListOfFilesFragment();
+                    }
+                    refreshSecondFragment(
+                            intent.getAction(),
+                            downloadedRemotePath,
+                            intent.getBooleanExtra(FileDownloader.EXTRA_DOWNLOAD_RESULT, false)
+                    );
                 }
     
                 if (mWaitingToSend != null) {
-                    mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath()); // Update the file to send
+                    mWaitingToSend = getStorageManager().getFileByPath(mWaitingToSend.getRemotePath());
                     if (mWaitingToSend.isDown()) { 
                         sendDownloadedFile();
                     }
@@ -1289,7 +1299,19 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
 
         private boolean isDescendant(String downloadedRemotePath) {
             OCFile currentDir = getCurrentDir();
-            return (currentDir != null && downloadedRemotePath != null && downloadedRemotePath.startsWith(currentDir.getRemotePath()));
+            return (
+                currentDir != null &&
+                downloadedRemotePath != null &&
+                downloadedRemotePath.startsWith(currentDir.getRemotePath())
+            );
+        }
+
+        private boolean isAscendant(String linkedToRemotePath) {
+            OCFile currentDir = getCurrentDir();
+            return (
+                currentDir != null &&
+                currentDir.getRemotePath().startsWith(linkedToRemotePath)
+            );
         }
 
         private boolean isSameAccount(Context context, Intent intent) {

+ 1 - 1
src/com/owncloud/android/ui/preview/PreviewImageActivity.java

@@ -426,7 +426,7 @@ ViewPager.OnPageChangeListener, OnRemoteOperationListener {
     
 
     /**
-     * Class waiting for broadcast events from the {@link FielDownloader} service.
+     * Class waiting for broadcast events from the {@link FileDownloader} service.
      * 
      * Updates the UI when a download is started or finished, provided that it is relevant for the
      * folder displayed in the gallery.