Skip to content

Commit 8ca1027

Browse files
committed
Handled the account removing.| #716
1 parent 0dc0f50 commit 8ca1027

File tree

6 files changed

+106
-77
lines changed

6 files changed

+106
-77
lines changed

FlowCrypt/src/main/java/com/flowcrypt/email/accounts/FlowcryptAccountAuthenticator.kt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import com.flowcrypt.email.api.oauth.OAuth2Helper
1717
import com.flowcrypt.email.api.retrofit.ApiHelper
1818
import com.flowcrypt.email.api.retrofit.ApiService
1919
import com.flowcrypt.email.security.KeyStoreCryptoManager
20+
import com.flowcrypt.email.ui.activity.EmailManagerActivity
2021
import com.flowcrypt.email.ui.activity.SignInActivity
2122

2223

@@ -112,7 +113,7 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe
112113

113114
private fun genBundleToAddNewAccount(response: AccountAuthenticatorResponse?): Bundle {
114115
val intent = Intent(context, SignInActivity::class.java).apply {
115-
action = SignInActivity.ACTION_ADD_ACCOUNT_FROM_SETTINGS
116+
action = SignInActivity.ACTION_ADD_ACCOUNT_VIA_SYSTEM_SETTINGS
116117
putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response)
117118
}
118119

@@ -121,6 +122,27 @@ class FlowcryptAccountAuthenticator(val context: Context) : AbstractAccountAuthe
121122
}
122123
}
123124

125+
override fun getAccountRemovalAllowed(response: AccountAuthenticatorResponse?, account: Account?): Bundle {
126+
val bundle = super.getAccountRemovalAllowed(response, account)
127+
128+
if (bundle?.containsKey(AccountManager.KEY_BOOLEAN_RESULT) == true) {
129+
val isRemovalAllowed = bundle.getBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)
130+
if (isRemovalAllowed) {
131+
return Bundle().apply {
132+
putParcelable(AccountManager.KEY_INTENT, Intent(context, EmailManagerActivity::class.java).apply {
133+
action = EmailManagerActivity.ACTION_REMOVE_ACCOUNT_VIA_SYSTEM_SETTINGS
134+
putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response)
135+
putExtra(EmailManagerActivity.KEY_ACCOUNT, account)
136+
})
137+
}
138+
}
139+
}
140+
141+
return Bundle().apply {
142+
putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false)
143+
}
144+
}
145+
124146
companion object {
125147
const val KEY_ACCOUNT_EMAIL = BuildConfig.APPLICATION_ID + ".KEY_ACCOUNT_EMAIL"
126148
const val KEY_REFRESH_TOKEN = BuildConfig.APPLICATION_ID + ".KEY_REFRESH_TOKEN"

FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EmailManagerActivity.kt

Lines changed: 28 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package com.flowcrypt.email.ui.activity
77

8+
import android.accounts.Account
89
import android.app.Activity
910
import android.app.SearchManager
1011
import android.content.Context
@@ -144,6 +145,8 @@ class EmailManagerActivity : BaseEmailListActivity(), NavigationView.OnNavigatio
144145
invalidateOptionsMenu()
145146
}
146147
})
148+
149+
handleLogoutFromSystemSettings()
147150
}
148151

149152
override fun onResume() {
@@ -163,7 +166,7 @@ class EmailManagerActivity : BaseEmailListActivity(), NavigationView.OnNavigatio
163166
if (ACTION_OPEN_OUTBOX_FOLDER.equals(intent?.action, true)) {
164167
val newLocalFolder = foldersManager?.folderOutbox
165168
changeFolder(newLocalFolder)
166-
}
169+
} else handleLogoutFromSystemSettings()
167170
}
168171

169172
override fun onAccountInfoRefreshed(accountEntity: AccountEntity?) {
@@ -383,7 +386,7 @@ class EmailManagerActivity : BaseEmailListActivity(), NavigationView.OnNavigatio
383386

384387
override fun onNavigationItemSelected(item: MenuItem): Boolean {
385388
when (item.itemId) {
386-
R.id.navMenuLogOut -> logout()
389+
R.id.navMenuLogOut -> doLogout()
387390

388391
R.id.navMenuActionSettings -> startActivity(Intent(this, SettingsActivity::class.java))
389392

@@ -484,44 +487,14 @@ class EmailManagerActivity : BaseEmailListActivity(), NavigationView.OnNavigatio
484487
Snackbar.LENGTH_INDEFINITE, View.OnClickListener { onRetryGoogleAuth() })
485488
}
486489

487-
private fun logout() {
488-
lifecycleScope.launch {
489-
activeAccount?.let { accountEntity ->
490-
countingIdlingResource.incrementSafely()
490+
private fun doLogout() {
491+
disconnectFromSyncService()
491492

492-
when (accountEntity.accountType) {
493-
AccountEntity.ACCOUNT_TYPE_GOOGLE -> client.signOut()
494-
}
495-
496-
val roomDatabase = FlowCryptRoomDatabase.getDatabase(applicationContext)
497-
//remove all info about the given account from the local db
498-
roomDatabase.accountDao().deleteSuspend(accountEntity)
499-
//todo-denbond7 Improve this via onDelete = ForeignKey.CASCADE
500-
roomDatabase.labelDao().deleteByEmailSuspend(accountEntity.email)
501-
roomDatabase.msgDao().deleteByEmailSuspend(accountEntity.email)
502-
roomDatabase.attachmentDao().deleteByEmailSuspend(accountEntity.email)
503-
roomDatabase.accountAliasesDao().deleteByEmailSuspend(accountEntity.email)
504-
505-
val nonactiveAccounts = roomDatabase.accountDao().getAllNonactiveAccountsSuspend()
506-
if (nonactiveAccounts.isNotEmpty()) {
507-
disconnectFromSyncService()
508-
val firstNonactiveAccount = nonactiveAccounts.first()
509-
roomDatabase.accountDao().updateAccountsSuspend(roomDatabase.accountDao().getAccountsSuspend().map { it.copy(isActive = false) })
510-
roomDatabase.accountDao().updateAccountSuspend(firstNonactiveAccount.copy(isActive = true))
511-
EmailSyncService.switchAccount(applicationContext)
512-
runEmailManagerActivity(this@EmailManagerActivity)
513-
finish()
514-
} else {
515-
stopService(Intent(applicationContext, EmailSyncService::class.java))
516-
val intent = Intent(applicationContext, SignInActivity::class.java)
517-
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
518-
startActivity(intent)
519-
finish()
520-
}
521-
522-
countingIdlingResource.decrementSafely()
523-
}
493+
activeAccount?.let {
494+
if (it.accountType == AccountEntity.ACCOUNT_TYPE_GOOGLE) client.signOut()
524495
}
496+
497+
logout()
525498
}
526499

527500
/**
@@ -763,15 +736,24 @@ class EmailManagerActivity : BaseEmailListActivity(), NavigationView.OnNavigatio
763736
}
764737
}
765738

739+
private fun handleLogoutFromSystemSettings() {
740+
if (ACTION_REMOVE_ACCOUNT_VIA_SYSTEM_SETTINGS.equals(intent?.action, true)) {
741+
val account = intent.getParcelableExtra<Account>(KEY_ACCOUNT)
742+
account?.let {
743+
toast(getString(R.string.open_side_menu_and_do_logout, it.name), Toast.LENGTH_LONG)
744+
}
745+
}
746+
}
747+
766748
/**
767749
* The custom realization of [ActionBarDrawerToggle]. Will be used to start a labels
768750
* update task when the drawer will be opened.
769751
*/
770-
private inner class CustomDrawerToggle internal constructor(activity: Activity,
771-
drawerLayout: DrawerLayout?,
772-
toolbar: Toolbar?,
773-
@StringRes openDrawerContentDescRes: Int,
774-
@StringRes closeDrawerContentDescRes: Int)
752+
private inner class CustomDrawerToggle(activity: Activity,
753+
drawerLayout: DrawerLayout?,
754+
toolbar: Toolbar?,
755+
@StringRes openDrawerContentDescRes: Int,
756+
@StringRes closeDrawerContentDescRes: Int)
775757
: ActionBarDrawerToggle(activity, drawerLayout, toolbar, openDrawerContentDescRes, closeDrawerContentDescRes) {
776758

777759
var slideOffset = 0f
@@ -809,6 +791,9 @@ class EmailManagerActivity : BaseEmailListActivity(), NavigationView.OnNavigatio
809791

810792
companion object {
811793
const val ACTION_OPEN_OUTBOX_FOLDER = BuildConfig.APPLICATION_ID + ".OPEN_OUTBOX_FOLDER"
794+
const val ACTION_REMOVE_ACCOUNT_VIA_SYSTEM_SETTINGS = BuildConfig.APPLICATION_ID + ".ACTION_REMOVE_ACCOUNT_VIA_SYSTEM_SETTINGS"
795+
const val KEY_ACCOUNT = BuildConfig.APPLICATION_ID + ".KEY_ACCOUNT"
796+
812797
private const val REQUEST_CODE_ADD_NEW_ACCOUNT = 100
813798
private const val REQUEST_CODE_SIGN_IN = 101
814799
private const val REQUEST_CODE_DIALOG_FORCE_SENDING = 103

FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SignInActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class SignInActivity : BaseNodeActivity() {
7272

7373
companion object {
7474
const val ACTION_ADD_ONE_MORE_ACCOUNT = BuildConfig.APPLICATION_ID + ".ACTION_ADD_ONE_MORE_ACCOUNT"
75-
const val ACTION_ADD_ACCOUNT_FROM_SETTINGS = BuildConfig.APPLICATION_ID + ".ACTION_ADD_ACCOUNT_FROM_SETTINGS"
75+
const val ACTION_ADD_ACCOUNT_VIA_SYSTEM_SETTINGS = BuildConfig.APPLICATION_ID + ".ACTION_ADD_ACCOUNT_VIA_SYSTEM_SETTINGS"
7676

7777
val KEY_EXTRA_NEW_ACCOUNT =
7878
GeneralUtil.generateUniqueExtraKey("KEY_EXTRA_NEW_ACCOUNT", SignInActivity::class.java)

FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/UserRecoverableAuthExceptionActivity.kt

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import com.flowcrypt.email.api.email.JavaEmailConstants
1919
import com.flowcrypt.email.database.FlowCryptRoomDatabase
2020
import com.flowcrypt.email.database.MessageState
2121
import com.flowcrypt.email.jetpack.workmanager.MessagesSenderWorker
22-
import com.flowcrypt.email.service.EmailSyncService
2322
import com.flowcrypt.email.ui.activity.base.BaseActivity
2423
import com.flowcrypt.email.ui.activity.settings.FeedbackActivity
2524
import com.flowcrypt.email.util.GeneralUtil
@@ -124,37 +123,6 @@ class UserRecoverableAuthExceptionActivity : BaseActivity(), View.OnClickListene
124123
findViewById<View>(R.id.buttonHelp)?.setOnClickListener(this)
125124
}
126125

127-
private fun logout() {
128-
val activeAccount = activeAccount ?: return
129-
lifecycleScope.launch {
130-
val roomDatabase = FlowCryptRoomDatabase.getDatabase(applicationContext)
131-
132-
//remove all info about the given account from the local db
133-
roomDatabase.accountDao().deleteSuspend(activeAccount)
134-
//todo-denbond7 Improve this via onDelete = ForeignKey.CASCADE
135-
roomDatabase.labelDao().deleteByEmailSuspend(activeAccount.email)
136-
roomDatabase.msgDao().deleteByEmailSuspend(activeAccount.email)
137-
roomDatabase.attachmentDao().deleteByEmailSuspend(activeAccount.email)
138-
roomDatabase.accountAliasesDao().deleteByEmailSuspend(activeAccount.email)
139-
140-
val nonactiveAccounts = roomDatabase.accountDao().getAllNonactiveAccountsSuspend()
141-
if (nonactiveAccounts.isNotEmpty()) {
142-
val firstNonactiveAccount = nonactiveAccounts.first()
143-
roomDatabase.accountDao().updateAccountsSuspend(roomDatabase.accountDao().getAccountsSuspend().map { it.copy(isActive = false) })
144-
roomDatabase.accountDao().updateAccountSuspend(firstNonactiveAccount.copy(isActive = true))
145-
EmailSyncService.switchAccount(applicationContext)
146-
EmailManagerActivity.runEmailManagerActivity(this@UserRecoverableAuthExceptionActivity)
147-
finish()
148-
} else {
149-
stopService(Intent(applicationContext, EmailSyncService::class.java))
150-
val intent = Intent(applicationContext, SignInActivity::class.java)
151-
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
152-
startActivity(intent)
153-
finish()
154-
}
155-
}
156-
}
157-
158126
companion object {
159127
private var lastCallTime = 0L
160128
private var isRunEnabled = true

FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/base/BaseActivity.kt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package com.flowcrypt.email.ui.activity.base
77

8+
import android.accounts.AccountManager
89
import android.app.Activity
910
import android.content.Context
1011
import android.content.Intent
@@ -22,23 +23,31 @@ import androidx.activity.viewModels
2223
import androidx.appcompat.app.AppCompatActivity
2324
import androidx.appcompat.widget.Toolbar
2425
import androidx.lifecycle.Observer
26+
import androidx.lifecycle.lifecycleScope
2527
import androidx.test.espresso.idling.CountingIdlingResource
2628
import com.flowcrypt.email.R
29+
import com.flowcrypt.email.database.FlowCryptRoomDatabase
2730
import com.flowcrypt.email.database.entity.AccountEntity
31+
import com.flowcrypt.email.extensions.decrementSafely
2832
import com.flowcrypt.email.extensions.hasActiveConnection
33+
import com.flowcrypt.email.extensions.incrementSafely
2934
import com.flowcrypt.email.extensions.shutdown
3035
import com.flowcrypt.email.jetpack.lifecycle.ConnectionLifecycleObserver
3136
import com.flowcrypt.email.jetpack.viewmodel.AccountViewModel
3237
import com.flowcrypt.email.jetpack.viewmodel.RoomBasicViewModel
3338
import com.flowcrypt.email.node.Node
3439
import com.flowcrypt.email.service.BaseService
40+
import com.flowcrypt.email.service.EmailSyncService
41+
import com.flowcrypt.email.ui.activity.EmailManagerActivity
42+
import com.flowcrypt.email.ui.activity.SignInActivity
3543
import com.flowcrypt.email.ui.activity.settings.FeedbackActivity
3644
import com.flowcrypt.email.util.GeneralUtil
3745
import com.flowcrypt.email.util.LogsUtil
3846
import com.flowcrypt.email.util.exception.ExceptionUtil
3947
import com.flowcrypt.email.util.idling.NodeIdlingResource
4048
import com.google.android.material.appbar.AppBarLayout
4149
import com.google.android.material.snackbar.Snackbar
50+
import kotlinx.coroutines.launch
4251
import java.lang.ref.WeakReference
4352

4453
/**
@@ -304,6 +313,50 @@ abstract class BaseActivity : AppCompatActivity(), BaseService.OnServiceCallback
304313
}
305314
}
306315

316+
protected fun removeAccountFromAccountManager(accountEntity: AccountEntity?) {
317+
val accountManager = AccountManager.get(this)
318+
accountManager.accounts.firstOrNull { it.name == accountEntity?.email }?.let { account ->
319+
accountManager.removeAccountExplicitly(account)
320+
}
321+
}
322+
323+
protected fun logout() {
324+
lifecycleScope.launch {
325+
activeAccount?.let { accountEntity ->
326+
countingIdlingResource.incrementSafely()
327+
328+
val roomDatabase = FlowCryptRoomDatabase.getDatabase(applicationContext)
329+
//remove all info about the given account from the local db
330+
roomDatabase.accountDao().deleteSuspend(accountEntity)
331+
removeAccountFromAccountManager(accountEntity)
332+
333+
//todo-denbond7 Improve this via onDelete = ForeignKey.CASCADE
334+
roomDatabase.labelDao().deleteByEmailSuspend(accountEntity.email)
335+
roomDatabase.msgDao().deleteByEmailSuspend(accountEntity.email)
336+
roomDatabase.attachmentDao().deleteByEmailSuspend(accountEntity.email)
337+
roomDatabase.accountAliasesDao().deleteByEmailSuspend(accountEntity.email)
338+
339+
val nonactiveAccounts = roomDatabase.accountDao().getAllNonactiveAccountsSuspend()
340+
if (nonactiveAccounts.isNotEmpty()) {
341+
val firstNonactiveAccount = nonactiveAccounts.first()
342+
roomDatabase.accountDao().updateAccountsSuspend(roomDatabase.accountDao().getAccountsSuspend().map { it.copy(isActive = false) })
343+
roomDatabase.accountDao().updateAccountSuspend(firstNonactiveAccount.copy(isActive = true))
344+
EmailSyncService.switchAccount(applicationContext)
345+
EmailManagerActivity.runEmailManagerActivity(this@BaseActivity)
346+
finish()
347+
} else {
348+
stopService(Intent(applicationContext, EmailSyncService::class.java))
349+
val intent = Intent(applicationContext, SignInActivity::class.java)
350+
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
351+
startActivity(intent)
352+
finish()
353+
}
354+
355+
countingIdlingResource.decrementSafely()
356+
}
357+
}
358+
}
359+
307360
private fun initAccountViewModel() {
308361
accountViewModel.activeAccountLiveData.observe(this, Observer {
309362
activeAccount = it

FlowCrypt/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,4 +470,5 @@
470470
<string name="error_with_value">Error: %1$s</string>
471471
<string name="oauth_error">OAuth error</string>
472472
<string name="loading_oauth_server_configuration">Loading OAuth server configuration&#8230;</string>
473+
<string name="open_side_menu_and_do_logout">Please open the side menu and do logout to remove %1$s</string>
473474
</resources>

0 commit comments

Comments
 (0)