1
0
mirror of https://github.com/etesync/android synced 2025-01-11 08:10:58 +00:00

Workaround Android account creation issue (ignoring userData)

It seems like there's an issue with Android that sometimes the userData
passed to addAccountExplicitly is not correctly set in the Android cache
making it return null on subsequent fetches. It doesn't always happen
because some cases clear the cache, however I can consistently trigger
it by creating and deleting an account a few times in a row.
This commit is contained in:
Tom Hacohen 2017-04-26 20:40:52 +01:00
parent db82757bc4
commit 674ea1eeca
3 changed files with 19 additions and 20 deletions

View File

@ -31,7 +31,6 @@ import com.etesync.syncadapter.model.CollectionInfo;
import com.etesync.syncadapter.resource.LocalAddressBook; import com.etesync.syncadapter.resource.LocalAddressBook;
import com.etesync.syncadapter.utils.Base64; import com.etesync.syncadapter.utils.Base64;
import java.lang.reflect.Method;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.List; import java.util.List;
@ -105,12 +104,11 @@ public class AccountSettings {
} }
} }
public static Bundle initialUserData(URI uri, String userName) { // XXX: Workaround a bug in Android where passing a bundle to addAccountExplicitly doesn't work.
Bundle bundle = new Bundle(); public static void setUserData(AccountManager accountManager, Account account, URI uri, String userName) {
bundle.putString(KEY_SETTINGS_VERSION, String.valueOf(CURRENT_VERSION)); accountManager.setUserData(account, KEY_SETTINGS_VERSION, String.valueOf(CURRENT_VERSION));
bundle.putString(KEY_USERNAME, userName); accountManager.setUserData(account, KEY_USERNAME, userName);
bundle.putString(KEY_URI, uri.toString()); accountManager.setUserData(account, KEY_URI, uri.toString());
return bundle;
} }
@ -286,8 +284,10 @@ public class AccountSettings {
info.displayName = account.name; info.displayName = account.name;
App.log.log(Level.INFO, "Creating new address book account", url); App.log.log(Level.INFO, "Creating new address book account", url);
Account addressBookAccount = new Account(LocalAddressBook.accountName(account, info), App.getAddressBookAccountType()); Account addressBookAccount = new Account(LocalAddressBook.accountName(account, info), App.getAddressBookAccountType());
if (!accountManager.addAccountExplicitly(addressBookAccount, null, LocalAddressBook.initialUserData(account, info.uid))) if (!accountManager.addAccountExplicitly(addressBookAccount, null, null))
throw new ContactsStorageException("Couldn't create address book account"); throw new ContactsStorageException("Couldn't create address book account");
LocalAddressBook.setUserData(accountManager, addressBookAccount, account, info.uid);
LocalAddressBook addressBook = new LocalAddressBook(context, addressBookAccount, provider); LocalAddressBook addressBook = new LocalAddressBook(context, addressBookAccount, provider);
// move contacts to new address book // move contacts to new address book

View File

@ -34,9 +34,7 @@ import com.etesync.syncadapter.App;
import com.etesync.syncadapter.model.CollectionInfo; import com.etesync.syncadapter.model.CollectionInfo;
import com.etesync.syncadapter.model.JournalEntity; import com.etesync.syncadapter.model.JournalEntity;
import com.etesync.syncadapter.utils.AndroidCompat; import com.etesync.syncadapter.utils.AndroidCompat;
import com.etesync.syncadapter.utils.Base64;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.util.Collections; import java.util.Collections;
@ -102,9 +100,10 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
AccountManager accountManager = AccountManager.get(context); AccountManager accountManager = AccountManager.get(context);
Account account = new Account(accountName(mainAccount, info), App.getAddressBookAccountType()); Account account = new Account(accountName(mainAccount, info), App.getAddressBookAccountType());
if (!accountManager.addAccountExplicitly(account, null, initialUserData(mainAccount, info.uid))) if (!accountManager.addAccountExplicitly(account, null, null))
throw new ContactsStorageException("Couldn't create address book account"); throw new ContactsStorageException("Couldn't create address book account");
setUserData(accountManager, account, mainAccount, info.uid);
LocalAddressBook addressBook = new LocalAddressBook(context, account, provider); LocalAddressBook addressBook = new LocalAddressBook(context, account, provider);
addressBook.setMainAccount(mainAccount); addressBook.setMainAccount(mainAccount);
addressBook.setURL(info.uid); addressBook.setURL(info.uid);
@ -360,12 +359,11 @@ public class LocalAddressBook extends AndroidAddressBook implements LocalCollect
// SETTINGS // SETTINGS
public static Bundle initialUserData(@NonNull Account mainAccount, @NonNull String url) { // XXX: Workaround a bug in Android where passing a bundle to addAccountExplicitly doesn't work.
Bundle bundle = new Bundle(3); public static void setUserData(@NonNull AccountManager accountManager, @NonNull Account account, @NonNull Account mainAccount, @NonNull String url) {
bundle.putString(USER_DATA_MAIN_ACCOUNT_NAME, mainAccount.name); accountManager.setUserData(account, USER_DATA_MAIN_ACCOUNT_NAME, mainAccount.name);
bundle.putString(USER_DATA_MAIN_ACCOUNT_TYPE, mainAccount.type); accountManager.setUserData(account, USER_DATA_MAIN_ACCOUNT_TYPE, mainAccount.type);
bundle.putString(USER_DATA_URL, url); accountManager.setUserData(account, USER_DATA_URL, url);
return bundle;
} }
public Account getMainAccount() throws ContactsStorageException { public Account getMainAccount() throws ContactsStorageException {

View File

@ -166,13 +166,14 @@ public class SetupEncryptionFragment extends DialogFragment implements LoaderMan
Account account = new Account(accountName, App.getAccountType()); Account account = new Account(accountName, App.getAccountType());
// create Android account // create Android account
Bundle userData = AccountSettings.initialUserData(config.url, config.userName); App.log.log(Level.INFO, "Creating Android account with initial config", new Object[] { account, config.userName, config.url });
App.log.log(Level.INFO, "Creating Android account with initial config", new Object[] { account, userData });
AccountManager accountManager = AccountManager.get(getContext()); AccountManager accountManager = AccountManager.get(getContext());
if (!accountManager.addAccountExplicitly(account, config.password, userData)) if (!accountManager.addAccountExplicitly(account, config.password, null))
return false; return false;
AccountSettings.setUserData(accountManager, account, config.url, config.userName);
// add entries for account to service DB // add entries for account to service DB
App.log.log(Level.INFO, "Writing account configuration to database", config); App.log.log(Level.INFO, "Writing account configuration to database", config);
try { try {