Merge tag 'oc-android-1.9' into sdcard-save
[pub/Android/ownCloud.git] / src / com / owncloud / android / utils / FileStorageUtils.java
index d6ebdbd..10d1709 100644 (file)
@@ -32,6 +32,7 @@ import com.owncloud.android.R;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.resources.files.RemoteFile;
 
+import android.accounts.Account;
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -52,13 +53,40 @@ public class FileStorageUtils {
     public static Integer mSortOrder = SORT_NAME;
     public static Boolean mSortAscending = true;
 
-    
-    //private static final String LOG_TAG = "FileStorageUtils";
+    //private static final String TAG = FileStorageUtils.class.getSimpleName();
+
+    @SuppressLint("NewApi")
+    private static final File getBaseStorePath() {
+        File baseStoragePath = Environment.getExternalStorageDirectory();
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+            File[] dirs = MainApp.getAppContext().getExternalFilesDirs(null);
+            if (dirs.length > 1) {
+                baseStoragePath = dirs[1];
+            }
+        }
+        return baseStoragePath;
+    }
+
+    @SuppressLint("NewApi")
+    private static final String getBaseStorePathString() {
+        File baseStoragePath = Environment.getExternalStorageDirectory();
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
+            File[] dirs = MainApp.getAppContext().getExternalFilesDirs(null);
+            if (dirs.length > 1) {
+                baseStoragePath = dirs[1];
+            }
+            return baseStoragePath.getAbsolutePath();
+        } else {
+            return baseStoragePath.getAbsolutePath() + "/" + MainApp.getDataFolder();
+        }
+    }
 
     public static final String getSavePath(String accountName) {
-        File sdCard = Environment.getExternalStorageDirectory();
-        return sdCard.getAbsolutePath() + "/" + MainApp.getDataFolder() + "/" + Uri.encode(accountName, "@");
+        //File sdCard = Environment.getExternalStorageDirectory();
+        //return sdCard.getAbsolutePath() + "/" + MainApp.getDataFolder() + "/" + Uri.encode(accountName, "@");
         // 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
+        //return getBaseStorePath().getAbsolutePath()  + "/" + Uri.encode(accountName, "@");
+        return getBaseStorePathString()  + "/" + Uri.encode(accountName, "@");
     }
 
     public static final String getDefaultSavePathFor(String accountName, OCFile file) {
@@ -66,14 +94,17 @@ public class FileStorageUtils {
     }
 
     public static final String getTemporalPath(String accountName) {
-        File sdCard = Environment.getExternalStorageDirectory();
-        return sdCard.getAbsolutePath() + "/" + MainApp.getDataFolder() + "/tmp/" + Uri.encode(accountName, "@");
+        //File sdCard = Environment.getExternalStorageDirectory();
+        //return sdCard.getAbsolutePath() + "/" + MainApp.getDataFolder() + "/tmp/" + Uri.encode(accountName, "@");
             // 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
+        //return getBaseStorePath().getAbsolutePath() + "/tmp/" + Uri.encode(accountName, "@");
+        return getBaseStorePathString() + "/tmp/" + Uri.encode(accountName, "@");        
     }
 
     @SuppressLint("NewApi")
     public static final long getUsableSpace(String accountName) {
-        File savePath = Environment.getExternalStorageDirectory();
+        //File savePath = Environment.getExternalStorageDirectory();
+        File savePath = getBaseStorePath();
         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
             return savePath.getUsableSpace();
 
@@ -120,7 +151,7 @@ public class FileStorageUtils {
      * Creates and populates a new {@link OCFile} object with the data read from the server.
      * 
      * @param remote    remote file read from the server (remote file or folder).
-     * @return          New OCFile instance representing the remote resource described by we.
+     * @return          New OCFile instance representing the remote resource described by remote.
      */
     public static OCFile fillOCFile(RemoteFile remote) {
         OCFile file = new OCFile(remote.getRemotePath());
@@ -133,7 +164,7 @@ public class FileStorageUtils {
         file.setRemoteId(remote.getRemoteId());
         return file;
     }
-    
+
     /**
      * Creates and populates a new {@link RemoteFile} object with the data read from an {@link OCFile}.
      * 
@@ -151,9 +182,9 @@ public class FileStorageUtils {
         file.setRemoteId(ocFile.getRemoteId());
         return file;
     }
-    
+
     /**
-     * Sorts all filenames, regarding last user decision 
+     * Sorts all filenames, regarding last user decision
      */
     public static Vector<OCFile> sortFolder(Vector<OCFile> files){
         switch (mSortOrder){
@@ -163,14 +194,14 @@ public class FileStorageUtils {
         case 1:
             files = FileStorageUtils.sortByDate(files);
             break;
-        case 2: 
+        case 2:
            // mFiles = FileStorageUtils.sortBySize(mSortAscending);
             break;
         }
-       
+
         return files;
     }
-    
+
     /**
      * Sorts list by Date
      * @param files
@@ -182,7 +213,7 @@ public class FileStorageUtils {
         } else {
             val = -1;
         }
-        
+
         Collections.sort(files, new Comparator<OCFile>() {
             public int compare(OCFile o1, OCFile o2) {
                 if (o1.isFolder() && o2.isFolder()) {
@@ -201,7 +232,7 @@ public class FileStorageUtils {
                 }
             }
         });
-        
+
         return files;
     }
 
@@ -216,7 +247,7 @@ public class FileStorageUtils {
 //        } else {
 //            val = -1;
 //        }
-//        
+//
 //        Collections.sort(files, new Comparator<OCFile>() {
 //            public int compare(OCFile o1, OCFile o2) {
 //                if (o1.isFolder() && o2.isFolder()) {
@@ -235,7 +266,7 @@ public class FileStorageUtils {
 //                }
 //            }
 //        });
-//        
+//
 //        return files;
 //    }
 
@@ -254,7 +285,7 @@ public class FileStorageUtils {
         Collections.sort(files, new Comparator<OCFile>() {
             public int compare(OCFile o1, OCFile o2) {
                 if (o1.isFolder() && o2.isFolder()) {
-                    return val * o1.getRemotePath().toLowerCase().compareTo(o2.getRemotePath().toLowerCase());
+                    return val * new AlphanumComparator().compare(o1, o2);
                 } else if (o1.isFolder()) {
                     return -1;
                 } else if (o2.isFolder()) {
@@ -263,10 +294,10 @@ public class FileStorageUtils {
                 return val * new AlphanumComparator().compare(o1, o2);
             }
         });
-        
+
         return files;
     }
-    
+
     /**
      * Local Folder size
      * @param dir File
@@ -302,5 +333,33 @@ public class FileStorageUtils {
         String result = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
         return (result != null) ? result : "";
     }
-  
+
+    /**
+     * Scans the default location for saving local copies of files searching for
+     * a 'lost' file with the same full name as the {@link OCFile} received as
+     * parameter.
+     *
+     * This method helps to keep linked local copies of the files when the app is uninstalled, and then
+     * reinstalled in the device. OR after the cache of the app was deleted in system settings.
+     *
+     * The method is assuming that all the local changes in the file where synchronized in the past. This is dangerous,
+     * but assuming the contrary could lead to massive unnecessary synchronizations of downloaded file after deleting
+     * the app cache.
+     *
+     * This should be changed in the near future to avoid any chance of data loss, but we need to add some options
+     * to limit hard automatic synchronizations to wifi, unless the user wants otherwise.
+     *
+     * @param file      File to associate a possible 'lost' local file.
+     * @param account   Account holding file.
+     */
+    public static void searchForLocalFileInDefaultPath(OCFile file, Account account) {
+        if (file.getStoragePath() == null && !file.isFolder()) {
+            File f = new File(FileStorageUtils.getDefaultSavePathFor(account.name, file));
+            if (f.exists()) {
+                file.setStoragePath(f.getAbsolutePath());
+                file.setLastSyncDateForData(f.lastModified());
+            }
+        }
+    }
+
 }