Przeglądaj źródła

Extract interface from ArbitraryDataProvider for better decoupling and testing

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
Álvaro Brey 2 lat temu
rodzic
commit
f490823e4e
33 zmienionych plików z 144 dodań i 58 usunięć
  1. 2 1
      app/src/androidTest/java/com/nextcloud/client/EndToEndRandomIT.java
  2. 2 2
      app/src/androidTest/java/com/nextcloud/client/SettingsActivityIT.kt
  3. 1 1
      app/src/androidTest/java/com/owncloud/android/datamodel/ArbitraryDataProviderIT.kt
  4. 4 3
      app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.java
  5. 9 2
      app/src/debug/java/com/nextcloud/client/TestActivity.kt
  6. 4 3
      app/src/gplay/java/com/owncloud/android/utils/PushUtils.java
  7. 2 1
      app/src/main/java/com/nextcloud/client/account/UserAccountManagerImpl.java
  8. 2 4
      app/src/main/java/com/nextcloud/client/di/AppModule.java
  9. 2 1
      app/src/main/java/com/nextcloud/client/jobs/AccountRemovalWork.kt
  10. 0 1
      app/src/main/java/com/nextcloud/client/jobs/ContactsBackupWork.kt
  11. 3 2
      app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt
  12. 2 1
      app/src/main/java/com/nextcloud/client/jobs/MediaFoldersDetectionWork.kt
  13. 5 4
      app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java
  14. 2 1
      app/src/main/java/com/owncloud/android/MainApp.java
  15. 47 0
      app/src/main/java/com/owncloud/android/datamodel/ArbitraryDataProvider.kt
  16. 19 9
      app/src/main/java/com/owncloud/android/datamodel/ArbitraryDataProviderImpl.java
  17. 1 1
      app/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
  18. 2 1
      app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java
  19. 2 1
      app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java
  20. 2 1
      app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.java
  21. 2 1
      app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java
  22. 2 1
      app/src/main/java/com/owncloud/android/providers/UsersAndGroupsSearchProvider.java
  23. 2 2
      app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
  24. 2 1
      app/src/main/java/com/owncloud/android/ui/activity/FileActivity.java
  25. 3 2
      app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java
  26. 2 1
      app/src/main/java/com/owncloud/android/ui/activity/NotificationsActivity.java
  27. 3 2
      app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java
  28. 5 3
      app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt
  29. 2 1
      app/src/main/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragment.java
  30. 2 1
      app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java
  31. 2 1
      app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java
  32. 2 1
      app/src/main/java/com/owncloud/android/utils/DisplayUtils.java
  33. 2 1
      app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java

+ 2 - 1
app/src/androidTest/java/com/nextcloud/client/EndToEndRandomIT.java

@@ -27,6 +27,7 @@ import android.accounts.AccountManager;
 import com.nextcloud.test.RandomStringGenerator;
 import com.owncloud.android.AbstractOnServerIT;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.db.OCUpload;
 import com.owncloud.android.files.services.FileUploader;
@@ -93,7 +94,7 @@ public class EndToEndRandomIT extends AbstractOnServerIT {
 
     @BeforeClass
     public static void initClass() throws Exception {
-        arbitraryDataProvider = new ArbitraryDataProvider(targetContext.getContentResolver());
+        arbitraryDataProvider = new ArbitraryDataProviderImpl(targetContext);
         createKeys();
     }
 

+ 2 - 2
app/src/androidTest/java/com/nextcloud/client/SettingsActivityIT.kt

@@ -26,7 +26,7 @@ import android.content.Intent
 import android.os.Looper
 import androidx.test.espresso.intent.rule.IntentsTestRule
 import com.owncloud.android.AbstractIT
-import com.owncloud.android.datamodel.ArbitraryDataProvider
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
 import com.owncloud.android.ui.activity.RequestCredentialsActivity
 import com.owncloud.android.ui.activity.SettingsActivity
 import com.owncloud.android.utils.EncryptionUtils
@@ -71,7 +71,7 @@ class SettingsActivityIT : AbstractIT() {
         }
         val intent = Intent()
         intent.putExtra(RequestCredentialsActivity.KEY_CHECK_RESULT, RequestCredentialsActivity.KEY_CHECK_RESULT_TRUE)
-        val arbitraryDataProvider = ArbitraryDataProvider(targetContext.contentResolver)
+        val arbitraryDataProvider = ArbitraryDataProviderImpl(targetContext)
         arbitraryDataProvider.storeOrUpdateKeyValue(user.accountName, EncryptionUtils.MNEMONIC, "Secret mnemonic")
         val sut = activityRule.launchActivity(null)
         sut.runOnUiThread {

+ 1 - 1
app/src/androidTest/java/com/owncloud/android/datamodel/ArbitraryDataProviderIT.kt

@@ -26,7 +26,7 @@ import org.junit.Assert.assertEquals
 import org.junit.Test
 
 class ArbitraryDataProviderIT : AbstractIT() {
-    private val arbitraryDataProvider = ArbitraryDataProvider(targetContext.contentResolver)
+    private val arbitraryDataProvider = ArbitraryDataProviderImpl(targetContext)
 
     @Test
     fun testNull() {

+ 4 - 3
app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.java

@@ -48,6 +48,7 @@ import com.nextcloud.ui.fileactions.FileActionsBottomSheet;
 import com.owncloud.android.AbstractIT;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.Creator;
@@ -390,9 +391,9 @@ public class DialogFragmentIT extends AbstractIT {
 
         String json = new Gson().toJson(directEditing);
 
-        new ArbitraryDataProvider(targetContext.getContentResolver()).storeOrUpdateKeyValue(user.getAccountName(),
-                                                                                            ArbitraryDataProvider.DIRECT_EDITING,
-                                                                                            json);
+        new ArbitraryDataProviderImpl(targetContext).storeOrUpdateKeyValue(user.getAccountName(),
+                                                                                                ArbitraryDataProvider.DIRECT_EDITING,
+                                                                                                json);
 
         // activate templates
         OCCapability capability = fda.getCapabilities();

+ 9 - 2
app/src/debug/java/com/nextcloud/client/TestActivity.kt

@@ -30,7 +30,7 @@ import com.nextcloud.client.network.ConnectivityService
 import com.nextcloud.utils.EditorUtils
 import com.owncloud.android.R
 import com.owncloud.android.databinding.TestLayoutBinding
-import com.owncloud.android.datamodel.ArbitraryDataProvider
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
 import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.files.services.FileDownloader
@@ -146,7 +146,14 @@ class TestActivity :
 
     override fun getFileOperationsHelper(): FileOperationsHelper {
         if (!this::fileOperation.isInitialized) {
-            fileOperation = FileOperationsHelper(this, userAccountManager, connectivityServiceMock, EditorUtils(ArbitraryDataProvider(baseContext)))
+            fileOperation = FileOperationsHelper(
+                this,
+                userAccountManager,
+                connectivityServiceMock,
+                EditorUtils(
+                    ArbitraryDataProviderImpl(baseContext)
+                )
+            )
         }
 
         return fileOperation

+ 4 - 3
app/src/gplay/java/com/owncloud/android/utils/PushUtils.java

@@ -38,6 +38,7 @@ import com.nextcloud.client.preferences.AppPreferencesImpl;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.PushConfigurationState;
 import com.owncloud.android.datamodel.SignatureVerification;
 import com.owncloud.android.lib.common.OwnCloudAccount;
@@ -151,7 +152,7 @@ public final class PushUtils {
     private static void deleteRegistrationForAccount(Account account) {
         Context context = MainApp.getAppContext();
         OwnCloudAccount ocAccount;
-        arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext());
+        arbitraryDataProvider = new ArbitraryDataProviderImpl(MainApp.getAppContext());
 
         try {
             ocAccount = new OwnCloudAccount(account, context);
@@ -193,7 +194,7 @@ public final class PushUtils {
     }
 
     public static void pushRegistrationToServer(final UserAccountManager accountManager, final String token) {
-        arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext());
+        arbitraryDataProvider = new ArbitraryDataProviderImpl(MainApp.getAppContext());
 
         if (!TextUtils.isEmpty(MainApp.getAppContext().getResources().getString(R.string.push_server_url)) &&
                 !TextUtils.isEmpty(token)) {
@@ -418,7 +419,7 @@ public final class PushUtils {
 
         Account[] accounts = accountManager.getAccounts();
 
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(context);
         String arbitraryValue;
         Gson gson = new Gson();
         PushConfigurationState pushArbitraryData;

+ 2 - 1
app/src/main/java/com/nextcloud/client/account/UserAccountManagerImpl.java

@@ -38,6 +38,7 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.OwnCloudAccount;
 import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
@@ -148,7 +149,7 @@ public class UserAccountManagerImpl implements UserAccountManager {
         Account[] ocAccounts = getAccounts();
         Account defaultAccount = null;
 
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(context);
 
         SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(context);
         String accountName = appPreferences.getString(PREF_SELECT_OC_ACCOUNT, null);

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

@@ -39,7 +39,6 @@ import com.nextcloud.client.core.AsyncRunner;
 import com.nextcloud.client.core.Clock;
 import com.nextcloud.client.core.ClockImpl;
 import com.nextcloud.client.core.ThreadPoolAsyncRunner;
-import com.nextcloud.client.database.NextcloudDatabase;
 import com.nextcloud.client.database.dao.ArbitraryDataDao;
 import com.nextcloud.client.device.DeviceInfo;
 import com.nextcloud.client.logger.FileLogHandler;
@@ -57,9 +56,9 @@ import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.client.utils.Throttler;
 import com.owncloud.android.authentication.PassCodeManager;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.UploadsStorageManager;
-import com.owncloud.android.db.ProviderMeta;
 import com.owncloud.android.ui.activities.data.activities.ActivitiesRepository;
 import com.owncloud.android.ui.activities.data.activities.ActivitiesServiceApi;
 import com.owncloud.android.ui.activities.data.activities.ActivitiesServiceApiImpl;
@@ -78,7 +77,6 @@ import javax.inject.Provider;
 import javax.inject.Singleton;
 
 import androidx.localbroadcastmanager.content.LocalBroadcastManager;
-import androidx.room.Room;
 import dagger.Module;
 import dagger.Provides;
 
@@ -120,7 +118,7 @@ class AppModule {
 
     @Provides
     ArbitraryDataProvider arbitraryDataProvider(ArbitraryDataDao dao) {
-        return new ArbitraryDataProvider(dao);
+        return new ArbitraryDataProviderImpl(dao);
     }
 
     @Provides

+ 2 - 1
app/src/main/java/com/nextcloud/client/jobs/AccountRemovalWork.kt

@@ -38,6 +38,7 @@ import com.nextcloud.java.util.Optional
 import com.owncloud.android.MainApp
 import com.owncloud.android.R
 import com.owncloud.android.datamodel.ArbitraryDataProvider
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
 import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.datamodel.FilesystemDataProvider
 import com.owncloud.android.datamodel.PushConfigurationState
@@ -88,7 +89,7 @@ class AccountRemovalWork(
             return Result.failure()
         }
         val remoteWipe = inputData.getBoolean(REMOTE_WIPE, false)
-        val arbitraryDataProvider = ArbitraryDataProvider(context)
+        val arbitraryDataProvider: ArbitraryDataProvider = ArbitraryDataProviderImpl(context)
         val user = optionalUser.get()
         backgroundJobManager.cancelPeriodicContactsBackup(user)
         val userRemoved = userAccountManager.removeUser(user)

+ 0 - 1
app/src/main/java/com/nextcloud/client/jobs/ContactsBackupWork.kt

@@ -55,7 +55,6 @@ import java.io.FileWriter
 import java.io.IOException
 import java.io.InputStream
 import java.io.InputStreamReader
-import java.util.ArrayList
 import java.util.Calendar
 
 @Suppress("LongParameterList") // legacy code

+ 3 - 2
app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt

@@ -36,6 +36,7 @@ import com.nextcloud.client.network.ConnectivityService
 import com.nextcloud.client.preferences.AppPreferences
 import com.owncloud.android.R
 import com.owncloud.android.datamodel.ArbitraryDataProvider
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
 import com.owncloud.android.datamodel.FilesystemDataProvider
 import com.owncloud.android.datamodel.MediaFolderType
 import com.owncloud.android.datamodel.SyncedFolder
@@ -133,8 +134,8 @@ class FilesSyncWork(
             return
         }
         val user = optionalUser.get()
-        val arbitraryDataProvider = if (lightVersion) {
-            ArbitraryDataProvider(context)
+        val arbitraryDataProvider: ArbitraryDataProvider? = if (lightVersion) {
+            ArbitraryDataProviderImpl(context)
         } else {
             null
         }

+ 2 - 1
app/src/main/java/com/nextcloud/client/jobs/MediaFoldersDetectionWork.kt

@@ -46,6 +46,7 @@ import com.nextcloud.client.preferences.AppPreferencesImpl
 import com.owncloud.android.MainApp
 import com.owncloud.android.R
 import com.owncloud.android.datamodel.ArbitraryDataProvider
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
 import com.owncloud.android.datamodel.MediaFolderType
 import com.owncloud.android.datamodel.MediaFoldersModel
 import com.owncloud.android.datamodel.MediaProvider
@@ -84,7 +85,7 @@ class MediaFoldersDetectionWork constructor(
 
     @Suppress("LongMethod", "ComplexMethod", "NestedBlockDepth") // legacy code
     override fun doWork(): Result {
-        val arbitraryDataProvider = ArbitraryDataProvider(context)
+        val arbitraryDataProvider: ArbitraryDataProvider = ArbitraryDataProviderImpl(context)
         val syncedFolderProvider = SyncedFolderProvider(contentResolver, preferences, clock)
         val gson = Gson()
         val mediaFoldersModel: MediaFoldersModel

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

@@ -29,6 +29,7 @@ import com.nextcloud.client.account.User;
 import com.nextcloud.client.account.UserAccountManager;
 import com.nextcloud.client.account.UserAccountManagerImpl;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.ui.activity.PassCodeActivity;
@@ -337,7 +338,7 @@ public final class AppPreferencesImpl implements AppPreferences {
             return defaultOrder;
         }
 
-        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProviderImpl(context);
 
         String value = dataProvider.getValue(user.getAccountName(), PREF__FOLDER_SORT_ORDER + "_" + type);
 
@@ -347,7 +348,7 @@ public final class AppPreferencesImpl implements AppPreferences {
     @Override
     public void setSortOrder(FileSortOrder.Type type, FileSortOrder sortOrder) {
         User user = userAccountManager.getUser();
-        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProviderImpl(context);
         dataProvider.storeOrUpdateKeyValue(user.getAccountName(), PREF__FOLDER_SORT_ORDER + "_" + type, sortOrder.name);
     }
 
@@ -604,7 +605,7 @@ public final class AppPreferencesImpl implements AppPreferences {
             return defaultValue;
         }
 
-        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProviderImpl(context);
         FileDataStorageManager storageManager = new FileDataStorageManager(user, context.getContentResolver());
 
         String value = dataProvider.getValue(user.getAccountName(), getKeyFromFolder(preferenceName, folder));
@@ -629,7 +630,7 @@ public final class AppPreferencesImpl implements AppPreferences {
                                             final String preferenceName,
                                             @Nullable final OCFile folder,
                                             final String value) {
-        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProviderImpl(context);
         dataProvider.storeOrUpdateKeyValue(user.getAccountName(), getKeyFromFolder(preferenceName, folder), value);
     }
 

+ 2 - 1
app/src/main/java/com/owncloud/android/MainApp.java

@@ -62,6 +62,7 @@ import com.nextcloud.client.preferences.DarkMode;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.authentication.PassCodeManager;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.MediaFolder;
 import com.owncloud.android.datamodel.MediaFolderType;
 import com.owncloud.android.datamodel.MediaProvider;
@@ -413,7 +414,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
     }
 
     public static void initContactsBackup(UserAccountManager accountManager, BackgroundJobManager backgroundJobManager) {
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(mContext);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(mContext);
         List<User> users = accountManager.getAllUsers();
         for (User user : users) {
             if (arbitraryDataProvider.getBooleanValue(user, PREFERENCE_CONTACTS_AUTOMATIC_BACKUP)) {

+ 47 - 0
app/src/main/java/com/owncloud/android/datamodel/ArbitraryDataProvider.kt

@@ -0,0 +1,47 @@
+/*
+ * Nextcloud Android client application
+ *
+ *  @author Álvaro Brey
+ *  Copyright (C) 2022 Álvaro Brey
+ *  Copyright (C) 2022 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
+ * 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.owncloud.android.datamodel
+
+import com.nextcloud.client.account.User
+
+@Suppress("Detekt.TooManyFunctions") // legacy interface, will get rid of `accountName` methods in the future
+interface ArbitraryDataProvider {
+    fun deleteKeyForAccount(account: String?, key: String?)
+
+    fun storeOrUpdateKeyValue(accountName: String?, key: String?, newValue: Long)
+    fun storeOrUpdateKeyValue(accountName: String?, key: String?, newValue: Boolean)
+    fun storeOrUpdateKeyValue(accountName: String, key: String, newValue: String?)
+
+    fun getLongValue(accountName: String?, key: String?): Long?
+    fun getLongValue(user: User?, key: String?): Long?
+    fun getBooleanValue(accountName: String?, key: String?): Boolean
+    fun getBooleanValue(user: User?, key: String?): Boolean
+    fun getIntegerValue(accountName: String?, key: String?): Int?
+    fun getValue(user: User?, key: String?): String
+    fun getValue(accountName: String?, key: String?): String?
+
+    companion object {
+        const val DIRECT_EDITING = "DIRECT_EDITING"
+        const val DIRECT_EDITING_ETAG = "DIRECT_EDITING_ETAG"
+        const val PREDEFINED_STATUS = "PREDEFINED_STATUS"
+    }
+}

+ 19 - 9
app/src/main/java/com/owncloud/android/datamodel/ArbitraryDataProvider.java → app/src/main/java/com/owncloud/android/datamodel/ArbitraryDataProviderImpl.java

@@ -33,41 +33,44 @@ import androidx.annotation.Nullable;
 
 /**
  * Database provider for handling the persistence aspects of arbitrary data table.
+ * <p>
+ * Don't instantiate this class, inject the interface instead.
  */
-public class ArbitraryDataProvider {
-    public static final String DIRECT_EDITING = "DIRECT_EDITING";
-    public static final String DIRECT_EDITING_ETAG = "DIRECT_EDITING_ETAG";
-    public static final String PREDEFINED_STATUS = "PREDEFINED_STATUS";
+public class ArbitraryDataProviderImpl implements ArbitraryDataProvider {
 
     private static final String TRUE = "true";
 
     private final ArbitraryDataDao arbitraryDataDao;
 
     /**
-     * @deprecated inject instead
+     * @deprecated inject interface instead
      */
     @Deprecated
-    public ArbitraryDataProvider(final Context context) {
+    public ArbitraryDataProviderImpl(final Context context) {
         this(NextcloudDatabase.getInstance(context).arbitraryDataDao());
     }
 
     @Inject
-    public ArbitraryDataProvider(final ArbitraryDataDao dao) {
+    public ArbitraryDataProviderImpl(final ArbitraryDataDao dao) {
         this.arbitraryDataDao = dao;
     }
 
+    @Override
     public void deleteKeyForAccount(String account, String key) {
         arbitraryDataDao.deleteValue(account, key);
     }
 
+    @Override
     public void storeOrUpdateKeyValue(String accountName, String key, long newValue) {
         storeOrUpdateKeyValue(accountName, key, String.valueOf(newValue));
     }
 
+    @Override
     public void storeOrUpdateKeyValue(final String accountName, final String key, final boolean newValue) {
         storeOrUpdateKeyValue(accountName, key, String.valueOf(newValue));
     }
 
+    @Override
     public void storeOrUpdateKeyValue(@NonNull String accountName,
                                       @NonNull String key,
                                       @Nullable String newValue) {
@@ -79,7 +82,8 @@ public class ArbitraryDataProvider {
         }
     }
 
-    Long getLongValue(String accountName, String key) {
+    @Override
+    public Long getLongValue(String accountName, String key) {
         String value = getValue(accountName, key);
 
         if (value.isEmpty()) {
@@ -90,14 +94,17 @@ public class ArbitraryDataProvider {
     }
 
 
+    @Override
     public Long getLongValue(User user, String key) {
         return getLongValue(user.getAccountName(), key);
     }
 
+    @Override
     public boolean getBooleanValue(String accountName, String key) {
         return TRUE.equalsIgnoreCase(getValue(accountName, key));
     }
 
+    @Override
     public boolean getBooleanValue(User user, String key) {
         return getBooleanValue(user.getAccountName(), key);
     }
@@ -106,9 +113,10 @@ public class ArbitraryDataProvider {
      * returns integer if found else -1
      *
      * @param accountName name of account
-     * @param key key to get value for
+     * @param key         key to get value for
      * @return Integer specified by account and key
      */
+    @Override
     public Integer getIntegerValue(String accountName, String key) {
         String value = getValue(accountName, key);
 
@@ -124,11 +132,13 @@ public class ArbitraryDataProvider {
      *
      * @return string if value found or empty string
      */
+    @Override
     @NonNull
     public String getValue(@Nullable User user, String key) {
         return user != null ? getValue(user.getAccountName(), key) : "";
     }
 
+    @Override
     public String getValue(String accountName, String key) {
         final String value = arbitraryDataDao.getValue(accountName, key);
         if (value == null) {

+ 1 - 1
app/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java

@@ -1047,7 +1047,7 @@ public final class ThumbnailsCacheManager {
 
             String accountName = mUserId + "@" + mServerName;
 
-            ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(mContext);
+            ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(mContext);
 
             String eTag = arbitraryDataProvider.getValue(accountName, ThumbnailsCacheManager.AVATAR);
             long timestamp = arbitraryDataProvider.getLongValue(accountName, ThumbnailsCacheManager.AVATAR_TIMESTAMP);

+ 2 - 1
app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java

@@ -26,6 +26,7 @@ import android.util.Pair;
 
 import com.nextcloud.client.account.User;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.DecryptedFolderMetadata;
 import com.owncloud.android.datamodel.EncryptedFolderMetadata;
 import com.owncloud.android.datamodel.FileDataStorageManager;
@@ -106,7 +107,7 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
     }
 
     private RemoteOperationResult encryptedCreate(OCFile parent, OwnCloudClient client) {
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(context);
         String privateKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PRIVATE_KEY);
         String publicKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PUBLIC_KEY);
 

+ 2 - 1
app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java

@@ -28,6 +28,7 @@ import com.nextcloud.android.lib.resources.directediting.DirectEditingObtainRemo
 import com.nextcloud.client.account.User;
 import com.nextcloud.common.NextcloudClient;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.DecryptedFolderMetadata;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
@@ -296,7 +297,7 @@ public class RefreshFolderOperation extends RemoteOperation {
     }
 
     private void updateCapabilities() {
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(mContext);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(mContext);
         String oldDirectEditingEtag = arbitraryDataProvider.getValue(user,
                                                                      ArbitraryDataProvider.DIRECT_EDITING_ETAG);
 

+ 2 - 1
app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.java

@@ -26,6 +26,7 @@ import android.content.Context;
 import com.google.gson.reflect.TypeToken;
 import com.nextcloud.client.account.User;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.DecryptedFolderMetadata;
 import com.owncloud.android.datamodel.EncryptedFolderMetadata;
 import com.owncloud.android.lib.common.OwnCloudClient;
@@ -84,7 +85,7 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation {
         this.user = user;
         this.fileName = fileName;
 
-        arbitraryDataProvider = new ArbitraryDataProvider(context);
+        arbitraryDataProvider = new ArbitraryDataProviderImpl(context);
     }
 
     /**

+ 2 - 1
app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java

@@ -33,6 +33,7 @@ import com.nextcloud.client.device.PowerManagementService;
 import com.nextcloud.client.network.Connectivity;
 import com.nextcloud.client.network.ConnectivityService;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.DecryptedFolderMetadata;
 import com.owncloud.android.datamodel.EncryptedFolderMetadata;
 import com.owncloud.android.datamodel.FileDataStorageManager;
@@ -455,7 +456,7 @@ public class UploadFileOperation extends SyncOperation {
         boolean metadataExists = false;
         String token = null;
 
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContext());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(getContext());
 
         String privateKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PRIVATE_KEY);
         String publicKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PUBLIC_KEY);

+ 2 - 1
app/src/main/java/com/owncloud/android/providers/UsersAndGroupsSearchProvider.java

@@ -40,6 +40,7 @@ import com.nextcloud.client.account.User;
 import com.nextcloud.client.account.UserAccountManager;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -377,7 +378,7 @@ public class UsersAndGroupsSearchProvider extends ContentProvider {
     @Override
     @SuppressFBWarnings("IOI_USE_OF_FILE_STREAM_CONSTRUCTORS") // TODO remove with API26
     public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException {
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContext());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(getContext());
 
         String userId = uri.getQueryParameter("shareWith");
         String displayName = uri.getQueryParameter("displayName");

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

@@ -51,7 +51,6 @@ import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroup.MarginLayoutParams;
 import android.webkit.URLUtil;
-import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -78,6 +77,7 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.PassCodeManager;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.ExternalLinksProvider;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.ExternalLink;
@@ -907,7 +907,7 @@ public abstract class DrawerActivity extends ToolbarActivity
         }
 
         externalLinksProvider = new ExternalLinksProvider(getContentResolver());
-        arbitraryDataProvider = new ArbitraryDataProvider(this);
+        arbitraryDataProvider = new ArbitraryDataProviderImpl(this);
     }
 
     @Override

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

@@ -50,6 +50,7 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
@@ -644,7 +645,7 @@ public abstract class FileActivity extends DrawerActivity
 
     public void checkForNewDevVersionNecessary(Context context) {
         if (getResources().getBoolean(R.bool.dev_version_direct_download_enabled)) {
-            ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
+            ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(this);
             int count = arbitraryDataProvider.getIntegerValue(FilesSyncHelper.GLOBAL, APP_OPENED_COUNT);
 
             if (count > 10 || count == -1) {

+ 3 - 2
app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java

@@ -48,6 +48,7 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.files.services.FileDownloader;
 import com.owncloud.android.files.services.FileUploader;
@@ -142,7 +143,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
             originalCurrentUser = currentUser.get().getAccountName();
         }
 
-        arbitraryDataProvider = new ArbitraryDataProvider(this);
+        arbitraryDataProvider = new ArbitraryDataProviderImpl(this);
 
         multipleAccountsSupported = getResources().getBoolean(R.bool.multiaccount_support);
 
@@ -426,7 +427,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
         }
 
         // store pending account removal
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(this);
         arbitraryDataProvider.storeOrUpdateKeyValue(user.getAccountName(), PENDING_FOR_REMOVAL, String.valueOf(true));
 
         // Cancel transfers

+ 2 - 1
app/src/main/java/com/owncloud/android/ui/activity/NotificationsActivity.java

@@ -38,6 +38,7 @@ import com.nextcloud.java.util.Optional;
 import com.owncloud.android.R;
 import com.owncloud.android.databinding.NotificationsLayoutBinding;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.lib.common.OwnCloudClient;
 import com.owncloud.android.lib.common.operations.RemoteOperation;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@@ -146,7 +147,7 @@ public class NotificationsActivity extends DrawerActivity implements Notificatio
                                          R.string.push_notifications_not_implemented,
                                          Snackbar.LENGTH_INDEFINITE);
             } else {
-                final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
+                final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(this);
                 final String accountName = optionalUser.isPresent() ? optionalUser.get().getAccountName() : "";
                 final boolean usesOldLogin = arbitraryDataProvider.getBooleanValue(accountName,
                                                                                    UserAccountManager.ACCOUNT_USES_STANDARD_PASSWORD);

+ 3 - 2
app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java

@@ -62,6 +62,7 @@ import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.authentication.AuthenticatorActivity;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.ExternalLinksProvider;
 import com.owncloud.android.datastorage.DataStorageProvider;
 import com.owncloud.android.datastorage.StoragePoint;
@@ -606,7 +607,7 @@ public class SettingsActivity extends PreferenceActivity
             preferenceScreen.removePreference(preferenceCategorySyncedFolders);
         } else {
             // Upload on WiFi
-            final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
+            final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(this);
 
             final SwitchPreference pUploadOnWifiCheckbox = (SwitchPreference) findPreference("synced_folder_on_wifi");
             pUploadOnWifiCheckbox.setChecked(
@@ -872,7 +873,7 @@ public class SettingsActivity extends PreferenceActivity
                                  RequestCredentialsActivity.KEY_CHECK_RESULT_FALSE) ==
                 RequestCredentialsActivity.KEY_CHECK_RESULT_TRUE) {
 
-                ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
+                ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(this);
                 String mnemonic = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.MNEMONIC);
 
                 AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.FallbackTheming_Dialog);

+ 5 - 3
app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt

@@ -48,7 +48,7 @@ import com.owncloud.android.BuildConfig
 import com.owncloud.android.MainApp
 import com.owncloud.android.R
 import com.owncloud.android.databinding.SyncedFoldersLayoutBinding
-import com.owncloud.android.datamodel.ArbitraryDataProvider
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
 import com.owncloud.android.datamodel.MediaFolder
 import com.owncloud.android.datamodel.MediaFolderType
 import com.owncloud.android.datamodel.MediaProvider
@@ -696,14 +696,16 @@ class SyncedFoldersActivity :
                 backgroundJobManager.startImmediateFilesSyncJob(skipCustomFolders = false, overridePowerSaving = false)
             } else {
                 val syncedFolderInitiatedKey = KEY_SYNCED_FOLDER_INITIATED_PREFIX + item.id
-                val arbitraryDataProvider = ArbitraryDataProvider(MainApp.getAppContext())
+                val arbitraryDataProvider =
+                    ArbitraryDataProviderImpl(MainApp.getAppContext())
                 arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey)
             }
         }
     }
 
     private fun storeSyncedFolder(item: SyncedFolderDisplayItem) {
-        val arbitraryDataProvider = ArbitraryDataProvider(MainApp.getAppContext())
+        val arbitraryDataProvider =
+            ArbitraryDataProviderImpl(MainApp.getAppContext())
         val storedId = syncedFolderProvider.storeSyncedFolder(item)
         if (storedId != -1L) {
             item.id = storedId

+ 2 - 1
app/src/main/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragment.java

@@ -36,6 +36,7 @@ import com.nextcloud.client.di.Injectable;
 import com.owncloud.android.R;
 import com.owncloud.android.databinding.SetupEncryptionDialogBinding;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.lib.common.accounts.AccountUtils;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.utils.Log_OC;
@@ -132,7 +133,7 @@ public class SetupEncryptionDialogFragment extends DialogFragment implements Inj
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         user = getArguments().getParcelable(ARG_USER);
 
-        arbitraryDataProvider = new ArbitraryDataProvider(getContext());
+        arbitraryDataProvider = new ArbitraryDataProviderImpl(getContext());
 
         // Inflate the layout for the dialog
         LayoutInflater inflater = getActivity().getLayoutInflater();

+ 2 - 1
app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java

@@ -33,6 +33,7 @@ import com.owncloud.android.R;
 import com.owncloud.android.databinding.FileListActionsBottomSheetCreatorBinding;
 import com.owncloud.android.databinding.FileListActionsBottomSheetFragmentBinding;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.Creator;
 import com.owncloud.android.lib.common.DirectEditing;
@@ -103,7 +104,7 @@ public class OCFileListBottomSheetDialog extends BottomSheetDialog implements In
             binding.templates.setVisibility(View.VISIBLE);
         }
 
-        String json = new ArbitraryDataProvider(getContext())
+        String json = new ArbitraryDataProviderImpl(getContext())
             .getValue(user, ArbitraryDataProvider.DIRECT_EDITING);
 
         if (!json.isEmpty() &&

+ 2 - 1
app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java

@@ -55,6 +55,7 @@ import com.nextcloud.utils.EditorUtils;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.files.StreamMediaFileOperation;
@@ -1120,7 +1121,7 @@ public class FileOperationsHelper {
     }
 
     public static boolean isEndToEndEncryptionSetup(Context context, User user) {
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(context);
 
         String publicKey = arbitraryDataProvider.getValue(user, EncryptionUtils.PUBLIC_KEY);
         String privateKey = arbitraryDataProvider.getValue(user, EncryptionUtils.PRIVATE_KEY);

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

@@ -69,6 +69,7 @@ import com.nextcloud.client.preferences.AppPreferences;
 import com.owncloud.android.MainApp;
 import com.owncloud.android.R;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.ThumbnailsCacheManager;
@@ -491,7 +492,7 @@ public final class DisplayUtils {
             ((View) callContext).setContentDescription(String.valueOf(user.toPlatformAccount().hashCode()));
         }
 
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(context);
 
         final String accountName = user.getAccountName();
         String serverName = accountName.substring(accountName.lastIndexOf('@') + 1);

+ 2 - 1
app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java

@@ -31,6 +31,7 @@ import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 import com.nextcloud.client.account.User;
 import com.owncloud.android.datamodel.ArbitraryDataProvider;
+import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
 import com.owncloud.android.datamodel.DecryptedFolderMetadata;
 import com.owncloud.android.datamodel.EncryptedFolderMetadata;
 import com.owncloud.android.datamodel.OCFile;
@@ -231,7 +232,7 @@ public final class EncryptionUtils {
         }
 
         // decrypt metadata
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(context);
         String serializedEncryptedMetadata = (String) getMetadataOperationResult.getData().get(0);
         String privateKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PRIVATE_KEY);