Просмотр исходного кода

Use Room DAO for ArbitraryDataProvider instead of contentResolver

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
Álvaro Brey 2 лет назад
Родитель
Сommit
5499441738
35 измененных файлов с 146 добавлено и 231 удалено
  1. 1 1
      app/src/debug/java/com/nextcloud/client/TestActivity.kt
  2. 3 3
      app/src/gplay/java/com/owncloud/android/utils/PushUtils.java
  3. 0 4
      app/src/main/AndroidManifest.xml
  4. 1 1
      app/src/main/java/com/nextcloud/client/account/UserAccountManagerImpl.java
  5. 7 11
      app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt
  6. 32 0
      app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt
  7. 41 0
      app/src/main/java/com/nextcloud/client/database/dao/ArbitraryDataDao.kt
  8. 4 1
      app/src/main/java/com/nextcloud/client/database/migrations/LegacyMigrationHelper.java
  9. 3 3
      app/src/main/java/com/nextcloud/client/di/AppModule.java
  10. 1 1
      app/src/main/java/com/nextcloud/client/jobs/AccountRemovalWork.kt
  11. 1 1
      app/src/main/java/com/nextcloud/client/jobs/FilesSyncWork.kt
  12. 1 1
      app/src/main/java/com/nextcloud/client/jobs/MediaFoldersDetectionWork.kt
  13. 4 4
      app/src/main/java/com/nextcloud/client/preferences/AppPreferencesImpl.java
  14. 1 1
      app/src/main/java/com/owncloud/android/MainApp.java
  15. 26 125
      app/src/main/java/com/owncloud/android/datamodel/ArbitraryDataProvider.java
  16. 0 27
      app/src/main/java/com/owncloud/android/datamodel/ArbitraryDataSet.kt
  17. 1 1
      app/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
  18. 0 2
      app/src/main/java/com/owncloud/android/db/ProviderMeta.java
  19. 1 1
      app/src/main/java/com/owncloud/android/operations/CreateFolderOperation.java
  20. 1 1
      app/src/main/java/com/owncloud/android/operations/RefreshFolderOperation.java
  21. 1 1
      app/src/main/java/com/owncloud/android/operations/RemoveRemoteEncryptedFileOperation.java
  22. 1 1
      app/src/main/java/com/owncloud/android/operations/UploadFileOperation.java
  23. 0 25
      app/src/main/java/com/owncloud/android/providers/FileContentProvider.java
  24. 1 1
      app/src/main/java/com/owncloud/android/providers/UsersAndGroupsSearchProvider.java
  25. 1 1
      app/src/main/java/com/owncloud/android/ui/activity/DrawerActivity.java
  26. 1 1
      app/src/main/java/com/owncloud/android/ui/activity/FileActivity.java
  27. 2 2
      app/src/main/java/com/owncloud/android/ui/activity/ManageAccountsActivity.java
  28. 1 1
      app/src/main/java/com/owncloud/android/ui/activity/NotificationsActivity.java
  29. 2 2
      app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java
  30. 2 2
      app/src/main/java/com/owncloud/android/ui/activity/SyncedFoldersActivity.kt
  31. 1 1
      app/src/main/java/com/owncloud/android/ui/dialog/SetupEncryptionDialogFragment.java
  32. 1 1
      app/src/main/java/com/owncloud/android/ui/fragment/OCFileListBottomSheetDialog.java
  33. 1 1
      app/src/main/java/com/owncloud/android/ui/helpers/FileOperationsHelper.java
  34. 1 1
      app/src/main/java/com/owncloud/android/utils/DisplayUtils.java
  35. 1 1
      app/src/main/java/com/owncloud/android/utils/EncryptionUtils.java

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

@@ -146,7 +146,7 @@ class TestActivity :
 
     override fun getFileOperationsHelper(): FileOperationsHelper {
         if (!this::fileOperation.isInitialized) {
-            fileOperation = FileOperationsHelper(this, userAccountManager, connectivityServiceMock, EditorUtils(ArbitraryDataProvider(contentResolver)))
+            fileOperation = FileOperationsHelper(this, userAccountManager, connectivityServiceMock, EditorUtils(ArbitraryDataProvider(baseContext)))
         }
 
         return fileOperation

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

@@ -151,7 +151,7 @@ public final class PushUtils {
     private static void deleteRegistrationForAccount(Account account) {
         Context context = MainApp.getAppContext();
         OwnCloudAccount ocAccount;
-        arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext().getContentResolver());
+        arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext());
 
         try {
             ocAccount = new OwnCloudAccount(account, context);
@@ -193,7 +193,7 @@ public final class PushUtils {
     }
 
     public static void pushRegistrationToServer(final UserAccountManager accountManager, final String token) {
-        arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext().getContentResolver());
+        arbitraryDataProvider = new ArbitraryDataProvider(MainApp.getAppContext());
 
         if (!TextUtils.isEmpty(MainApp.getAppContext().getResources().getString(R.string.push_server_url)) &&
                 !TextUtils.isEmpty(token)) {
@@ -418,7 +418,7 @@ public final class PushUtils {
 
         Account[] accounts = accountManager.getAccounts();
 
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
         String arbitraryValue;
         Gson gson = new Gson();
         PushConfigurationState pushArbitraryData;

+ 0 - 4
app/src/main/AndroidManifest.xml

@@ -280,10 +280,6 @@
                 android:pathPrefix="/external_links"
                 android:readPermission="false"
                 android:writePermission="false" />
-            <path-permission
-                android:pathPrefix="/arbitrary_data"
-                android:readPermission="false"
-                android:writePermission="false" />
             <path-permission
                 android:pathPrefix="/virtual"
                 android:readPermission="false"

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

@@ -148,7 +148,7 @@ public class UserAccountManagerImpl implements UserAccountManager {
         Account[] ocAccounts = getAccounts();
         Account defaultAccount = null;
 
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
 
         SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(context);
         String accountName = appPreferences.getString(PREF_SELECT_OC_ACCOUNT, null);

+ 7 - 11
app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt

@@ -23,11 +23,8 @@
 package com.nextcloud.client.database
 
 import android.content.Context
-import androidx.room.Room
 import com.nextcloud.client.core.Clock
-import com.nextcloud.client.database.migrations.RoomMigration
-import com.nextcloud.client.database.migrations.addLegacyMigrations
-import com.owncloud.android.db.ProviderMeta
+import com.nextcloud.client.database.dao.ArbitraryDataDao
 import dagger.Module
 import dagger.Provides
 import javax.inject.Singleton
@@ -37,13 +34,12 @@ class DatabaseModule {
 
     @Provides
     @Singleton
-    @Suppress("Detekt.SpreadOperator") // forced by Room API
     fun database(context: Context, clock: Clock): NextcloudDatabase {
-        return Room
-            .databaseBuilder(context, NextcloudDatabase::class.java, ProviderMeta.DB_NAME)
-            .addLegacyMigrations(clock)
-            .addMigrations(RoomMigration())
-            .fallbackToDestructiveMigration()
-            .build()
+        return NextcloudDatabase.getInstance(context, clock)
+    }
+
+    @Provides
+    fun arbitraryDataDao(nextcloudDatabase: NextcloudDatabase): ArbitraryDataDao {
+        return nextcloudDatabase.arbitraryDataDao()
     }
 }

+ 32 - 0
app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt

@@ -22,8 +22,13 @@
 
 package com.nextcloud.client.database
 
+import android.content.Context
 import androidx.room.Database
+import androidx.room.Room
 import androidx.room.RoomDatabase
+import com.nextcloud.client.core.Clock
+import com.nextcloud.client.core.ClockImpl
+import com.nextcloud.client.database.dao.ArbitraryDataDao
 import com.nextcloud.client.database.entity.ArbitraryDataEntity
 import com.nextcloud.client.database.entity.CapabilityEntity
 import com.nextcloud.client.database.entity.ExternalLinkEntity
@@ -33,6 +38,8 @@ import com.nextcloud.client.database.entity.ShareEntity
 import com.nextcloud.client.database.entity.SyncedFolderEntity
 import com.nextcloud.client.database.entity.UploadEntity
 import com.nextcloud.client.database.entity.VirtualEntity
+import com.nextcloud.client.database.migrations.RoomMigration
+import com.nextcloud.client.database.migrations.addLegacyMigrations
 import com.owncloud.android.db.ProviderMeta
 
 @Database(
@@ -52,7 +59,32 @@ import com.owncloud.android.db.ProviderMeta
 )
 @Suppress("Detekt.UnnecessaryAbstractClass") // needed by Room
 abstract class NextcloudDatabase : RoomDatabase() {
+
+    abstract fun arbitraryDataDao(): ArbitraryDataDao
+
     companion object {
         const val FIRST_ROOM_DB_VERSION = 65
+        private var INSTANCE: NextcloudDatabase? = null
+
+        @JvmStatic
+        @Suppress("DeprecatedCallableAddReplaceWith")
+        @Deprecated("Here for legacy purposes, inject this class or use getInstance(context, clock) instead")
+        fun getInstance(context: Context): NextcloudDatabase {
+            return getInstance(context, ClockImpl())
+        }
+
+        @JvmStatic
+        fun getInstance(context: Context, clock: Clock): NextcloudDatabase {
+            if (INSTANCE == null) {
+                INSTANCE = Room
+                    .databaseBuilder(context, NextcloudDatabase::class.java, ProviderMeta.DB_NAME)
+                    .allowMainThreadQueries()
+                    .addLegacyMigrations(clock)
+                    .addMigrations(RoomMigration())
+                    .fallbackToDestructiveMigration()
+                    .build()
+            }
+            return INSTANCE!!
+        }
     }
 }

+ 41 - 0
app/src/main/java/com/nextcloud/client/database/dao/ArbitraryDataDao.kt

@@ -0,0 +1,41 @@
+/*
+ * 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.nextcloud.client.database.dao
+
+import androidx.room.Dao
+import androidx.room.Query
+
+@Dao
+interface ArbitraryDataDao {
+    @Query("INSERT INTO arbitrary_data(cloud_id, `key`, value) VALUES(:accountName, :key, :value)")
+    fun insertValue(accountName: String, key: String, value: String?)
+
+    @Query("SELECT value FROM arbitrary_data WHERE cloud_id = :accountName AND `key` = :key LIMIT 1")
+    fun getValue(accountName: String, key: String): String?
+
+    @Query("UPDATE arbitrary_data SET value = :value WHERE cloud_id = :accountName AND `key` = :key ")
+    fun updateValue(accountName: String, key: String, value: String?)
+
+    @Query("DELETE FROM arbitrary_data WHERE cloud_id = :accountName AND `key` = :key")
+    fun deleteValue(accountName: String, key: String)
+}

+ 4 - 1
app/src/main/java/com/nextcloud/client/database/migrations/LegacyMigrationHelper.java

@@ -41,6 +41,9 @@ public class LegacyMigrationHelper {
 
     private static final String TAG = LegacyMigrationHelper.class.getSimpleName();
 
+    public static final int ARBITRARY_DATA_TABLE_INTRODUCTION_VERSION = 20;
+
+
     private static final String ALTER_TABLE = "ALTER TABLE ";
     private static final String ADD_COLUMN = " ADD COLUMN ";
     private static final String INTEGER = " INTEGER, ";
@@ -176,7 +179,7 @@ public class LegacyMigrationHelper {
                     db.execSQL(ALTER_TABLE + ProviderMeta.ProviderTableMeta.FILE_TABLE_NAME +
                                    ADD_COLUMN + ProviderMeta.ProviderTableMeta.FILE_ENCRYPTED_NAME + " TEXT ");
                 }
-                if (oldVersion > FileContentProvider.ARBITRARY_DATA_TABLE_INTRODUCTION_VERSION) {
+                if (oldVersion > ARBITRARY_DATA_TABLE_INTRODUCTION_VERSION) {
                     if (!checkIfColumnExists(db, ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME,
                                              ProviderMeta.ProviderTableMeta.CAPABILITIES_END_TO_END_ENCRYPTION)) {
                         db.execSQL(ALTER_TABLE + ProviderMeta.ProviderTableMeta.CAPABILITIES_TABLE_NAME +

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

@@ -40,6 +40,7 @@ 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;
 import com.nextcloud.client.logger.Logger;
@@ -118,9 +119,8 @@ class AppModule {
     }
 
     @Provides
-    ArbitraryDataProvider arbitraryDataProvider(Context context) {
-        final ContentResolver resolver = context.getContentResolver();
-        return new ArbitraryDataProvider(resolver);
+    ArbitraryDataProvider arbitraryDataProvider(ArbitraryDataDao dao) {
+        return new ArbitraryDataProvider(dao);
     }
 
     @Provides

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

@@ -88,7 +88,7 @@ class AccountRemovalWork(
             return Result.failure()
         }
         val remoteWipe = inputData.getBoolean(REMOTE_WIPE, false)
-        val arbitraryDataProvider = ArbitraryDataProvider(context.contentResolver)
+        val arbitraryDataProvider = ArbitraryDataProvider(context)
         val user = optionalUser.get()
         backgroundJobManager.cancelPeriodicContactsBackup(user)
         val userRemoved = userAccountManager.removeUser(user)

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

@@ -134,7 +134,7 @@ class FilesSyncWork(
         }
         val user = optionalUser.get()
         val arbitraryDataProvider = if (lightVersion) {
-            ArbitraryDataProvider(contentResolver)
+            ArbitraryDataProvider(context)
         } else {
             null
         }

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

@@ -84,7 +84,7 @@ class MediaFoldersDetectionWork constructor(
 
     @Suppress("LongMethod", "ComplexMethod", "NestedBlockDepth") // legacy code
     override fun doWork(): Result {
-        val arbitraryDataProvider = ArbitraryDataProvider(contentResolver)
+        val arbitraryDataProvider = ArbitraryDataProvider(context)
         val syncedFolderProvider = SyncedFolderProvider(contentResolver, preferences, clock)
         val gson = Gson()
         val mediaFoldersModel: MediaFoldersModel

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

@@ -337,7 +337,7 @@ public final class AppPreferencesImpl implements AppPreferences {
             return defaultOrder;
         }
 
-        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context);
 
         String value = dataProvider.getValue(user.getAccountName(), PREF__FOLDER_SORT_ORDER + "_" + type);
 
@@ -347,7 +347,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.getContentResolver());
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context);
         dataProvider.storeOrUpdateKeyValue(user.getAccountName(), PREF__FOLDER_SORT_ORDER + "_" + type, sortOrder.name);
     }
 
@@ -604,7 +604,7 @@ public final class AppPreferencesImpl implements AppPreferences {
             return defaultValue;
         }
 
-        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context);
         FileDataStorageManager storageManager = new FileDataStorageManager(user, context.getContentResolver());
 
         String value = dataProvider.getValue(user.getAccountName(), getKeyFromFolder(preferenceName, folder));
@@ -629,7 +629,7 @@ public final class AppPreferencesImpl implements AppPreferences {
                                             final String preferenceName,
                                             @Nullable final OCFile folder,
                                             final String value) {
-        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        ArbitraryDataProvider dataProvider = new ArbitraryDataProvider(context);
         dataProvider.storeOrUpdateKeyValue(user.getAccountName(), getKeyFromFolder(preferenceName, folder), value);
     }
 

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

@@ -413,7 +413,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
     }
 
     public static void initContactsBackup(UserAccountManager accountManager, BackgroundJobManager backgroundJobManager) {
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(mContext.getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(mContext);
         List<User> users = accountManager.getAllUsers();
         for (User user : users) {
             if (arbitraryDataProvider.getBooleanValue(user, PREFERENCE_CONTACTS_AUTOMATIC_BACKUP)) {

+ 26 - 125
app/src/main/java/com/owncloud/android/datamodel/ArbitraryDataProvider.java

@@ -20,14 +20,13 @@
  */
 package com.owncloud.android.datamodel;
 
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
+import android.content.Context;
 
 import com.nextcloud.client.account.User;
-import com.owncloud.android.db.ProviderMeta;
-import com.owncloud.android.lib.common.utils.Log_OC;
+import com.nextcloud.client.database.NextcloudDatabase;
+import com.nextcloud.client.database.dao.ArbitraryDataDao;
+
+import javax.inject.Inject;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -40,25 +39,25 @@ public class ArbitraryDataProvider {
     public static final String DIRECT_EDITING_ETAG = "DIRECT_EDITING_ETAG";
     public static final String PREDEFINED_STATUS = "PREDEFINED_STATUS";
 
-    private static final String TAG = ArbitraryDataProvider.class.getSimpleName();
     private static final String TRUE = "true";
 
-    private ContentResolver contentResolver;
+    private final ArbitraryDataDao arbitraryDataDao;
 
-    public ArbitraryDataProvider(ContentResolver contentResolver) {
-        if (contentResolver == null) {
-            throw new IllegalArgumentException("Cannot create an instance with a NULL contentResolver");
-        }
-        this.contentResolver = contentResolver;
+    /**
+     * @deprecated inject instead
+     */
+    @Deprecated
+    public ArbitraryDataProvider(final Context context) {
+        this(NextcloudDatabase.getInstance(context).arbitraryDataDao());
+    }
+
+    @Inject
+    public ArbitraryDataProvider(final ArbitraryDataDao dao) {
+        this.arbitraryDataDao = dao;
     }
 
-    public int deleteKeyForAccount(String account, String key) {
-        return contentResolver.delete(
-            ProviderMeta.ProviderTableMeta.CONTENT_URI_ARBITRARY_DATA,
-            ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_CLOUD_ID + " = ? AND " +
-                ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_KEY + "= ?",
-            new String[]{account, key}
-                                     );
+    public void deleteKeyForAccount(String account, String key) {
+        arbitraryDataDao.deleteValue(account, key);
     }
 
     public void storeOrUpdateKeyValue(String accountName, String key, long newValue) {
@@ -72,49 +71,11 @@ public class ArbitraryDataProvider {
     public void storeOrUpdateKeyValue(@NonNull String accountName,
                                       @NonNull String key,
                                       @Nullable String newValue) {
-        ArbitraryDataSet data = getArbitraryDataSet(accountName, key);
-
-        String value;
-        if (newValue == null) {
-            value = "";
-        } else {
-            value = newValue;
-        }
-
-        if (data == null) {
-            Log_OC.v(TAG, "Adding arbitrary data with cloud id: " + accountName + " key: " + key
-                + " value: " + value);
-
-            ContentValues cv = new ContentValues();
-            cv.put(ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_CLOUD_ID, accountName);
-            cv.put(ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_KEY, key);
-            cv.put(ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_VALUE, value);
-
-            Uri result = contentResolver.insert(ProviderMeta.ProviderTableMeta.CONTENT_URI_ARBITRARY_DATA, cv);
-
-            if (result == null) {
-                Log_OC.v(TAG, "Failed to store arbitrary data with cloud id: " + accountName + " key: " + key
-                    + " value: " + value);
-            }
+        final String currentValue = arbitraryDataDao.getValue(accountName, key);
+        if (currentValue != null) {
+            arbitraryDataDao.updateValue(accountName, key, newValue);
         } else {
-            Log_OC.v(TAG, "Updating arbitrary data with cloud id: " + accountName + " key: " + key
-                + " value: " + value);
-            ContentValues cv = new ContentValues();
-            cv.put(ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_CLOUD_ID, data.getCloudId());
-            cv.put(ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_KEY, data.getKey());
-            cv.put(ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_VALUE, value);
-
-            int result = contentResolver.update(
-                    ProviderMeta.ProviderTableMeta.CONTENT_URI_ARBITRARY_DATA,
-                    cv,
-                    ProviderMeta.ProviderTableMeta._ID + "=?",
-                    new String[]{String.valueOf(data.getId())}
-            );
-
-            if (result == 0) {
-                Log_OC.v(TAG, "Failed to update arbitrary data with cloud id: " + accountName + " key: " + key
-                    + " value: " + value);
-            }
+            arbitraryDataDao.insertValue(accountName, key, newValue);
         }
     }
 
@@ -169,70 +130,10 @@ public class ArbitraryDataProvider {
     }
 
     public String getValue(String accountName, String key) {
-        Cursor cursor = contentResolver.query(
-            ProviderMeta.ProviderTableMeta.CONTENT_URI_ARBITRARY_DATA,
-            null,
-            ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_CLOUD_ID + " = ? and " +
-                ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_KEY + " = ?",
-            new String[]{accountName, key},
-            null
-                                             );
-
-        if (cursor != null) {
-            if (cursor.moveToFirst()) {
-                String value = cursor.getString(cursor.getColumnIndexOrThrow(
-                        ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_VALUE));
-                if (value == null) {
-                    Log_OC.e(TAG, "Arbitrary value could not be created from cursor");
-                } else {
-                    cursor.close();
-                    return value;
-                }
-            }
-            cursor.close();
+        final String value = arbitraryDataDao.getValue(accountName, key);
+        if (value == null) {
             return "";
-        } else {
-            Log_OC.e(TAG, "DB error restoring arbitrary values.");
-        }
-
-        return "";
-    }
-
-    private ArbitraryDataSet getArbitraryDataSet(String accountName, String key) {
-        Cursor cursor = contentResolver.query(
-                ProviderMeta.ProviderTableMeta.CONTENT_URI_ARBITRARY_DATA,
-                null,
-                ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_CLOUD_ID + " = ? and " +
-                        ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_KEY + " = ?",
-                new String[]{accountName, key},
-                null
-        );
-
-        ArbitraryDataSet dataSet = null;
-        if (cursor != null) {
-            if (cursor.moveToFirst()) {
-                int id = cursor.getInt(cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta._ID));
-                String dbAccount = cursor.getString(cursor.getColumnIndexOrThrow(
-                        ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_CLOUD_ID));
-                String dbKey = cursor.getString(cursor.getColumnIndexOrThrow(
-                        ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_KEY));
-                String dbValue = cursor.getString(cursor.getColumnIndexOrThrow(
-                        ProviderMeta.ProviderTableMeta.ARBITRARY_DATA_VALUE));
-
-                if (id == -1) {
-                    Log_OC.e(TAG, "Arbitrary value could not be created from cursor");
-                } else {
-                    if (dbValue == null) {
-                        dbValue = "";
-                    }
-                    dataSet = new ArbitraryDataSet(id, dbAccount, dbKey, dbValue);
-                }
-            }
-            cursor.close();
-        } else {
-            Log_OC.e(TAG, "DB error restoring arbitrary values.");
         }
-
-        return dataSet;
+        return value;
     }
 }

+ 0 - 27
app/src/main/java/com/owncloud/android/datamodel/ArbitraryDataSet.kt

@@ -1,27 +0,0 @@
-/*
- *
- * Nextcloud Android client application
- *
- * @author Tobias Kaminsky
- * Copyright (C) 2020 Tobias Kaminsky
- * Copyright (C) 2020 Nextcloud GmbH
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-package com.owncloud.android.datamodel
-
-/**
- * Data set for [ArbitraryDataProvider]
- */
-internal class ArbitraryDataSet(val id: Int, val cloudId: String, val key: String, val value: String)

+ 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.getContentResolver());
+            ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(mContext);
 
             String eTag = arbitraryDataProvider.getValue(accountName, ThumbnailsCacheManager.AVATAR);
             long timestamp = arbitraryDataProvider.getLongValue(accountName, ThumbnailsCacheManager.AVATAR_TIMESTAMP);

+ 0 - 2
app/src/main/java/com/owncloud/android/db/ProviderMeta.java

@@ -72,8 +72,6 @@ public class ProviderMeta {
                 + MainApp.getAuthority() + "/synced_folders");
         public static final Uri CONTENT_URI_EXTERNAL_LINKS = Uri.parse(CONTENT_PREFIX
                 + MainApp.getAuthority() + "/external_links");
-        public static final Uri CONTENT_URI_ARBITRARY_DATA = Uri.parse(CONTENT_PREFIX
-                + MainApp.getAuthority() + "/arbitrary_data");
         public static final Uri CONTENT_URI_VIRTUAL = Uri.parse(CONTENT_PREFIX + MainApp.getAuthority() + "/virtual");
         public static final Uri CONTENT_URI_FILESYSTEM = Uri.parse(CONTENT_PREFIX
                 + MainApp.getAuthority() + "/filesystem");

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

@@ -106,7 +106,7 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
     }
 
     private RemoteOperationResult encryptedCreate(OCFile parent, OwnCloudClient client) {
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
         String privateKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PRIVATE_KEY);
         String publicKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PUBLIC_KEY);
 

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

@@ -296,7 +296,7 @@ public class RefreshFolderOperation extends RemoteOperation {
     }
 
     private void updateCapabilities() {
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(mContext.getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(mContext);
         String oldDirectEditingEtag = arbitraryDataProvider.getValue(user,
                                                                      ArbitraryDataProvider.DIRECT_EDITING_ETAG);
 

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

@@ -84,7 +84,7 @@ public class RemoveRemoteEncryptedFileOperation extends RemoteOperation {
         this.user = user;
         this.fileName = fileName;
 
-        arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        arbitraryDataProvider = new ArbitraryDataProvider(context);
     }
 
     /**

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

@@ -455,7 +455,7 @@ public class UploadFileOperation extends SyncOperation {
         boolean metadataExists = false;
         String token = null;
 
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContext().getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContext());
 
         String privateKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PRIVATE_KEY);
         String publicKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PUBLIC_KEY);

+ 0 - 25
app/src/main/java/com/owncloud/android/providers/FileContentProvider.java

@@ -75,14 +75,12 @@ public class FileContentProvider extends ContentProvider {
     private static final int UPLOADS = 6;
     private static final int SYNCED_FOLDERS = 7;
     private static final int EXTERNAL_LINKS = 8;
-    private static final int ARBITRARY_DATA = 9;
     private static final int VIRTUAL = 10;
     private static final int FILESYSTEM = 11;
     private static final String TAG = FileContentProvider.class.getSimpleName();
     // todo avoid string concatenation and use string formatting instead later.
     private static final String ERROR = "ERROR ";
     private static final int SINGLE_PATH_SEGMENT = 1;
-    public static final int ARBITRARY_DATA_TABLE_INTRODUCTION_VERSION = 20;
     public static final int MINIMUM_PATH_SEGMENTS_SIZE = 1;
 
     private static final String[] PROJECTION_CONTENT_TYPE = new String[]{
@@ -160,9 +158,6 @@ public class FileContentProvider extends ContentProvider {
             case EXTERNAL_LINKS:
                 count = db.delete(ProviderTableMeta.EXTERNAL_LINKS_TABLE_NAME, where, whereArgs);
                 break;
-            case ARBITRARY_DATA:
-                count = db.delete(ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME, where, whereArgs);
-                break;
             case VIRTUAL:
                 count = db.delete(ProviderTableMeta.VIRTUAL_TABLE_NAME, where, whereArgs);
                 break;
@@ -361,16 +356,6 @@ public class FileContentProvider extends ContentProvider {
                 }
                 return insertedExternalLinkUri;
 
-            case ARBITRARY_DATA:
-                Uri insertedArbitraryDataUri;
-                long arbitraryDataId = db.insert(ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
-                if (arbitraryDataId > 0) {
-                    insertedArbitraryDataUri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_ARBITRARY_DATA,
-                                                                          arbitraryDataId);
-                } else {
-                    throw new SQLException("ERROR " + uri);
-                }
-                return insertedArbitraryDataUri;
             case VIRTUAL:
                 Uri insertedVirtualUri;
                 long virtualId = db.insert(ProviderTableMeta.VIRTUAL_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values);
@@ -456,7 +441,6 @@ public class FileContentProvider extends ContentProvider {
         mUriMatcher.addURI(authority, "uploads/#", UPLOADS);
         mUriMatcher.addURI(authority, "synced_folders", SYNCED_FOLDERS);
         mUriMatcher.addURI(authority, "external_links", EXTERNAL_LINKS);
-        mUriMatcher.addURI(authority, "arbitrary_data", ARBITRARY_DATA);
         mUriMatcher.addURI(authority, "virtual", VIRTUAL);
         mUriMatcher.addURI(authority, "filesystem", FILESYSTEM);
 
@@ -525,9 +509,6 @@ public class FileContentProvider extends ContentProvider {
             case EXTERNAL_LINKS:
                 tableName = ProviderTableMeta.EXTERNAL_LINKS_TABLE_NAME;
                 break;
-            case ARBITRARY_DATA:
-                tableName = ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME;
-                break;
             case VIRTUAL:
                 tableName = ProviderTableMeta.VIRTUAL_TABLE_NAME;
                 break;
@@ -567,9 +548,6 @@ public class FileContentProvider extends ContentProvider {
                 case EXTERNAL_LINKS:
                     order = ProviderTableMeta.EXTERNAL_LINKS_NAME;
                     break;
-                case ARBITRARY_DATA:
-                    order = ProviderTableMeta.ARBITRARY_DATA_CLOUD_ID;
-                    break;
                 case VIRTUAL:
                     order = ProviderTableMeta.VIRTUAL_TYPE;
                     break;
@@ -659,8 +637,6 @@ public class FileContentProvider extends ContentProvider {
                 return db.update(ProviderTableMeta.UPLOADS_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
             case SYNCED_FOLDERS:
                 return db.update(ProviderTableMeta.SYNCED_FOLDERS_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
-            case ARBITRARY_DATA:
-                return db.update(ProviderTableMeta.ARBITRARY_DATA_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
             case FILESYSTEM:
                 return db.update(ProviderTableMeta.FILESYSTEM_TABLE_NAME, SQLiteDatabase.CONFLICT_REPLACE, values, selection, selectionArgs);
             default:
@@ -699,7 +675,6 @@ public class FileContentProvider extends ContentProvider {
             case UPLOADS:
             case SYNCED_FOLDERS:
             case EXTERNAL_LINKS:
-            case ARBITRARY_DATA:
             case VIRTUAL:
             case FILESYSTEM:
                 String callingPackage = mContext.getPackageManager().getNameForUid(Binder.getCallingUid());

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

@@ -377,7 +377,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().getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContext());
 
         String userId = uri.getQueryParameter("shareWith");
         String displayName = uri.getQueryParameter("displayName");

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

@@ -907,7 +907,7 @@ public abstract class DrawerActivity extends ToolbarActivity
         }
 
         externalLinksProvider = new ExternalLinksProvider(getContentResolver());
-        arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
+        arbitraryDataProvider = new ArbitraryDataProvider(this);
     }
 
     @Override

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

@@ -644,7 +644,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(getContentResolver());
+            ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
             int count = arbitraryDataProvider.getIntegerValue(FilesSyncHelper.GLOBAL, APP_OPENED_COUNT);
 
             if (count > 10 || count == -1) {

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

@@ -142,7 +142,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
             originalCurrentUser = currentUser.get().getAccountName();
         }
 
-        arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
+        arbitraryDataProvider = new ArbitraryDataProvider(this);
 
         multipleAccountsSupported = getResources().getBoolean(R.bool.multiaccount_support);
 
@@ -426,7 +426,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
         }
 
         // store pending account removal
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
         arbitraryDataProvider.storeOrUpdateKeyValue(user.getAccountName(), PENDING_FOR_REMOVAL, String.valueOf(true));
 
         // Cancel transfers

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

@@ -146,7 +146,7 @@ public class NotificationsActivity extends DrawerActivity implements Notificatio
                                          R.string.push_notifications_not_implemented,
                                          Snackbar.LENGTH_INDEFINITE);
             } else {
-                final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
+                final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
                 final String accountName = optionalUser.isPresent() ? optionalUser.get().getAccountName() : "";
                 final boolean usesOldLogin = arbitraryDataProvider.getBooleanValue(accountName,
                                                                                    UserAccountManager.ACCOUNT_USES_STANDARD_PASSWORD);

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

@@ -606,7 +606,7 @@ public class SettingsActivity extends PreferenceActivity
             preferenceScreen.removePreference(preferenceCategorySyncedFolders);
         } else {
             // Upload on WiFi
-            final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
+            final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
 
             final SwitchPreference pUploadOnWifiCheckbox = (SwitchPreference) findPreference("synced_folder_on_wifi");
             pUploadOnWifiCheckbox.setChecked(
@@ -872,7 +872,7 @@ public class SettingsActivity extends PreferenceActivity
                                  RequestCredentialsActivity.KEY_CHECK_RESULT_FALSE) ==
                 RequestCredentialsActivity.KEY_CHECK_RESULT_TRUE) {
 
-                ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(getContentResolver());
+                ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(this);
                 String mnemonic = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.MNEMONIC);
 
                 AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.FallbackTheming_Dialog);

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

@@ -696,14 +696,14 @@ class SyncedFoldersActivity :
                 backgroundJobManager.startImmediateFilesSyncJob(skipCustomFolders = false, overridePowerSaving = false)
             } else {
                 val syncedFolderInitiatedKey = KEY_SYNCED_FOLDER_INITIATED_PREFIX + item.id
-                val arbitraryDataProvider = ArbitraryDataProvider(MainApp.getAppContext().contentResolver)
+                val arbitraryDataProvider = ArbitraryDataProvider(MainApp.getAppContext())
                 arbitraryDataProvider.deleteKeyForAccount("global", syncedFolderInitiatedKey)
             }
         }
     }
 
     private fun storeSyncedFolder(item: SyncedFolderDisplayItem) {
-        val arbitraryDataProvider = ArbitraryDataProvider(MainApp.getAppContext().contentResolver)
+        val arbitraryDataProvider = ArbitraryDataProvider(MainApp.getAppContext())
         val storedId = syncedFolderProvider.storeSyncedFolder(item)
         if (storedId != -1L) {
             item.id = storedId

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

@@ -132,7 +132,7 @@ public class SetupEncryptionDialogFragment extends DialogFragment implements Inj
     public Dialog onCreateDialog(Bundle savedInstanceState) {
         user = getArguments().getParcelable(ARG_USER);
 
-        arbitraryDataProvider = new ArbitraryDataProvider(getContext().getContentResolver());
+        arbitraryDataProvider = new ArbitraryDataProvider(getContext());
 
         // Inflate the layout for the dialog
         LayoutInflater inflater = getActivity().getLayoutInflater();

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

@@ -103,7 +103,7 @@ public class OCFileListBottomSheetDialog extends BottomSheetDialog implements In
             binding.templates.setVisibility(View.VISIBLE);
         }
 
-        String json = new ArbitraryDataProvider(getContext().getContentResolver())
+        String json = new ArbitraryDataProvider(getContext())
             .getValue(user, ArbitraryDataProvider.DIRECT_EDITING);
 
         if (!json.isEmpty() &&

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

@@ -1120,7 +1120,7 @@ public class FileOperationsHelper {
     }
 
     public static boolean isEndToEndEncryptionSetup(Context context, User user) {
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
 
         String publicKey = arbitraryDataProvider.getValue(user, EncryptionUtils.PUBLIC_KEY);
         String privateKey = arbitraryDataProvider.getValue(user, EncryptionUtils.PRIVATE_KEY);

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

@@ -491,7 +491,7 @@ public final class DisplayUtils {
             ((View) callContext).setContentDescription(String.valueOf(user.toPlatformAccount().hashCode()));
         }
 
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
 
         final String accountName = user.getAccountName();
         String serverName = accountName.substring(accountName.lastIndexOf('@') + 1);

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

@@ -231,7 +231,7 @@ public final class EncryptionUtils {
         }
 
         // decrypt metadata
-        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context.getContentResolver());
+        ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProvider(context);
         String serializedEncryptedMetadata = (String) getMetadataOperationResult.getData().get(0);
         String privateKey = arbitraryDataProvider.getValue(user.getAccountName(), EncryptionUtils.PRIVATE_KEY);