Better handling of address book accounts without main account (closes #694)

This commit is contained in:
Ricki Hirner 2024-04-01 21:25:33 +02:00
parent 6b88052e10
commit 44d2446d22
4 changed files with 30 additions and 19 deletions

View file

@ -128,19 +128,22 @@ open class LocalAddressBook(
* Finds and returns the main account of the given address book's account (sub-account)
*
* @param account the address book account to find the main account for
* @return the associated main account
* @throws IllegalArgumentException if the given account is not a address book account or does not have a main account
*
* @return the associated main account, `null` if none can be found (e.g. when main account has been deleted)
*
* @throws IllegalArgumentException when [account] is not an address book account
*/
fun mainAccount(context: Context, account: Account): Account =
fun mainAccount(context: Context, account: Account): Account? =
if (account.type == context.getString(R.string.account_type_address_book)) {
val manager = AccountManager.get(context)
val accountName = manager.getUserData(account, USER_DATA_MAIN_ACCOUNT_NAME)
val accountType = manager.getUserData(account, USER_DATA_MAIN_ACCOUNT_TYPE)
if (accountName == null || accountType == null)
throw IllegalArgumentException("Address book account does not have a main account")
Account(accountName, accountType)
if (accountName != null && accountType != null)
Account(accountName, accountType)
else
null
} else
throw IllegalArgumentException("Account is not an address book account")
throw IllegalArgumentException("$account is not an address book account")
}
@ -157,7 +160,7 @@ open class LocalAddressBook(
* but if it is enabled, [findDirty] will find dirty [LocalContact]s and [LocalGroup]s.
*/
open val groupMethod: GroupMethod by lazy {
val accountSettings = AccountSettings(context, mainAccount)
val accountSettings = AccountSettings(context, requireMainAccount())
accountSettings.getGroupMethod()
}
val includeGroups
@ -169,7 +172,7 @@ open class LocalAddressBook(
*
* @throws IllegalArgumentException when [account] is not an address book account or when no main account is assigned
*/
open var mainAccount: Account
open var mainAccount: Account?
get() {
_mainAccount?.let { return it }
@ -178,6 +181,9 @@ open class LocalAddressBook(
return result
}
set(newMainAccount) {
if (newMainAccount == null)
throw IllegalArgumentException("Main account must not be null")
AccountManager.get(context).let { accountManager ->
accountManager.setAndVerifyUserData(account, USER_DATA_MAIN_ACCOUNT_NAME, newMainAccount.name)
accountManager.setAndVerifyUserData(account, USER_DATA_MAIN_ACCOUNT_TYPE, newMainAccount.type)
@ -185,6 +191,8 @@ open class LocalAddressBook(
_mainAccount = newMainAccount
}
fun requireMainAccount(): Account =
mainAccount ?: throw IllegalArgumentException("No main account assigned to address book $account")
var url: String
get() = AccountManager.get(context).getUserData(account, USER_DATA_URL)
@ -236,7 +244,7 @@ open class LocalAddressBook(
* @param forceReadOnly `true`: set the address book to "force read-only"; `false`: determine read-only flag from [info]
*/
fun update(info: Collection, forceReadOnly: Boolean) {
val newAccountName = accountName(mainAccount, info)
val newAccountName = accountName(requireMainAccount(), info)
if (account.name != newAccountName) {
// no need to re-assign contacts to new account, because they will be deleted by contacts provider in any case

View file

@ -141,16 +141,18 @@ class AccountSettings(
val account: Account
init {
when (argAccount.type) {
account = when (argAccount.type) {
context.getString(R.string.account_type_address_book) -> {
/* argAccount is an address book account, which is not a main account. However settings are
stored in the main account, so resolve and use the main account instead. */
account = LocalAddressBook.mainAccount(context, argAccount)
stored in the main account, so resolve and use the main account instead. */
LocalAddressBook.mainAccount(context, argAccount) ?: throw IllegalArgumentException("Main account of $argAccount not found")
}
context.getString(R.string.account_type) ->
account = argAccount
argAccount
else ->
throw IllegalArgumentException("Account type not supported")
throw IllegalArgumentException("Account type ${argAccount.type} not supported")
}
// synchronize because account migration must only be run one time

View file

@ -75,8 +75,9 @@ class AccountsCleanupWorker @AssistedInject constructor(
.map { addressBookAccount -> LocalAddressBook(context, addressBookAccount, null) }
for (addressBook in addressBooks) {
try {
if (!mainAccountNames.contains(addressBook.mainAccount.name))
// the main account for this address book doesn't exist anymore
val mainAccount = addressBook.mainAccount
if (mainAccount == null || !mainAccountNames.contains(mainAccount.name))
// the main account for this address book doesn't exist anymore
addressBook.delete()
} catch(e: Exception) {
Logger.log.log(Level.SEVERE, "Couldn't delete address book account", e)

View file

@ -809,7 +809,7 @@ abstract class SyncManager<ResourceType: LocalResource<*>, out CollectionType: L
.setContentTitle(localCollection.title)
.setContentText(message)
.setStyle(NotificationCompat.BigTextStyle(builder).bigText(message))
.setSubText(mainAccount.name)
.setSubText(mainAccount?.name)
.setOnlyAlertOnce(true)
.setContentIntent(PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
.setPriority(priority)
@ -863,7 +863,7 @@ abstract class SyncManager<ResourceType: LocalResource<*>, out CollectionType: L
builder .setSmallIcon(R.drawable.ic_warning_notify)
.setContentTitle(notifyInvalidResourceTitle())
.setContentText(context.getString(R.string.sync_invalid_resources_ignoring))
.setSubText(mainAccount.name)
.setSubText(mainAccount?.name)
.setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
.setAutoCancel(true)
.setOnlyAlertOnce(true)