From 6f14ab8eeb8e95f974629b789083b4c1911ca12d Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Wed, 6 Jul 2022 18:50:14 +0600 Subject: [PATCH 1/2] 5560-sync_account_with_mail_app issue: https://gitlab.e.foundation/e/backlog/-/issues/5560 Call Mail app's accountSyncBroadCastReceiver on new account loggedIn or, account loggedOut from the accountManager app. --- .../e/accountmanager/MailAccountSyncHelper.kt | 53 +++++++++++++++++++ .../resource/LocalAddressBook.kt | 36 +++++++++++-- .../ui/account/AccountActivity.kt | 5 ++ .../ui/setup/AccountDetailsFragment.kt | 2 + 4 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/foundation/e/accountmanager/MailAccountSyncHelper.kt diff --git a/app/src/main/java/foundation/e/accountmanager/MailAccountSyncHelper.kt b/app/src/main/java/foundation/e/accountmanager/MailAccountSyncHelper.kt new file mode 100644 index 000000000..b93fcfa2b --- /dev/null +++ b/app/src/main/java/foundation/e/accountmanager/MailAccountSyncHelper.kt @@ -0,0 +1,53 @@ +/* + * Copyright ECORP SAS 2022 + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package foundation.e.accountmanager + +import android.content.ComponentName +import android.content.Context +import android.content.Intent + +object MailAccountSyncHelper { + + private const val MAIL_PACKAGE = "foundation.e.mail" + private const val MAIL_RECEIVER_CLASS = "com.fsck.k9.account.AccountSyncReceiver" + private const val ACTION_PREFIX = "foundation.e.accountmanager.account." + + fun accountLoggedIn(applicationContext : Context?) { + val intent = getIntent() + intent.action = ACTION_PREFIX + "create" + applicationContext?.sendBroadcast(intent) + } + + fun accountLoggedOut(applicationContext: Context?, email: String?) { + email?.let { + if (!it.contains("@")) { + return@let + } + val intent = getIntent() + intent.action = ACTION_PREFIX + "remove" + intent.putExtra("account", it) + applicationContext?.sendBroadcast(intent) + } + } + + private fun getIntent() : Intent { + val intent = Intent() + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) + intent.component = ComponentName(MAIL_PACKAGE, MAIL_RECEIVER_CLASS) + return intent + } +} \ No newline at end of file diff --git a/app/src/main/java/foundation/e/accountmanager/resource/LocalAddressBook.kt b/app/src/main/java/foundation/e/accountmanager/resource/LocalAddressBook.kt index b36a1b701..09b360aa5 100644 --- a/app/src/main/java/foundation/e/accountmanager/resource/LocalAddressBook.kt +++ b/app/src/main/java/foundation/e/accountmanager/resource/LocalAddressBook.kt @@ -12,6 +12,8 @@ import android.accounts.AccountManager import android.content.* import android.os.Build import android.os.Bundle +import android.os.Handler +import android.os.Looper import android.os.RemoteException import android.provider.ContactsContract import android.provider.ContactsContract.CommonDataKinds.GroupMembership @@ -19,11 +21,13 @@ import android.provider.ContactsContract.Groups import android.provider.ContactsContract.RawContacts import android.util.Base64 import foundation.e.accountmanager.DavUtils +import foundation.e.accountmanager.MailAccountSyncHelper import foundation.e.accountmanager.R import foundation.e.accountmanager.log.Logger import foundation.e.accountmanager.model.Collection import foundation.e.accountmanager.model.AppDatabase import foundation.e.accountmanager.model.SyncState +import foundation.e.accountmanager.settings.AccountSettings import foundation.e.vcard4android.* import java.io.ByteArrayOutputStream import java.util.* @@ -243,11 +247,35 @@ class LocalAddressBook( fun delete() { val accountManager = AccountManager.get(context) + val email = accountManager.getUserData(account, AccountSettings.KEY_EMAIL_ADDRESS) + @Suppress("DEPRECATION") - if (Build.VERSION.SDK_INT >= 22) - accountManager.removeAccount(account, null, null, null) - else - accountManager.removeAccount(account, null, null) + if (Build.VERSION.SDK_INT >= 22) { + accountManager.removeAccount(account, null, { + try { + if (it.result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) { + Handler(Looper.getMainLooper()).post { + MailAccountSyncHelper.accountLoggedOut(context.applicationContext, email) + } + } + } catch(e: Exception) { + Logger.log.log(Level.SEVERE, "Couldn't remove account", e) + } + }, null) + } + else { + accountManager.removeAccount(account, { + try { + if (it.result) { + Handler(Looper.getMainLooper()).post { + MailAccountSyncHelper.accountLoggedOut(context.applicationContext, email) + } + } + } catch (e: Exception) { + Logger.log.log(Level.SEVERE, "Couldn't remove account", e) + } + }, null) + } } diff --git a/app/src/main/java/foundation/e/accountmanager/ui/account/AccountActivity.kt b/app/src/main/java/foundation/e/accountmanager/ui/account/AccountActivity.kt index 0abe8d140..8743dc22b 100644 --- a/app/src/main/java/foundation/e/accountmanager/ui/account/AccountActivity.kt +++ b/app/src/main/java/foundation/e/accountmanager/ui/account/AccountActivity.kt @@ -30,6 +30,8 @@ import foundation.e.accountmanager.resource.LocalTaskList import foundation.e.ical4android.TaskProvider import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar +import foundation.e.accountmanager.MailAccountSyncHelper +import foundation.e.accountmanager.settings.AccountSettings import kotlinx.android.synthetic.main.activity_account.* import java.util.concurrent.Executors import java.util.logging.Level @@ -124,12 +126,14 @@ class AccountActivity: AppCompatActivity() { private fun deleteAccount() { val accountManager = AccountManager.get(this) + val email = accountManager.getUserData(model.account, AccountSettings.KEY_EMAIL_ADDRESS) if (Build.VERSION.SDK_INT >= 22) accountManager.removeAccount(model.account, this, { future -> try { if (future.result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) Handler(Looper.getMainLooper()).post { + MailAccountSyncHelper.accountLoggedOut(applicationContext, email) finish() } } catch(e: Exception) { @@ -141,6 +145,7 @@ class AccountActivity: AppCompatActivity() { try { if (future.result) Handler(Looper.getMainLooper()).post { + MailAccountSyncHelper.accountLoggedOut(applicationContext, email) finish() } } catch (e: Exception) { diff --git a/app/src/main/java/foundation/e/accountmanager/ui/setup/AccountDetailsFragment.kt b/app/src/main/java/foundation/e/accountmanager/ui/setup/AccountDetailsFragment.kt index b5ffc66b6..cefb05f1e 100644 --- a/app/src/main/java/foundation/e/accountmanager/ui/setup/AccountDetailsFragment.kt +++ b/app/src/main/java/foundation/e/accountmanager/ui/setup/AccountDetailsFragment.kt @@ -27,6 +27,7 @@ import androidx.lifecycle.* import foundation.e.accountmanager.Constants import foundation.e.accountmanager.DavService import foundation.e.accountmanager.InvalidAccountException +import foundation.e.accountmanager.MailAccountSyncHelper import foundation.e.accountmanager.R import foundation.e.accountmanager.databinding.LoginAccountDetailsBinding import foundation.e.accountmanager.log.Logger @@ -155,6 +156,7 @@ class AccountDetailsFragment : Fragment() { if (success) { Toast.makeText(context, "Added account successfully", Toast.LENGTH_LONG) .show() + MailAccountSyncHelper.accountLoggedIn(context?.applicationContext) requireActivity().setResult(Activity.RESULT_OK) requireActivity().finish() if (requireActivity().intent.hasExtra( -- GitLab From 6f7f44a9855d01262038069ad045d12b636b30d9 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Thu, 7 Jul 2022 13:19:14 +0600 Subject: [PATCH 2/2] refactor removeAccount method --- .../resource/LocalAddressBook.kt | 50 ++++++++++-------- .../ui/account/AccountActivity.kt | 52 +++++++++++-------- 2 files changed, 59 insertions(+), 43 deletions(-) diff --git a/app/src/main/java/foundation/e/accountmanager/resource/LocalAddressBook.kt b/app/src/main/java/foundation/e/accountmanager/resource/LocalAddressBook.kt index 09b360aa5..2d9fe422e 100644 --- a/app/src/main/java/foundation/e/accountmanager/resource/LocalAddressBook.kt +++ b/app/src/main/java/foundation/e/accountmanager/resource/LocalAddressBook.kt @@ -251,31 +251,39 @@ class LocalAddressBook( @Suppress("DEPRECATION") if (Build.VERSION.SDK_INT >= 22) { - accountManager.removeAccount(account, null, { - try { - if (it.result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) { - Handler(Looper.getMainLooper()).post { - MailAccountSyncHelper.accountLoggedOut(context.applicationContext, email) - } - } - } catch(e: Exception) { - Logger.log.log(Level.SEVERE, "Couldn't remove account", e) - } - }, null) + removeAccount(accountManager, email) } else { - accountManager.removeAccount(account, { - try { - if (it.result) { - Handler(Looper.getMainLooper()).post { - MailAccountSyncHelper.accountLoggedOut(context.applicationContext, email) - } + removeAccountForOlderSdk(accountManager, email) + } + } + + private fun removeAccountForOlderSdk(accountManager: AccountManager, email: String?) { + accountManager.removeAccount(account, { + try { + if (it.result) { + Handler(Looper.getMainLooper()).post { + MailAccountSyncHelper.accountLoggedOut(context.applicationContext, email) } - } catch (e: Exception) { - Logger.log.log(Level.SEVERE, "Couldn't remove account", e) } - }, null) - } + } catch (e: Exception) { + Logger.log.log(Level.SEVERE, "Couldn't remove account", e) + } + }, null) + } + + private fun removeAccount(accountManager: AccountManager, email: String?) { + accountManager.removeAccount(account, null, { + try { + if (it.result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) { + Handler(Looper.getMainLooper()).post { + MailAccountSyncHelper.accountLoggedOut(context.applicationContext, email) + } + } + } catch (e: Exception) { + Logger.log.log(Level.SEVERE, "Couldn't remove account", e) + } + }, null) } diff --git a/app/src/main/java/foundation/e/accountmanager/ui/account/AccountActivity.kt b/app/src/main/java/foundation/e/accountmanager/ui/account/AccountActivity.kt index 8743dc22b..d7070bd9e 100644 --- a/app/src/main/java/foundation/e/accountmanager/ui/account/AccountActivity.kt +++ b/app/src/main/java/foundation/e/accountmanager/ui/account/AccountActivity.kt @@ -129,29 +129,37 @@ class AccountActivity: AppCompatActivity() { val email = accountManager.getUserData(model.account, AccountSettings.KEY_EMAIL_ADDRESS) if (Build.VERSION.SDK_INT >= 22) - accountManager.removeAccount(model.account, this, { future -> - try { - if (future.result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) - Handler(Looper.getMainLooper()).post { - MailAccountSyncHelper.accountLoggedOut(applicationContext, email) - finish() - } - } catch(e: Exception) { - Logger.log.log(Level.SEVERE, "Couldn't remove account", e) - } - }, null) + removeAccount(accountManager, email) else - accountManager.removeAccount(model.account, { future -> - try { - if (future.result) - Handler(Looper.getMainLooper()).post { - MailAccountSyncHelper.accountLoggedOut(applicationContext, email) - finish() - } - } catch (e: Exception) { - Logger.log.log(Level.SEVERE, "Couldn't remove account", e) - } - }, null) + removeAccountForOlderSdk(accountManager, email) + } + + private fun removeAccountForOlderSdk(accountManager: AccountManager, email: String?) { + accountManager.removeAccount(model.account, { future -> + try { + if (future.result) + Handler(Looper.getMainLooper()).post { + MailAccountSyncHelper.accountLoggedOut(applicationContext, email) + finish() + } + } catch (e: Exception) { + Logger.log.log(Level.SEVERE, "Couldn't remove account", e) + } + }, null) + } + + private fun removeAccount(accountManager: AccountManager, email: String?) { + accountManager.removeAccount(model.account, this, { future -> + try { + if (future.result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) + Handler(Looper.getMainLooper()).post { + MailAccountSyncHelper.accountLoggedOut(applicationContext, email) + finish() + } + } catch (e: Exception) { + Logger.log.log(Level.SEVERE, "Couldn't remove account", e) + } + }, null) } -- GitLab