rename AccountManager to AccountPreferenceSerializer, move more things out of Account

This commit is contained in:
Vincent Breitmoser 2018-11-26 19:14:54 +01:00
parent 912b5d70a4
commit cd01aec9d8
5 changed files with 60 additions and 75 deletions

View file

@ -467,32 +467,6 @@ public class Account implements BaseAccount, StoreConfig {
}
}
private static int findNewAccountNumber(List<Integer> accountNumbers) {
int newAccountNumber = -1;
Collections.sort(accountNumbers);
for (int accountNumber : accountNumbers) {
if (accountNumber > newAccountNumber + 1) {
break;
}
newAccountNumber = accountNumber;
}
newAccountNumber++;
return newAccountNumber;
}
private static List<Integer> getExistingAccountNumbers(Preferences preferences) {
List<Account> accounts = preferences.getAccounts();
List<Integer> accountNumbers = new ArrayList<>(accounts.size());
for (Account a : accounts) {
accountNumbers.add(a.getAccountNumber());
}
return accountNumbers;
}
public static int generateAccountNumber(Preferences preferences) {
List<Integer> accountNumbers = getExistingAccountNumbers(preferences);
return findNewAccountNumber(accountNumbers);
}
public void move(Preferences preferences, boolean moveUp) {
String[] uuids = preferences.getStorage().getString("accountUuids", "").split(",");
StorageEditor editor = preferences.getStorage().edit();
@ -526,7 +500,7 @@ public class Account implements BaseAccount, StoreConfig {
}
public synchronized void save() {
DI.get(AccountManager.class).save(this);
DI.get(Preferences.class).saveAccount(this);
}
private void resetVisibleLimits() {

View file

@ -7,44 +7,14 @@ import com.fsck.k9.preferences.Storage
import com.fsck.k9.preferences.StorageEditor
import java.util.*
class AccountManager(
private val preferences: Preferences,
private val localKeyStoreManager: LocalKeyStoreManager
) {
class AccountPreferenceSerializer {
@Synchronized
fun save(account: Account) {
fun save(storage: Storage, editor: StorageEditor, account: Account) {
val accountUuid = account.uuid
val editor = preferences.storage.edit()
if (!preferences.storage.getString("accountUuids", "").contains(accountUuid)) {
/*
* When the account is first created we assign it a unique account number. The
* account number will be unique to that account for the lifetime of the account.
* So, we get all the existing account numbers, sort them ascending, loop through
* the list and check if the number is greater than 1 + the previous number. If so
* we use the previous number + 1 as the account number. This refills gaps.
* accountNumber starts as -1 on a newly created account. It must be -1 for this
* algorithm to work.
*
* I bet there is a much smarter way to do this. Anyone like to suggest it?
*/
val accounts = preferences.accounts
val accountNumbers = IntArray(accounts.size)
for (i in accounts.indices) {
accountNumbers[i] = accounts[i].accountNumber
}
Arrays.sort(accountNumbers)
for (accountNumber in accountNumbers) {
if (accountNumber > account.accountNumber + 1) {
break
}
account.accountNumber = accountNumber
}
account.accountNumber += 1
var accountUuids = preferences.storage.getString("accountUuids", "")
accountUuids += (if (accountUuids.isNotEmpty()) "," else "") + accountUuid
if (!storage.getString("accountUuids", "").contains(account.uuid)) {
var accountUuids = storage.getString("accountUuids", "")
accountUuids += (if (accountUuids.isNotEmpty()) "," else "") + account.uuid
editor.putString("accountUuids", accountUuids)
}
@ -140,20 +110,18 @@ class AccountManager(
}
}
saveIdentities(account, preferences.storage, editor)
saveIdentities(account, storage, editor)
editor.commit()
}
@Synchronized
fun delete(account: Account) {
localKeyStoreManager.deleteCertificates(account)
fun delete(storage: Storage, account: Account) {
val accountUuid = account.uuid
// Get the list of account UUIDs
val uuids = preferences.storage.getString("accountUuids", "").split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val uuids = storage.getString("accountUuids", "").split(",".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
// Create a list of all account UUIDs excluding this account
val newUuids = ArrayList<String>(uuids.size)
@ -163,7 +131,7 @@ class AccountManager(
}
}
val editor = preferences.storage.edit()
val editor = storage.edit()
// Only change the 'accountUuids' value if this account's UUID was listed before
if (newUuids.size < uuids.size) {
@ -254,7 +222,7 @@ class AccountManager(
for (type in NetworkType.values()) {
editor.remove(accountUuid + ".useCompression." + type.name)
}
deleteIdentities(account, preferences.storage, editor)
deleteIdentities(account, storage, editor)
// TODO: Remove preference settings that may exist for individual folders in the account.
editor.commit()
}

View file

@ -26,8 +26,9 @@ public class Preferences {
public static synchronized Preferences getPreferences(Context context) {
Context appContext = context.getApplicationContext();
CoreResourceProvider resourceProvider = DI.get(CoreResourceProvider.class);
LocalKeyStoreManager localKeyStoreManager = DI.get(LocalKeyStoreManager.class);
if (preferences == null) {
preferences = new Preferences(appContext, resourceProvider);
preferences = new Preferences(appContext, resourceProvider, localKeyStoreManager);
}
return preferences;
}
@ -38,11 +39,13 @@ public class Preferences {
private Account newAccount;
private Context context;
private final CoreResourceProvider resourceProvider;
private final LocalKeyStoreManager localKeyStoreManager;
private Preferences(Context context, CoreResourceProvider resourceProvider) {
private Preferences(Context context, CoreResourceProvider resourceProvider, LocalKeyStoreManager localKeyStoreManager) {
storage = Storage.getStorage(context);
this.context = context;
this.resourceProvider = resourceProvider;
this.localKeyStoreManager = localKeyStoreManager;
if (storage.isEmpty()) {
Timber.i("Preferences storage is zero-size, importing from Android-style preferences");
StorageEditor editor = storage.edit();
@ -135,7 +138,8 @@ public class Preferences {
}
LocalStore.removeAccount(account);
DI.get(AccountManager.class).delete(account);
DI.get(AccountPreferenceSerializer.class).delete(storage, account);
localKeyStoreManager.deleteCertificates(account);
if (newAccount == account) {
newAccount = null;
@ -190,4 +194,43 @@ public class Preferences {
private BackendManager getBackendManager() {
return DI.get(BackendManager.class);
}
public void saveAccount(Account account) {
StorageEditor editor = storage.edit();
if (!accounts.containsKey(account.getUuid())) {
int accountNumber = generateAccountNumber();
account.setAccountNumber(accountNumber);
}
DI.get(AccountPreferenceSerializer.class).save(storage, editor, account);
}
public int generateAccountNumber() {
List<Integer> accountNumbers = getExistingAccountNumbers();
return findNewAccountNumber(accountNumbers);
}
private List<Integer> getExistingAccountNumbers() {
List<Account> accounts = getAccounts();
List<Integer> accountNumbers = new ArrayList<>(accounts.size());
for (Account a : accounts) {
accountNumbers.add(a.getAccountNumber());
}
return accountNumbers;
}
private static int findNewAccountNumber(List<Integer> accountNumbers) {
int newAccountNumber = -1;
Collections.sort(accountNumbers);
for (int accountNumber : accountNumbers) {
if (accountNumber > newAccountNumber + 1) {
break;
}
newAccountNumber = accountNumber;
}
newAccountNumber++;
return newAccountNumber;
}
}

View file

@ -3,7 +3,7 @@ package com.fsck.k9.notification
import android.app.NotificationManager
import android.content.Context
import android.support.v4.app.NotificationManagerCompat
import com.fsck.k9.AccountManager
import com.fsck.k9.AccountPreferenceSerializer
import com.fsck.k9.LocalKeyStoreManager
import com.fsck.k9.mail.ssl.LocalKeyStore
import org.koin.dsl.module.applicationContext
@ -21,7 +21,7 @@ val coreNotificationModule = applicationContext {
get()
)
}
bean { AccountManager(get(), get()) }
bean { AccountPreferenceSerializer() }
bean { LocalKeyStore.getInstance() }
bean { LocalKeyStoreManager(get()) }
bean { CertificateErrorNotifications(get(), get(), get()) }

View file

@ -417,7 +417,7 @@ public class SettingsImporter {
// If it's a new account generate and write a new "accountNumber"
if (!mergeImportedAccount) {
int newAccountNumber = Account.generateAccountNumber(prefs);
int newAccountNumber = prefs.generateAccountNumber();
putString(editor, accountKeyPrefix + "accountNumber", Integer.toString(newAccountNumber));
}