Ver código fonte

- strike out the account name (aka, you can't click it)
- switch to other acc if it exists, if not show login screen
- run a job with all the delete magic
- prevent adding the same account while there is pending delete for that account

tobiaskaminsky 8 anos atrás
pai
commit
87ae252a09

+ 26 - 10
src/main/java/com/owncloud/android/authentication/AccountUtils.java

@@ -28,12 +28,14 @@ import android.net.Uri;
 import android.preference.PreferenceManager;
 
 import com.owncloud.android.MainApp;
+import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.lib.common.accounts.AccountTypeUtils;
 import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;
+import com.owncloud.android.ui.activity.ManageAccountsActivity;
 import com.owncloud.android.operations.GetCapabilitiesOperarion;
 
 import java.util.Locale;
@@ -63,10 +65,10 @@ public class AccountUtils {
         Account[] ocAccounts = getAccounts(context);
         Account defaultAccount = null;
 
-        SharedPreferences appPreferences = PreferenceManager
-                .getDefaultSharedPreferences(context);
-        String accountName = appPreferences
-                .getString("select_oc_account", null);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
+
+        SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+        String accountName = appPreferences.getString("select_oc_account", null);
 
         // account validation: the saved account MUST be in the list of ownCloud Accounts known by the AccountManager
         if (accountName != null) {
@@ -77,10 +79,18 @@ public class AccountUtils {
                 }
             }
         }
-        
-        if (defaultAccount == null && ocAccounts.length != 0) {
-            // take first account as fallback
-            defaultAccount = ocAccounts[0];
+
+        if (defaultAccount == null && ocAccounts.length > 0) {
+            // take first which is not pending for removal account as fallback
+            for (Account account: ocAccounts) {
+                boolean pendingForRemoval = arbitraryDataProvider.getBooleanValue(account,
+                        ManageAccountsActivity.PENDING_FOR_REMOVAL);
+
+                if (!pendingForRemoval) {
+                    defaultAccount = account;
+                    break;
+                }
+            }
         }
 
         return defaultAccount;
@@ -155,8 +165,7 @@ public class AccountUtils {
             for (final Account account : getAccounts(context)) {
                 found = (account.name.equals(accountName));
                 if (found) {
-                    SharedPreferences.Editor appPrefs = PreferenceManager
-                            .getDefaultSharedPreferences(context).edit();
+                    SharedPreferences.Editor appPrefs = PreferenceManager.getDefaultSharedPreferences(context).edit();
                     appPrefs.putString("select_oc_account", accountName);
 
                     // update credentials
@@ -182,6 +191,13 @@ public class AccountUtils {
         return result;
     }
 
+    public static void resetOwnCloudAccount(Context context) {
+        SharedPreferences.Editor appPrefs = PreferenceManager.getDefaultSharedPreferences(context).edit();
+        appPrefs.putString("select_oc_account", null);
+
+        appPrefs.apply();
+    }
+
     /**
      * Returns the proper URL path to access the WebDAV interface of an ownCloud server,
      * according to its version and the authorization method used.

+ 93 - 0
src/main/java/com/owncloud/android/services/AccountRemovalJob.java

@@ -0,0 +1,93 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2017 Tobias Kaminsky
+ * Copyright (C) 2017 Nextcloud GmbH.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.services;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerCallback;
+import android.accounts.AccountManagerFuture;
+import android.content.Context;
+import android.support.annotation.NonNull;
+
+import com.evernote.android.job.Job;
+import com.evernote.android.job.util.support.PersistableBundleCompat;
+import com.owncloud.android.MainApp;
+import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.FileDataStorageManager;
+import com.owncloud.android.ui.events.AccountRemovedEvent;
+import com.owncloud.android.utils.FileStorageUtils;
+
+import org.greenrobot.eventbus.EventBus;
+
+import java.io.File;
+
+import static android.content.Context.ACCOUNT_SERVICE;
+import static com.owncloud.android.ui.activity.ManageAccountsActivity.PENDING_FOR_REMOVAL;
+
+/**
+ * Removes account and all local files
+ */
+
+public class AccountRemovalJob extends Job implements AccountManagerCallback<Boolean> {
+    public static final String TAG = "AccountRemovalJob";
+    public static final String ACCOUNT = "account";
+
+    @NonNull
+    @Override
+    protected Result onRunJob(Params params) {
+        Context context = MainApp.getAppContext();
+        PersistableBundleCompat bundle = params.getExtras();
+        Account account = AccountUtils.getOwnCloudAccountByName(context, bundle.getString(ACCOUNT, ""));
+
+        if (account != null ) {
+            AccountManager am = (AccountManager) context.getSystemService(ACCOUNT_SERVICE);
+            am.removeAccount(account, this, null);
+
+            FileDataStorageManager storageManager = new FileDataStorageManager(account, context.getContentResolver());
+
+            File tempDir = new File(FileStorageUtils.getTemporalPath(account.name));
+            File saveDir = new File(FileStorageUtils.getSavePath(account.name));
+
+            FileStorageUtils.deleteRecursively(tempDir, storageManager);
+            FileStorageUtils.deleteRecursively(saveDir, storageManager);
+
+            // delete all database entries
+            storageManager.deleteAllFiles();
+
+            // remove pending account removal
+            ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
+            arbitraryDataProvider.deleteKeyForAccount(account, PENDING_FOR_REMOVAL);
+
+            return Result.SUCCESS;
+        } else {
+            return Result.FAILURE;
+        }
+    }
+
+    @Override
+    public void run(AccountManagerFuture<Boolean> future) {
+        if (future.isDone()) {
+            EventBus.getDefault().post(new AccountRemovedEvent());
+        }
+    }
+}

+ 2 - 0
src/main/java/com/owncloud/android/services/NCJobCreator.java

@@ -37,6 +37,8 @@ public class NCJobCreator implements JobCreator {
                 return new ContactsBackupJob();
             case ContactsImportJob.TAG:
                 return new ContactsImportJob();
+            case AccountRemovalJob.TAG:
+                return new AccountRemovalJob();
             default:
                 return null;
         }

+ 52 - 21
src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java

@@ -54,6 +54,7 @@ import com.bumptech.glide.request.target.SimpleTarget;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.ExternalLinksProvider;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.ExternalLink;
@@ -69,6 +70,7 @@ import com.owncloud.android.lib.resources.files.SearchOperation;
 import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;
 import com.owncloud.android.operations.GetCapabilitiesOperarion;
 import com.owncloud.android.ui.TextDrawable;
+import com.owncloud.android.ui.events.AccountRemovedEvent;
 import com.owncloud.android.ui.events.ChangeMenuEvent;
 import com.owncloud.android.ui.events.DummyDrawerEvent;
 import com.owncloud.android.ui.events.MenuItemClickEvent;
@@ -182,6 +184,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
 
     private ExternalLinksProvider externalLinksProvider;
     private SharedPreferences sharedPreferences;
+    private ArbitraryDataProvider arbitraryDataProvider;
 
     /**
      * Initializes the drawer, its content and highlights the menu item with the given id.
@@ -605,7 +608,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
     /**
      * Enable or disable the drawer indicator.
      *
-     * @param enable <code>true</code> to enable, <code>false</code> to disable
+     * @param enable true to enable, false to disable
      */
     public void setDrawerIndicatorEnabled(boolean enable) {
         if (mDrawerToggle != null) {
@@ -618,9 +621,21 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
      */
     public void updateAccountList() {
         Account[] accounts = AccountManager.get(this).getAccountsByType(MainApp.getAccountType());
+
+        ArrayList<Account> persistingAccounts = new ArrayList<>();
+
+        for (Account acc: accounts) {
+            boolean pendingForRemoval = arbitraryDataProvider.getBooleanValue(acc,
+                    ManageAccountsActivity.PENDING_FOR_REMOVAL);
+
+            if (!pendingForRemoval) {
+                persistingAccounts.add(acc);
+            }
+        }
+
         if (mNavigationView != null && mDrawerLayout != null) {
-            if (accounts.length > 0) {
-                repopulateAccountList(accounts);
+            if (persistingAccounts.size() > 0) {
+                repopulateAccountList(persistingAccounts);
                 setAccountInDrawer(AccountUtils.getCurrentOwnCloudAccount(this));
                 populateDrawerOwnCloudAccounts();
 
@@ -655,25 +670,24 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
      *
      * @param accounts list of accounts
      */
-    private void repopulateAccountList(Account[] accounts) {
+    private void repopulateAccountList(ArrayList<Account> accounts) {
         // remove all accounts from list
         mNavigationView.getMenu().removeGroup(R.id.drawer_menu_accounts);
 
         // add all accounts to list
-        for (int i = 0; i < accounts.length; i++) {
+        for (Account account: accounts) {
             try {
-                // show all accounts except the currently active one
-                if (!getAccount().name.equals(accounts[i].name)) {
+                // show all accounts except the currently active one and those pending for removal
+
+                if (!getAccount().name.equals(account.name)) {
                     MenuItem accountMenuItem = mNavigationView.getMenu().add(
                             R.id.drawer_menu_accounts,
                             Menu.NONE,
                             MENU_ORDER_ACCOUNT,
-                            accounts[i].name)
-                            .setIcon(TextDrawable.createAvatar(
-                                    accounts[i].name,
-                                    mMenuAccountAvatarRadiusDimension)
-                            );
-                    DisplayUtils.setAvatar(accounts[i], this, mMenuAccountAvatarRadiusDimension, getResources(), getStorageManager(), accountMenuItem);
+                            account.name)
+                            .setIcon(TextDrawable.createAvatar(account.name, mMenuAccountAvatarRadiusDimension));
+                    DisplayUtils.setAvatar(account, this, mMenuAccountAvatarRadiusDimension, getResources(),
+                            getStorageManager(), accountMenuItem);
                 }
             } catch (Exception e) {
                 Log_OC.e(TAG, "Error calculating RGB value for account menu item.", e);
@@ -681,7 +695,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
                         R.id.drawer_menu_accounts,
                         Menu.NONE,
                         MENU_ORDER_ACCOUNT,
-                        accounts[i].name)
+                        account.name)
                         .setIcon(R.drawable.ic_user);
             }
         }
@@ -1056,6 +1070,7 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
                 .getDimension(R.dimen.nav_drawer_menu_avatar_radius);
 
         externalLinksProvider = new ExternalLinksProvider(MainApp.getAppContext().getContentResolver());
+        arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
 
         sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
     }
@@ -1130,13 +1145,13 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
         // update Account list and active account if Manage Account activity replies with
         // - ACCOUNT_LIST_CHANGED = true
         // - RESULT_OK
-        if (requestCode == ACTION_MANAGE_ACCOUNTS
-                && resultCode == RESULT_OK
+        if (requestCode == ACTION_MANAGE_ACCOUNTS && resultCode == RESULT_OK
                 && data.getBooleanExtra(ManageAccountsActivity.KEY_ACCOUNT_LIST_CHANGED, false)) {
 
             // current account has changed
             if (data.getBooleanExtra(ManageAccountsActivity.KEY_CURRENT_ACCOUNT_CHANGED, false)) {
                 setAccount(AccountUtils.getCurrentOwnCloudAccount(this));
+                updateAccountList();
                 restart();
             } else {
                 updateAccountList();
@@ -1194,15 +1209,26 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
      */
     private void populateDrawerOwnCloudAccounts() {
         mAvatars = new Account[3];
-        Account[] accountsAll = AccountManager.get(this).getAccountsByType
-                (MainApp.getAccountType());
+        Account[] accountsAll = AccountManager.get(this).getAccountsByType(MainApp.getAccountType());
+
+        ArrayList<Account> persistingAccounts = new ArrayList<>();
+
+        for (Account acc: accountsAll) {
+            boolean pendingForRemoval = arbitraryDataProvider.getBooleanValue(acc,
+                    ManageAccountsActivity.PENDING_FOR_REMOVAL);
+
+            if (!pendingForRemoval) {
+                persistingAccounts.add(acc);
+            }
+        }
+
         Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(this);
 
         mAvatars[0] = currentAccount;
         int j = 0;
-        for (int i = 1; i <= 2 && i < accountsAll.length && j < accountsAll.length; j++) {
-            if (!currentAccount.equals(accountsAll[j])) {
-                mAvatars[i] = accountsAll[j];
+        for (int i = 1; i <= 2 && i < persistingAccounts.size() && j < persistingAccounts.size(); j++) {
+            if (!currentAccount.equals(persistingAccounts.get(j))) {
+                mAvatars[i] = persistingAccounts.get(j);
                 i++;
             }
         }
@@ -1260,6 +1286,11 @@ public abstract class DrawerActivity extends ToolbarActivity implements DisplayU
         super.onStop();
     }
 
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void onAccountRemovedEvent(AccountRemovedEvent event) {
+        updateAccountList();
+    }
+
     /**
      * Retrieves external links via api from 'external' app
      */

+ 109 - 37
src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java

@@ -1,4 +1,4 @@
-/**
+/*
  * ownCloud Android client application
  *
  * @author Andy Scherzinger
@@ -29,7 +29,6 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.graphics.drawable.Drawable;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -40,27 +39,34 @@ import android.view.View;
 import android.widget.AdapterView;
 import android.widget.ListView;
 
+import com.evernote.android.job.JobRequest;
+import com.evernote.android.job.util.support.PersistableBundleCompat;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileUploader;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.services.AccountRemovalJob;
+import com.owncloud.android.services.AutoUploadJob;
 import com.owncloud.android.services.OperationsService;
 import com.owncloud.android.ui.adapter.AccountListAdapter;
 import com.owncloud.android.ui.adapter.AccountListItem;
+import com.owncloud.android.ui.events.AccountRemovedEvent;
 import com.owncloud.android.ui.helpers.FileOperationsHelper;
 import com.owncloud.android.utils.AnalyticsUtils;
 import com.owncloud.android.utils.DisplayUtils;
-import com.owncloud.android.utils.FileStorageUtils;
 import com.owncloud.android.utils.ThemeUtils;
 
+import org.greenrobot.eventbus.Subscribe;
+import org.greenrobot.eventbus.ThreadMode;
 import org.parceler.Parcels;
 
-import java.io.File;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Set;
 
 /**
@@ -72,6 +78,8 @@ public class ManageAccountsActivity extends FileActivity
     public static final String KEY_ACCOUNT_LIST_CHANGED = "ACCOUNT_LIST_CHANGED";
     public static final String KEY_CURRENT_ACCOUNT_CHANGED = "CURRENT_ACCOUNT_CHANGED";
 
+    public static final String PENDING_FOR_REMOVAL = "PENDING_FOR_REMOVAL";
+
     private static final String KEY_ACCOUNT = "ACCOUNT";
     private static final String KEY_DISPLAY_NAME = "DISPLAY_NAME";
 
@@ -88,6 +96,7 @@ public class ManageAccountsActivity extends FileActivity
     private Drawable mTintedCheck;
 
     private static final String SCREEN_NAME = "Logs";
+    private ArbitraryDataProvider arbitraryDataProvider;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -105,12 +114,14 @@ public class ManageAccountsActivity extends FileActivity
         updateActionBarTitleAndHomeButtonByString(getResources().getString(R.string.prefs_manage_accounts));
 
         Account[] accountList = AccountManager.get(this).getAccountsByType(MainApp.getAccountType());
-        mOriginalAccounts = DisplayUtils.toAccountNameSet(accountList);
+        mOriginalAccounts = DisplayUtils.toAccountNameSet(Arrays.asList(accountList));
         mOriginalCurrentAccount = AccountUtils.getCurrentOwnCloudAccount(this).name;
 
         setAccount(AccountUtils.getCurrentOwnCloudAccount(this));
         onAccountSet(false);
 
+        arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
+
         mAccountListAdapter = new AccountListAdapter(this, getAccountListItems(), mTintedCheck);
 
         mListView.setAdapter(mAccountListAdapter);
@@ -120,16 +131,20 @@ public class ManageAccountsActivity extends FileActivity
         mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-                Account account = mAccountListAdapter.getItem(position).getAccount();
-                intent.putExtra(KEY_ACCOUNT, Parcels.wrap(account));
-                try {
-                    OwnCloudAccount oca = new OwnCloudAccount(account, MainApp.getAppContext());
-                    intent.putExtra(KEY_DISPLAY_NAME, oca.getDisplayName());
-                } catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
-                    Log_OC.d(TAG, "Failed to find NC account");
-                }
+                AccountListItem item = mAccountListAdapter.getItem(position);
+
+                if (item != null && item.isEnabled()) {
+                    Account account = item.getAccount();
+                    intent.putExtra(KEY_ACCOUNT, Parcels.wrap(account));
+                    try {
+                        OwnCloudAccount oca = new OwnCloudAccount(account, MainApp.getAppContext());
+                        intent.putExtra(KEY_DISPLAY_NAME, oca.getDisplayName());
+                    } catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
+                        Log_OC.d(TAG, "Failed to find NC account");
+                    }
 
-                startActivityForResult(intent, KEY_USER_INFO_REQUEST_CODE);
+                    startActivityForResult(intent, KEY_USER_INFO_REQUEST_CODE);
+                }
             }
         });
 
@@ -174,18 +189,28 @@ public class ManageAccountsActivity extends FileActivity
     /**
      * checks the set of actual accounts against the set of original accounts when the activity has been started.
      *
-     * @return <code>true</code> if aacount list has changed, <code>false</code> if not
+     * @return true if account list has changed, false if not
      */
     private boolean hasAccountListChanged() {
         Account[] accountList = AccountManager.get(this).getAccountsByType(MainApp.getAccountType());
-        Set<String> actualAccounts = DisplayUtils.toAccountNameSet(accountList);
+
+        ArrayList<Account> newList = new ArrayList<>();
+        for (Account account : accountList) {
+            boolean pendingForRemoval = arbitraryDataProvider.getBooleanValue(account, PENDING_FOR_REMOVAL);
+
+            if (!pendingForRemoval) {
+                newList.add(account);
+            }
+        }
+
+        Set<String> actualAccounts = DisplayUtils.toAccountNameSet(newList);
         return !mOriginalAccounts.equals(actualAccounts);
     }
 
     /**
      * checks actual current account against current accounts when the activity has been started.
      *
-     * @return <code>true</code> if aacount list has changed, <code>false</code> if not
+     * @return true if account list has changed, false if not
      */
     private boolean hasCurrentAccountChanged() {
         Account account = AccountUtils.getCurrentOwnCloudAccount(this);
@@ -221,7 +246,8 @@ public class ManageAccountsActivity extends FileActivity
         Account[] accountList = AccountManager.get(this).getAccountsByType(MainApp.getAccountType());
         ArrayList<AccountListItem> adapterAccountList = new ArrayList<>(accountList.length);
         for (Account account : accountList) {
-            adapterAccountList.add(new AccountListItem(account));
+            boolean pendingForRemoval = arbitraryDataProvider.getBooleanValue(account, PENDING_FOR_REMOVAL);
+            adapterAccountList.add(new AccountListItem(account, !pendingForRemoval));
         }
 
         // Add Create Account item at the end of account list if multi-account is enabled
@@ -284,6 +310,14 @@ public class ManageAccountsActivity extends FileActivity
                 }, mHandler);
     }
 
+    @Subscribe(threadMode = ThreadMode.MAIN)
+    public void onAccountRemovedEvent(AccountRemovedEvent event) {
+        ArrayList<AccountListItem> accountListItemArray = getAccountListItems();
+        mAccountListAdapter.clear();
+        mAccountListAdapter.addAll(accountListItemArray);
+        mAccountListAdapter.notifyDataSetChanged();
+    }
+
     @Override
     public void run(AccountManagerFuture<Boolean> future) {
         if (future.isDone()) {
@@ -359,32 +393,70 @@ public class ManageAccountsActivity extends FileActivity
     }
 
     private void performAccountRemoval(Account account) {
-        AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
-        am.removeAccount(account, this, this.getHandler());
+        // disable account in list view
+        for (int i = 0; i < mAccountListAdapter.getCount(); i++) {
+            AccountListItem item = mAccountListAdapter.getItem(i);
 
-        deleteAccountFiles(account);
-    }
-
-    private void deleteAccountFiles(final Account account) {
-        AsyncTask removalTask = new AsyncTask() {
-            @Override
-            protected Object doInBackground(Object[] params) {
-                FileDataStorageManager storageManager = new FileDataStorageManager(account, getContentResolver());
+            if (item != null && item.getAccount().equals(account)) {
+                item.setEnabled(false);
+                break;
+            }
 
-                File tempDir = new File(FileStorageUtils.getTemporalPath(account.name));
-                File saveDir = new File(FileStorageUtils.getSavePath(account.name));
+            mAccountListAdapter.notifyDataSetChanged();
+        }
 
-                FileStorageUtils.deleteRecursively(tempDir, storageManager);
-                FileStorageUtils.deleteRecursively(saveDir, storageManager);
+        // store pending account removal
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
+        arbitraryDataProvider.storeOrUpdateKeyValue(account, PENDING_FOR_REMOVAL, String.valueOf(true));
 
-                // delete all database entries
-                storageManager.deleteAllFiles();
+        // Cancel transfers
+        if (mUploaderBinder != null) {
+            mUploaderBinder.cancel(account);
+        }
+        if (mDownloaderBinder != null) {
+            mDownloaderBinder.cancel(account);
+        }
 
-                return true;
+        // schedule job
+        PersistableBundleCompat bundle = new PersistableBundleCompat();
+        bundle.putString(AutoUploadJob.ACCOUNT, account.name);
+
+        new JobRequest.Builder(AccountRemovalJob.TAG)
+                .setExecutionWindow(1_000L, 10_000L)
+                .setExtras(bundle)
+                .setPersisted(false)
+                .setUpdateCurrent(false)
+                .build()
+                .schedule();
+
+        // immediately select a new account
+        Account[] accounts = AccountManager.get(this).getAccountsByType(MainApp.getAccountType());
+
+        String newAccountName = "";
+        for (Account acc: accounts) {
+            if (!account.name.equalsIgnoreCase(acc.name)) {
+                newAccountName = acc.name;
+                break;
             }
-        };
+        }
 
-        removalTask.execute();
+        if (newAccountName.isEmpty()) {
+            Log_OC.d(TAG, "new account set to null");
+            AccountUtils.resetOwnCloudAccount(this);
+        } else {
+            Log_OC.d(TAG, "new account set to: " + newAccountName);
+            AccountUtils.setCurrentOwnCloudAccount(this, newAccountName);
+        }
+
+        // only one to be (deleted) account remaining
+        if (accounts.length < 2) {
+            Intent resultIntent = new Intent();
+            resultIntent.putExtra(KEY_ACCOUNT_LIST_CHANGED, true);
+            resultIntent.putExtra(KEY_CURRENT_ACCOUNT_CHANGED, true);
+            setResult(RESULT_OK, resultIntent);
+
+            super.onBackPressed();
+        }
     }
 
     /**

+ 12 - 0
src/main/java/com/owncloud/android/ui/adapter/AccountListAdapter.java

@@ -20,6 +20,7 @@
 package com.owncloud.android.ui.adapter;
 
 import android.accounts.Account;
+import android.graphics.Paint;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.NonNull;
 import android.view.LayoutInflater;
@@ -93,6 +94,17 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements
                 setAvatar(viewHolder, account);
                 setCurrentlyActiveState(viewHolder, account);
 
+                TextView usernameView = viewHolder.usernameViewItem;
+                TextView accountView = viewHolder.accountViewItem;
+
+                if (!accountListItem.isEnabled()) {
+                    usernameView.setPaintFlags(usernameView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
+                    accountView.setPaintFlags(accountView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
+                } else {
+                    usernameView.setPaintFlags(usernameView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
+                    accountView.setPaintFlags(accountView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
+                }
+
             } // create add account action item
             else if (AccountListItem.TYPE_ACTION_ADD == accountListItem.getType() && mListener != null) {
                 return setupAddAccountListItem(parent);

+ 16 - 0
src/main/java/com/owncloud/android/ui/adapter/AccountListItem.java

@@ -30,6 +30,7 @@ public class AccountListItem {
 
     private Account mAccount;
     private int mType;
+    private boolean mEnabled;
 
     /**
      * creates an account list item containing an {@link Account}.
@@ -39,6 +40,13 @@ public class AccountListItem {
     public AccountListItem(Account account) {
         mAccount = account;
         mType = TYPE_ACCOUNT;
+        mEnabled = true;
+    }
+
+    public AccountListItem(Account account, boolean enabled) {
+        mAccount = account;
+        mType = TYPE_ACCOUNT;
+        mEnabled = enabled;
     }
 
     /**
@@ -55,4 +63,12 @@ public class AccountListItem {
     public int getType() {
         return mType;
     }
+
+    public void setEnabled(boolean bool) {
+        mEnabled = bool;
+    }
+
+    public boolean isEnabled() {
+        return mEnabled;
+    }
 }

+ 30 - 0
src/main/java/com/owncloud/android/ui/events/AccountRemovedEvent.java

@@ -0,0 +1,30 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Tobias Kaminsky
+ * Copyright (C) 2017 Tobias Kaminsky
+ * Copyright (C) 2017 Nextcloud GmbH.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.owncloud.android.ui.events;
+
+/**
+ * Event that notifies that an account was removed
+ */
+
+public class AccountRemovedEvent {
+
+}

+ 1 - 1
src/main/java/com/owncloud/android/ui/events/TokenPushEvent.java

@@ -1,4 +1,4 @@
-/**
+/*
  * Nextcloud Android client application
  *
  * @author Mario Danic

+ 3 - 2
src/main/java/com/owncloud/android/utils/DisplayUtils.java

@@ -81,6 +81,7 @@ import java.io.InputStreamReader;
 import java.math.BigDecimal;
 import java.net.IDN;
 import java.text.DateFormat;
+import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -278,8 +279,8 @@ public class DisplayUtils {
      * @param accountList the account array
      * @return set of account names
      */
-    public static Set<String> toAccountNameSet(Account[] accountList) {
-        Set<String> actualAccounts = new HashSet<>(accountList.length);
+    public static Set<String> toAccountNameSet(Collection<Account> accountList) {
+        Set<String> actualAccounts = new HashSet<>(accountList.size());
         for (Account account : accountList) {
             actualAccounts.add(account.name);
         }