Added indexed tree of synchronizing folders to SyncFolderHandler
[pub/Android/ownCloud.git] / src / com / owncloud / android / files / services / FileDownloader.java
index 2b70606..06ebc0b 100644 (file)
@@ -1,6 +1,6 @@
 /* ownCloud Android client application
  *   Copyright (C) 2012 Bartek Przybylski
 /* ownCloud Android client application
  *   Copyright (C) 2012 Bartek Przybylski
- *   Copyright (C) 2012-2013 ownCloud Inc.
+ *   Copyright (C) 2012-2015 ownCloud Inc.
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -21,7 +21,6 @@ package com.owncloud.android.files.services;
 import java.io.File;
 import java.io.IOException;
 import java.util.AbstractList;
 import java.io.File;
 import java.io.IOException;
 import java.util.AbstractList;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -63,19 +62,19 @@ import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
 import android.support.v4.app.NotificationCompat;
 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 {
     
     public static final String EXTRA_ACCOUNT = "ACCOUNT";
     public static final String EXTRA_FILE = "FILE";
 
 
 public class FileDownloader extends Service implements OnDatatransferProgressListener {
     
     public static final String EXTRA_ACCOUNT = "ACCOUNT";
     public static final String EXTRA_FILE = "FILE";
 
-    public static final String ACTION_CANCEL_FILE_DOWNLOAD = "CANCEL_FILE_DOWNLOAD";
-
     private static final String DOWNLOAD_ADDED_MESSAGE = "DOWNLOAD_ADDED";
     private static final String DOWNLOAD_FINISH_MESSAGE = "DOWNLOAD_FINISH";
     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";
     private static final String DOWNLOAD_ADDED_MESSAGE = "DOWNLOAD_ADDED";
     private static final String DOWNLOAD_FINISH_MESSAGE = "DOWNLOAD_FINISH";
     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";
     public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
     
     private static final String TAG = "FileDownloader";
@@ -84,7 +83,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     private ServiceHandler mServiceHandler;
     private IBinder mBinder;
     private OwnCloudClient mDownloadClient = null;
     private ServiceHandler mServiceHandler;
     private IBinder mBinder;
     private OwnCloudClient mDownloadClient = null;
-    private Account mLastAccount = null;
+    private Account mCurrentAccount = null;
     private FileDataStorageManager mStorageManager;
     
     private IndexedForest<DownloadFileOperation> mPendingDownloads = new IndexedForest<DownloadFileOperation>();
     private FileDataStorageManager mStorageManager;
     
     private IndexedForest<DownloadFileOperation> mPendingDownloads = new IndexedForest<DownloadFileOperation>();
@@ -97,11 +96,11 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
 
     
     public static String getDownloadAddedMessage() {
 
     
     public static String getDownloadAddedMessage() {
-        return FileDownloader.class.getName().toString() + DOWNLOAD_ADDED_MESSAGE;
+        return FileDownloader.class.getName() + DOWNLOAD_ADDED_MESSAGE;
     }
     
     public static String getDownloadFinishMessage() {
     }
     
     public static String getDownloadFinishMessage() {
-        return FileDownloader.class.getName().toString() + DOWNLOAD_FINISH_MESSAGE;
+        return FileDownloader.class.getName() + DOWNLOAD_FINISH_MESSAGE;
     }
     
     /**
     }
     
     /**
@@ -136,6 +135,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
             final Account account = intent.getParcelableExtra(EXTRA_ACCOUNT);
             final OCFile file = intent.getParcelableExtra(EXTRA_FILE);
 
             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() {
             if (ACTION_CANCEL_FILE_DOWNLOAD.equals(intent.getAction())) {
 
                 new Thread(new Runnable() {
@@ -146,13 +146,17 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                 }).start();
 
             } else {
                 }).start();
 
             } else {
+            */
 
                 AbstractList<String> requestedDownloads = new Vector<String>();
                 try {
                     DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
 
                 AbstractList<String> requestedDownloads = new Vector<String>();
                 try {
                     DownloadFileOperation newDownload = new DownloadFileOperation(account, file);
-                    String downloadKey = mPendingDownloads.putIfAbsent(account, file.getRemotePath(), newDownload);
                     newDownload.addDatatransferProgressListener(this);
                     newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
                     newDownload.addDatatransferProgressListener(this);
                     newDownload.addDatatransferProgressListener((FileDownloaderBinder) mBinder);
+                    Pair<String, String> putResult = mPendingDownloads.putIfAbsent(
+                        account, file.getRemotePath(), newDownload
+                    );
+                    String downloadKey = putResult.first;
                     requestedDownloads.add(downloadKey);
 
                     // Store file on db with state 'downloading'
                     requestedDownloads.add(downloadKey);
 
                     // Store file on db with state 'downloading'
@@ -163,7 +167,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                     storageManager.saveFile(file);
                     */
 
                     storageManager.saveFile(file);
                     */
 
-                    sendBroadcastNewDownload(newDownload);
+                    sendBroadcastNewDownload(newDownload, putResult.second);
 
                 } catch (IllegalArgumentException e) {
                     Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
 
                 } catch (IllegalArgumentException e) {
                     Log_OC.e(TAG, "Not enough information provided in intent: " + e.getMessage());
@@ -176,7 +180,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                     msg.obj = requestedDownloads;
                     mServiceHandler.sendMessage(msg);
                 }
                     msg.obj = requestedDownloads;
                     mServiceHandler.sendMessage(msg);
                 }
-            }
+            //}
         }
 
         return START_NOT_STICKY;
         }
 
         return START_NOT_STICKY;
@@ -223,14 +227,20 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         /**
          * Cancels a pending or current download of a remote file.
          *
         /**
          * Cancels a pending or current download of a remote file.
          *
-         * @param account       Owncloud account where the remote file is stored.
+         * @param account       ownCloud account where the remote file is stored.
          * @param file          A file in the queue of pending downloads
          */
         public void cancel(Account account, OCFile file) {
          * @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();
             if (download != null) {
                 download.cancel();
+            } else {
+                if (mCurrentDownload != null && mCurrentAccount != null &&
+                        mCurrentDownload.getRemotePath().startsWith(file.getRemotePath()) &&
+                        account.name.equals(mCurrentAccount.name)) {
+                    mCurrentDownload.cancel();
+                }
             }
         }
         
             }
         }
         
@@ -349,11 +359,11 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
             RemoteOperationResult downloadResult = null;
             try {
                 /// prepare client object to send the request to the ownCloud server
             RemoteOperationResult downloadResult = null;
             try {
                 /// prepare client object to send the request to the ownCloud server
-                if (mDownloadClient == null || !mLastAccount.equals(mCurrentDownload.getAccount())) {
-                    mLastAccount = mCurrentDownload.getAccount();
+                if (mDownloadClient == null || !mCurrentAccount.equals(mCurrentDownload.getAccount())) {
+                    mCurrentAccount = mCurrentDownload.getAccount();
                     mStorageManager = 
                     mStorageManager = 
-                            new FileDataStorageManager(mLastAccount, getContentResolver());
-                    OwnCloudAccount ocAccount = new OwnCloudAccount(mLastAccount, this);
+                            new FileDataStorageManager(mCurrentAccount, getContentResolver());
+                    OwnCloudAccount ocAccount = new OwnCloudAccount(mCurrentAccount, this);
                     mDownloadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
                             getClientFor(ocAccount, this);
                 }
                     mDownloadClient = OwnCloudClientManagerFactory.getDefaultSingleton().
                             getClientFor(ocAccount, this);
                 }
@@ -368,21 +378,22 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                 }
             
             } catch (AccountsException e) {
                 }
             
             } catch (AccountsException e) {
-                Log_OC.e(TAG, "Error while trying to get authorization for " + mLastAccount.name, e);
+                Log_OC.e(TAG, "Error while trying to get authorization for " + mCurrentAccount.name, e);
                 downloadResult = new RemoteOperationResult(e);
             } catch (IOException e) {
                 downloadResult = new RemoteOperationResult(e);
             } catch (IOException e) {
-                Log_OC.e(TAG, "Error while trying to get authorization for " + mLastAccount.name, e);
+                Log_OC.e(TAG, "Error while trying to get authorization for " + mCurrentAccount.name, e);
                 downloadResult = new RemoteOperationResult(e);
                 
             } finally {
                 downloadResult = new RemoteOperationResult(e);
                 
             } finally {
-                mPendingDownloads.remove(mLastAccount, mCurrentDownload.getRemotePath());
+                Pair<DownloadFileOperation, String> removeResult =
+                        mPendingDownloads.removePayload(mCurrentAccount, mCurrentDownload.getRemotePath());
+
+                /// notify result
+                notifyDownloadResult(mCurrentDownload, downloadResult);
+
+                sendBroadcastDownloadFinished(mCurrentDownload, downloadResult, removeResult.second);
             }
 
             }
 
-            
-            /// notify result
-            notifyDownloadResult(mCurrentDownload, downloadResult);
-            
-            sendBroadcastDownloadFinished(mCurrentDownload, downloadResult);
         }
     }
 
         }
     }
 
@@ -548,15 +559,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
      * 
     /**
      * 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());
         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);
     }
     
         sendStickyBroadcast(end);
     }
     
@@ -564,13 +582,15 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     /**
      * Sends a broadcast when a new download is added to the queue.
      * 
     /**
      * 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());
         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);
     }
 
         sendStickyBroadcast(added);
     }
 
@@ -578,7 +598,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
      * Cancel operation
      * @param account       ownCloud account where the remote file is stored.
      * @param file          File OCFile
      * 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());
     public void cancel(Account account, OCFile file){
         DownloadFileOperation download = null;
         //String targetKey = buildKey(account, file.getRemotePath());
@@ -607,7 +627,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                 }
             }
 
                 }
             }
 
-            */
+            *-/
 
         } else {
             // this is not really expected...
 
         } else {
             // this is not really expected...
@@ -618,5 +638,6 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
             }
         }
     }
             }
         }
     }
+    */
 
 }
 
 }