Fixed cancel button in landscape account activity
[pub/Android/ownCloud.git] / src / eu / alefzero / owncloud / files / services / FileDownloader.java
index 3ee316f..b0dd2b2 100644 (file)
@@ -1,21 +1,19 @@
 package eu.alefzero.owncloud.files.services;\r
 \r
 import java.io.File;\r
-import java.io.IOException;\r
 import java.util.Collections;\r
 import java.util.HashMap;\r
 import java.util.Map;\r
 \r
 import android.accounts.Account;\r
 import android.accounts.AccountManager;\r
-import android.accounts.AuthenticatorException;\r
-import android.accounts.OperationCanceledException;\r
 import android.app.Notification;\r
 import android.app.NotificationManager;\r
 import android.app.PendingIntent;\r
 import android.app.Service;\r
 import android.content.ContentValues;\r
 import android.content.Intent;\r
+import android.net.Uri;\r
 import android.os.Environment;\r
 import android.os.Handler;\r
 import android.os.HandlerThread;\r
@@ -24,14 +22,11 @@ import android.os.Looper;
 import android.os.Message;\r
 import android.os.Process;\r
 import android.util.Log;\r
-import android.util.LogPrinter;\r
 import android.widget.RemoteViews;\r
-import android.widget.Toast;\r
 import eu.alefzero.owncloud.R;\r
 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;\r
 import eu.alefzero.owncloud.db.ProviderMeta.ProviderTableMeta;\r
 import eu.alefzero.owncloud.files.interfaces.OnDatatransferProgressListener;\r
-import eu.alefzero.owncloud.syncadapter.FileSyncService;\r
 import eu.alefzero.webdav.WebdavClient;\r
 \r
 public class FileDownloader extends Service implements OnDatatransferProgressListener {\r
@@ -41,7 +36,8 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
     public static final String EXTRA_FILE_PATH = "FILE_PATH";\r
     public static final String EXTRA_REMOTE_PATH = "REMOTE_PATH";\r
     public static final String EXTRA_FILE_SIZE = "FILE_SIZE";\r
-    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";    \r
+    public static final String ACCOUNT_NAME = "ACCOUNT_NAME";\r
+    \r
     private static final String TAG = "FileDownloader";\r
 \r
     private NotificationManager mNotificationMngr;\r
@@ -87,14 +83,16 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         }\r
     }\r
     \r
-    public static final String getSavePath() {\r
+    public static final String getSavePath(String accountName) {\r
         File sdCard = Environment.getExternalStorageDirectory();\r
-        return sdCard.getAbsolutePath() + "/owncloud/";\r
+        return sdCard.getAbsolutePath() + "/owncloud/" + Uri.encode(accountName, "@");   \r
+            // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B\r
     }\r
     \r
-    public static final String getTemporalPath() {\r
+    public static final String getTemporalPath(String accountName) {\r
         File sdCard = Environment.getExternalStorageDirectory();\r
-        return sdCard.getAbsolutePath() + "/owncloud.tmp/";\r
+        return sdCard.getAbsolutePath() + "/owncloud/tmp/" + Uri.encode(accountName, "@");\r
+            // URL encoding is an 'easy fix' to overcome that NTFS and FAT32 don't allow ":" in file names, that can be in the accountName since 0.1.190B\r
     }\r
 \r
     @Override\r
@@ -120,7 +118,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                 !intent.hasExtra(EXTRA_REMOTE_PATH)\r
            ) {\r
             Log.e(TAG, "Not enough information provided in intent");\r
-            return START_STICKY;\r
+            return START_NOT_STICKY;\r
         }\r
         mAccount = intent.getParcelableExtra(EXTRA_ACCOUNT);\r
         mFilePath = intent.getStringExtra(EXTRA_FILE_PATH);\r
@@ -135,7 +133,10 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         return START_NOT_STICKY;\r
     }\r
 \r
-    void downloadFile() {\r
+    /**\r
+     * Core download method: requests the file to download and stores it.\r
+     */\r
+    private void downloadFile() {\r
         boolean downloadResult = false;\r
 \r
         /// prepare client object to send the request to the ownCloud server\r
@@ -148,7 +149,6 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
                     AccountAuthenticator.AUTH_TOKEN_TYPE, true);\r
         } catch (Exception e) {\r
             Log.e(TAG, "Access to account credentials failed", e);\r
-            // TODO - check if that log prints the stack trace\r
             sendFinalBroadcast(downloadResult, null);\r
             return;\r
         }\r
@@ -158,7 +158,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
 \r
         \r
         /// download will be in a temporal file\r
-        File tmpFile = new File(getTemporalPath() + mAccount.name + mFilePath);\r
+        File tmpFile = new File(getTemporalPath(mAccount.name) + mFilePath);\r
         \r
         /// create status notification to show the download progress\r
         mNotification = new Notification(R.drawable.icon, getString(R.string.downloader_download_in_progress_ticker), System.currentTimeMillis());\r
@@ -167,8 +167,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, mTotalDownloadSize == -1);\r
         mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), 0, tmpFile.getName()));\r
         mNotification.contentView.setImageViewResource(R.id.status_icon, R.drawable.icon);\r
-        // dvelasco ; contentIntent MUST be assigned to avoid app crashes in versions previous to Android 4.x ;\r
-        //              BUT an empty Intent is not a very elegant solution; something smart should happen when a user 'clicks' on a download in the notification bar\r
+        // TODO put something smart in the contentIntent below\r
         mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);\r
         mNotificationMngr.notify(R.string.downloader_download_in_progress_ticker, mNotification);\r
         \r
@@ -177,36 +176,38 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         tmpFile.getParentFile().mkdirs();\r
         mDownloadsInProgress.put(buildRemoteName(mAccount.name, mRemotePath), tmpFile.getAbsolutePath());\r
         File newFile = null;\r
-        if (wdc.downloadFile(mRemotePath, tmpFile)) {\r
-            newFile = new File(getSavePath() + mAccount.name + mFilePath);\r
-            newFile.getParentFile().mkdirs();\r
-            boolean moved = tmpFile.renameTo(newFile);\r
+        try {\r
+            if (wdc.downloadFile(mRemotePath, tmpFile)) {\r
+                newFile = new File(getSavePath(mAccount.name) + mFilePath);\r
+                newFile.getParentFile().mkdirs();\r
+                boolean moved = tmpFile.renameTo(newFile);\r
             \r
-            if (moved) {\r
-                ContentValues cv = new ContentValues();\r
-                cv.put(ProviderTableMeta.FILE_STORAGE_PATH, newFile.getAbsolutePath());\r
-                getContentResolver().update(\r
-                    ProviderTableMeta.CONTENT_URI,\r
-                    cv,\r
-                    ProviderTableMeta.FILE_NAME + "=? AND "\r
-                            + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
-                    new String[] {\r
-                            mFilePath.substring(mFilePath.lastIndexOf('/') + 1),\r
-                            mAccount.name });\r
-                downloadResult = true;\r
+                if (moved) {\r
+                    ContentValues cv = new ContentValues();\r
+                    cv.put(ProviderTableMeta.FILE_STORAGE_PATH, newFile.getAbsolutePath());\r
+                    getContentResolver().update(\r
+                            ProviderTableMeta.CONTENT_URI,\r
+                            cv,\r
+                            ProviderTableMeta.FILE_NAME + "=? AND "\r
+                                    + ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?",\r
+                            new String[] {\r
+                                mFilePath.substring(mFilePath.lastIndexOf('/') + 1),\r
+                                mAccount.name });\r
+                    downloadResult = true;\r
+                }\r
             }\r
+        } finally {\r
+            mDownloadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePath));\r
         }\r
-        mDownloadsInProgress.remove(buildRemoteName(mAccount.name, mRemotePath));\r
 \r
         \r
         /// notify result\r
         mNotificationMngr.cancel(R.string.downloader_download_in_progress_ticker);\r
-        int tickerId = (downloadResult) ? R.string.downloader_download_succeed_ticker : R.string.downloader_download_failed_ticker;\r
-        int contentId = (downloadResult) ? R.string.downloader_download_succeed_content : R.string.downloader_download_failed_content;\r
+        int tickerId = (downloadResult) ? R.string.downloader_download_succeeded_ticker : R.string.downloader_download_failed_ticker;\r
+        int contentId = (downloadResult) ? R.string.downloader_download_succeeded_content : R.string.downloader_download_failed_content;\r
         Notification finalNotification = new Notification(R.drawable.icon, getString(tickerId), System.currentTimeMillis());\r
         finalNotification.flags |= Notification.FLAG_AUTO_CANCEL;\r
-        // dvelasco ; contentIntent MUST be assigned to avoid app crashes in versions previous to Android 4.x ;\r
-        //              BUT an empty Intent is not a very elegant solution; something smart should happen when a user 'clicks' on a download in the notification bar\r
+        // TODO put something smart in the contentIntent below\r
         finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT);\r
         finalNotification.setLatestEventInfo(getApplicationContext(), getString(tickerId), String.format(getString(contentId), tmpFile.getName()), finalNotification.contentIntent);\r
         mNotificationMngr.notify(tickerId, finalNotification);\r
@@ -214,7 +215,9 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
         sendFinalBroadcast(downloadResult, (downloadResult)?newFile.getAbsolutePath():null);\r
     }\r
 \r
-    \r
+    /**\r
+     * Callback method to update the progress bar in the status notification.\r
+     */\r
     @Override\r
     public void transferProgress(long progressRate) {\r
         mCurrentDownloadSize += progressRate;\r