From 3acb8500c8768d9b199ed61ca47c405e9a493cf1 Mon Sep 17 00:00:00 2001 From: M66B Date: Fri, 20 Jan 2023 18:48:04 +0100 Subject: [PATCH] Cloud sync: switches for send/receive --- .../java/eu/faircode/email/CloudSync.java | 24 +++++++++++- .../java/eu/faircode/email/DaoAccount.java | 10 ++--- .../java/eu/faircode/email/DaoIdentity.java | 5 +++ .../faircode/email/FragmentOptionsBackup.java | 21 ++++++++++ .../res/layout/fragment_options_backup.xml | 39 +++++++++++++++++-- app/src/main/res/values/strings.xml | 9 ++++- 6 files changed, 97 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/CloudSync.java b/app/src/main/java/eu/faircode/email/CloudSync.java index d9154909d1..79aa0ea21b 100644 --- a/app/src/main/java/eu/faircode/email/CloudSync.java +++ b/app/src/main/java/eu/faircode/email/CloudSync.java @@ -215,6 +215,12 @@ public class CloudSync { throws JSONException, GeneralSecurityException, IOException { DB db = DB.getInstance(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean cloud_send = prefs.getBoolean("cloud_send", true); + + if (!cloud_send) { + Log.w("Cloud skip send"); + return; + } List accounts = db.account().getSynchronizingAccounts(null); Log.i("Cloud accounts=" + (accounts == null ? null : accounts.size())); @@ -299,6 +305,12 @@ public class CloudSync { throws JSONException, GeneralSecurityException, IOException { DB db = DB.getInstance(context); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean cloud_receive = prefs.getBoolean("cloud_receive", true); + + if (!cloud_receive) { + Log.w("Cloud skip receive"); + return; + } // New revision boolean updates = false; @@ -416,10 +428,12 @@ public class CloudSync { db.account().resetPrimary(); db.account().setAccountPrimary(raccount.id, true); } - db.account().setLastModified(raccount.id, rrevision); + db.account().setAccountLastModified(raccount.id, rrevision); } db.setTransactionSuccessful(); + + updates = true; } finally { db.endTransaction(); } @@ -474,6 +488,14 @@ public class CloudSync { db.identity().updateIdentity(ridentity); } + if (ridentity.id != null) { + if (ridentity.primary) { + db.identity().resetPrimary(ridentity.account); + db.identity().setIdentityPrimary(ridentity.id, true); + } + db.identity().setIdentityLastModified(ridentity.id, rrevision); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); diff --git a/app/src/main/java/eu/faircode/email/DaoAccount.java b/app/src/main/java/eu/faircode/email/DaoAccount.java index 2c20adea42..15987e94f4 100644 --- a/app/src/main/java/eu/faircode/email/DaoAccount.java +++ b/app/src/main/java/eu/faircode/email/DaoAccount.java @@ -288,11 +288,6 @@ public interface DaoAccount { " AND (NOT (swipe_left IS :left) OR NOT (swipe_right IS :right))") int setAccountSwipes(long id, Long left, Long right); - @Query("UPDATE account" + - " SET last_modified = :last_modified" + - " WHERE id = :id") - int setLastModified(long id, Long last_modified); - @Query("UPDATE account SET `primary` = 0 WHERE NOT (`primary` IS 0)") void resetPrimary(); @@ -305,6 +300,11 @@ public interface DaoAccount { @Query("UPDATE account SET capability_uidl = :uidl WHERE id = :id AND NOT (capability_uidl IS :uidl)") int setAccountUidl(long id, Boolean uidl); + @Query("UPDATE account" + + " SET last_modified = :last_modified" + + " WHERE id = :id") + int setAccountLastModified(long id, Long last_modified); + @Query("DELETE FROM account WHERE id = :id") int deleteAccount(long id); } diff --git a/app/src/main/java/eu/faircode/email/DaoIdentity.java b/app/src/main/java/eu/faircode/email/DaoIdentity.java index f10f59d701..a5f2bb2d29 100644 --- a/app/src/main/java/eu/faircode/email/DaoIdentity.java +++ b/app/src/main/java/eu/faircode/email/DaoIdentity.java @@ -153,6 +153,11 @@ public interface DaoIdentity { @Query("UPDATE identity SET `primary` = 0 WHERE account = :account AND NOT (`primary` IS 0)") void resetPrimary(long account); + @Query("UPDATE identity" + + " SET last_modified = :last_modified" + + " WHERE id = :id") + int setIdentityLastModified(long id, Long last_modified); + @Query("DELETE FROM identity WHERE id = :id") int deleteIdentity(long id); } diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsBackup.java b/app/src/main/java/eu/faircode/email/FragmentOptionsBackup.java index 7a74ba4101..2decdda27d 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsBackup.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsBackup.java @@ -119,6 +119,8 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere private TextInputLayout tilPassword; private Button btnLogin; private TextView tvLogin; + private CheckBox cbSend; + private CheckBox cbReceive; private ImageButton ibSync; private TextView tvLastSync; private Button btnLogout; @@ -159,6 +161,8 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere tilPassword = view.findViewById(R.id.tilPassword); btnLogin = view.findViewById(R.id.btnLogin); tvLogin = view.findViewById(R.id.tvLogin); + cbSend = view.findViewById(R.id.cbSend); + cbReceive = view.findViewById(R.id.cbReceive); ibSync = view.findViewById(R.id.ibSync); tvLastSync = view.findViewById(R.id.tvLastSync); btnLogout = view.findViewById(R.id.btnLogout); @@ -212,6 +216,20 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere } }); + cbSend.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + prefs.edit().putBoolean("cloud_send", isChecked).apply(); + } + }); + + cbReceive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + prefs.edit().putBoolean("cloud_receive", isChecked).apply(); + } + }); + btnLogout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -229,6 +247,9 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere ? View.VISIBLE : View.GONE); Helper.linkPro(tvCloudPro); + cbSend.setChecked(prefs.getBoolean("cloud_send", true)); + cbReceive.setChecked(prefs.getBoolean("cloud_receive", true)); + prefs.registerOnSharedPreferenceChangeListener(this); onSharedPreferenceChanged(prefs, null); diff --git a/app/src/main/res/layout/fragment_options_backup.xml b/app/src/main/res/layout/fragment_options_backup.xml index 8ee0a33ded..3586a5aaa0 100644 --- a/app/src/main/res/layout/fragment_options_backup.xml +++ b/app/src/main/res/layout/fragment_options_backup.xml @@ -184,7 +184,18 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginTop="12dp" - android:layout_marginEnd="12dp" + android:text="@string/title_advanced_cloud_info" + android:textAppearance="@style/TextAppearance.AppCompat.Small" + android:textStyle="italic" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/tvCloud" /> + + + app:layout_constraintTop_toBottomOf="@id/tvCloudInfo" /> + app:layout_constraintTop_toBottomOf="@id/tvCloudSecurity" /> + + + + This is an experimental feature! + This feature is for synchronizing data between devices All data is encrypted end-to-end and the cloud server will never see the username, password and data Login Logging in for the first time will automatically create an account Invalid username or password - Only the data of enabled accounts will be synced and existing accounts on the device will never be deleted. + + Only enabled accounts and identities will be synchronized. + Folder properties will not be synchronized. + Existing accounts on the device will never be deleted. + + Receive data + Send data Last sync: %1$s Logout Wipe cloud data on logout