Merge remote-tracking branch 'remotes/upstream/externalSD2' into beta
authortobiasKaminsky <tobias@kaminsky.me>
Fri, 20 Nov 2015 17:32:55 +0000 (18:32 +0100)
committertobiasKaminsky <tobias@kaminsky.me>
Fri, 20 Nov 2015 17:32:55 +0000 (18:32 +0100)
1  2 
AndroidManifest.xml
owncloud-android-library
res/values-hu-rHU/strings.xml
res/values/strings.xml
res/xml/preferences.xml
src/com/owncloud/android/MainApp.java
src/com/owncloud/android/datamodel/FileDataStorageManager.java
src/com/owncloud/android/ui/activity/Preferences.java
src/com/owncloud/android/ui/activity/UploadFilesActivity.java
src/com/owncloud/android/utils/FileStorageUtils.java

              </intent-filter>
          </activity>
          <activity android:name=".ui.activity.UploadFilesActivity" />
 -        <activity android:name=".ui.activity.Uploader" >
+         <activity android:name=".ui.activity.LocalDirectorySelectorActivity" />
+         <activity android:name=".ui.activity.StorageMigrationActivity" />
 +        <activity android:name=".ui.activity.Uploader"
 +            android:label="@string/uploader_top_message"
 +            android:theme="@style/Theme.ownCloud">
              <intent-filter>
                  <action android:name="android.intent.action.SEND" />
  
@@@ -1,1 -1,1 +1,1 @@@
- Subproject commit 2e0f2a79224383145d61cc15ca42c6bcc59902d5
 -Subproject commit b09969d078b3a790b01c8d61a7298a37439a9f24
++Subproject commit 4f9a7528cab0563cb234a8b817e8ee371dd6cc25
Simple merge
      <string name="file_list__footer__files">%1$d files</string>
      <string name="file_list__footer__files_and_folder">%1$d files, 1 folder</string>
      <string name="file_list__footer__files_and_folders">%1$d files, %2$d folders</string>
 +    <string name="action_switch_grid_view">Switch to grid view</string>
 +    <string name="action_switch_list_view">Switch to list view</string>
 +    <string name="common_category">Common</string>
 +    <string name="pref_cache_size">Cache size</string>
 +    <string name="prefs_instant_behaviour_dialogTitle">Upload file to server and ...</string>
 +    <string name="prefs_instant_behaviour_title">Behaviour</string>
 +    <string name="upload_copy_files">Copy file</string>
 +    <string name="upload_move_files">Move file</string>
+     <string name="prefs_storage_path">Storage path</string>
+     <string name="prefs_common">Common</string>
  
 +    <string name="pref_behaviour_entries_do_nothing">do nothing</string>
 +    <string name="pref_behaviour_entries_copy">copy file to OC folder</string>
 +    <string name="pref_behaviour_entries_move">move file to OC folder</string>
 +    <string name="pref_behaviour_entries_delete">delete origin file</string>
 +    <string name="confirmation_remove_files_alert">Do you really want to remove selected items?</string>
 +    <string name="confirmation_remove_folders_alert">Do you really want to remove a folder and its content?</string>
 +    <string name="confirmation_remove_files">selected items</string>
 +    <string name="error_log_exit">Exit</string>
 +    <string name="error_log_send">Send Log</string>
 +    <string name="error_log_title">Error Log</string>
 +    <string name="action_stream_file">Stream file with external player</string>
 +    <string name="stream_expose_password">Do you want to stream this file with an external app?\n\nCAUTION: This may expose your password!</string>
 +    <string name="set_picture_as">Set picture as</string>
 +
      <string name="share_dialog_title">Sharing</string>
      <string name="share_with_user_section_title">Share with Users and Groups</string>
      <string name="share_no_users">No data shared with users yet</string>
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  -->
  <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
-     <PreferenceCategory
-               android:title="@string/prefs_category_accounts"
-               android:key="accounts_category">
+       <PreferenceCategory android:title="@string/prefs_category_general">
+               <com.owncloud.android.ui.PreferenceWithLongSummary
+                       android:title="@string/prefs_storage_path"
+                       android:key="storage_path" />
+       </PreferenceCategory>
+     <PreferenceCategory android:title="@string/prefs_category_accounts" android:key="accounts_category">
      </PreferenceCategory>
 -    
 +
        <PreferenceCategory android:title="@string/prefs_category_security">
 -          <android.preference.CheckBoxPreference android:title="@string/prefs_passcode" android:key="set_pincode" />
 +              <android.preference.CheckBoxPreference android:title="@string/prefs_passcode" android:key="set_pincode" />
        </PreferenceCategory>
  
      <PreferenceCategory android:title="@string/prefs_category_instant_uploading" android:key="instant_uploading_category">
@@@ -23,7 -23,7 +23,8 @@@ package com.owncloud.android
  import android.app.Activity;
  import android.app.Application;
  import android.content.Context;
 +import android.content.Intent;
+ import android.content.SharedPreferences;
  import android.content.pm.PackageInfo;
  import android.content.pm.PackageManager;
  import android.os.Build;
@@@ -56,16 -57,22 +59,24 @@@ public class MainApp extends Applicatio
  
      private static Context mContext;
  
 -    // TODO Enable when "On Device" is recovered?
 -    // TODO better place
 -    // private static boolean mOnlyOnDevice = false;
+     private static String storagePath;
 +    private static boolean mOnlyOnDevice = false;
  
      
      public void onCreate(){
          super.onCreate();
          MainApp.mContext = getApplicationContext();
  
 +        // Setup handler for uncaught exceptions.
 +        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
 +        
++
+         SharedPreferences appPrefs =
+                 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+         MainApp.storagePath = appPrefs.getString("storage_path", Environment.
+                               getExternalStorageDirectory().getAbsolutePath());
          boolean isSamlAuth = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
  
          OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
@@@ -717,40 -713,71 +710,72 @@@ public class FileDataStorageManager 
          }
      }
  
-     private boolean copyFile(File src, File target) {
-         boolean ret = true;
+     public void migrateStoredFiles(String srcPath, String dstPath) throws Exception {
+         Cursor c = null;
+         if (getContentResolver() != null) {
+             c = getContentResolver().query(ProviderTableMeta.CONTENT_URI_FILE,
+                     null,
+                     ProviderTableMeta.FILE_STORAGE_PATH  + " IS NOT NULL",
+                     null,
+                     null);
+         } else {
+             try {
+                 c = getContentProviderClient().query(ProviderTableMeta.CONTENT_URI_FILE,
+                         new String[]{ProviderTableMeta._ID, ProviderTableMeta.FILE_STORAGE_PATH},
+                         ProviderTableMeta.FILE_STORAGE_PATH + " IS NOT NULL",
+                         null,
+                         null);
+             } catch (RemoteException e) {
+                 Log_OC.e(TAG, e.getMessage());
+                 throw e;
+             }
+         }
+         ArrayList<ContentProviderOperation> operations =
+                 new ArrayList<ContentProviderOperation>(c.getCount());
+         if (c.moveToFirst()) {
+             do {
+                 ContentValues cv = new ContentValues();
+                 long fileId = c.getLong(c.getColumnIndex(ProviderTableMeta._ID));
+                 String oldFileStoragePath = c.getString(c.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH));
+                 if (oldFileStoragePath.startsWith(srcPath)) {
+                     cv.put(
+                             ProviderTableMeta.FILE_STORAGE_PATH,
+                             oldFileStoragePath.replaceFirst(srcPath, dstPath));
+                     operations.add(
+                             ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+                                     withValues(cv).
+                                     withSelection(
+                                             ProviderTableMeta._ID + "=?",
+                                             new String[]{String.valueOf(fileId)}
+                                     )
+                                     .build());
+                 }
  
-         InputStream in = null;
-         OutputStream out = null;
+             } while (c.moveToNext());
+         }
+         c.close();
  
+         /// 3. apply updates in batch
          try {
-             in = new FileInputStream(src);
-             out = new FileOutputStream(target);
-             byte[] buf = new byte[1024];
-             int len;
-             while ((len = in.read(buf)) > 0) {
-                 out.write(buf, 0, len);
-             }
-         } catch (IOException ex) {
-             ret = false;
-         } finally {
-             if (in != null) try {
-                 in.close();
-             } catch (IOException e) {
-                 e.printStackTrace(System.err);
-             }
-             if (out != null) try {
-                 out.close();
-             } catch (IOException e) {
-                 e.printStackTrace(System.err);
+             if (getContentResolver() != null) {
+                 getContentResolver().applyBatch(MainApp.getAuthority(), operations);
+             } else {
+                 getContentProviderClient().applyBatch(operations);
              }
-         }
  
-         return ret;
+         } catch (Exception e) {
+             throw e;
+         }
      }
  
 -    private Vector<OCFile> getFolderContent(long parentId/*, boolean onlyOnDevice*/) {
 +    
 +    private Vector<OCFile> getFolderContent(long parentId, boolean onlyOnDevice) {
  
          Vector<OCFile> ret = new Vector<OCFile>();
  
@@@ -34,8 -34,8 +34,9 @@@ import android.content.pm.PackageInfo
  import android.content.pm.PackageManager.NameNotFoundException;
  import android.content.res.Configuration;
  import android.net.Uri;
 +import android.os.AsyncTask;
  import android.os.Bundle;
+ import android.os.Environment;
  import android.os.Handler;
  import android.os.IBinder;
  import android.preference.CheckBoxPreference;
@@@ -82,12 -81,7 +84,13 @@@ import com.owncloud.android.ui.Preferen
  import com.owncloud.android.ui.RadioButtonPreference;
  import com.owncloud.android.utils.DisplayUtils;
  
 +import java.io.BufferedReader;
 +import java.io.IOException;
 +import java.io.InputStreamReader;
 +import java.net.MalformedURLException;
 +import java.net.URL;
 +import java.util.concurrent.ExecutionException;
+ import java.io.File;
  
  
  /**
@@@ -460,17 -460,10 +490,17 @@@ public class Preferences extends Prefer
          });
              
          /* About App */
-        pAboutApp = (Preference) findPreference("about_app");
+        pAboutApp = findPreference("about_app");
         if (pAboutApp != null) { 
 -               pAboutApp.setTitle(String.format(getString(R.string.about_android), getString(R.string.app_name)));
 -               pAboutApp.setSummary(String.format(getString(R.string.about_version), appVersion));
 +               pAboutApp.setTitle(String.format(getString(R.string.about_android),
 +                                                getString(R.string.app_name)));
 +           try {
 +               Integer currentVersion = getPackageManager().getPackageInfo
 +                  (getPackageName(), 0).versionCode;
 +               pAboutApp.setSummary(String.format(getString(R.string.about_version),
 +                                    currentVersion));
 +           } catch (NameNotFoundException e) {
 +           }
         }
  
         loadInstantUploadPath();
  package com.owncloud.android.utils;
  
  import java.io.File;
 +import java.util.ArrayList;
 +import java.util.Arrays;
+ import java.io.FileInputStream;
+ import java.io.FileOutputStream;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.OutputStream;
  import java.util.Collections;
  import java.util.Comparator;
 +import java.util.List;
  import java.util.Vector;
  
  import third_parties.daveKoeller.AlphanumComparator;