From 544eb3b6e29a32b89c1c1fd555684d7ab0021cd5 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Wed, 2 Nov 2022 19:33:17 +0600 Subject: [PATCH 1/9] Handle sync status on account setup issue: https://gitlab.e.foundation/e/backlog/-/issues/3081 On murena & google account auto setup, check the sync status first. If the master sync or the mail sync for that account is disable, ignore the account & don't setup. --- app/core/src/main/java/com/fsck/k9/Account.kt | 5 +++ .../fsck/k9/setup/AccountManagerConstants.kt | 2 ++ .../fsck/k9/account/AccountSyncReceiver.kt | 5 +++ .../java/com/fsck/k9/activity/MessageList.kt | 7 ++++ .../accountmanager/EeloAccountCreator.java | 32 +++++++++++++++---- 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/app/core/src/main/java/com/fsck/k9/Account.kt b/app/core/src/main/java/com/fsck/k9/Account.kt index 71d4d6fc04..0c008832fb 100644 --- a/app/core/src/main/java/com/fsck/k9/Account.kt +++ b/app/core/src/main/java/com/fsck/k9/Account.kt @@ -589,6 +589,11 @@ class Account(override val uuid: String) : BaseAccount { isFinishedSetup = true } + @Synchronized + fun markSetupUnfinished() { + isFinishedSetup = false + } + @Synchronized fun updateNotificationSettings(block: (oldNotificationSettings: NotificationSettings) -> NotificationSettings) { notificationSettings = block(notificationSettings) diff --git a/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt b/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt index 368a5a2abb..b70aad6478 100644 --- a/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt +++ b/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt @@ -26,4 +26,6 @@ object AccountManagerConstants { const val OPEN_APP_PACKAGE_AFTER_AUTH = "open_app_package_after_auth" const val OPEN_APP_ACTIVITY_AFTER_AUTH = "open_app_activity_after_auth" + + const val IGNORE_ACCOUNT_SETUP = "ignore_account_setup" } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt index ce18077553..9c4c7ab20f 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt @@ -66,6 +66,11 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { val account = intent.extras?.getString("account") ?: return preferences.accounts.forEach { if (it.email == account) { + // sometimes messageList page opens before remove account is called. + // To resolve this issue, mark the account as unfinished before removing the account + it.markSetupUnfinished() + preferences.saveAccount(it) + accountRemover.removeAccountAsync(it.uuid) return@forEach } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt index e0fed2a766..9cf29a9812 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt @@ -69,6 +69,7 @@ import com.fsck.k9.search.SearchSpecification import com.fsck.k9.search.SearchSpecification.SearchCondition import com.fsck.k9.search.SearchSpecification.SearchField import com.fsck.k9.search.isUnifiedInbox +import com.fsck.k9.setup.AccountManagerConstants import com.fsck.k9.ui.BuildConfig import com.fsck.k9.ui.K9Drawer import com.fsck.k9.ui.R @@ -166,6 +167,12 @@ open class MessageList : super.onCreate(savedInstanceState) setLayout(R.layout.message_list_loading) + if (intent.getBooleanExtra(AccountManagerConstants.IGNORE_ACCOUNT_SETUP, false)) { + // no need to setup mail accounts for accountManager accounts + onAccountConfigurationFinish(savedInstanceState) + return + } + addNewAccountsAutomatically(savedInstanceState) } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java index bcfe1ec6d6..f07e41c687 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java @@ -18,8 +18,10 @@ package com.fsck.k9.activity.setup.accountmanager; import java.util.List; +import java.util.stream.Collectors; import android.accounts.AccountManager; +import android.content.ContentResolver; import android.content.Context; import android.os.Build.VERSION_CODES; @@ -60,8 +62,7 @@ public class EeloAccountCreator { try { AccountManager accountManager = AccountManager.get(context); - List accounts = preferences.getAccounts(); - deleteIncompleteAccounts(accounts, accountRemover); + List accounts = deleteIncompleteAccounts(preferences.getAccounts(), accountRemover); loadEeloAccounts(context, accounts, accountManager); loadGoogleAccounts(context, accounts, accountManager); @@ -73,6 +74,20 @@ public class EeloAccountCreator { } } + // check the account sync for mail authority is enable or not + private static boolean isSyncable(@Nullable android.accounts.Account account) { + if (account == null) { + return false; + } + + // if master sync disable, then account sync is disable + if (!ContentResolver.getMasterSyncAutomatically()) { + return false; + } + + return ContentResolver.getSyncAutomatically(account, AccountManagerConstants.MAIL_CONTENT_AUTHORITY); + } + @RequiresApi(api = VERSION_CODES.N) private static void loadGoogleAccounts(@NonNull Context context, List accounts, @NonNull AccountManager accountManager) { @@ -89,7 +104,7 @@ public class EeloAccountCreator { .filter(account -> emailId.equalsIgnoreCase(account.getEmail())) .peek(account -> updateAccountNameIfMissing(context, emailId, account)) .findAny().isPresent(); - if (!accountAlreadyPresent) { + if (!accountAlreadyPresent && isSyncable(googleAccount)) { String authState = accountManager.getUserData(googleAccount, AccountManagerConstants.KEY_AUTH_STATE); createAccount(context, emailId, "", authState); } @@ -113,15 +128,14 @@ public class EeloAccountCreator { android.accounts.Account[] eeloAccounts = accountManager.getAccountsByType(AccountManagerConstants.EELO_ACCOUNT_TYPE); for (android.accounts.Account eeloAccount : eeloAccounts) { - String emailId = - accountManager.getUserData(eeloAccount, AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY); + String emailId = accountManager.getUserData(eeloAccount, AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY); if (isInvalidEmail(emailId)) { continue; } boolean isNewAccount = accounts.stream() .noneMatch(account -> emailId.equalsIgnoreCase(account.getEmail())); - if (isNewAccount) { + if (isNewAccount && isSyncable(eeloAccount)) { String password = accountManager.getPassword(eeloAccount); createAccount(context, emailId, password, null); } @@ -129,9 +143,13 @@ public class EeloAccountCreator { } @RequiresApi(api = VERSION_CODES.N) - private static void deleteIncompleteAccounts(List accounts, BackgroundAccountRemover accountRemover) { + private static List deleteIncompleteAccounts(List accounts, BackgroundAccountRemover accountRemover) { accounts.stream().filter(account -> !account.isFinishedSetup()) .forEach(account -> accountRemover.removeAccountAsync(account.getUuid())); + + return accounts.stream() + .filter(Account::isFinishedSetup) + .collect(Collectors.toList()); } private static void createAccount(Context context, String emailId, String password, @Nullable String authState) { -- GitLab From ab4fb3cd6fbb3aeafe908b8ff7f13bdadbc6331f Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Mon, 7 Nov 2022 19:14:26 +0600 Subject: [PATCH 2/9] Revert "Handle sync status on account setup" This reverts commit 544eb3b6e29a32b89c1c1fd555684d7ab0021cd5. --- app/core/src/main/java/com/fsck/k9/Account.kt | 5 --- .../fsck/k9/setup/AccountManagerConstants.kt | 2 -- .../fsck/k9/account/AccountSyncReceiver.kt | 5 --- .../java/com/fsck/k9/activity/MessageList.kt | 7 ---- .../accountmanager/EeloAccountCreator.java | 32 ++++--------------- 5 files changed, 7 insertions(+), 44 deletions(-) diff --git a/app/core/src/main/java/com/fsck/k9/Account.kt b/app/core/src/main/java/com/fsck/k9/Account.kt index 0c008832fb..71d4d6fc04 100644 --- a/app/core/src/main/java/com/fsck/k9/Account.kt +++ b/app/core/src/main/java/com/fsck/k9/Account.kt @@ -589,11 +589,6 @@ class Account(override val uuid: String) : BaseAccount { isFinishedSetup = true } - @Synchronized - fun markSetupUnfinished() { - isFinishedSetup = false - } - @Synchronized fun updateNotificationSettings(block: (oldNotificationSettings: NotificationSettings) -> NotificationSettings) { notificationSettings = block(notificationSettings) diff --git a/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt b/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt index b70aad6478..368a5a2abb 100644 --- a/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt +++ b/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt @@ -26,6 +26,4 @@ object AccountManagerConstants { const val OPEN_APP_PACKAGE_AFTER_AUTH = "open_app_package_after_auth" const val OPEN_APP_ACTIVITY_AFTER_AUTH = "open_app_activity_after_auth" - - const val IGNORE_ACCOUNT_SETUP = "ignore_account_setup" } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt index 9c4c7ab20f..ce18077553 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt @@ -66,11 +66,6 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { val account = intent.extras?.getString("account") ?: return preferences.accounts.forEach { if (it.email == account) { - // sometimes messageList page opens before remove account is called. - // To resolve this issue, mark the account as unfinished before removing the account - it.markSetupUnfinished() - preferences.saveAccount(it) - accountRemover.removeAccountAsync(it.uuid) return@forEach } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt index 9cf29a9812..e0fed2a766 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt @@ -69,7 +69,6 @@ import com.fsck.k9.search.SearchSpecification import com.fsck.k9.search.SearchSpecification.SearchCondition import com.fsck.k9.search.SearchSpecification.SearchField import com.fsck.k9.search.isUnifiedInbox -import com.fsck.k9.setup.AccountManagerConstants import com.fsck.k9.ui.BuildConfig import com.fsck.k9.ui.K9Drawer import com.fsck.k9.ui.R @@ -167,12 +166,6 @@ open class MessageList : super.onCreate(savedInstanceState) setLayout(R.layout.message_list_loading) - if (intent.getBooleanExtra(AccountManagerConstants.IGNORE_ACCOUNT_SETUP, false)) { - // no need to setup mail accounts for accountManager accounts - onAccountConfigurationFinish(savedInstanceState) - return - } - addNewAccountsAutomatically(savedInstanceState) } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java index f07e41c687..bcfe1ec6d6 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java @@ -18,10 +18,8 @@ package com.fsck.k9.activity.setup.accountmanager; import java.util.List; -import java.util.stream.Collectors; import android.accounts.AccountManager; -import android.content.ContentResolver; import android.content.Context; import android.os.Build.VERSION_CODES; @@ -62,7 +60,8 @@ public class EeloAccountCreator { try { AccountManager accountManager = AccountManager.get(context); - List accounts = deleteIncompleteAccounts(preferences.getAccounts(), accountRemover); + List accounts = preferences.getAccounts(); + deleteIncompleteAccounts(accounts, accountRemover); loadEeloAccounts(context, accounts, accountManager); loadGoogleAccounts(context, accounts, accountManager); @@ -74,20 +73,6 @@ public class EeloAccountCreator { } } - // check the account sync for mail authority is enable or not - private static boolean isSyncable(@Nullable android.accounts.Account account) { - if (account == null) { - return false; - } - - // if master sync disable, then account sync is disable - if (!ContentResolver.getMasterSyncAutomatically()) { - return false; - } - - return ContentResolver.getSyncAutomatically(account, AccountManagerConstants.MAIL_CONTENT_AUTHORITY); - } - @RequiresApi(api = VERSION_CODES.N) private static void loadGoogleAccounts(@NonNull Context context, List accounts, @NonNull AccountManager accountManager) { @@ -104,7 +89,7 @@ public class EeloAccountCreator { .filter(account -> emailId.equalsIgnoreCase(account.getEmail())) .peek(account -> updateAccountNameIfMissing(context, emailId, account)) .findAny().isPresent(); - if (!accountAlreadyPresent && isSyncable(googleAccount)) { + if (!accountAlreadyPresent) { String authState = accountManager.getUserData(googleAccount, AccountManagerConstants.KEY_AUTH_STATE); createAccount(context, emailId, "", authState); } @@ -128,14 +113,15 @@ public class EeloAccountCreator { android.accounts.Account[] eeloAccounts = accountManager.getAccountsByType(AccountManagerConstants.EELO_ACCOUNT_TYPE); for (android.accounts.Account eeloAccount : eeloAccounts) { - String emailId = accountManager.getUserData(eeloAccount, AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY); + String emailId = + accountManager.getUserData(eeloAccount, AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY); if (isInvalidEmail(emailId)) { continue; } boolean isNewAccount = accounts.stream() .noneMatch(account -> emailId.equalsIgnoreCase(account.getEmail())); - if (isNewAccount && isSyncable(eeloAccount)) { + if (isNewAccount) { String password = accountManager.getPassword(eeloAccount); createAccount(context, emailId, password, null); } @@ -143,13 +129,9 @@ public class EeloAccountCreator { } @RequiresApi(api = VERSION_CODES.N) - private static List deleteIncompleteAccounts(List accounts, BackgroundAccountRemover accountRemover) { + private static void deleteIncompleteAccounts(List accounts, BackgroundAccountRemover accountRemover) { accounts.stream().filter(account -> !account.isFinishedSetup()) .forEach(account -> accountRemover.removeAccountAsync(account.getUuid())); - - return accounts.stream() - .filter(Account::isFinishedSetup) - .collect(Collectors.toList()); } private static void createAccount(Context context, String emailId, String password, @Nullable String authState) { -- GitLab From a9d4ae64f3fc8ee1998c41e99ca8707baea81fda Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Wed, 2 Nov 2022 19:33:17 +0600 Subject: [PATCH 3/9] Handle sync status on account setup issue: https://gitlab.e.foundation/e/backlog/-/issues/3081 On murena & google account auto setup, check the sync status first. If the master sync or the mail sync for that account is disable, ignore the account & don't setup. --- .../accountmanager/EeloAccountCreator.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java index bcfe1ec6d6..01e82ec869 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java @@ -20,6 +20,7 @@ package com.fsck.k9.activity.setup.accountmanager; import java.util.List; import android.accounts.AccountManager; +import android.content.ContentResolver; import android.content.Context; import android.os.Build.VERSION_CODES; @@ -73,6 +74,20 @@ public class EeloAccountCreator { } } + // check the account sync for mail authority is enable or not + private static boolean isSyncable(@Nullable android.accounts.Account account) { + if (account == null) { + return false; + } + + // if master sync disable, then account sync is disable + if (!ContentResolver.getMasterSyncAutomatically()) { + return false; + } + + return ContentResolver.getSyncAutomatically(account, AccountManagerConstants.MAIL_CONTENT_AUTHORITY); + } + @RequiresApi(api = VERSION_CODES.N) private static void loadGoogleAccounts(@NonNull Context context, List accounts, @NonNull AccountManager accountManager) { @@ -89,7 +104,7 @@ public class EeloAccountCreator { .filter(account -> emailId.equalsIgnoreCase(account.getEmail())) .peek(account -> updateAccountNameIfMissing(context, emailId, account)) .findAny().isPresent(); - if (!accountAlreadyPresent) { + if (!accountAlreadyPresent && isSyncable(googleAccount)) { String authState = accountManager.getUserData(googleAccount, AccountManagerConstants.KEY_AUTH_STATE); createAccount(context, emailId, "", authState); } @@ -113,15 +128,14 @@ public class EeloAccountCreator { android.accounts.Account[] eeloAccounts = accountManager.getAccountsByType(AccountManagerConstants.EELO_ACCOUNT_TYPE); for (android.accounts.Account eeloAccount : eeloAccounts) { - String emailId = - accountManager.getUserData(eeloAccount, AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY); + String emailId = accountManager.getUserData(eeloAccount, AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY); if (isInvalidEmail(emailId)) { continue; } boolean isNewAccount = accounts.stream() .noneMatch(account -> emailId.equalsIgnoreCase(account.getEmail())); - if (isNewAccount) { + if (isNewAccount && isSyncable(eeloAccount)) { String password = accountManager.getPassword(eeloAccount); createAccount(context, emailId, password, null); } -- GitLab From de62d53cb4baf109bc7850b71d1c3c1ce035c083 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Wed, 2 Nov 2022 19:36:03 +0600 Subject: [PATCH 4/9] Add support to ignore auto account setup on opening the app issue: https://gitlab.e.foundation/e/backlog/-/issues/3081 For certain conditions (ex: google account setup called from mail app), right after account setup accountManager opens the mail app, in those case according to latest update, account creation will be handled via syncAdapter onPerformSync call. To handle the race condition, we want option to open the mail app without setting up the automated mail accounts. --- .../main/java/com/fsck/k9/setup/AccountManagerConstants.kt | 2 ++ .../src/main/java/com/fsck/k9/activity/MessageList.kt | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt b/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt index 368a5a2abb..b70aad6478 100644 --- a/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt +++ b/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt @@ -26,4 +26,6 @@ object AccountManagerConstants { const val OPEN_APP_PACKAGE_AFTER_AUTH = "open_app_package_after_auth" const val OPEN_APP_ACTIVITY_AFTER_AUTH = "open_app_activity_after_auth" + + const val IGNORE_ACCOUNT_SETUP = "ignore_account_setup" } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt index e0fed2a766..9cf29a9812 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt @@ -69,6 +69,7 @@ import com.fsck.k9.search.SearchSpecification import com.fsck.k9.search.SearchSpecification.SearchCondition import com.fsck.k9.search.SearchSpecification.SearchField import com.fsck.k9.search.isUnifiedInbox +import com.fsck.k9.setup.AccountManagerConstants import com.fsck.k9.ui.BuildConfig import com.fsck.k9.ui.K9Drawer import com.fsck.k9.ui.R @@ -166,6 +167,12 @@ open class MessageList : super.onCreate(savedInstanceState) setLayout(R.layout.message_list_loading) + if (intent.getBooleanExtra(AccountManagerConstants.IGNORE_ACCOUNT_SETUP, false)) { + // no need to setup mail accounts for accountManager accounts + onAccountConfigurationFinish(savedInstanceState) + return + } + addNewAccountsAutomatically(savedInstanceState) } -- GitLab From d880d5c519799a99c41aaba1f4e3867f67f62419 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Mon, 7 Nov 2022 23:10:59 +0600 Subject: [PATCH 5/9] Add disableSync action in accountSyncReceiver --- app/k9mail/src/main/AndroidManifest.xml | 1 + .../fsck/k9/account/AccountSyncReceiver.kt | 37 ++++++++++++++++--- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/app/k9mail/src/main/AndroidManifest.xml b/app/k9mail/src/main/AndroidManifest.xml index 5ab09c4ff1..ccb5349bc3 100644 --- a/app/k9mail/src/main/AndroidManifest.xml +++ b/app/k9mail/src/main/AndroidManifest.xml @@ -344,6 +344,7 @@ + diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt index ce18077553..74f1732a82 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt @@ -19,9 +19,11 @@ package com.fsck.k9.account import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import com.fsck.k9.Account import com.fsck.k9.Preferences import com.fsck.k9.activity.setup.accountmanager.EeloAccountCreator import com.fsck.k9.controller.push.PushController +import com.fsck.k9.job.K9JobManager import java.util.concurrent.Executors import org.koin.core.component.KoinComponent import org.koin.core.component.inject @@ -29,13 +31,20 @@ import org.koin.core.component.inject class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { companion object { - private const val ACCOUNT_CREATION_ACTION = "foundation.e.accountmanager.account.create" - private const val ACCOUNT_REMOVAL_ACTION = "foundation.e.accountmanager.account.remove" + private const val ACTION_PREFIX = "foundation.e.accountmanager.account" + + private const val ACCOUNT_CREATION_ACTION = "$ACTION_PREFIX.create" + private const val ACCOUNT_REMOVAL_ACTION = "$ACTION_PREFIX.remove" + private const val ACCOUNT_DISABLE_SYNC = "$ACTION_PREFIX.disablesync" + + private const val ACCOUNT = "account" + private const val FREQUENCY_NEVER = -1 } private val pushController: PushController by inject() private val preferences: Preferences by inject() private val accountRemover: BackgroundAccountRemover by inject() + private val jobManager: K9JobManager by inject() override fun onReceive(context: Context?, intent: Intent?) { if (intent == null) { @@ -45,6 +54,7 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { when (intent.action) { ACCOUNT_CREATION_ACTION -> createNewAccount(context) ACCOUNT_REMOVAL_ACTION -> removeAccount(intent) + ACCOUNT_DISABLE_SYNC -> disableSync(intent) } } @@ -63,12 +73,29 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { } private fun removeAccount(intent: Intent) { - val account = intent.extras?.getString("account") ?: return + val account = getAccount(intent) ?: return + accountRemover.removeAccountAsync(account.uuid) + } + + private fun disableSync(intent: Intent) { + val account = getAccount(intent) ?: return + + if (account.updateAutomaticCheckIntervalMinutes(FREQUENCY_NEVER)) { + preferences.saveAccount(account) + jobManager.scheduleMailSync(account) + } + } + + + private fun getAccount(intent: Intent) : Account? { + val account = intent.extras?.getString(ACCOUNT) ?: return null + preferences.accounts.forEach { if (it.email == account) { - accountRemover.removeAccountAsync(it.uuid) - return@forEach + return it } } + + return null } } \ No newline at end of file -- GitLab From a0480f9f00a43114d03ab8141ab7f6d509947838 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Tue, 8 Nov 2022 00:05:59 +0600 Subject: [PATCH 6/9] enableSync from accountCreator page --- .../fsck/k9/account/AccountSyncReceiver.kt | 4 +- .../java/com/fsck/k9/activity/MessageList.kt | 4 +- .../accountmanager/EeloAccountCreator.java | 54 +++++++++++++++---- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt index 74f1732a82..1914033666 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt @@ -38,7 +38,6 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { private const val ACCOUNT_DISABLE_SYNC = "$ACTION_PREFIX.disablesync" private const val ACCOUNT = "account" - private const val FREQUENCY_NEVER = -1 } private val pushController: PushController by inject() @@ -66,6 +65,7 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { it.applicationContext, preferences, accountRemover, + jobManager, null ) } @@ -80,7 +80,7 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { private fun disableSync(intent: Intent) { val account = getAccount(intent) ?: return - if (account.updateAutomaticCheckIntervalMinutes(FREQUENCY_NEVER)) { + if (account.updateAutomaticCheckIntervalMinutes(Account.INTERVAL_MINUTES_NEVER)) { preferences.saveAccount(account) jobManager.scheduleMailSync(account) } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt index 9cf29a9812..83695f9add 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/MessageList.kt @@ -61,6 +61,7 @@ import com.fsck.k9.fragment.MessageListFragment import com.fsck.k9.fragment.MessageListFragment.MessageListFragmentListener import com.fsck.k9.helper.Contacts import com.fsck.k9.helper.ParcelableUtil +import com.fsck.k9.job.K9JobManager import com.fsck.k9.mailstore.SearchStatusManager import com.fsck.k9.preferences.GeneralSettingsManager import com.fsck.k9.search.LocalSearch @@ -120,6 +121,7 @@ open class MessageList : private val accountRemover: BackgroundAccountRemover by inject() private val generalSettingsManager: GeneralSettingsManager by inject() private val messagingController: MessagingController by inject() + private val jobManager: K9JobManager by inject() private val permissionUiHelper: PermissionUiHelper = K9PermissionUiHelper(this) @@ -1453,7 +1455,7 @@ open class MessageList : private fun addNewAccountsAutomatically(savedInstanceState: Bundle?) { lifecycleScope.launch(Dispatchers.IO) { - EeloAccountCreator.loadAccountsFromAccountManager(applicationContext, preferences, accountRemover) { + EeloAccountCreator.loadAccountsFromAccountManager(applicationContext, preferences, accountRemover, jobManager) { lifecycleScope.launch(Dispatchers.Main) { onAccountConfigurationFinish(savedInstanceState) } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java index 01e82ec869..d72ca6204d 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java @@ -39,6 +39,7 @@ import com.fsck.k9.autodiscovery.api.DiscoveredServerSettings; import com.fsck.k9.autodiscovery.api.DiscoveryResults; import com.fsck.k9.autodiscovery.api.DiscoveryTarget; import com.fsck.k9.autodiscovery.providersxml.ProvidersXmlDiscovery; +import com.fsck.k9.job.K9JobManager; import com.fsck.k9.mail.AuthType; import com.fsck.k9.mail.ConnectionSecurity; import com.fsck.k9.mail.ServerSettings; @@ -57,15 +58,15 @@ public class EeloAccountCreator { @RequiresApi(api = VERSION_CODES.N) @WorkerThread public static void loadAccountsFromAccountManager(@NonNull Context context, @NonNull Preferences preferences, - @NonNull BackgroundAccountRemover accountRemover, @Nullable OnAccountLoadCompleteCallBack callBack) { + @NonNull BackgroundAccountRemover accountRemover, @NonNull K9JobManager jobManager, @Nullable OnAccountLoadCompleteCallBack callBack) { try { AccountManager accountManager = AccountManager.get(context); List accounts = preferences.getAccounts(); deleteIncompleteAccounts(accounts, accountRemover); - loadEeloAccounts(context, accounts, accountManager); - loadGoogleAccounts(context, accounts, accountManager); + loadEeloAccounts(context, accounts, accountManager, jobManager); + loadGoogleAccounts(context, accounts, accountManager, jobManager); } catch (SecurityException e) { Timber.e(e, "Failed to load accounts from accountManager because of security violation"); } @@ -90,7 +91,7 @@ public class EeloAccountCreator { @RequiresApi(api = VERSION_CODES.N) private static void loadGoogleAccounts(@NonNull Context context, List accounts, - @NonNull AccountManager accountManager) { + @NonNull AccountManager accountManager, @NonNull K9JobManager jobManager) { android.accounts.Account[] googleAccounts = accountManager.getAccountsByType(AccountManagerConstants.GOOGLE_ACCOUNT_TYPE); for (android.accounts.Account googleAccount : googleAccounts) { @@ -100,14 +101,22 @@ public class EeloAccountCreator { continue; } - boolean accountAlreadyPresent = accounts.stream() + if (!isSyncable(googleAccount)) { + continue; + } + + var existenceAccount = accounts.stream() .filter(account -> emailId.equalsIgnoreCase(account.getEmail())) .peek(account -> updateAccountNameIfMissing(context, emailId, account)) - .findAny().isPresent(); - if (!accountAlreadyPresent && isSyncable(googleAccount)) { + .findAny(); + + if (!existenceAccount.isPresent()) { String authState = accountManager.getUserData(googleAccount, AccountManagerConstants.KEY_AUTH_STATE); createAccount(context, emailId, "", authState); + continue; } + + enableSync(jobManager, existenceAccount.get()); } } @@ -124,7 +133,7 @@ public class EeloAccountCreator { @RequiresApi(api = VERSION_CODES.N) private static void loadEeloAccounts(@NonNull Context context, List accounts, - @NonNull AccountManager accountManager) { + @NonNull AccountManager accountManager, @NonNull K9JobManager jobManager) { android.accounts.Account[] eeloAccounts = accountManager.getAccountsByType(AccountManagerConstants.EELO_ACCOUNT_TYPE); for (android.accounts.Account eeloAccount : eeloAccounts) { @@ -133,12 +142,35 @@ public class EeloAccountCreator { continue; } - boolean isNewAccount = accounts.stream() - .noneMatch(account -> emailId.equalsIgnoreCase(account.getEmail())); - if (isNewAccount && isSyncable(eeloAccount)) { + if (!isSyncable(eeloAccount)) { + continue; + } + + var existenceAccount = accounts.stream() + .filter(account -> emailId.equalsIgnoreCase(account.getEmail())) + .findAny(); + + if (!existenceAccount.isPresent()) { String password = accountManager.getPassword(eeloAccount); createAccount(context, emailId, password, null); + continue; } + + enableSync(jobManager, existenceAccount.get()); + } + } + + // enable account sync if not already enabled + private static void enableSync(@NonNull K9JobManager jobManager, @NonNull Account account) { + // sync is already enabled, ignore + if (account.getAutomaticCheckIntervalMinutes() != Account.INTERVAL_MINUTES_NEVER) { + return; + } + + // set sync to default interval + if (account.updateAutomaticCheckIntervalMinutes(Account.DEFAULT_SYNC_INTERVAL)) { + Preferences.getPreferences().saveAccount(account); + jobManager.scheduleMailSync(account); } } -- GitLab From 8322295811288bb2de9f4763319907b3b2b54a88 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Tue, 8 Nov 2022 10:46:06 +0600 Subject: [PATCH 7/9] fix typo --- .../src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt index 1914033666..f87f2ce5c5 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt @@ -35,7 +35,7 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { private const val ACCOUNT_CREATION_ACTION = "$ACTION_PREFIX.create" private const val ACCOUNT_REMOVAL_ACTION = "$ACTION_PREFIX.remove" - private const val ACCOUNT_DISABLE_SYNC = "$ACTION_PREFIX.disablesync" + private const val ACCOUNT_DISABLE_SYNC_ACTION = "$ACTION_PREFIX.disablesync" private const val ACCOUNT = "account" } @@ -53,7 +53,7 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { when (intent.action) { ACCOUNT_CREATION_ACTION -> createNewAccount(context) ACCOUNT_REMOVAL_ACTION -> removeAccount(intent) - ACCOUNT_DISABLE_SYNC -> disableSync(intent) + ACCOUNT_DISABLE_SYNC_ACTION -> disableSync(intent) } } -- GitLab From c1b8a35584f15cd683bd1ebc973afa1607b5bd17 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Tue, 8 Nov 2022 13:52:50 +0600 Subject: [PATCH 8/9] Schedule all mail job on sync update --- .../src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt | 2 +- .../k9/activity/setup/accountmanager/EeloAccountCreator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt index f87f2ce5c5..b0dc4f1bf0 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt @@ -82,7 +82,7 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { if (account.updateAutomaticCheckIntervalMinutes(Account.INTERVAL_MINUTES_NEVER)) { preferences.saveAccount(account) - jobManager.scheduleMailSync(account) + jobManager.scheduleAllMailJobs() } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java index d72ca6204d..1570511589 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java @@ -170,7 +170,7 @@ public class EeloAccountCreator { // set sync to default interval if (account.updateAutomaticCheckIntervalMinutes(Account.DEFAULT_SYNC_INTERVAL)) { Preferences.getPreferences().saveAccount(account); - jobManager.scheduleMailSync(account); + jobManager.scheduleAllMailJobs(); } } -- GitLab From 1fc8273a6736e8ba1863bbd66e1ddf5173bbca91 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Tue, 8 Nov 2022 17:12:46 +0600 Subject: [PATCH 9/9] add backgroundSync pref for accounts --- app/core/src/main/java/com/fsck/k9/Account.kt | 4 ++++ .../java/com/fsck/k9/AccountPreferenceSerializer.kt | 3 +++ .../java/com/fsck/k9/controller/push/PushController.kt | 2 +- .../src/main/java/com/fsck/k9/job/MailSyncWorker.kt | 5 +++++ .../main/java/com/fsck/k9/job/MailSyncWorkerManager.kt | 4 ++++ .../java/com/fsck/k9/account/AccountSyncReceiver.kt | 8 +++----- .../setup/accountmanager/EeloAccountCreator.java | 10 ++++------ 7 files changed, 24 insertions(+), 12 deletions(-) diff --git a/app/core/src/main/java/com/fsck/k9/Account.kt b/app/core/src/main/java/com/fsck/k9/Account.kt index 71d4d6fc04..f3906ab6ab 100644 --- a/app/core/src/main/java/com/fsck/k9/Account.kt +++ b/app/core/src/main/java/com/fsck/k9/Account.kt @@ -360,6 +360,10 @@ class Account(override val uuid: String) : BaseAccount { @set:Synchronized var messagesNotificationChannelVersion = 0 + @get:Synchronized + @set:Synchronized + var backgroundSync = true + @get:Synchronized @set:Synchronized var isChangedVisibleLimits = false diff --git a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt index e827460425..4851915118 100644 --- a/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt +++ b/app/core/src/main/java/com/fsck/k9/AccountPreferenceSerializer.kt @@ -54,6 +54,7 @@ class AccountPreferenceSerializer( isIgnoreChatMessages = storage.getBoolean("$accountUuid.ignoreChatMessages", false) isNotifySync = storage.getBoolean("$accountUuid.notifyMailCheck", false) messagesNotificationChannelVersion = storage.getInt("$accountUuid.messagesNotificationChannelVersion", 0) + backgroundSync = storage.getBoolean("$accountUuid.backgroundSync", true) deletePolicy = DeletePolicy.fromInt(storage.getInt("$accountUuid.deletePolicy", DeletePolicy.NEVER.setting)) legacyInboxFolder = storage.getString("$accountUuid.inboxFolderName", null) importedDraftsFolder = storage.getString("$accountUuid.draftsFolderName", null) @@ -259,6 +260,7 @@ class AccountPreferenceSerializer( editor.putBoolean("$accountUuid.ignoreChatMessages", isIgnoreChatMessages) editor.putBoolean("$accountUuid.notifyMailCheck", isNotifySync) editor.putInt("$accountUuid.messagesNotificationChannelVersion", messagesNotificationChannelVersion) + editor.putBoolean("$accountUuid.backgroundSync", backgroundSync) editor.putInt("$accountUuid.deletePolicy", deletePolicy.setting) editor.putString("$accountUuid.inboxFolderName", legacyInboxFolder) editor.putString("$accountUuid.draftsFolderName", importedDraftsFolder) @@ -549,6 +551,7 @@ class AccountPreferenceSerializer( isNotifyContactsMailOnly = false isIgnoreChatMessages = false messagesNotificationChannelVersion = 0 + backgroundSync = true folderDisplayMode = FolderMode.NOT_SECOND_CLASS folderSyncMode = FolderMode.FIRST_CLASS folderPushMode = FolderMode.ALL diff --git a/app/core/src/main/java/com/fsck/k9/controller/push/PushController.kt b/app/core/src/main/java/com/fsck/k9/controller/push/PushController.kt index 9edc8b295c..a47dd70189 100644 --- a/app/core/src/main/java/com/fsck/k9/controller/push/PushController.kt +++ b/app/core/src/main/java/com/fsck/k9/controller/push/PushController.kt @@ -211,7 +211,7 @@ class PushController internal constructor( private fun getPushAccounts(): List { return preferences.accounts.filter { account -> - account.folderPushMode != FolderMode.NONE && backendManager.getBackend(account)?.isPushCapable ?: false + account.folderPushMode != FolderMode.NONE && account.backgroundSync && backendManager.getBackend(account)?.isPushCapable ?: false } } private fun setPushNotificationState(notificationState: PushNotificationState) { diff --git a/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt b/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt index 3b317628df..057fa69092 100644 --- a/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt +++ b/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt @@ -41,6 +41,11 @@ class MailSyncWorker( return Result.success() } + if (!account.backgroundSync) { + Timber.d("Mail sync is disable for this account. Skipping mail sync.") + return Result.success() + } + if (account.incomingServerSettings.isMissingCredentials) { Timber.d("Password for this account is missing. Skipping mail sync.") return Result.success() diff --git a/app/core/src/main/java/com/fsck/k9/job/MailSyncWorkerManager.kt b/app/core/src/main/java/com/fsck/k9/job/MailSyncWorkerManager.kt index 77ea8abbc1..87df71d0c1 100644 --- a/app/core/src/main/java/com/fsck/k9/job/MailSyncWorkerManager.kt +++ b/app/core/src/main/java/com/fsck/k9/job/MailSyncWorkerManager.kt @@ -24,6 +24,10 @@ class MailSyncWorkerManager(private val workManager: WorkManager, val clock: Clo fun scheduleMailSync(account: Account) { if (isNeverSyncInBackground()) return + if (!account.backgroundSync) { + return + } + getSyncIntervalIfEnabled(account)?.let { syncIntervalMinutes -> Timber.v("Scheduling mail sync worker for %s", account) Timber.v(" sync interval: %d minutes", syncIntervalMinutes) diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt index b0dc4f1bf0..6a79dce909 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt +++ b/app/ui/legacy/src/main/java/com/fsck/k9/account/AccountSyncReceiver.kt @@ -79,11 +79,9 @@ class AccountSyncReceiver : BroadcastReceiver(), KoinComponent { private fun disableSync(intent: Intent) { val account = getAccount(intent) ?: return - - if (account.updateAutomaticCheckIntervalMinutes(Account.INTERVAL_MINUTES_NEVER)) { - preferences.saveAccount(account) - jobManager.scheduleAllMailJobs() - } + account.backgroundSync = false + preferences.saveAccount(account) + jobManager.scheduleAllMailJobs() } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java index 1570511589..56cde0a6b7 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java @@ -163,15 +163,13 @@ public class EeloAccountCreator { // enable account sync if not already enabled private static void enableSync(@NonNull K9JobManager jobManager, @NonNull Account account) { // sync is already enabled, ignore - if (account.getAutomaticCheckIntervalMinutes() != Account.INTERVAL_MINUTES_NEVER) { + if (account.getBackgroundSync()) { return; } - // set sync to default interval - if (account.updateAutomaticCheckIntervalMinutes(Account.DEFAULT_SYNC_INTERVAL)) { - Preferences.getPreferences().saveAccount(account); - jobManager.scheduleAllMailJobs(); - } + account.setBackgroundSync(true); + Preferences.getPreferences().saveAccount(account); + jobManager.scheduleAllMailJobs(); } @RequiresApi(api = VERSION_CODES.N) -- GitLab