Browse Source

Actually persist backup preferences

Currently, the backup is always enabled if the permissions are granted, so the checkboxes make no sense.

This fixes that by actually persisting the checkbox status as a preference, and honoring that for schedulling/cancelling the backup jobs.

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
Álvaro Brey 2 years ago
parent
commit
7a1e8189da

+ 7 - 0
app/src/main/java/com/nextcloud/client/preferences/AppPreferences.java

@@ -20,6 +20,7 @@
 
 
 package com.nextcloud.client.preferences;
 package com.nextcloud.client.preferences;
 
 
+import com.nextcloud.client.account.User;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.utils.FileSortOrder;
 import com.owncloud.android.utils.FileSortOrder;
 
 
@@ -377,4 +378,10 @@ public interface AppPreferences {
     boolean isStoragePermissionRequested();
     boolean isStoragePermissionRequested();
 
 
     void setStoragePermissionRequested(boolean value);
     void setStoragePermissionRequested(boolean value);
+
+    boolean isContactsBackupEnabled(final User user);
+    void setContactsBackupEnabled(final User user, final boolean value);
+
+    boolean isCalendarBackupEnabled(final User user);
+    void setCalendarBackupEnabled(final User user, final boolean value);
 }
 }

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

@@ -24,6 +24,7 @@ package com.nextcloud.client.preferences;
 import android.annotation.SuppressLint;
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences;
+import android.net.Uri;
 
 
 import com.nextcloud.client.account.CurrentAccountProvider;
 import com.nextcloud.client.account.CurrentAccountProvider;
 import com.nextcloud.client.account.User;
 import com.nextcloud.client.account.User;
@@ -99,6 +100,9 @@ public final class AppPreferencesImpl implements AppPreferences {
 
 
     private static final String PREF__STORAGE_PERMISSION_REQUESTED = "storage_permission_requested";
     private static final String PREF__STORAGE_PERMISSION_REQUESTED = "storage_permission_requested";
 
 
+    private static final String PREF__CALENDAR_BACKUP_ENABLED = "calendar_backup_enabled";
+    private static final String PREF__CONTACTS_BACKUP_ENABLED = "contacts_backup_enabled";
+
     private final Context context;
     private final Context context;
     private final SharedPreferences preferences;
     private final SharedPreferences preferences;
     private final CurrentAccountProvider currentAccountProvider;
     private final CurrentAccountProvider currentAccountProvider;
@@ -164,6 +168,10 @@ public final class AppPreferencesImpl implements AppPreferences {
         this.preferences.registerOnSharedPreferenceChangeListener(listeners);
         this.preferences.registerOnSharedPreferenceChangeListener(listeners);
     }
     }
 
 
+    private String getUserScopedKey(final User user, final String originalKey) {
+        return Uri.encode(user.getAccountName()) + "__" + originalKey;
+    }
+
     @Override
     @Override
     public void addListener(@Nullable AppPreferences.Listener listener) {
     public void addListener(@Nullable AppPreferences.Listener listener) {
         this.listeners.add(listener);
         this.listeners.add(listener);
@@ -708,6 +716,30 @@ public final class AppPreferencesImpl implements AppPreferences {
         preferences.edit().putBoolean(PREF__STORAGE_PERMISSION_REQUESTED, value).apply();
         preferences.edit().putBoolean(PREF__STORAGE_PERMISSION_REQUESTED, value).apply();
     }
     }
 
 
+    @Override
+    public boolean isContactsBackupEnabled(final User user) {
+        final String key = getUserScopedKey(user, PREF__CONTACTS_BACKUP_ENABLED);
+        return preferences.getBoolean(key, false);
+    }
+
+    @Override
+    public void setContactsBackupEnabled(final User user, boolean value) {
+        final String key = getUserScopedKey(user, PREF__CONTACTS_BACKUP_ENABLED);
+        preferences.edit().putBoolean(key, value).apply();
+    }
+
+    @Override
+    public boolean isCalendarBackupEnabled(final User user) {
+        final String key = getUserScopedKey(user, PREF__CALENDAR_BACKUP_ENABLED);
+        return preferences.getBoolean(key, false);
+    }
+
+    @Override
+    public void setCalendarBackupEnabled(final User user, boolean value) {
+        final String key = getUserScopedKey(user, PREF__CALENDAR_BACKUP_ENABLED);
+        preferences.edit().putBoolean(key, value).apply();
+    }
+
     @VisibleForTesting
     @VisibleForTesting
     public int computeBruteForceDelay(int count) {
     public int computeBruteForceDelay(int count) {
         return (int) Math.min(count / 3d, 10);
         return (int) Math.min(count / 3d, 10);

+ 92 - 52
app/src/main/java/com/owncloud/android/ui/fragment/contactsbackup/BackupFragment.java

@@ -37,6 +37,7 @@ import android.widget.Toast;
 import com.nextcloud.client.account.User;
 import com.nextcloud.client.account.User;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.di.Injectable;
 import com.nextcloud.client.jobs.BackgroundJobManager;
 import com.nextcloud.client.jobs.BackgroundJobManager;
+import com.nextcloud.client.preferences.AppPreferences;
 import com.nextcloud.java.util.Optional;
 import com.nextcloud.java.util.Optional;
 import com.owncloud.android.R;
 import com.owncloud.android.R;
 import com.owncloud.android.databinding.BackupFragmentBinding;
 import com.owncloud.android.databinding.BackupFragmentBinding;
@@ -44,6 +45,7 @@ import com.owncloud.android.datamodel.ArbitraryDataProvider;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.FileDataStorageManager;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.datamodel.OCFile;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 import com.owncloud.android.lib.common.operations.RemoteOperationResult;
+import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.operations.RefreshFolderOperation;
 import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
 import com.owncloud.android.ui.activity.ContactsPreferenceActivity;
 import com.owncloud.android.ui.activity.SettingsActivity;
 import com.owncloud.android.ui.activity.SettingsActivity;
@@ -90,6 +92,8 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
     @Inject ThemeUtils themeUtils;
     @Inject ThemeUtils themeUtils;
     @Inject ThemeCheckableUtils themeCheckableUtils;
     @Inject ThemeCheckableUtils themeCheckableUtils;
     @Inject ThemeButtonUtils themeButtonUtils;
     @Inject ThemeButtonUtils themeButtonUtils;
+    @Inject ArbitraryDataProvider arbitraryDataProvider;
+    @Inject AppPreferences appPreferences;
 
 
     private Date selectedDate;
     private Date selectedDate;
     private boolean calendarPickerOpen;
     private boolean calendarPickerOpen;
@@ -99,7 +103,6 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
     private CompoundButton.OnCheckedChangeListener dailyBackupCheckedChangeListener;
     private CompoundButton.OnCheckedChangeListener dailyBackupCheckedChangeListener;
     private CompoundButton.OnCheckedChangeListener contactsCheckedListener;
     private CompoundButton.OnCheckedChangeListener contactsCheckedListener;
     private CompoundButton.OnCheckedChangeListener calendarCheckedListener;
     private CompoundButton.OnCheckedChangeListener calendarCheckedListener;
-    private ArbitraryDataProvider arbitraryDataProvider;
     private User user;
     private User user;
     private boolean showSidebar = true;
     private boolean showSidebar = true;
 
 
@@ -111,6 +114,22 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
         return fragment;
         return fragment;
     }
     }
 
 
+    private boolean isCalendarBackupEnabled() {
+        return appPreferences.isCalendarBackupEnabled(user);
+    }
+
+    private void setCalendarBackupEnabled(final boolean enabled) {
+        appPreferences.setCalendarBackupEnabled(user, enabled);
+    }
+
+    private boolean isContactsBackupEnabled() {
+        return appPreferences.isContactsBackupEnabled(user);
+    }
+
+    private void setContactsBackupEnabled(final boolean enabled) {
+        appPreferences.setContactsBackupEnabled(user, enabled);
+    }
+
     @Override
     @Override
     public View onCreateView(@NonNull final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     public View onCreateView(@NonNull final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 
 
@@ -140,7 +159,6 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
             themeToolbarUtils.tintBackButton(actionBar, getContext());
             themeToolbarUtils.tintBackButton(actionBar, getContext());
         }
         }
 
 
-        arbitraryDataProvider = new ArbitraryDataProvider(getContext().getContentResolver());
 
 
         themeCheckableUtils.tintSwitch(binding.contacts, themeColorUtils);
         themeCheckableUtils.tintSwitch(binding.contacts, themeColorUtils);
         themeCheckableUtils.tintSwitch(binding.calendar, themeColorUtils);
         themeCheckableUtils.tintSwitch(binding.calendar, themeColorUtils);
@@ -148,46 +166,15 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
         binding.dailyBackup.setChecked(arbitraryDataProvider.getBooleanValue(user,
         binding.dailyBackup.setChecked(arbitraryDataProvider.getBooleanValue(user,
                                                                              PREFERENCE_CONTACTS_AUTOMATIC_BACKUP));
                                                                              PREFERENCE_CONTACTS_AUTOMATIC_BACKUP));
 
 
-        binding.contacts.setChecked(checkContactBackupPermission());
-        binding.calendar.setChecked(checkCalendarBackupPermission(getContext()));
-
-        dailyBackupCheckedChangeListener = (buttonView, isChecked) -> {
-            if (checkAndAskForContactsReadPermission()) {
-                setAutomaticBackup(isChecked);
-            }
-        };
+        binding.contacts.setChecked(isContactsBackupEnabled() && checkContactBackupPermission());
+        binding.calendar.setChecked(isCalendarBackupEnabled() && checkCalendarBackupPermission(getContext()));
 
 
-        contactsCheckedListener = (buttonView, isChecked) -> {
-            if (isChecked) {
-                if (checkAndAskForContactsReadPermission()) {
-                    binding.backupNow.setVisibility(View.VISIBLE);
-                }
-            } else {
-                if (!binding.calendar.isChecked()) {
-                    binding.backupNow.setVisibility(View.INVISIBLE);
-                }
-            }
-        };
-        binding.contacts.setOnCheckedChangeListener(contactsCheckedListener);
 
 
-        calendarCheckedListener = (buttonView, isChecked) -> {
-            if (isChecked) {
-                if (checkAndAskForCalendarReadPermission()) {
-                    binding.backupNow.setVisibility(View.VISIBLE);
-                }
-            } else {
-                if (!binding.contacts.isChecked()) {
-                    binding.backupNow.setVisibility(View.INVISIBLE);
-                }
-            }
-        };
+        setupCheckListeners();
 
 
-        binding.calendar.setOnCheckedChangeListener(calendarCheckedListener);
+        setBackupNowButtonVisibility();
 
 
-        binding.dailyBackup.setOnCheckedChangeListener(dailyBackupCheckedChangeListener);
-        binding.backupNow.setOnClickListener(v -> backup());
-        binding.backupNow.setEnabled(checkBackupNowPermission());
-        binding.backupNow.setVisibility(checkBackupNowPermission() ? View.VISIBLE : View.GONE);
+        binding.backupNow.setOnClickListener(v -> backupNow());
 
 
         binding.contactsDatepicker.setOnClickListener(v -> openCleanDate());
         binding.contactsDatepicker.setOnClickListener(v -> openCleanDate());
 
 
@@ -222,6 +209,50 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
         return view;
         return view;
     }
     }
 
 
+    private void setupCheckListeners() {
+        dailyBackupCheckedChangeListener = (buttonView, isChecked) -> {
+            if (checkAndAskForContactsReadPermission()) {
+                setAutomaticBackup(isChecked);
+            }
+        };
+        binding.dailyBackup.setOnCheckedChangeListener(dailyBackupCheckedChangeListener);
+
+
+        contactsCheckedListener = (buttonView, isChecked) -> {
+            if (isChecked) {
+                if (checkAndAskForContactsReadPermission()) {
+                    setContactsBackupEnabled(true);
+                }
+            } else {
+                setContactsBackupEnabled(false);
+            }
+            setBackupNowButtonVisibility();
+            setAutomaticBackup(binding.dailyBackup.isChecked());
+        };
+        binding.contacts.setOnCheckedChangeListener(contactsCheckedListener);
+
+        calendarCheckedListener = (buttonView, isChecked) -> {
+            if (isChecked) {
+                if (checkAndAskForCalendarReadPermission()) {
+                    setCalendarBackupEnabled(true);
+                }
+            } else {
+                setCalendarBackupEnabled(false);
+            }
+            setBackupNowButtonVisibility();
+            setAutomaticBackup(binding.dailyBackup.isChecked());
+        };
+        binding.calendar.setOnCheckedChangeListener(calendarCheckedListener);
+    }
+
+    private void setBackupNowButtonVisibility() {
+        if (binding.contacts.isChecked() || binding.calendar.isChecked()) {
+            binding.backupNow.setVisibility(View.VISIBLE);
+        } else {
+            binding.backupNow.setVisibility(View.INVISIBLE);
+        }
+    }
+
     @Override
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
         super.onActivityCreated(savedInstanceState);
@@ -329,6 +360,7 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
                 if (Manifest.permission.READ_CONTACTS.equalsIgnoreCase(permissions[index])) {
                 if (Manifest.permission.READ_CONTACTS.equalsIgnoreCase(permissions[index])) {
                     if (grantResults[index] >= 0) {
                     if (grantResults[index] >= 0) {
                         // if approved, exit for loop
                         // if approved, exit for loop
+                        setContactsBackupEnabled(true);
                         break;
                         break;
                     }
                     }
 
 
@@ -355,21 +387,21 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
                 binding.calendar.setOnCheckedChangeListener(null);
                 binding.calendar.setOnCheckedChangeListener(null);
                 binding.calendar.setChecked(false);
                 binding.calendar.setChecked(false);
                 binding.calendar.setOnCheckedChangeListener(calendarCheckedListener);
                 binding.calendar.setOnCheckedChangeListener(calendarCheckedListener);
-
-                binding.backupNow.setVisibility(checkBackupNowPermission() ? View.VISIBLE : View.GONE);
+            } else {
+                setCalendarBackupEnabled(true);
             }
             }
         }
         }
 
 
-        binding.backupNow.setVisibility(checkBackupNowPermission() ? View.VISIBLE : View.GONE);
-        binding.backupNow.setEnabled(checkBackupNowPermission());
+        setBackupNowButtonVisibility();
+        setAutomaticBackup(binding.dailyBackup.isChecked());
     }
     }
 
 
-    public void backup() {
-        if (binding.contacts.isChecked() && checkAndAskForContactsReadPermission()) {
+    public void backupNow() {
+        if (isContactsBackupEnabled() && checkContactBackupPermission()) {
             startContactsBackupJob();
             startContactsBackupJob();
         }
         }
 
 
-        if (binding.calendar.isChecked() && checkAndAskForCalendarReadPermission()) {
+        if (isCalendarBackupEnabled() && checkCalendarBackupPermission(requireContext())) {
             startCalendarBackupJob();
             startCalendarBackupJob();
         }
         }
 
 
@@ -409,9 +441,22 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
         }
         }
         User user = optionalUser.get();
         User user = optionalUser.get();
         if (enabled) {
         if (enabled) {
-            backgroundJobManager.schedulePeriodicContactsBackup(user);
-            backgroundJobManager.schedulePeriodicCalendarBackup(user);
+            if (isContactsBackupEnabled()) {
+                Log_OC.d(TAG, "Scheduling contacts backup job");
+                backgroundJobManager.schedulePeriodicContactsBackup(user);
+            } else {
+                Log_OC.d(TAG, "Cancelling contacts backup job");
+                backgroundJobManager.cancelPeriodicContactsBackup(user);
+            }
+            if (isCalendarBackupEnabled()) {
+                Log_OC.d(TAG, "Scheduling calendar backup job");
+                backgroundJobManager.schedulePeriodicCalendarBackup(user);
+            } else {
+                Log_OC.d(TAG, "Cancelling calendar backup job");
+                backgroundJobManager.cancelPeriodicCalendarBackup(user);
+            }
         } else {
         } else {
+            Log_OC.d(TAG, "Cancelling all backup jobs");
             backgroundJobManager.cancelPeriodicContactsBackup(user);
             backgroundJobManager.cancelPeriodicContactsBackup(user);
             backgroundJobManager.cancelPeriodicCalendarBackup(user);
             backgroundJobManager.cancelPeriodicCalendarBackup(user);
         }
         }
@@ -449,11 +494,6 @@ public class BackupFragment extends FileFragment implements DatePickerDialog.OnD
         }
         }
     }
     }
 
 
-    private boolean checkBackupNowPermission() {
-        return (checkCalendarBackupPermission(getContext()) && binding.calendar.isChecked()) ||
-            (checkContactBackupPermission() && binding.contacts.isChecked());
-    }
-
     private boolean checkCalendarBackupPermission(final Context context) {
     private boolean checkCalendarBackupPermission(final Context context) {
         return PermissionUtil.checkSelfPermission(context, Manifest.permission.READ_CALENDAR) && PermissionUtil.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR);
         return PermissionUtil.checkSelfPermission(context, Manifest.permission.READ_CALENDAR) && PermissionUtil.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR);
     }
     }