Bartosz Przybylski 9 жил өмнө
parent
commit
8b587cead2

+ 33 - 33
src/com/owncloud/android/ui/activity/Preferences.java

@@ -119,11 +119,11 @@ public class Preferences extends PreferenceActivity
     private PreferenceWithLongSummary mPrefStoragePath;
     private String mStoragePath;
 
-	public static class Keys {
-		public static final String STORAGE_PATH = "storage_path";
-		public static final String INSTANT_UPLOAD_PATH = "instant_upload_path";
-		public static final String INSTANT_VIDEO_UPLOAD_PATH = "instant_video_upload_path";
-	}
+    public static class Keys {
+        public static final String STORAGE_PATH = "storage_path";
+        public static final String INSTANT_UPLOAD_PATH = "instant_upload_path";
+        public static final String INSTANT_VIDEO_UPLOAD_PATH = "instant_video_upload_path";
+    }
 
     @SuppressWarnings("deprecation")
     @Override
@@ -347,28 +347,28 @@ public class Preferences extends PreferenceActivity
 
         mPrefStoragePath =  (ListPreference) findPreference(Keys.STORAGE_PATH);
         if (mPrefStoragePath != null) {
-			DataStorageUtils.Storage[] storageOptions = DataStorageUtils.getAvailableStoragePoints(getApplicationContext());
-			String[] entries = new String[storageOptions.length];
-			String[] values = new String[storageOptions.length];
-			for (int i = 0; i < storageOptions.length; ++i) {
-				entries[i] = storageOptions[i].getDescription();
-				values[i] = storageOptions[i].getPath();
-			}
-			mPrefStoragePath.setEntries(entries);
-			mPrefStoragePath.setEntryValues(values);
+            DataStorageUtils.Storage[] storageOptions = DataStorageUtils.getAvailableStoragePoints(getApplicationContext());
+            String[] entries = new String[storageOptions.length];
+            String[] values = new String[storageOptions.length];
+            for (int i = 0; i < storageOptions.length; ++i) {
+                entries[i] = storageOptions[i].getDescription();
+                values[i] = storageOptions[i].getPath();
+            }
+            mPrefStoragePath.setEntries(entries);
+            mPrefStoragePath.setEntryValues(values);
 
             mPrefStoragePath.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
                     @Override
                     public boolean onPreferenceChange(Preference preference, Object newValue) {
-						String newPath = (String)newValue;
-						if (mStoragePath.equals(newPath))
-							return true;
+                        String newPath = (String)newValue;
+                        if (mStoragePath.equals(newPath))
+                            return true;
 
-						StorageMigration storageMigration = new StorageMigration(Preferences.this, mStoragePath, newPath);
+                        StorageMigration storageMigration = new StorageMigration(Preferences.this, mStoragePath, newPath);
 
-						storageMigration.setStorageMigrationProgressListener(Preferences.this);
+                        storageMigration.setStorageMigrationProgressListener(Preferences.this);
 
-						storageMigration.migrate();
+                        storageMigration.migrate();
 
                         return false;
                     }
@@ -764,9 +764,9 @@ public class Preferences extends PreferenceActivity
         SharedPreferences.Editor editor = appPrefs.edit();
         editor.putString(Keys.STORAGE_PATH, mStoragePath);
         editor.commit();
-		String storageDescription = DataStorageUtils.getStorageDescriptionByPath(mStoragePath, this);
+        String storageDescription = DataStorageUtils.getStorageDescriptionByPath(mStoragePath, this);
         mPrefStoragePath.setSummary(storageDescription);
-		mPrefStoragePath.setValue(newStoragePath);
+        mPrefStoragePath.setValue(newStoragePath);
     }
 
     /**
@@ -777,8 +777,8 @@ public class Preferences extends PreferenceActivity
                 PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
         mStoragePath = appPrefs.getString(Keys.STORAGE_PATH, Environment.getExternalStorageDirectory()
                                                          .getAbsolutePath());
-		String storageDescription = DataStorageUtils.getStorageDescriptionByPath(mStoragePath, getApplicationContext());
-		mPrefStoragePath.setSummary(storageDescription);
+        String storageDescription = DataStorageUtils.getStorageDescriptionByPath(mStoragePath, getApplicationContext());
+        mPrefStoragePath.setSummary(storageDescription);
     }
 
     /**
@@ -810,14 +810,14 @@ public class Preferences extends PreferenceActivity
         editor.commit();
     }
 
-	@Override
-	public void onStorageMigrationFinished(String storagePath, boolean succeed) {
-		if (succeed)
-			saveStoragePath(storagePath);
-	}
+    @Override
+    public void onStorageMigrationFinished(String storagePath, boolean succeed) {
+        if (succeed)
+            saveStoragePath(storagePath);
+    }
 
-	@Override
-	public void onCancelMigration() {
-		// Migration was canceled so we don't do anything
-	}
+    @Override
+    public void onCancelMigration() {
+        // Migration was canceled so we don't do anything
+    }
 }

+ 343 - 343
src/com/owncloud/android/ui/activity/StorageMigration.java

@@ -42,350 +42,350 @@ import java.io.File;
  * Created by Bartosz Przybylski on 07.11.2015.
  */
 public class StorageMigration {
-	private static final String TAG = StorageMigration.class.getName();
-
-	public interface StorageMigrationProgressListener {
-		void onStorageMigrationFinished(String storagePath, boolean succeed);
-		void onCancelMigration();
-	}
-
-	private ProgressDialog mProgressDialog;
-	private Context mContext;
-	private String mSourceStoragePath;
-	private String mTargetStoragePath;
-
-	private StorageMigrationProgressListener mListener;
-
-	public StorageMigration(Context context, String sourcePath, String targetPath) {
-		mContext = context;
-		mSourceStoragePath = sourcePath;
-		mTargetStoragePath = targetPath;
-	}
-
-	public void setStorageMigrationProgressListener(StorageMigrationProgressListener listener) {
-		mListener = listener;
-	}
-
-	public void migrate() {
-		if (storageFolderAlreadyExists())
-			askToOverride();
-		else {
-			AlertDialog progressDialog = createMigrationProgressDialog();
-			progressDialog.show();
-			new FileMigrationTask(
-					mContext,
-					mSourceStoragePath,
-					mTargetStoragePath,
-					progressDialog,
-					mListener).execute();
-
-			progressDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
-		}
-	}
-
-	private boolean storageFolderAlreadyExists() {
-		File f = new File(mTargetStoragePath, MainApp.getDataFolder());
-		return f.exists() && f.isDirectory();
-	}
-
-	private void askToOverride() {
-
-		new AlertDialog.Builder(mContext)
-				.setMessage(R.string.file_migration_directory_already_exists)
-				.setCancelable(true)
-				.setOnCancelListener(new DialogInterface.OnCancelListener() {
-					@Override
-					public void onCancel(DialogInterface dialogInterface) {
-						if (mListener != null)
-							mListener.onCancelMigration();
-					}
-				})
-				.setNegativeButton(R.string.common_cancel, new OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialogInterface, int i) {
-						if (mListener != null)
-							mListener.onCancelMigration();
-					}
-				})
-				.setNeutralButton(R.string.file_migration_use_data_folder, new OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialogInterface, int i) {
-						AlertDialog progressDialog = createMigrationProgressDialog();
-						progressDialog.show();
-						new StoragePathSwitchTask(
-								mContext,
-								mSourceStoragePath,
-								mTargetStoragePath,
-								progressDialog,
-								mListener).execute();
-
-						progressDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
-
-					}
-				})
-				.setPositiveButton(R.string.file_migration_override_data_folder, new OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialogInterface, int i) {
-						AlertDialog progressDialog = createMigrationProgressDialog();
-						progressDialog.show();
-						new FileMigrationTask(
-								mContext,
-								mSourceStoragePath,
-								mTargetStoragePath,
-								progressDialog,
-								mListener).execute();
-
-						progressDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
-					}
-				})
-				.create()
-				.show();
-	}
-
-	private AlertDialog createMigrationProgressDialog() {
-		AlertDialog progressDialog = new AlertDialog.Builder(mContext)
-				.setCancelable(false)
-				.setTitle(R.string.file_migration_dialog_title)
-				.setMessage(R.string.file_migration_preparing)
-				.setPositiveButton(R.string.drawer_close, new OnClickListener() {
-					@Override
-					public void onClick(DialogInterface dialogInterface, int i) {
-						dialogInterface.dismiss();
-					}
-				})
-				.create();
-		return progressDialog;
-	}
-
-	abstract static private class FileMigrationTaskBase extends AsyncTask<Void, Integer, Integer> {
-		protected String mStorageSource;
-		protected String mStorageTarget;
-		protected Context mContext;
-		protected AlertDialog mProgressDialog;
-		protected StorageMigrationProgressListener mListener;
-
-		protected String mAuthority;
-		protected Account[] mOcAccounts;
-
-		public FileMigrationTaskBase(Context context, String source, String target, AlertDialog progressDialog, StorageMigrationProgressListener listener) {
-			mContext = context;
-			mStorageSource = source;
-			mStorageTarget = target;
-			mProgressDialog = progressDialog;
-			mListener = listener;
-
-			mAuthority = mContext.getString(R.string.authority);
-			mOcAccounts = AccountManager.get(mContext).getAccountsByType(MainApp.getAccountType());
-		}
-
-		@Override
-		protected void onProgressUpdate(Integer... progress) {
-			if (progress.length > 1 && progress[0] != 0)
-				mProgressDialog.setMessage(mContext.getString(progress[0]));
-		}
-
-		@Override
-		protected void onPostExecute(Integer code) {
-			if (code != 0) {
-				mProgressDialog.setMessage(mContext.getString(code));
-			} else {
-				mProgressDialog.setMessage(mContext.getString(R.string.file_migration_ok_finished));
-			}
-			mProgressDialog.getButton(android.app.AlertDialog.BUTTON_POSITIVE).setEnabled(true);
-			boolean succeed = code == 0;
-			if (mListener != null)
-				mListener.onStorageMigrationFinished(succeed ? mStorageTarget : mStorageSource, succeed);
-		}
-
-		protected boolean[] saveAccountsSyncStatus() {
-			boolean[] syncs = new boolean[mOcAccounts.length];
-			for (int i = 0; i < mOcAccounts.length; ++i)
-				syncs[i] = ContentResolver.getSyncAutomatically(mOcAccounts[i], mAuthority);
-			return syncs;
-		}
-
-		protected void stopAccountsSyncing() {
-			for (int i = 0; i < mOcAccounts.length; ++i)
-				ContentResolver.setSyncAutomatically(mOcAccounts[i], mAuthority, false);
-		}
-
-		protected void waitForUnfinishedSynchronizations() {
-			for (int i = 0; i < mOcAccounts.length; ++i)
-				while (ContentResolver.isSyncActive(mOcAccounts[i], mAuthority))
-					try {
-						Thread.sleep(1000);
-					} catch (InterruptedException e) {
-						Log_OC.w(TAG, "Thread interrupted while waiting for account to end syncing");
-						Thread.currentThread().interrupt();
-					}
-		}
-
-		protected void restoreAccountsSyncStatus(boolean oldSync[]) {
-			for (int i = 0; i < mOcAccounts.length; ++i)
-				ContentResolver.setSyncAutomatically(mOcAccounts[i], mAuthority, oldSync[i]);
-		}
-	}
-
-	static private class StoragePathSwitchTask extends FileMigrationTaskBase {
-
-		public StoragePathSwitchTask(Context context, String source, String target, AlertDialog progressDialog, StorageMigrationProgressListener listener) {
-			super(context, source, target, progressDialog, listener);
-		}
-
-		@Override
-		protected Integer doInBackground(Void... voids) {
-			publishProgress(R.string.file_migration_preparing);
-
-			Log_OC.stopLogging();
-			boolean[] syncStates = new boolean[0];
-			try {
-				publishProgress(R.string.file_migration_saving_accounts_configuration);
-				syncStates = saveAccountsSyncStatus();
-
-				publishProgress(R.string.file_migration_waiting_for_unfinished_sync);
-				stopAccountsSyncing();
-				waitForUnfinishedSynchronizations();
-			} finally {
-				publishProgress(R.string.file_migration_restoring_accounts_configuration);
-				restoreAccountsSyncStatus(syncStates);
-			}
-			Log_OC.startLogging(mStorageTarget);
-
-			return 0;
-		}
-	}
-
-	static private class FileMigrationTask extends FileMigrationTaskBase {
-		private class MigrationException extends Exception {
-			private int mResId;
-
-			MigrationException(int resId) {
-				super();
-				this.mResId = resId;
-			}
-
-			int getResId() { return mResId; }
-		}
-
-		public FileMigrationTask(Context context, String source, String target, AlertDialog progressDialog, StorageMigrationProgressListener listener) {
-			super(context, source, target, progressDialog, listener);
-		}
-
-		@Override
-		protected Integer doInBackground(Void... args) {
-			publishProgress(R.string.file_migration_preparing);
-			Log_OC.stopLogging();
-
-			boolean[] syncState = new boolean[0];
-
-			try {
-				File dstFile = new File(mStorageTarget + File.separator + MainApp.getDataFolder());
-				deleteRecursive(dstFile);
-				dstFile.delete();
-
-				publishProgress(R.string.file_migration_checking_destination);
-
-				checkDestinationAvailability();
-
-				publishProgress(R.string.file_migration_saving_accounts_configuration);
-				syncState = saveAccountsSyncStatus();
-
-				publishProgress(R.string.file_migration_waiting_for_unfinished_sync);
-				stopAccountsSyncing();
-				waitForUnfinishedSynchronizations();
-
-				publishProgress(R.string.file_migration_migrating);
-				copyFiles();
-
-				publishProgress(R.string.file_migration_updating_index);
-				updateIndex(mContext);
-
-				publishProgress(R.string.file_migration_cleaning);
-				cleanup();
-
-			} catch (MigrationException e) {
-				rollback();
-				Log_OC.startLogging(mStorageSource);
-				return e.getResId();
-			} finally {
-				publishProgress(R.string.file_migration_restoring_accounts_configuration);
-				restoreAccountsSyncStatus(syncState);
-			}
-
-			Log_OC.startLogging(mStorageTarget);
-			publishProgress(R.string.file_migration_ok_finished);
-
-			return 0;
-		}
-
-
-		void checkDestinationAvailability() throws MigrationException {
-			File srcFile = new File(mStorageSource);
-			File dstFile = new File(mStorageTarget);
-
-			if (!dstFile.canRead() || !srcFile.canRead())
-				throw new MigrationException(R.string.file_migration_failed_not_readable);
-
-			if (!dstFile.canWrite() || !srcFile.canWrite())
-				throw new MigrationException(R.string.file_migration_failed_not_writable);
-
-			if (new File(dstFile, MainApp.getDataFolder()).exists())
-				throw new MigrationException(R.string.file_migration_failed_dir_already_exists);
-
-			if (dstFile.getFreeSpace() < FileStorageUtils.getFolderSize(new File(srcFile, MainApp.getDataFolder())))
-				throw new MigrationException(R.string.file_migration_failed_not_enough_space);
-		}
-
-		void copyFiles() throws MigrationException {
-			File srcFile = new File(mStorageSource + File.separator + MainApp.getDataFolder());
-			File dstFile = new File(mStorageTarget + File.separator + MainApp.getDataFolder());
-
-			copyDirs(srcFile, dstFile);
-		}
-
-		void copyDirs(File src, File dst) throws MigrationException {
-			if (!dst.mkdirs())
-				throw new MigrationException(R.string.file_migration_failed_while_coping);
-
-			for (File f : src.listFiles()) {
-				if (f.isDirectory())
-					copyDirs(f, new File(dst, f.getName()));
-				else if (!FileStorageUtils.copyFile(f, new File(dst, f.getName())))
-					throw new MigrationException(R.string.file_migration_failed_while_coping);
-			}
+    private static final String TAG = StorageMigration.class.getName();
+
+    public interface StorageMigrationProgressListener {
+        void onStorageMigrationFinished(String storagePath, boolean succeed);
+        void onCancelMigration();
+    }
+
+    private ProgressDialog mProgressDialog;
+    private Context mContext;
+    private String mSourceStoragePath;
+    private String mTargetStoragePath;
+
+    private StorageMigrationProgressListener mListener;
+
+    public StorageMigration(Context context, String sourcePath, String targetPath) {
+        mContext = context;
+        mSourceStoragePath = sourcePath;
+        mTargetStoragePath = targetPath;
+    }
+
+    public void setStorageMigrationProgressListener(StorageMigrationProgressListener listener) {
+        mListener = listener;
+    }
+
+    public void migrate() {
+        if (storageFolderAlreadyExists())
+            askToOverride();
+        else {
+            AlertDialog progressDialog = createMigrationProgressDialog();
+            progressDialog.show();
+            new FileMigrationTask(
+                    mContext,
+                    mSourceStoragePath,
+                    mTargetStoragePath,
+                    progressDialog,
+                    mListener).execute();
+
+            progressDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
+        }
+    }
+
+    private boolean storageFolderAlreadyExists() {
+        File f = new File(mTargetStoragePath, MainApp.getDataFolder());
+        return f.exists() && f.isDirectory();
+    }
+
+    private void askToOverride() {
+
+        new AlertDialog.Builder(mContext)
+                .setMessage(R.string.file_migration_directory_already_exists)
+                .setCancelable(true)
+                .setOnCancelListener(new DialogInterface.OnCancelListener() {
+                    @Override
+                    public void onCancel(DialogInterface dialogInterface) {
+                        if (mListener != null)
+                            mListener.onCancelMigration();
+                    }
+                })
+                .setNegativeButton(R.string.common_cancel, new OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialogInterface, int i) {
+                        if (mListener != null)
+                            mListener.onCancelMigration();
+                    }
+                })
+                .setNeutralButton(R.string.file_migration_use_data_folder, new OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialogInterface, int i) {
+                        AlertDialog progressDialog = createMigrationProgressDialog();
+                        progressDialog.show();
+                        new StoragePathSwitchTask(
+                                mContext,
+                                mSourceStoragePath,
+                                mTargetStoragePath,
+                                progressDialog,
+                                mListener).execute();
+
+                        progressDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
+
+                    }
+                })
+                .setPositiveButton(R.string.file_migration_override_data_folder, new OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialogInterface, int i) {
+                        AlertDialog progressDialog = createMigrationProgressDialog();
+                        progressDialog.show();
+                        new FileMigrationTask(
+                                mContext,
+                                mSourceStoragePath,
+                                mTargetStoragePath,
+                                progressDialog,
+                                mListener).execute();
+
+                        progressDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
+                    }
+                })
+                .create()
+                .show();
+    }
+
+    private AlertDialog createMigrationProgressDialog() {
+        AlertDialog progressDialog = new AlertDialog.Builder(mContext)
+                .setCancelable(false)
+                .setTitle(R.string.file_migration_dialog_title)
+                .setMessage(R.string.file_migration_preparing)
+                .setPositiveButton(R.string.drawer_close, new OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialogInterface, int i) {
+                        dialogInterface.dismiss();
+                    }
+                })
+                .create();
+        return progressDialog;
+    }
+
+    abstract static private class FileMigrationTaskBase extends AsyncTask<Void, Integer, Integer> {
+        protected String mStorageSource;
+        protected String mStorageTarget;
+        protected Context mContext;
+        protected AlertDialog mProgressDialog;
+        protected StorageMigrationProgressListener mListener;
+
+        protected String mAuthority;
+        protected Account[] mOcAccounts;
+
+        public FileMigrationTaskBase(Context context, String source, String target, AlertDialog progressDialog, StorageMigrationProgressListener listener) {
+            mContext = context;
+            mStorageSource = source;
+            mStorageTarget = target;
+            mProgressDialog = progressDialog;
+            mListener = listener;
+
+            mAuthority = mContext.getString(R.string.authority);
+            mOcAccounts = AccountManager.get(mContext).getAccountsByType(MainApp.getAccountType());
+        }
+
+        @Override
+        protected void onProgressUpdate(Integer... progress) {
+            if (progress.length > 1 && progress[0] != 0)
+                mProgressDialog.setMessage(mContext.getString(progress[0]));
+        }
+
+        @Override
+        protected void onPostExecute(Integer code) {
+            if (code != 0) {
+                mProgressDialog.setMessage(mContext.getString(code));
+            } else {
+                mProgressDialog.setMessage(mContext.getString(R.string.file_migration_ok_finished));
+            }
+            mProgressDialog.getButton(android.app.AlertDialog.BUTTON_POSITIVE).setEnabled(true);
+            boolean succeed = code == 0;
+            if (mListener != null)
+                mListener.onStorageMigrationFinished(succeed ? mStorageTarget : mStorageSource, succeed);
+        }
+
+        protected boolean[] saveAccountsSyncStatus() {
+            boolean[] syncs = new boolean[mOcAccounts.length];
+            for (int i = 0; i < mOcAccounts.length; ++i)
+                syncs[i] = ContentResolver.getSyncAutomatically(mOcAccounts[i], mAuthority);
+            return syncs;
+        }
+
+        protected void stopAccountsSyncing() {
+            for (int i = 0; i < mOcAccounts.length; ++i)
+                ContentResolver.setSyncAutomatically(mOcAccounts[i], mAuthority, false);
+        }
+
+        protected void waitForUnfinishedSynchronizations() {
+            for (int i = 0; i < mOcAccounts.length; ++i)
+                while (ContentResolver.isSyncActive(mOcAccounts[i], mAuthority))
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {
+                        Log_OC.w(TAG, "Thread interrupted while waiting for account to end syncing");
+                        Thread.currentThread().interrupt();
+                    }
+        }
+
+        protected void restoreAccountsSyncStatus(boolean oldSync[]) {
+            for (int i = 0; i < mOcAccounts.length; ++i)
+                ContentResolver.setSyncAutomatically(mOcAccounts[i], mAuthority, oldSync[i]);
+        }
+    }
+
+    static private class StoragePathSwitchTask extends FileMigrationTaskBase {
+
+        public StoragePathSwitchTask(Context context, String source, String target, AlertDialog progressDialog, StorageMigrationProgressListener listener) {
+            super(context, source, target, progressDialog, listener);
+        }
+
+        @Override
+        protected Integer doInBackground(Void... voids) {
+            publishProgress(R.string.file_migration_preparing);
+
+            Log_OC.stopLogging();
+            boolean[] syncStates = new boolean[0];
+            try {
+                publishProgress(R.string.file_migration_saving_accounts_configuration);
+                syncStates = saveAccountsSyncStatus();
+
+                publishProgress(R.string.file_migration_waiting_for_unfinished_sync);
+                stopAccountsSyncing();
+                waitForUnfinishedSynchronizations();
+            } finally {
+                publishProgress(R.string.file_migration_restoring_accounts_configuration);
+                restoreAccountsSyncStatus(syncStates);
+            }
+            Log_OC.startLogging(mStorageTarget);
+
+            return 0;
+        }
+    }
+
+    static private class FileMigrationTask extends FileMigrationTaskBase {
+        private class MigrationException extends Exception {
+            private int mResId;
+
+            MigrationException(int resId) {
+                super();
+                this.mResId = resId;
+            }
+
+            int getResId() { return mResId; }
+        }
+
+        public FileMigrationTask(Context context, String source, String target, AlertDialog progressDialog, StorageMigrationProgressListener listener) {
+            super(context, source, target, progressDialog, listener);
+        }
+
+        @Override
+        protected Integer doInBackground(Void... args) {
+            publishProgress(R.string.file_migration_preparing);
+            Log_OC.stopLogging();
+
+            boolean[] syncState = new boolean[0];
+
+            try {
+                File dstFile = new File(mStorageTarget + File.separator + MainApp.getDataFolder());
+                deleteRecursive(dstFile);
+                dstFile.delete();
+
+                publishProgress(R.string.file_migration_checking_destination);
+
+                checkDestinationAvailability();
+
+                publishProgress(R.string.file_migration_saving_accounts_configuration);
+                syncState = saveAccountsSyncStatus();
+
+                publishProgress(R.string.file_migration_waiting_for_unfinished_sync);
+                stopAccountsSyncing();
+                waitForUnfinishedSynchronizations();
+
+                publishProgress(R.string.file_migration_migrating);
+                copyFiles();
+
+                publishProgress(R.string.file_migration_updating_index);
+                updateIndex(mContext);
+
+                publishProgress(R.string.file_migration_cleaning);
+                cleanup();
+
+            } catch (MigrationException e) {
+                rollback();
+                Log_OC.startLogging(mStorageSource);
+                return e.getResId();
+            } finally {
+                publishProgress(R.string.file_migration_restoring_accounts_configuration);
+                restoreAccountsSyncStatus(syncState);
+            }
+
+            Log_OC.startLogging(mStorageTarget);
+            publishProgress(R.string.file_migration_ok_finished);
+
+            return 0;
+        }
+
+
+        void checkDestinationAvailability() throws MigrationException {
+            File srcFile = new File(mStorageSource);
+            File dstFile = new File(mStorageTarget);
+
+            if (!dstFile.canRead() || !srcFile.canRead())
+                throw new MigrationException(R.string.file_migration_failed_not_readable);
+
+            if (!dstFile.canWrite() || !srcFile.canWrite())
+                throw new MigrationException(R.string.file_migration_failed_not_writable);
+
+            if (new File(dstFile, MainApp.getDataFolder()).exists())
+                throw new MigrationException(R.string.file_migration_failed_dir_already_exists);
+
+            if (dstFile.getFreeSpace() < FileStorageUtils.getFolderSize(new File(srcFile, MainApp.getDataFolder())))
+                throw new MigrationException(R.string.file_migration_failed_not_enough_space);
+        }
+
+        void copyFiles() throws MigrationException {
+            File srcFile = new File(mStorageSource + File.separator + MainApp.getDataFolder());
+            File dstFile = new File(mStorageTarget + File.separator + MainApp.getDataFolder());
+
+            copyDirs(srcFile, dstFile);
+        }
+
+        void copyDirs(File src, File dst) throws MigrationException {
+            if (!dst.mkdirs())
+                throw new MigrationException(R.string.file_migration_failed_while_coping);
+
+            for (File f : src.listFiles()) {
+                if (f.isDirectory())
+                    copyDirs(f, new File(dst, f.getName()));
+                else if (!FileStorageUtils.copyFile(f, new File(dst, f.getName())))
+                    throw new MigrationException(R.string.file_migration_failed_while_coping);
+            }
 
-		}
-
-		void updateIndex(Context context) throws MigrationException {
-			FileDataStorageManager manager = new FileDataStorageManager(null, context.getContentResolver());
+        }
+
+        void updateIndex(Context context) throws MigrationException {
+            FileDataStorageManager manager = new FileDataStorageManager(null, context.getContentResolver());
 
-			try {
-				manager.migrateStoredFiles(mStorageSource, mStorageTarget);
-			} catch (Exception e) {
-				throw new MigrationException(R.string.file_migration_failed_while_updating_index);
-			}
-		}
+            try {
+                manager.migrateStoredFiles(mStorageSource, mStorageTarget);
+            } catch (Exception e) {
+                throw new MigrationException(R.string.file_migration_failed_while_updating_index);
+            }
+        }
 
-		void cleanup() {
-			File srcFile = new File(mStorageSource + File.separator + MainApp.getDataFolder());
-			if (!deleteRecursive(srcFile))
-				Log_OC.w(TAG, "Migration cleanup step failed");
-			srcFile.delete();
-		}
-
-		boolean deleteRecursive(File f) {
-			boolean res = true;
-			if (f.isDirectory())
-				for (File c : f.listFiles())
-					res = deleteRecursive(c) && res;
-			return f.delete() && res;
-		}
-
-		void rollback() {
-			File dstFile = new File(mStorageTarget + File.separator + MainApp.getDataFolder());
-			if (dstFile.exists())
-				if (!dstFile.delete())
-					Log_OC.w(TAG, "Rollback step failed");
-		}
-	}
+        void cleanup() {
+            File srcFile = new File(mStorageSource + File.separator + MainApp.getDataFolder());
+            if (!deleteRecursive(srcFile))
+                Log_OC.w(TAG, "Migration cleanup step failed");
+            srcFile.delete();
+        }
+
+        boolean deleteRecursive(File f) {
+            boolean res = true;
+            if (f.isDirectory())
+                for (File c : f.listFiles())
+                    res = deleteRecursive(c) && res;
+            return f.delete() && res;
+        }
+
+        void rollback() {
+            File dstFile = new File(mStorageTarget + File.separator + MainApp.getDataFolder());
+            if (dstFile.exists())
+                if (!dstFile.delete())
+                    Log_OC.w(TAG, "Rollback step failed");
+        }
+    }
 }