Bladeren bron

Create UserAccountManager and move getAccounts()

Signed-off-by: Chris Narkiewicz <hello@ezaquarii.com>
Chris Narkiewicz 6 jaren geleden
bovenliggende
commit
bbaf355328
34 gewijzigde bestanden met toevoegingen van 640 en 241 verwijderingen
  1. 3 0
      findbugs-filter.xml
  2. 26 0
      src/generic/java/com/nextcloud/client/di/VariantComponentsModule.java
  3. 11 3
      src/generic/java/com/owncloud/android/utils/PushUtils.java
  4. 30 0
      src/gplay/java/com/nextcloud/client/di/VariantComponentsModule.java
  5. 10 4
      src/gplay/java/com/owncloud/android/services/firebase/NCFirebaseInstanceIDService.java
  6. 15 7
      src/gplay/java/com/owncloud/android/utils/PushUtils.java
  7. 65 0
      src/main/java/com/nextcloud/client/account/UserAccountManager.java
  8. 196 0
      src/main/java/com/nextcloud/client/account/UserAccountManagerImpl.java
  9. 15 2
      src/main/java/com/nextcloud/client/di/AppModule.java
  10. 6 0
      src/main/java/com/nextcloud/client/di/ComponentsModule.java
  11. 4 8
      src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java
  12. 48 15
      src/main/java/com/owncloud/android/MainApp.java
  13. 1 150
      src/main/java/com/owncloud/android/authentication/AccountUtils.java
  14. 5 3
      src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
  15. 14 2
      src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java
  16. 15 4
      src/main/java/com/owncloud/android/jobs/FilesSyncJob.java
  17. 9 2
      src/main/java/com/owncloud/android/jobs/MediaFoldersDetectionJob.java
  18. 24 5
      src/main/java/com/owncloud/android/jobs/NCJobCreator.java
  19. 10 0
      src/main/java/com/owncloud/android/jobs/NotificationJob.java
  20. 9 1
      src/main/java/com/owncloud/android/jobs/OfflineSyncJob.java
  21. 14 2
      src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java
  22. 7 3
      src/main/java/com/owncloud/android/ui/TextDrawable.java
  23. 5 2
      src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
  24. 7 2
      src/main/java/com/owncloud/android/ui/activity/FileActivity.java
  25. 7 4
      src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java
  26. 6 1
      src/main/java/com/owncloud/android/ui/activity/FirstRunActivity.java
  27. 4 1
      src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java
  28. 8 2
      src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java
  29. 5 1
      src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java
  30. 4 1
      src/main/java/com/owncloud/android/ui/adapter/AccountListAdapter.java
  31. 8 6
      src/main/java/com/owncloud/android/utils/FilesSyncHelper.java
  32. 10 7
      src/main/java/com/owncloud/android/utils/ReceiversHelper.java
  33. 26 0
      src/versionDev/java/com/nextcloud/client/di/VariantComponentsModule.java
  34. 13 3
      src/versionDev/java/com/owncloud/android/utils/PushUtils.java

+ 3 - 0
findbugs-filter.xml

@@ -22,4 +22,7 @@
     </Match>
     <Bug pattern="PATH_TRAVERSAL_IN" />
     <Bug pattern="ANDROID_EXTERNAL_FILE_ACCESS" />
+
+    <!-- This is unmanageable for now dur to large amount of interconnected static state -->
+    <Bug pattern="FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY"/>
 </FindBugsFilter>

+ 26 - 0
src/generic/java/com/nextcloud/client/di/VariantComponentsModule.java

@@ -0,0 +1,26 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2919 Chris Narkiewicz <hello@ezaquarii.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or 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.nextcloud.client.di;
+
+import dagger.Module;
+
+@Module
+abstract class VariantComponentsModule {
+}

+ 11 - 3
src/generic/java/com/owncloud/android/utils/PushUtils.java

@@ -2,7 +2,9 @@
  * Nextcloud Android client application
  *
  * @author Mario Danic
+ * @author Chris Narkiewicz
  * Copyright (C) 2017 Mario Danic
+ * Copyright (C) 2019 Chris Narkiewicz
  *
  * 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
@@ -22,6 +24,7 @@ package com.owncloud.android.utils;
 
 import android.content.Context;
 
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.SignatureVerification;
 import com.nextcloud.client.preferences.AppPreferencesImpl;
@@ -34,11 +37,11 @@ public final class PushUtils {
     private PushUtils() {
     }
 
-    public static void pushRegistrationToServer(final String pushToken) {
+    public static void pushRegistrationToServer(final UserAccountManager accountManager, final String pushToken) {
         // do nothing
     }
 
-    public static void reinitKeys() {
+    public static void reinitKeys(UserAccountManager accountManager) {
         Context context = MainApp.getAppContext();
         AppPreferencesImpl.fromContext(context).setKeysReInitEnabled();
     }
@@ -47,7 +50,12 @@ public final class PushUtils {
         return null;
     }
 
-    public static SignatureVerification verifySignature(Context context, byte[] signatureBytes, byte[] subjectBytes) {
+    public static SignatureVerification verifySignature(
+        final Context context,
+        final UserAccountManager accountManager,
+        final byte[] signatureBytes,
+        final byte[] subjectBytes
+    ) {
         return null;
     }
 

+ 30 - 0
src/gplay/java/com/nextcloud/client/di/VariantComponentsModule.java

@@ -0,0 +1,30 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2919 Chris Narkiewicz <hello@ezaquarii.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or 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.nextcloud.client.di;
+
+import com.owncloud.android.services.firebase.NCFirebaseInstanceIDService;
+
+import dagger.Module;
+import dagger.android.ContributesAndroidInjector;
+
+@Module
+abstract class VariantComponentsModule {
+    @ContributesAndroidInjector abstract NCFirebaseInstanceIDService ncFirebaseInstanceIDService();
+}

+ 10 - 4
src/gplay/java/com/owncloud/android/services/firebase/NCFirebaseInstanceIDService.java

@@ -23,19 +23,25 @@ import android.text.TextUtils;
 
 import com.google.firebase.iid.FirebaseInstanceId;
 import com.google.firebase.iid.FirebaseInstanceIdService;
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.preferences.AppPreferences;
-import com.nextcloud.client.preferences.AppPreferencesImpl;
 import com.owncloud.android.R;
 import com.owncloud.android.utils.PushUtils;
 
+import javax.inject.Inject;
+
+import dagger.android.AndroidInjection;
+
 public class NCFirebaseInstanceIDService extends FirebaseInstanceIdService {
 
-    private AppPreferences preferences;
+
+    @Inject AppPreferences preferences;
+    @Inject UserAccountManager accountManager;
 
     @Override
     public void onCreate() {
         super.onCreate();
-        preferences = AppPreferencesImpl.fromContext(this);
+        AndroidInjection.inject(this);
     }
 
     @Override
@@ -43,7 +49,7 @@ public class NCFirebaseInstanceIDService extends FirebaseInstanceIdService {
         //You can implement this method to store the token on your server
         if (!TextUtils.isEmpty(getResources().getString(R.string.push_server_url))) {
             preferences.setPushToken(FirebaseInstanceId.getInstance().getToken());
-            PushUtils.pushRegistrationToServer(preferences.getPushToken());
+            PushUtils.pushRegistrationToServer(accountManager, preferences.getPushToken());
         }
     }
 }

+ 15 - 7
src/gplay/java/com/owncloud/android/utils/PushUtils.java

@@ -2,7 +2,9 @@
  * Nextcloud Android client application
  *
  * @author Mario Danic
+ * @author Chris Narkiewicz
  * Copyright (C) 2017-2018 Mario Danic
+ * Copyright (C) 2019 Chris Narkiewicz
  *
  * 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
@@ -29,6 +31,7 @@ import android.util.Base64;
 import android.util.Log;
 
 import com.google.gson.Gson;
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.client.preferences.AppPreferencesImpl;
 import com.owncloud.android.MainApp;
@@ -194,7 +197,7 @@ public final class PushUtils {
         }
     }
 
-    public static void pushRegistrationToServer(final String token) {
+    public static void pushRegistrationToServer(final UserAccountManager accountManager, final String token) {
         arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext().getContentResolver());
 
         if (!TextUtils.isEmpty(MainApp.getAppContext().getResources().getString(R.string.push_server_url)) &&
@@ -213,7 +216,7 @@ public final class PushUtils {
                 String providerValue;
                 PushConfigurationState accountPushData = null;
                 Gson gson = new Gson();
-                for (Account account : AccountUtils.getAccounts(context)) {
+                for (Account account : accountManager.getAccounts()) {
                     providerValue = arbitraryDataProvider.getValue(account, KEY_PUSH);
                     if (!TextUtils.isEmpty(providerValue)) {
                         accountPushData = gson.fromJson(providerValue,
@@ -359,9 +362,9 @@ public final class PushUtils {
         return -1;
     }
 
-    public static void reinitKeys() {
+    public static void reinitKeys(final UserAccountManager accountManager) {
         Context context = MainApp.getAppContext();
-        Account[] accounts = AccountUtils.getAccounts(context);
+        Account[] accounts = accountManager.getAccounts();
         for (Account account : accounts) {
             deleteRegistrationForAccount(account);
         }
@@ -375,7 +378,7 @@ public final class PushUtils {
 
         AppPreferences preferences = AppPreferencesImpl.fromContext(context);
         String pushToken = preferences.getPushToken();
-        pushRegistrationToServer(pushToken);
+        pushRegistrationToServer(accountManager, pushToken);
         preferences.setKeysReInitEnabled();
     }
 
@@ -411,13 +414,18 @@ public final class PushUtils {
         }
     }
 
-    public static SignatureVerification verifySignature(Context context, byte[] signatureBytes, byte[] subjectBytes) {
+    public static SignatureVerification verifySignature(
+        final Context context,
+        final UserAccountManager accountManager,
+        final byte[] signatureBytes,
+        final byte[] subjectBytes
+    ) {
         Signature signature = null;
         PublicKey publicKey;
         SignatureVerification signatureVerification = new SignatureVerification();
         signatureVerification.setSignatureValid(false);
 
-        Account[] accounts = AccountUtils.getAccounts(context);
+        Account[] accounts = accountManager.getAccounts();
 
         ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
         String arbitraryValue;

+ 65 - 0
src/main/java/com/nextcloud/client/account/UserAccountManager.java

@@ -0,0 +1,65 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or 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.nextcloud.client.account;
+
+import android.accounts.Account;
+
+import androidx.annotation.NonNull;
+
+public interface UserAccountManager {
+
+    int ACCOUNT_VERSION = 1;
+    int ACCOUNT_VERSION_WITH_PROPER_ID = 2;
+    String ACCOUNT_USES_STANDARD_PASSWORD = "ACCOUNT_USES_STANDARD_PASSWORD";
+
+    /**
+     * Get configured NextCloud's user accounts.
+     *
+     * @return Array of accounts or empty array, if accounts are not configured.
+     */
+    @NonNull
+    Account[] getAccounts();
+
+    /**
+     * Update the accounts in AccountManager to meet the current
+     * version of accounts expected by the app, if needed.
+     * <p>
+     * Introduced to handle a change in the structure of stored account names
+     * needed to allow different Nextcloud servers in the same domain, but not in
+     * the same path.
+     */
+    void updateAccountVersion();
+
+    /**
+     * Extract username from account.
+     *
+     * Full account name is in form of "username@nextcloud.domain".
+     *
+     * @param account Account instance
+     * @return User name (without domain) or null, if name cannot be extracted.
+     */
+    static String getUsername(Account account) {
+        if (account != null && account.name != null) {
+            return account.name.substring(0, account.name.lastIndexOf('@'));
+        } else {
+            return null;
+        }
+    }
+}

+ 196 - 0
src/main/java/com/nextcloud/client/account/UserAccountManagerImpl.java

@@ -0,0 +1,196 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2019 Chris Narkiewicz
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or 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.nextcloud.client.account;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.content.Context;
+import android.net.Uri;
+
+import com.owncloud.android.MainApp;
+import com.owncloud.android.R;
+import com.owncloud.android.authentication.AccountUtils;
+import com.owncloud.android.lib.common.OwnCloudAccount;
+import com.owncloud.android.lib.common.OwnCloudClient;
+import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
+import com.owncloud.android.lib.common.UserInfo;
+import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;
+
+import javax.inject.Inject;
+
+import androidx.annotation.NonNull;
+
+public class UserAccountManagerImpl implements UserAccountManager {
+
+    private static final String TAG = AccountUtils.class.getSimpleName();
+    private static final String PREF_SELECT_OC_ACCOUNT = "select_oc_account";
+
+    private Context context;
+    private AccountManager accountManager;
+
+    @Inject
+    public UserAccountManagerImpl(Context context, AccountManager accountManager) {
+        this.context = context;
+        this.accountManager = accountManager;
+    }
+
+    @Override
+    @NonNull
+    public Account[] getAccounts() {
+        return accountManager.getAccountsByType(getAccountType());
+    }
+
+    public void updateAccountVersion() {
+        Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(context);
+
+        if (currentAccount == null) {
+            return;
+        }
+
+        final String currentAccountVersion = accountManager.getUserData(currentAccount, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_OC_ACCOUNT_VERSION);
+        final boolean needsUpdate = !String.valueOf(ACCOUNT_VERSION_WITH_PROPER_ID).equalsIgnoreCase(currentAccountVersion);
+        if (!needsUpdate) {
+            return;
+        }
+
+        Log_OC.i(TAG, "Upgrading accounts to account version #" + ACCOUNT_VERSION_WITH_PROPER_ID);
+
+        Account[] ocAccounts = accountManager.getAccountsByType(MainApp.getAccountType(context));
+        String serverUrl;
+        String username;
+        String displayName;
+        String newAccountName;
+        Account newAccount;
+        GetRemoteUserInfoOperation remoteUserNameOperation = new GetRemoteUserInfoOperation();
+
+        for (Account account : ocAccounts) {
+            // build new account name
+            serverUrl = accountManager.getUserData(account, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_OC_BASE_URL);
+
+            // update user name
+            try {
+                OwnCloudAccount ocAccount = new OwnCloudAccount(account, context);
+                OwnCloudClient client = OwnCloudClientManagerFactory.getDefaultSingleton()
+                    .getClientFor(ocAccount, context);
+
+                RemoteOperationResult result = remoteUserNameOperation.execute(client);
+
+                if (result.isSuccess()) {
+                    UserInfo userInfo = (UserInfo) result.getData().get(0);
+                    username = userInfo.id;
+                    displayName = userInfo.displayName;
+                } else {
+                    // skip account, try it next time
+                    Log_OC.e(TAG, "Error while getting username for account: " + account.name);
+                    continue;
+                }
+            } catch (Exception e) {
+                Log_OC.e(TAG, "Error while getting username: " + e.getMessage());
+                continue;
+            }
+
+            newAccountName = com.owncloud.android.lib.common.accounts.AccountUtils.
+                buildAccountName(Uri.parse(serverUrl), username);
+
+            // migrate to a new account, if needed
+            if (!newAccountName.equals(account.name)) {
+                newAccount = migrateAccount(context, currentAccount, accountManager, serverUrl, newAccountName,
+                                            account);
+
+            } else {
+                // servers which base URL is in the root of their domain need no change
+                Log_OC.d(TAG, account.name + " needs no upgrade ");
+                newAccount = account;
+            }
+
+            accountManager.setUserData(newAccount, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_DISPLAY_NAME, displayName);
+            accountManager.setUserData(newAccount, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID, username);
+
+            // at least, upgrade account version
+            Log_OC.d(TAG, "Setting version " + ACCOUNT_VERSION_WITH_PROPER_ID + " to " + newAccountName);
+            accountManager.setUserData(newAccount, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_OC_ACCOUNT_VERSION,
+                                   Integer.toString(ACCOUNT_VERSION_WITH_PROPER_ID));
+        }
+    }
+
+    @NonNull
+    private Account migrateAccount(Context context, Account currentAccount, AccountManager accountMgr,
+                                          String serverUrl, String newAccountName, Account account) {
+
+        Log_OC.d(TAG, "Upgrading " + account.name + " to " + newAccountName);
+
+        // create the new account
+        Account newAccount = new Account(newAccountName, MainApp.getAccountType(context));
+        String password = accountMgr.getPassword(account);
+        accountMgr.addAccountExplicitly(newAccount, (password != null) ? password : "", null);
+
+        // copy base URL
+        accountMgr.setUserData(newAccount, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_OC_BASE_URL, serverUrl);
+
+        // copy server version
+        accountMgr.setUserData(
+            newAccount,
+            com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_OC_VERSION,
+            accountMgr.getUserData(account, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_OC_VERSION)
+        );
+
+        // copy cookies
+        accountMgr.setUserData(
+            newAccount,
+            com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_COOKIES,
+            accountMgr.getUserData(account, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_COOKIES)
+        );
+
+        // copy type of authentication
+        final String isSamlStr = accountMgr.getUserData(account, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO);
+        if (Boolean.parseBoolean(isSamlStr)) {
+            accountMgr.setUserData(newAccount, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_SUPPORTS_SAML_WEB_SSO, "TRUE");
+        }
+
+        final String isOauthStr = accountMgr.getUserData(account, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_SUPPORTS_OAUTH2);
+        if (Boolean.parseBoolean(isOauthStr)) {
+            accountMgr.setUserData(newAccount, com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_SUPPORTS_OAUTH2, "TRUE");
+        }
+
+        /* TODO - study if it's possible to run this method in a background thread to copy the authToken
+        if (isOAuth || isSaml) {
+            accountMgr.setAuthToken(newAccount, mAuthTokenType, mAuthToken);
+        }
+        */
+
+        // don't forget the account saved in preferences as the current one
+        if (currentAccount.name.equals(account.name)) {
+            AccountUtils.setCurrentOwnCloudAccount(context, newAccountName);
+        }
+
+        // remove the old account
+        accountMgr.removeAccount(account, null, null);
+
+        // will assume it succeeds, not a big deal otherwise
+        return newAccount;
+    }
+
+    private String getAccountType() {
+        return context.getString(R.string.account_type);
+    }
+}

+ 15 - 2
src/main/java/com/nextcloud/client/di/AppModule.java

@@ -20,25 +20,38 @@
 
 package com.nextcloud.client.di;
 
+import android.accounts.AccountManager;
 import android.app.Application;
 import android.content.Context;
 
+import com.nextcloud.client.account.UserAccountManager;
+import com.nextcloud.client.account.UserAccountManagerImpl;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.client.preferences.AppPreferencesImpl;
 
 import dagger.Module;
 import dagger.Provides;
 
-@Module(includes = {ComponentsModule.class})
+@Module(includes = {ComponentsModule.class, VariantComponentsModule.class})
 class AppModule {
 
+    @Provides
+    AccountManager accountManager(Application application) {
+        return (AccountManager)application.getSystemService(Context.ACCOUNT_SERVICE);
+    }
+
     @Provides
     Context context(Application application) {
-        return application.getApplicationContext();
+        return application;
     }
 
     @Provides
     AppPreferences preferences(Application application) {
         return AppPreferencesImpl.fromContext(application);
     }
+
+    @Provides
+    UserAccountManager userAccountManager(Context context, AccountManager accountManager) {
+        return new UserAccountManagerImpl(context, accountManager);
+    }
 }

+ 6 - 0
src/main/java/com/nextcloud/client/di/ComponentsModule.java

@@ -22,6 +22,8 @@ package com.nextcloud.client.di;
 
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.authentication.DeepLinkLoginActivity;
+import com.owncloud.android.files.BootupBroadcastReceiver;
+import com.owncloud.android.providers.DocumentsStorageProvider;
 import com.owncloud.android.ui.activities.ActivitiesActivity;
 import com.owncloud.android.ui.activity.ConflictsResolveActivity;
 import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
@@ -109,4 +111,8 @@ abstract class ComponentsModule {
     @ContributesAndroidInjector abstract FileDetailFragment fileDetailFragment();
     @ContributesAndroidInjector abstract LocalFileListFragment localFileListFragment();
     @ContributesAndroidInjector abstract OCFileListFragment ocFileListFragment();
+
+    @ContributesAndroidInjector abstract BootupBroadcastReceiver bootupBroadcastReceiver();
+
+    @ContributesAndroidInjector abstract DocumentsStorageProvider documentsStorageProvider();
 }

+ 4 - 8
src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java

@@ -2,7 +2,9 @@
  * ownCloud Android client application
  *
  * @author David A. Velasco
+ * @author Chris Narkiewicz Chris Narkiewicz
  * Copyright (C) 2016 ownCloud Inc.
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -71,14 +73,8 @@ public final class AppPreferencesImpl implements AppPreferences {
     private final SharedPreferences preferences;
 
     public static AppPreferences fromContext(Context context) {
-        Context appContext = context.getApplicationContext();
-        SharedPreferences prefs = getDefaultSharedPreferences(appContext);
-
-        return new AppPreferencesImpl(appContext, prefs);
-    }
-
-    private static SharedPreferences getDefaultSharedPreferences(Context context) {
-        return android.preference.PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
+        SharedPreferences prefs = android.preference.PreferenceManager.getDefaultSharedPreferences(context);
+        return new AppPreferencesImpl(context, prefs);
     }
 
     AppPreferencesImpl(Context appContext, SharedPreferences preferences) {

+ 48 - 15
src/main/java/com/owncloud/android/MainApp.java

@@ -3,7 +3,9 @@
  *
  * @author masensio
  * @author David A. Velasco
+ * @author Chris Narkiewicz
  * Copyright (C) 2015 ownCloud Inc.
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -26,6 +28,8 @@ import android.app.Activity;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -40,6 +44,7 @@ import android.view.WindowManager;
 
 import com.evernote.android.job.JobManager;
 import com.evernote.android.job.JobRequest;
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.di.ActivityInjector;
 import com.nextcloud.client.di.DaggerAppComponent;
 import com.nextcloud.client.preferences.AppPreferences;
@@ -89,6 +94,8 @@ import androidx.multidex.MultiDexApplication;
 import dagger.android.AndroidInjector;
 import dagger.android.DispatchingAndroidInjector;
 import dagger.android.HasActivityInjector;
+import dagger.android.HasBroadcastReceiverInjector;
+import dagger.android.HasContentProviderInjector;
 import dagger.android.HasServiceInjector;
 import dagger.android.support.HasSupportFragmentInjector;
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -105,7 +112,9 @@ import static com.owncloud.android.ui.activity.ContactsPreferenceActivity.PREFER
 public class MainApp extends MultiDexApplication implements
     HasActivityInjector,
     HasSupportFragmentInjector,
-    HasServiceInjector {
+    HasServiceInjector,
+    HasContentProviderInjector,
+    HasBroadcastReceiverInjector {
 
     public static final OwnCloudVersion OUTDATED_SERVER_VERSION = OwnCloudVersion.nextcloud_14;
     public static final OwnCloudVersion MINIMUM_SUPPORTED_SERVER_VERSION = OwnCloudVersion.nextcloud_12;
@@ -137,24 +146,37 @@ public class MainApp extends MultiDexApplication implements
     @Inject
     DispatchingAndroidInjector<Service> dispatchingServiceInjector;
 
+    @Inject
+    DispatchingAndroidInjector<ContentProvider> dispatchingContentProviderInjector;
+
+    @Inject
+    DispatchingAndroidInjector<BroadcastReceiver> dispatchingBroadcastReceiverInjector;
+
+    @Inject
+    UserAccountManager accountManager;
+
     private PassCodeManager passCodeManager;
 
     @SuppressWarnings("unused")
     private boolean mBound;
 
-    @SuppressFBWarnings("ST")
     @Override
-    public void onCreate() {
-        super.onCreate();
-
+    protected void attachBaseContext(Context base) {
+        super.attachBaseContext(base);
         DaggerAppComponent.builder()
             .application(this)
             .build()
             .inject(this);
+    }
+
+    @SuppressFBWarnings("ST")
+    @Override
+    public void onCreate() {
+        super.onCreate();
 
         registerActivityLifecycleCallbacks(new ActivityInjector());
 
-        JobManager.create(this).addJobCreator(new NCJobCreator());
+        JobManager.create(this).addJobCreator(new NCJobCreator(getApplicationContext(), accountManager, preferences));
         MainApp.mContext = getApplicationContext();
 
         new SecurityUtils();
@@ -195,8 +217,8 @@ public class MainApp extends MultiDexApplication implements
             }
         }
 
-        initSyncOperations();
-        initContactsBackup();
+        initSyncOperations(accountManager);
+        initContactsBackup(accountManager);
         notificationChannels();
 
 
@@ -256,9 +278,9 @@ public class MainApp extends MultiDexApplication implements
         });
     }
 
-    public static void initContactsBackup() {
+    public static void initContactsBackup(UserAccountManager accountManager) {
         ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(mContext.getContentResolver());
-        Account[] accounts = AccountUtils.getAccounts(mContext);
+        Account[] accounts = accountManager.getAccounts();
 
         for (Account account : accounts) {
             if (arbitraryDataProvider.getBooleanValue(account, PREFERENCE_CONTACTS_AUTOMATIC_BACKUP)) {
@@ -320,7 +342,7 @@ public class MainApp extends MultiDexApplication implements
         }
     }
 
-    public static void initSyncOperations() {
+    public static void initSyncOperations(UserAccountManager accountManager) {
         updateToAutoUpload();
         cleanOldEntries();
         updateAutoUploadEntries();
@@ -338,17 +360,18 @@ public class MainApp extends MultiDexApplication implements
         initiateExistingAutoUploadEntries();
 
         FilesSyncHelper.scheduleFilesSyncIfNeeded(mContext);
-        FilesSyncHelper.restartJobsIfNeeded();
+        FilesSyncHelper.restartJobsIfNeeded(accountManager);
         FilesSyncHelper.scheduleOfflineSyncIfNeeded();
 
-        ReceiversHelper.registerNetworkChangeReceiver();
+        ReceiversHelper.registerNetworkChangeReceiver(accountManager);
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-            ReceiversHelper.registerPowerChangeReceiver();
+            ReceiversHelper.registerPowerChangeReceiver(accountManager
+            );
         }
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            ReceiversHelper.registerPowerSaveReceiver();
+            ReceiversHelper.registerPowerSaveReceiver(accountManager);
         }
     }
 
@@ -698,4 +721,14 @@ public class MainApp extends MultiDexApplication implements
     public AndroidInjector<Service> serviceInjector() {
         return dispatchingServiceInjector;
     }
+
+    @Override
+    public AndroidInjector<ContentProvider> contentProviderInjector() {
+        return dispatchingContentProviderInjector;
+    }
+
+    @Override
+    public AndroidInjector<BroadcastReceiver> broadcastReceiverInjector() {
+        return dispatchingBroadcastReceiverInjector;
+    }
 }

+ 1 - 150
src/main/java/com/owncloud/android/authentication/AccountUtils.java

@@ -103,7 +103,7 @@ public final class AccountUtils {
         return defaultAccount;
     }
 
-    public static Account[] getAccounts(Context context) {
+    private static Account[] getAccounts(Context context) {
         AccountManager accountManager = AccountManager.get(context);
         return accountManager.getAccountsByType(MainApp.getAccountType(context));
     }
@@ -131,20 +131,6 @@ public final class AccountUtils {
         return false;
     }
 
-    /**
-     * returns the user's name based on the account name.
-     *
-     * @param accountName the account name
-     * @return the user's name
-     */
-    public static String getAccountUsername(String accountName) {
-        if (accountName != null) {
-            return accountName.substring(0, accountName.lastIndexOf('@'));
-        } else {
-            return null;
-        }
-    }
-
     /**
      * Returns owncloud account identified by accountName or null if it does not exist.
      * @param context the context
@@ -212,141 +198,6 @@ public final class AccountUtils {
         return getServerVersion(account).isSearchSupported();
     }
 
-    /**
-     * Update the accounts in AccountManager to meet the current version of accounts expected by the app, if needed.
-     * <p>
-     * Introduced to handle a change in the structure of stored account names needed to allow different OC servers in
-     * the same domain, but not in the same path.
-     *
-     * @param context Used to access the AccountManager.
-     */
-    public static void updateAccountVersion(Context context) {
-        Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(context);
-        AccountManager accountMgr = AccountManager.get(context);
-
-        if (currentAccount != null) {
-            String currentAccountVersion = accountMgr.getUserData(currentAccount, Constants.KEY_OC_ACCOUNT_VERSION);
-
-            if (!String.valueOf(ACCOUNT_VERSION_WITH_PROPER_ID).equalsIgnoreCase(currentAccountVersion)) {
-                Log_OC.i(TAG, "Upgrading accounts to account version #" + ACCOUNT_VERSION_WITH_PROPER_ID);
-
-                Account[] ocAccounts = accountMgr.getAccountsByType(MainApp.getAccountType(context));
-                String serverUrl;
-                String username;
-                String displayName;
-                String newAccountName;
-                Account newAccount;
-                GetRemoteUserInfoOperation remoteUserNameOperation = new GetRemoteUserInfoOperation();
-
-                for (Account account : ocAccounts) {
-                    // build new account name
-                    serverUrl = accountMgr.getUserData(account, Constants.KEY_OC_BASE_URL);
-
-                    // update user name
-                    try {
-                        OwnCloudAccount ocAccount = new OwnCloudAccount(account, context);
-                        OwnCloudClient client = OwnCloudClientManagerFactory.getDefaultSingleton()
-                            .getClientFor(ocAccount, context);
-
-                        RemoteOperationResult result = remoteUserNameOperation.execute(client);
-
-                        if (result.isSuccess()) {
-                            UserInfo userInfo = (UserInfo) result.getData().get(0);
-                            username = userInfo.id;
-                            displayName = userInfo.displayName;
-                        } else {
-                            // skip account, try it next time
-                            Log_OC.e(TAG, "Error while getting username for account: " + account.name);
-                            continue;
-                        }
-                    } catch (Exception e) {
-                        Log_OC.e(TAG, "Error while getting username: " + e.getMessage());
-                        continue;
-                    }
-
-                    newAccountName = com.owncloud.android.lib.common.accounts.AccountUtils.
-                        buildAccountName(Uri.parse(serverUrl), username);
-
-                    // migrate to a new account, if needed
-                    if (!newAccountName.equals(account.name)) {
-                        newAccount = migrateAccount(context, currentAccount, accountMgr, serverUrl, newAccountName,
-                                                    account);
-
-                    } else {
-                        // servers which base URL is in the root of their domain need no change
-                        Log_OC.d(TAG, account.name + " needs no upgrade ");
-                        newAccount = account;
-                    }
-
-                    accountMgr.setUserData(newAccount, Constants.KEY_DISPLAY_NAME, displayName);
-                    accountMgr.setUserData(newAccount, Constants.KEY_USER_ID, username);
-
-                    // at least, upgrade account version
-                    Log_OC.d(TAG, "Setting version " + ACCOUNT_VERSION_WITH_PROPER_ID + " to " + newAccountName);
-                    accountMgr.setUserData(newAccount, Constants.KEY_OC_ACCOUNT_VERSION,
-                                           Integer.toString(ACCOUNT_VERSION_WITH_PROPER_ID));
-                }
-            }
-        }
-    }
-
-    @NonNull
-    private static Account migrateAccount(Context context, Account currentAccount, AccountManager accountMgr,
-                                          String serverUrl, String newAccountName, Account account) {
-
-        Log_OC.d(TAG, "Upgrading " + account.name + " to " + newAccountName);
-
-        // create the new account
-        Account newAccount = new Account(newAccountName, MainApp.getAccountType(context));
-        String password = accountMgr.getPassword(account);
-        accountMgr.addAccountExplicitly(newAccount, (password != null) ? password : "", null);
-
-        // copy base URL
-        accountMgr.setUserData(newAccount, Constants.KEY_OC_BASE_URL, serverUrl);
-
-        // copy server version
-        accountMgr.setUserData(
-            newAccount,
-            Constants.KEY_OC_VERSION,
-            accountMgr.getUserData(account, Constants.KEY_OC_VERSION)
-        );
-
-        // copy cookies
-        accountMgr.setUserData(
-            newAccount,
-            Constants.KEY_COOKIES,
-            accountMgr.getUserData(account, Constants.KEY_COOKIES)
-        );
-
-        // copy type of authentication
-        final String isSamlStr = accountMgr.getUserData(account, Constants.KEY_SUPPORTS_SAML_WEB_SSO);
-        if (Boolean.parseBoolean(isSamlStr)) {
-            accountMgr.setUserData(newAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO, "TRUE");
-        }
-
-        final String isOauthStr = accountMgr.getUserData(account, Constants.KEY_SUPPORTS_OAUTH2);
-        if (Boolean.parseBoolean(isOauthStr)) {
-            accountMgr.setUserData(newAccount, Constants.KEY_SUPPORTS_OAUTH2, "TRUE");
-        }
-
-        /* TODO - study if it's possible to run this method in a background thread to copy the authToken
-        if (isOAuth || isSaml) {
-            accountMgr.setAuthToken(newAccount, mAuthTokenType, mAuthToken);
-        }
-        */
-
-        // don't forget the account saved in preferences as the current one
-        if (currentAccount.name.equals(account.name)) {
-            AccountUtils.setCurrentOwnCloudAccount(context, newAccountName);
-        }
-
-        // remove the old account
-        accountMgr.removeAccount(account, null, null);
-
-        // will assume it succeeds, not a big deal otherwise
-        return newAccount;
-    }
-
     /**
      * Checks if an account owns the file (file's ownerId is the same as account name)
      * @param file File to check

+ 5 - 3
src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java

@@ -3,7 +3,9 @@
  *
  *   @author Tobias Kaminsky
  *   @author David A. Velasco
+ *   @author Chris Narkiewicz
  *   Copyright (C) 2015 ownCloud Inc.
+ *   Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -906,7 +908,7 @@ public final class ThumbnailsCacheManager {
                                 String newImageKey = "a_" + mUserId + "_" + mServerName + "_" + newETag;
                                 addBitmapToCache(newImageKey, avatar);
                             } else {
-                                return TextDrawable.createAvatar(mAccount.name, mAvatarRadius);
+                                return TextDrawable.createAvatar(mAccount, mAvatarRadius);
                             }
                             break;
 
@@ -923,7 +925,7 @@ public final class ThumbnailsCacheManager {
                     }
                 } catch (Exception e) {
                     try {
-                        return TextDrawable.createAvatar(mAccount.name, mAvatarRadius);
+                        return TextDrawable.createAvatar(mAccount, mAvatarRadius);
                     } catch (Exception e1) {
                         Log_OC.e(TAG, "Error generating fallback avatar");
                     }
@@ -936,7 +938,7 @@ public final class ThumbnailsCacheManager {
 
             if (avatar == null) {
                 try {
-                    return TextDrawable.createAvatar(mAccount.name, mAvatarRadius);
+                    return TextDrawable.createAvatar(mAccount, mAvatarRadius);
                 } catch (Exception e1) {
                     return mResources.getDrawable(R.drawable.ic_user);
                 }

+ 14 - 2
src/main/java/com/owncloud/android/files/BootupBroadcastReceiver.java

@@ -2,9 +2,11 @@
  * ownCloud Android client application
  *
  * @author David A. Velasco
+ * @author Chris Narkiewicz
  * Copyright (C) 2012 Bartek Przybylski
  * Copyright (C) 2015 ownCloud Inc.
  * Copyright (C) 2017 Mario Danic
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -25,9 +27,14 @@ import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.lib.common.utils.Log_OC;
 
+import javax.inject.Inject;
+
+import dagger.android.AndroidInjection;
+
 
 /**
  * App-registered receiver catching the broadcast intent reporting that the system was 
@@ -37,6 +44,9 @@ public class BootupBroadcastReceiver extends BroadcastReceiver {
 
     private static final String TAG = BootupBroadcastReceiver.class.getSimpleName();
 
+    @Inject
+    UserAccountManager accountManager;
+
     /**
      * Receives broadcast intent reporting that the system was just boot up.
      **
@@ -45,9 +55,11 @@ public class BootupBroadcastReceiver extends BroadcastReceiver {
      */
     @Override
     public void onReceive(Context context, Intent intent) {
+        AndroidInjection.inject(this, context);
+
         if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
-            MainApp.initSyncOperations();
-            MainApp.initContactsBackup();
+            MainApp.initSyncOperations(accountManager);
+            MainApp.initContactsBackup(accountManager);
         } else {
             Log_OC.d(TAG, "Getting wrong intent: " + intent.getAction());
         }

+ 15 - 4
src/main/java/com/owncloud/android/jobs/FilesSyncJob.java

@@ -2,8 +2,10 @@
  * Nextcloud Android client application
  *
  * @author Mario Danic
+ * @author Chris Narkiewicz
  * Copyright (C) 2017 Mario Danic
  * Copyright (C) 2017 Nextcloud
+ * Copyright (C) 2919 Chris Narkiewicz
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -31,7 +33,8 @@ import android.text.TextUtils;
 
 import com.evernote.android.job.Job;
 import com.evernote.android.job.util.support.PersistableBundleCompat;
-import com.nextcloud.client.preferences.AppPreferencesImpl;
+import com.nextcloud.client.account.UserAccountManager;
+import com.nextcloud.client.preferences.AppPreferences;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
@@ -72,6 +75,14 @@ public class FilesSyncJob extends Job {
     public static final String OVERRIDE_POWER_SAVING = "overridePowerSaving";
     private static final String WAKELOCK_TAG_SEPARATION = ":";
 
+    private UserAccountManager userAccountManager;
+    private AppPreferences preferences;
+
+    public FilesSyncJob(UserAccountManager userAccountManager, AppPreferences preferences) {
+        this.userAccountManager = userAccountManager;
+        this.preferences = preferences;
+    }
+
     @NonNull
     @Override
     protected Result onRunJob(@NonNull Params params) {
@@ -98,14 +109,14 @@ public class FilesSyncJob extends Job {
         boolean lightVersion = resources.getBoolean(R.bool.syncedFolder_light);
 
         final boolean skipCustom = bundle.getBoolean(SKIP_CUSTOM, false);
-        FilesSyncHelper.restartJobsIfNeeded();
-        FilesSyncHelper.insertAllDBEntries(skipCustom);
+        FilesSyncHelper.restartJobsIfNeeded(userAccountManager);
+        FilesSyncHelper.insertAllDBEntries(preferences, skipCustom);
 
         // Create all the providers we'll need
         final ContentResolver contentResolver = context.getContentResolver();
         final FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver);
         SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver,
-                                                                             AppPreferencesImpl.fromContext(context));
+                                                                             preferences);
 
         Locale currentLocale = context.getResources().getConfiguration().locale;
         SimpleDateFormat sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", currentLocale);

+ 9 - 2
src/main/java/com/owncloud/android/jobs/MediaFoldersDetectionJob.java

@@ -3,8 +3,10 @@
  *
  * @author Mario Danic
  * @author Andy Scherzinger
+ * @author Chris Narkiewicz
  * Copyright (C) 2018 Mario Danic
  * Copyright (C) 2018 Andy Scherzinger
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -36,10 +38,10 @@ import android.text.TextUtils;
 
 import com.evernote.android.job.Job;
 import com.google.gson.Gson;
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.client.preferences.AppPreferencesImpl;
 import com.owncloud.android.R;
-import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.MediaFolder;
 import com.owncloud.android.datamodel.MediaFoldersModel;
@@ -72,8 +74,13 @@ public class MediaFoldersDetectionJob extends Job {
 
     private static final String DISABLE_DETECTION_CLICK = "DISABLE_DETECTION_CLICK";
 
+    private UserAccountManager userAccountManager;
     private Random randomId = new Random();
 
+    MediaFoldersDetectionJob(UserAccountManager accountManager) {
+        this.userAccountManager = accountManager;
+    }
+
     @NonNull
     @Override
     protected Result onRunJob(@NonNull Params params) {
@@ -114,7 +121,7 @@ public class MediaFoldersDetectionJob extends Job {
                 videoMediaFolderPaths.removeAll(mediaFoldersModel.getVideoMediaFolders());
 
                 if (!imageMediaFolderPaths.isEmpty() || !videoMediaFolderPaths.isEmpty()) {
-                    Account[] accounts = AccountUtils.getAccounts(getContext());
+                    Account[] accounts = userAccountManager.getAccounts();
                     List<Account> accountList = new ArrayList<>();
                     for (Account account : accounts) {
                         if (!arbitraryDataProvider.getBooleanValue(account, ManageAccountsActivity.PENDING_FOR_REMOVAL)) {

+ 24 - 5
src/main/java/com/owncloud/android/jobs/NCJobCreator.java

@@ -2,8 +2,10 @@
  * Nextcloud Android client application
  *
  * @author Mario Danic
+ * @author Chris Narkiewicz
  * Copyright (C) 2017 Mario Danic
  * Copyright (C) 2017 Nextcloud GmbH
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  * <p>
  * 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
@@ -20,16 +22,33 @@
  */
 package com.owncloud.android.jobs;
 
+import android.content.Context;
+
 import com.evernote.android.job.Job;
 import com.evernote.android.job.JobCreator;
+import com.nextcloud.client.account.UserAccountManager;
+import com.nextcloud.client.preferences.AppPreferences;
+
+import androidx.annotation.NonNull;
 
 /**
  * Job creator for android-job
  */
 
 public class NCJobCreator implements JobCreator {
+
+    private final Context context;
+    private final UserAccountManager accountManager;
+    private final AppPreferences preferences;
+
+    public NCJobCreator(Context context, UserAccountManager accountManager, AppPreferences preferences) {
+        this.context = context;
+        this.accountManager = accountManager;
+        this.preferences = preferences;
+    }
+
     @Override
-    public Job create(String tag) {
+    public Job create(@NonNull String tag) {
         switch (tag) {
             case ContactsBackupJob.TAG:
                 return new ContactsBackupJob();
@@ -38,13 +57,13 @@ public class NCJobCreator implements JobCreator {
             case AccountRemovalJob.TAG:
                 return new AccountRemovalJob();
             case FilesSyncJob.TAG:
-                return new FilesSyncJob();
+                return new FilesSyncJob(accountManager, preferences);
             case OfflineSyncJob.TAG:
-                return new OfflineSyncJob();
+                return new OfflineSyncJob(accountManager);
             case NotificationJob.TAG:
-                return new NotificationJob();
+                return new NotificationJob(context, accountManager);
             case MediaFoldersDetectionJob.TAG:
-                return new MediaFoldersDetectionJob();
+                return new MediaFoldersDetectionJob(accountManager);
             default:
                 return null;
         }

+ 10 - 0
src/main/java/com/owncloud/android/jobs/NotificationJob.java

@@ -2,7 +2,9 @@
  * Nextcloud application
  *
  * @author Mario Danic
+ * @author Chris Narkiewicz
  * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,6 +40,7 @@ import android.util.Log;
 import com.evernote.android.job.Job;
 import com.evernote.android.job.util.support.PersistableBundleCompat;
 import com.google.gson.Gson;
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.DecryptedPushMessage;
@@ -92,6 +95,12 @@ public class NotificationJob extends Job {
 
     private SecureRandom randomId = new SecureRandom();
     private Context context;
+    private UserAccountManager accountManager;
+
+    public NotificationJob(final Context context, final UserAccountManager accountManager) {
+        this.context = context;
+        this.accountManager = accountManager;
+    }
 
     @NonNull
     @Override
@@ -109,6 +118,7 @@ public class NotificationJob extends Job {
 
                 try {
                     SignatureVerification signatureVerification = PushUtils.verifySignature(context,
+                                                                                            accountManager,
                                                                                             base64DecodedSignature,
                                                                                             base64DecodedSubject);
 

+ 9 - 1
src/main/java/com/owncloud/android/jobs/OfflineSyncJob.java

@@ -2,7 +2,9 @@
  * Nextcloud Android client application
  *
  * @author Mario Danic
+ * @author Chris Narkiewicz
  * Copyright (C) 2018 Mario Danic
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -28,6 +30,7 @@ import com.evernote.android.job.Job;
 import com.evernote.android.job.JobManager;
 import com.evernote.android.job.JobRequest;
 import com.evernote.android.job.util.Device;
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.FileDataStorageManager;
@@ -49,6 +52,11 @@ public class OfflineSyncJob extends Job {
     public static final String TAG = "OfflineSyncJob";
 
     private static final String WAKELOCK_TAG_SEPARATION = ":";
+    private UserAccountManager userAccountManager;
+
+    public OfflineSyncJob(UserAccountManager userAccountManager) {
+        this.userAccountManager = userAccountManager;
+    }
 
     @NonNull
     @Override
@@ -76,7 +84,7 @@ public class OfflineSyncJob extends Job {
                 }
             }
 
-            Account[] accounts = AccountUtils.getAccounts(context);
+            Account[] accounts = userAccountManager.getAccounts();
 
             for (Account account : accounts) {
                 FileDataStorageManager storageManager = new FileDataStorageManager(account,

+ 14 - 2
src/main/java/com/owncloud/android/providers/DocumentsStorageProvider.java

@@ -2,7 +2,9 @@
  *   Nextcloud Android client application
  *
  *   @author Bartosz Przybylski
+ *   @author Chris Narkiewicz
  *   Copyright (C) 2016  Bartosz Przybylski <bart.p.pl@gmail.com>
+ *   Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -43,6 +45,7 @@ import android.widget.Toast;
 
 import com.evernote.android.job.JobRequest;
 import com.evernote.android.job.util.Device;
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.client.preferences.AppPreferencesImpl;
 import com.owncloud.android.MainApp;
@@ -82,6 +85,10 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.inject.Inject;
+
+import dagger.android.AndroidInjection;
+
 @TargetApi(Build.VERSION_CODES.KITKAT)
 public class DocumentsStorageProvider extends DocumentsProvider {
 
@@ -91,6 +98,10 @@ public class DocumentsStorageProvider extends DocumentsProvider {
     private Map<Long, FileDataStorageManager> rootIdToStorageManager;
     private OwnCloudClient client;
 
+    @Inject UserAccountManager accountManager;
+
+
+
     @Override
     public Cursor queryRoots(String[] projection) throws FileNotFoundException {
         Context context = MainApp.getAppContext();
@@ -104,7 +115,7 @@ public class DocumentsStorageProvider extends DocumentsProvider {
 
         final RootCursor result = new RootCursor(projection);
 
-        for (Account account : AccountUtils.getAccounts(getContext())) {
+        for (Account account : accountManager.getAccounts()) {
             result.addRoot(account, getContext());
         }
 
@@ -288,6 +299,7 @@ public class DocumentsStorageProvider extends DocumentsProvider {
 
     @Override
     public boolean onCreate() {
+        AndroidInjection.inject(this);
         return true;
     }
 
@@ -587,7 +599,7 @@ public class DocumentsStorageProvider extends DocumentsProvider {
 
         ContentResolver contentResolver = context.getContentResolver();
 
-        for (Account account : AccountUtils.getAccounts(getContext())) {
+        for (Account account : accountManager.getAccounts()) {
             final FileDataStorageManager storageManager = new FileDataStorageManager(account, contentResolver);
             final OCFile rootDir = storageManager.getFileByPath("/");
             rootIdToStorageManager.put(rootDir.getFileId(), storageManager);

+ 7 - 3
src/main/java/com/owncloud/android/ui/TextDrawable.java

@@ -3,8 +3,10 @@
  *
  * @author Andy Scherzinger
  * @author Tobias Kaminsiky
+ * @author Chris Narkiewicz
  * Copyright (C) 2016 ownCloud Inc.
  * Copyright (C) 2018 Andy Scherzinger
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -21,6 +23,7 @@
 
 package com.owncloud.android.ui;
 
+import android.accounts.Account;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
@@ -28,6 +31,7 @@ import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
 
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.utils.BitmapUtils;
 import com.owncloud.android.utils.NextcloudServer;
@@ -91,7 +95,7 @@ public class TextDrawable extends Drawable {
      * creates an avatar in form of a TextDrawable with the first letter of the account name in a circle with the
      * given radius.
      *
-     * @param accountName the account name
+     * @param account user account
      * @param radiusInDp  the circle's radius
      * @return the avatar as a TextDrawable
      * @throws UnsupportedEncodingException if the charset is not supported when calculating the color values
@@ -99,9 +103,9 @@ public class TextDrawable extends Drawable {
      */
     @NonNull
     @NextcloudServer(max = 12)
-    public static TextDrawable createAvatar(String accountName, float radiusInDp) throws
+    public static TextDrawable createAvatar(Account account, float radiusInDp) throws
             NoSuchAlgorithmException {
-        String username = AccountUtils.getAccountUsername(accountName);
+        String username = UserAccountManager.getUsername(account);
         return createNamedAvatar(username, radiusInDp);
     }
 

+ 5 - 2
src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java

@@ -3,10 +3,12 @@
  *
  * @author Andy Scherzinger
  * @author Tobias Kaminsky
+ * @author Chris Narkiewicz
  * Copyright (C) 2016 Andy Scherzinger
  * Copyright (C) 2017 Tobias Kaminsky
  * Copyright (C) 2016 Nextcloud
  * Copyright (C) 2016 ownCloud Inc.
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -54,6 +56,7 @@ import com.bumptech.glide.Glide;
 import com.bumptech.glide.request.animation.GlideAnimation;
 import com.bumptech.glide.request.target.SimpleTarget;
 import com.google.android.material.navigation.NavigationView;
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.owncloud.android.MainApp;
@@ -704,7 +707,7 @@ public abstract class DrawerActivity extends ToolbarActivity
                             Menu.NONE,
                             MENU_ORDER_ACCOUNT,
                             account.name)
-                            .setIcon(TextDrawable.createAvatar(account.name, mMenuAccountAvatarRadiusDimension));
+                            .setIcon(TextDrawable.createAvatar(account, mMenuAccountAvatarRadiusDimension));
                     DisplayUtils.setAvatar(account, this, mMenuAccountAvatarRadiusDimension, getResources(),
                             accountMenuItem, this);
                 }
@@ -771,7 +774,7 @@ public abstract class DrawerActivity extends ToolbarActivity
                 username.setTextColor(ThemeUtils.fontColor(this));
             } catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
                 Log_OC.w(TAG, "Couldn't read display name of account fallback to account name");
-                username.setText(AccountUtils.getAccountUsername(account.name));
+                username.setText(UserAccountManager.getUsername(account));
             }
 
             View currentAccountView = findNavigationViewChildById(R.id.drawer_current_account);

+ 7 - 2
src/main/java/com/owncloud/android/ui/activity/FileActivity.java

@@ -2,8 +2,10 @@
  *   ownCloud Android client application
  *
  *   @author David A. Velasco
+ *   @author Chris Narkiewicz
  *   Copyright (C) 2011  Bartek Przybylski
  *   Copyright (C) 2016 ownCloud Inc.
+ *   Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -37,6 +39,7 @@ import android.os.IBinder;
 import android.view.View;
 
 import com.google.android.material.snackbar.Snackbar;
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
@@ -78,6 +81,8 @@ import com.owncloud.android.utils.ErrorMessageAdapter;
 import com.owncloud.android.utils.FilesSyncHelper;
 import com.owncloud.android.utils.ThemeUtils;
 
+import javax.inject.Inject;
+
 import androidx.fragment.app.DialogFragment;
 import androidx.fragment.app.Fragment;
 import androidx.fragment.app.FragmentManager;
@@ -136,7 +141,7 @@ public abstract class FileActivity extends DrawerActivity
     private ServiceConnection mDownloadServiceConnection;
     private ServiceConnection mUploadServiceConnection;
 
-
+    @Inject UserAccountManager accountManager;
 
     @Override
     public void showFiles(boolean onDeviceOnly) {
@@ -174,7 +179,7 @@ public abstract class FileActivity extends DrawerActivity
 
         Thread t = new Thread(() -> {
             // best place, before any access to AccountManager or database
-            AccountUtils.updateAccountVersion(this);
+            accountManager.updateAccountVersion();
         });
         t.start();
 

+ 7 - 4
src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.java

@@ -4,9 +4,11 @@
  * @author Bartek Przybylski
  * @author David A. Velasco
  * @author Andy Scherzinger
+ * @author Chris Narkiewicz
  * Copyright (C) 2011  Bartek Przybylski
  * Copyright (C) 2016 ownCloud Inc.
  * Copyright (C) 2018 Andy Scherzinger
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -56,6 +58,7 @@ import android.widget.ImageView;
 
 import com.google.android.material.bottomnavigation.BottomNavigationView;
 import com.google.android.material.snackbar.Snackbar;
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.di.Injectable;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
@@ -210,8 +213,8 @@ public class FileDisplayActivity extends FileActivity
     private boolean searchOpen;
 
     private SearchView searchView;
-    @Inject
-    AppPreferences preferences;
+    @Inject AppPreferences preferences;
+    @Inject UserAccountManager accountManager;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -2567,9 +2570,9 @@ public class FileDisplayActivity extends FileActivity
     @Subscribe(threadMode = ThreadMode.BACKGROUND)
     public void onMessageEvent(TokenPushEvent event) {
         if (!preferences.isKeysReInitEnabled()) {
-            PushUtils.reinitKeys();
+            PushUtils.reinitKeys(accountManager);
         } else {
-            PushUtils.pushRegistrationToServer(preferences.getPushToken());
+            PushUtils.pushRegistrationToServer(accountManager, preferences.getPushToken());
         }
     }
 

+ 6 - 1
src/main/java/com/owncloud/android/ui/activity/FirstRunActivity.java

@@ -2,9 +2,11 @@
  * Nextcloud Android client application
  *
  * @author Bartosz Przybylski
+ * @author Chris Narkiewicz
  * Copyright (C) 2015 Bartosz Przybylski
  * Copyright (C) 2015 ownCloud Inc.
  * Copyright (C) 2016 Nextcloud.
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -37,6 +39,7 @@ import android.widget.LinearLayout;
 import android.widget.TextView;
 import androidx.viewpager.widget.ViewPager;
 
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.owncloud.android.MainApp;
@@ -60,6 +63,8 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
     public static final int FIRST_RUN_RESULT_CODE = 199;
 
     private ProgressIndicator progressIndicator;
+
+    @Inject UserAccountManager userAccountManager;
     @Inject AppPreferences preferences;
 
     @Override
@@ -112,7 +117,7 @@ public class FirstRunActivity extends BaseActivity implements ViewPager.OnPageCh
         if (isFirstRun(this)) {
             AccountManager am = (AccountManager) getSystemService(ACCOUNT_SERVICE);
             if (am != null) {
-                for (Account account : AccountUtils.getAccounts(this)) {
+                for (Account account : userAccountManager.getAccounts()) {
                     am.removeAccount(account, null, null);
                 }
             }

+ 4 - 1
src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java

@@ -3,9 +3,11 @@
  *
  *   @author Bartek Przybylski
  *   @author David A. Velasco
+ *   @author Chris Narkiewicz
  *   Copyright (C) 2011  Bartek Przybylski
  *   Copyright (C) 2016 ownCloud Inc.
  *   Copyright (C) 2016 Nextcloud
+ *   Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  *   This program is free software: you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License version 2,
@@ -55,6 +57,7 @@ import androidx.appcompat.app.AlertDialog;
 import androidx.appcompat.app.AppCompatDelegate;
 import androidx.core.content.res.ResourcesCompat;
 
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.client.preferences.AppPreferencesImpl;
@@ -751,7 +754,7 @@ public class SettingsActivity extends PreferenceActivity
             if (serverBaseUri != null) {
                 davDroidLoginIntent.putExtra("url", serverBaseUri.toString() + DAV_PATH);
             }
-            davDroidLoginIntent.putExtra("username", AccountUtils.getAccountUsername(account.name));
+            davDroidLoginIntent.putExtra("username", UserAccountManager.getUsername(account));
             startActivityForResult(davDroidLoginIntent, ACTION_REQUEST_CODE_DAVDROID_SETUP);
         } else {
             // DAVdroid not installed

+ 8 - 2
src/main/java/com/owncloud/android/ui/activity/UploadListActivity.java

@@ -2,8 +2,10 @@
  * Nextcloud Android client application
  *
  * @author Tobias Kaminsky
+ * @author Chris Narkiewicz
  * Copyright (C) 2018 Tobias Kaminsky
  * Copyright (C) 2018 Nextcloud
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -42,6 +44,7 @@ import com.evernote.android.job.JobManager;
 import com.evernote.android.job.JobRequest;
 import com.evernote.android.job.util.support.PersistableBundleCompat;
 import com.google.android.material.bottomnavigation.BottomNavigationView;
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.UploadsStorageManager;
 import com.owncloud.android.files.services.FileUploader;
@@ -60,6 +63,8 @@ import com.owncloud.android.utils.ThemeUtils;
 
 import java.util.Set;
 
+import javax.inject.Inject;
+
 import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
 import butterknife.BindString;
@@ -103,6 +108,7 @@ public class UploadListActivity extends FileActivity {
     public String noResultsMessage;
 
     private Unbinder unbinder;
+    @Inject UserAccountManager userAccountManager;
 
     @Override
     public void showFiles(boolean onDeviceOnly) {
@@ -275,7 +281,7 @@ public class UploadListActivity extends FileActivity {
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
         if (requestCode == FileActivity.REQUEST_CODE__UPDATE_CREDENTIALS && resultCode == RESULT_OK) {
-            FilesSyncHelper.restartJobsIfNeeded();
+            FilesSyncHelper.restartJobsIfNeeded(userAccountManager);
         }
     }
 
@@ -295,7 +301,7 @@ public class UploadListActivity extends FileActivity {
 
             } else {
                 // already updated -> just retry!
-                FilesSyncHelper.restartJobsIfNeeded();
+                FilesSyncHelper.restartJobsIfNeeded(userAccountManager);
             }
 
         } else {

+ 5 - 1
src/main/java/com/owncloud/android/ui/activity/UserInfoActivity.java

@@ -3,9 +3,11 @@
  *
  * @author Mario Danic
  * @author Andy Scherzinger
+ * @author Chris Narkiewicz
  * Copyright (C) 2017 Mario Danic
  * Copyright (C) 2017 Andy Scherzinger
  * Copyright (C) 2017 Nextcloud GmbH.
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * 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
@@ -51,6 +53,7 @@ import com.bumptech.glide.Glide;
 import com.bumptech.glide.request.animation.GlideAnimation;
 import com.bumptech.glide.request.target.SimpleTarget;
 import com.google.gson.Gson;
+import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.preferences.AppPreferences;
 import com.owncloud.android.R;
@@ -117,6 +120,7 @@ public class UserInfoActivity extends FileActivity implements Injectable {
     @BindString(R.string.user_information_retrieval_error) protected String sorryMessage;
 
     @Inject AppPreferences preferences;
+    @Inject UserAccountManager accountManager;
     private float mCurrentAccountAvatarRadiusDimension;
 
     private Unbinder unbinder;
@@ -443,7 +447,7 @@ public class UserInfoActivity extends FileActivity implements Injectable {
 
     @Subscribe(threadMode = ThreadMode.BACKGROUND)
     public void onMessageEvent(TokenPushEvent event) {
-        PushUtils.pushRegistrationToServer(preferences.getPushToken());
+        PushUtils.pushRegistrationToServer(accountManager, preferences.getPushToken());
     }
 
 

+ 4 - 1
src/main/java/com/owncloud/android/ui/adapter/AccountListAdapter.java

@@ -2,7 +2,9 @@
  * ownCloud Android client application
  *
  * @author Andy Scherzinger
+ * @author Chris Narkiewicz
  * Copyright (C) 2016 ownCloud Inc.
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  * <p/>
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -29,6 +31,7 @@ import android.widget.ArrayAdapter;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.lib.common.OwnCloudAccount;
@@ -173,7 +176,7 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements
             viewHolder.usernameViewItem.setText(oca.getDisplayName());
         } catch (Exception e) {
             Log_OC.w(TAG, "Account not found right after being read; using account name instead");
-            viewHolder.usernameViewItem.setText(AccountUtils.getAccountUsername(account.name));
+            viewHolder.usernameViewItem.setText(UserAccountManager.getUsername(account));
         }
         viewHolder.usernameViewItem.setTag(account.name);
     }

+ 8 - 6
src/main/java/com/owncloud/android/utils/FilesSyncHelper.java

@@ -2,8 +2,10 @@
  * Nextcloud Android client application
  *
  * @author Mario Danic
+ * @author Chris Narkiewicz
  * Copyright (C) 2017 Mario Danic
  * Copyright (C) 2017 Nextcloud
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -36,9 +38,9 @@ import android.util.Log;
 import com.evernote.android.job.JobManager;
 import com.evernote.android.job.JobRequest;
 import com.evernote.android.job.util.Device;
-import com.nextcloud.client.preferences.AppPreferencesImpl;
+import com.nextcloud.client.account.UserAccountManager;
+import com.nextcloud.client.preferences.AppPreferences;
 import com.owncloud.android.MainApp;
-import com.owncloud.android.authentication.AccountUtils;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.FilesystemDataProvider;
 import com.owncloud.android.datamodel.MediaFolderType;
@@ -155,11 +157,11 @@ public final class FilesSyncHelper {
         }
     }
 
-    public static void insertAllDBEntries(boolean skipCustom) {
+    public static void insertAllDBEntries(AppPreferences preferences, boolean skipCustom) {
         final Context context = MainApp.getAppContext();
         final ContentResolver contentResolver = context.getContentResolver();
         SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver,
-                                                                             AppPreferencesImpl.fromContext(context));
+                                                                             preferences);
 
         for (SyncedFolder syncedFolder : syncedFolderProvider.getSyncedFolders()) {
             if (syncedFolder.isEnabled() && (MediaFolderType.CUSTOM != syncedFolder.getType() || !skipCustom)) {
@@ -212,7 +214,7 @@ public final class FilesSyncHelper {
         }
     }
 
-    public static void restartJobsIfNeeded() {
+    public static void restartJobsIfNeeded(UserAccountManager accountManager) {
         final Context context = MainApp.getAppContext();
 
         FileUploader.UploadRequester uploadRequester = new FileUploader.UploadRequester();
@@ -226,7 +228,7 @@ public final class FilesSyncHelper {
             accountExists = false;
 
             // check if accounts still exists
-            for (Account account : AccountUtils.getAccounts(context)) {
+            for (Account account : accountManager.getAccounts()) {
                 if (account.name.equals(failedUpload.getAccountName())) {
                     accountExists = true;
                     break;

+ 10 - 7
src/main/java/com/owncloud/android/utils/ReceiversHelper.java

@@ -1,9 +1,11 @@
-/**
+/*
  * Nextcloud Android client application
  *
  * @author Mario Danic
+ * @author Chris Narkiewicz
  * Copyright (C) 2017 Mario Danic
  * Copyright (C) 2017 Nextcloud
+ * Copyright (C) 2019 Chris Narkiewicz <hello@ezaquarii.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -27,6 +29,7 @@ import android.content.IntentFilter;
 
 import com.evernote.android.job.JobRequest;
 import com.evernote.android.job.util.Device;
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.MainApp;
 
 /**
@@ -38,7 +41,7 @@ public final class ReceiversHelper {
         // utility class -> private constructor
     }
 
-    public static void registerNetworkChangeReceiver() {
+    public static void registerNetworkChangeReceiver(final UserAccountManager accountManager) {
         Context context = MainApp.getAppContext();
 
         IntentFilter intentFilter = new IntentFilter();
@@ -49,7 +52,7 @@ public final class ReceiversHelper {
             @Override
             public void onReceive(Context context, Intent intent) {
                 if (!Device.getNetworkType(context).equals(JobRequest.NetworkType.ANY)) {
-                    FilesSyncHelper.restartJobsIfNeeded();
+                    FilesSyncHelper.restartJobsIfNeeded(accountManager);
                 }
             }
         };
@@ -57,7 +60,7 @@ public final class ReceiversHelper {
         context.registerReceiver(broadcastReceiver, intentFilter);
     }
 
-    public static void registerPowerChangeReceiver() {
+    public static void registerPowerChangeReceiver(final UserAccountManager accountManager) {
         Context context = MainApp.getAppContext();
 
         IntentFilter intentFilter = new IntentFilter();
@@ -68,7 +71,7 @@ public final class ReceiversHelper {
             @Override
             public void onReceive(Context context, Intent intent) {
                 if (Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())) {
-                    FilesSyncHelper.restartJobsIfNeeded();
+                    FilesSyncHelper.restartJobsIfNeeded(accountManager);
                 }
             }
         };
@@ -76,7 +79,7 @@ public final class ReceiversHelper {
         context.registerReceiver(broadcastReceiver, intentFilter);
     }
 
-    public static void registerPowerSaveReceiver() {
+    public static void registerPowerSaveReceiver(final UserAccountManager accountManager) {
         Context context = MainApp.getAppContext();
 
         IntentFilter intentFilter = new IntentFilter();
@@ -86,7 +89,7 @@ public final class ReceiversHelper {
             @Override
             public void onReceive(Context context, Intent intent) {
                 if (!PowerUtils.isPowerSaveMode(context)) {
-                    FilesSyncHelper.restartJobsIfNeeded();
+                    FilesSyncHelper.restartJobsIfNeeded(accountManager);
                 }
             }
         };

+ 26 - 0
src/versionDev/java/com/nextcloud/client/di/VariantComponentsModule.java

@@ -0,0 +1,26 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Chris Narkiewicz
+ * Copyright (C) 2919 Chris Narkiewicz <hello@ezaquarii.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or 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.nextcloud.client.di;
+
+import dagger.Module;
+
+@Module
+abstract class VariantComponentsModule {
+}

+ 13 - 3
src/versionDev/java/com/owncloud/android/utils/PushUtils.java

@@ -2,7 +2,9 @@
  * Nextcloud Android client application
  *
  * @author Mario Danic
+ * @author Chris Narkiewicz
  * Copyright (C) 2017 Mario Danic
+ * Copyright (C) 2019 Chris Narkiewicz
  *
  * 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
@@ -22,6 +24,7 @@ package com.owncloud.android.utils;
 
 import android.content.Context;
 
+import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.SignatureVerification;
 import com.nextcloud.client.preferences.AppPreferencesImpl;
@@ -34,11 +37,14 @@ public final class PushUtils {
     private PushUtils() {
     }
 
-    public static void pushRegistrationToServer(final String pushToken) {
+    public static void pushRegistrationToServer(
+        final UserAccountManager accountManager,
+        final String pushToken)
+    {
         // do nothing
     }
 
-    public static void reinitKeys() {
+    public static void reinitKeys(final UserAccountManager accountManager) {
         Context context = MainApp.getAppContext();
         AppPreferencesImpl.fromContext(context).setKeysReInitEnabled();
     }
@@ -47,7 +53,11 @@ public final class PushUtils {
         return null;
     }
 
-    public static SignatureVerification verifySignature(Context context, byte[] signatureBytes, byte[] subjectBytes) {
+    public static SignatureVerification verifySignature(
+        final Context context,
+        final UserAccountManager accountManager,
+        final byte[] signatureBytes, final byte[] subjectBytes
+    ) {
         return null;
     }
 }