Merge branch 'readonly-p4-master'
This commit is contained in:
commit
3c4552eb4a
|
@ -30,16 +30,24 @@ import java.util.UUID;
|
|||
* Account stores all of the settings for a single account defined by the user. It is able to save
|
||||
* and delete itself given a Preferences to work with. Each account is defined by a UUID.
|
||||
*/
|
||||
public class Account implements Serializable {
|
||||
public class Account implements Serializable, Store.PersistentDataCallbacks {
|
||||
public static final int DELETE_POLICY_NEVER = 0;
|
||||
public static final int DELETE_POLICY_7DAYS = 1;
|
||||
public static final int DELETE_POLICY_ON_DELETE = 2;
|
||||
|
||||
public static final int CHECK_INTERVAL_NEVER = -1;
|
||||
public static final int CHECK_INTERVAL_PUSH = -2;
|
||||
|
||||
private static final long serialVersionUID = 2975156672298625121L;
|
||||
|
||||
/**
|
||||
* This should never be used for persistance, only for marshalling.
|
||||
* TODO: Remove serializable (VERY SLOW) and replace with Parcelable
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// transient values - do not serialize
|
||||
private transient Preferences mPreferences;
|
||||
|
||||
// serialized values
|
||||
String mUuid;
|
||||
String mStoreUri;
|
||||
String mLocalStoreUri;
|
||||
|
@ -57,6 +65,12 @@ public class Account implements Serializable {
|
|||
int mAccountNumber;
|
||||
boolean mVibrate;
|
||||
String mRingtoneUri;
|
||||
String mStorePersistent;
|
||||
|
||||
/**
|
||||
* TODO: all fields should be tagged here
|
||||
*/
|
||||
private final String PREF_TAG_STORE_PERSISTENT = ".storePersist";
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
|
@ -87,6 +101,8 @@ public class Account implements Serializable {
|
|||
* Refresh the account from the stored settings.
|
||||
*/
|
||||
public void refresh(Preferences preferences) {
|
||||
mPreferences = preferences;
|
||||
|
||||
mStoreUri = Utility.base64Decode(preferences.mSharedPreferences.getString(mUuid
|
||||
+ ".storeUri", null));
|
||||
mLocalStoreUri = preferences.mSharedPreferences.getString(mUuid + ".localStoreUri", null);
|
||||
|
@ -129,6 +145,9 @@ public class Account implements Serializable {
|
|||
mVibrate = preferences.mSharedPreferences.getBoolean(mUuid + ".vibrate", false);
|
||||
mRingtoneUri = preferences.mSharedPreferences.getString(mUuid + ".ringtone",
|
||||
"content://settings/system/notification_sound");
|
||||
|
||||
mStorePersistent = preferences.mSharedPreferences.getString(
|
||||
mUuid + PREF_TAG_STORE_PERSISTENT, null);
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
|
@ -223,7 +242,8 @@ public class Account implements Serializable {
|
|||
editor.remove(mUuid + ".accountNumber");
|
||||
editor.remove(mUuid + ".vibrate");
|
||||
editor.remove(mUuid + ".ringtone");
|
||||
|
||||
editor.remove(mUuid + PREF_TAG_STORE_PERSISTENT);
|
||||
|
||||
// also delete any deprecated fields
|
||||
editor.remove(mUuid + ".transportUri");
|
||||
|
||||
|
@ -231,6 +251,8 @@ public class Account implements Serializable {
|
|||
}
|
||||
|
||||
public void save(Preferences preferences) {
|
||||
mPreferences = preferences;
|
||||
|
||||
if (!preferences.mSharedPreferences.getString("accountUuids", "").contains(mUuid)) {
|
||||
/*
|
||||
* When the account is first created we assign it a unique account number. The
|
||||
|
@ -284,12 +306,17 @@ public class Account implements Serializable {
|
|||
editor.putBoolean(mUuid + ".vibrate", mVibrate);
|
||||
editor.putString(mUuid + ".ringtone", mRingtoneUri);
|
||||
|
||||
// The following fields are *not* written because they need to be more fine-grained
|
||||
// and not risk rewriting with old data.
|
||||
// editor.putString(mUuid + PREF_TAG_STORE_PERSISTENT, mStorePersistent);
|
||||
|
||||
// also delete any deprecated fields
|
||||
editor.remove(mUuid + ".transportUri");
|
||||
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mDescription;
|
||||
}
|
||||
|
@ -380,6 +407,44 @@ public class Account implements Serializable {
|
|||
return mAccountNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a small place for Stores to store persistent data. This will need to be
|
||||
* expanded in the future, but is sufficient for now.
|
||||
* @param storeData Data to persist. All data must be encoded into a string,
|
||||
* so use base64 or some other encoding if necessary.
|
||||
*/
|
||||
public void setPersistentString(String storeData) {
|
||||
synchronized (this.getClass()) {
|
||||
mStorePersistent = mPreferences.mSharedPreferences.getString(
|
||||
mUuid + PREF_TAG_STORE_PERSISTENT, null);
|
||||
if ((mStorePersistent == null && storeData != null) ||
|
||||
(mStorePersistent != null && !mStorePersistent.equals(storeData))) {
|
||||
mStorePersistent = storeData;
|
||||
SharedPreferences.Editor editor = mPreferences.mSharedPreferences.edit();
|
||||
editor.putString(mUuid + PREF_TAG_STORE_PERSISTENT, mStorePersistent);
|
||||
editor.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the data saved by the Store, or null if never set.
|
||||
*/
|
||||
public String getPersistentString() {
|
||||
synchronized (this.getClass()) {
|
||||
mStorePersistent = mPreferences.mSharedPreferences.getString(
|
||||
mUuid + PREF_TAG_STORE_PERSISTENT, null);
|
||||
}
|
||||
return mStorePersistent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An implementation of Store.PersistentDataCallbacks
|
||||
*/
|
||||
public Store.PersistentDataCallbacks getStoreCallbacks() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof Account) {
|
||||
|
|
|
@ -189,7 +189,7 @@ public class MessagingController implements Runnable {
|
|||
l.listFoldersStarted(account);
|
||||
}
|
||||
try {
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
Folder[] localFolders = localStore.getPersonalNamespaces();
|
||||
|
||||
if (localFolders == null || localFolders.length == 0) {
|
||||
|
@ -210,13 +210,13 @@ public class MessagingController implements Runnable {
|
|||
put("listFolders", listener, new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
Store store = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Store store = Store.getInstance(account.getStoreUri(), mApplication,
|
||||
account.getStoreCallbacks());
|
||||
|
||||
Folder[] remoteFolders = store.getPersonalNamespaces();
|
||||
|
||||
Store localStore = Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
mApplication);
|
||||
account.getLocalStoreUri(), mApplication, null);
|
||||
HashSet<String> remoteFolderNames = new HashSet<String>();
|
||||
for (int i = 0, count = remoteFolders.length; i < count; i++) {
|
||||
Folder localFolder = localStore.getFolder(remoteFolders[i].getName());
|
||||
|
@ -284,7 +284,7 @@ public class MessagingController implements Runnable {
|
|||
}
|
||||
|
||||
try {
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
Folder localFolder = localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
Message[] localMessages = localFolder.getMessages(null);
|
||||
|
@ -311,8 +311,7 @@ public class MessagingController implements Runnable {
|
|||
public void loadMoreMessages(Account account, String folder, MessagingListener listener) {
|
||||
try {
|
||||
LocalStore localStore = (LocalStore) Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
mApplication);
|
||||
account.getLocalStoreUri(), mApplication, null);
|
||||
LocalFolder localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||
localFolder.setVisibleLimit(localFolder.getVisibleLimit()
|
||||
+ Email.VISIBLE_LIMIT_INCREMENT);
|
||||
|
@ -327,7 +326,7 @@ public class MessagingController implements Runnable {
|
|||
for (Account account : accounts) {
|
||||
try {
|
||||
LocalStore localStore =
|
||||
(LocalStore) Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
(LocalStore) Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
localStore.resetVisibleLimits();
|
||||
}
|
||||
catch (MessagingException e) {
|
||||
|
@ -387,7 +386,7 @@ public class MessagingController implements Runnable {
|
|||
* the uids within the list.
|
||||
*/
|
||||
final LocalStore localStore =
|
||||
(LocalStore) Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
(LocalStore) Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
final LocalFolder localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
Message[] localMessages = localFolder.getMessages(null);
|
||||
|
@ -396,7 +395,8 @@ public class MessagingController implements Runnable {
|
|||
localUidMap.put(message.getUid(), message);
|
||||
}
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication,
|
||||
account.getStoreCallbacks());
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
|
||||
/*
|
||||
|
@ -753,8 +753,7 @@ public class MessagingController implements Runnable {
|
|||
private void queuePendingCommand(Account account, PendingCommand command) {
|
||||
try {
|
||||
LocalStore localStore = (LocalStore) Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
mApplication);
|
||||
account.getLocalStoreUri(), mApplication, null);
|
||||
localStore.addPendingCommand(command);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
@ -783,8 +782,7 @@ public class MessagingController implements Runnable {
|
|||
|
||||
private void processPendingCommandsSynchronous(Account account) throws MessagingException {
|
||||
LocalStore localStore = (LocalStore) Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
mApplication);
|
||||
account.getLocalStoreUri(), mApplication, null);
|
||||
ArrayList<PendingCommand> commands = localStore.getPendingCommands();
|
||||
for (PendingCommand command : commands) {
|
||||
/*
|
||||
|
@ -823,8 +821,7 @@ public class MessagingController implements Runnable {
|
|||
String uid = command.arguments[1];
|
||||
|
||||
LocalStore localStore = (LocalStore) Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
mApplication);
|
||||
account.getLocalStoreUri(), mApplication, null);
|
||||
LocalFolder localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||
LocalMessage localMessage = (LocalMessage) localFolder.getMessage(uid);
|
||||
|
||||
|
@ -832,7 +829,8 @@ public class MessagingController implements Runnable {
|
|||
return;
|
||||
}
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication,
|
||||
account.getStoreCallbacks());
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
if (!remoteFolder.exists()) {
|
||||
if (!remoteFolder.create(FolderType.HOLDS_MESSAGES)) {
|
||||
|
@ -916,7 +914,8 @@ public class MessagingController implements Runnable {
|
|||
String folder = command.arguments[0];
|
||||
String uid = command.arguments[1];
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication,
|
||||
account.getStoreCallbacks());
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
if (!remoteFolder.exists()) {
|
||||
return;
|
||||
|
@ -966,7 +965,8 @@ public class MessagingController implements Runnable {
|
|||
String uid = command.arguments[1];
|
||||
boolean read = Boolean.parseBoolean(command.arguments[2]);
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication,
|
||||
account.getStoreCallbacks());
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
if (!remoteFolder.exists()) {
|
||||
return;
|
||||
|
@ -999,7 +999,7 @@ public class MessagingController implements Runnable {
|
|||
final String uid,
|
||||
final boolean seen) {
|
||||
try {
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
Folder localFolder = localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
|
@ -1021,7 +1021,8 @@ public class MessagingController implements Runnable {
|
|||
put("loadMessageForViewRemote", listener, new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Store localStore = Store.getInstance(
|
||||
account.getLocalStoreUri(), mApplication, null);
|
||||
LocalFolder localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
|
@ -1052,7 +1053,8 @@ public class MessagingController implements Runnable {
|
|||
* fully if possible.
|
||||
*/
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication,
|
||||
account.getStoreCallbacks());
|
||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
||||
remoteFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
|
@ -1099,7 +1101,7 @@ public class MessagingController implements Runnable {
|
|||
l.loadMessageForViewStarted(account, folder, uid);
|
||||
}
|
||||
try {
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
LocalFolder localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
||||
|
@ -1185,8 +1187,8 @@ public class MessagingController implements Runnable {
|
|||
put("loadAttachment", listener, new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
LocalStore localStore =
|
||||
(LocalStore) Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
LocalStore localStore = (LocalStore) Store.getInstance(
|
||||
account.getLocalStoreUri(), mApplication, null);
|
||||
/*
|
||||
* We clear out any attachments already cached in the entire store and then
|
||||
* we update the passed in message to reflect that there are no cached
|
||||
|
@ -1200,7 +1202,8 @@ public class MessagingController implements Runnable {
|
|||
for (Part attachment : attachments) {
|
||||
attachment.setBody(null);
|
||||
}
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication,
|
||||
account.getStoreCallbacks());
|
||||
LocalFolder localFolder =
|
||||
(LocalFolder) localStore.getFolder(message.getFolder().getName());
|
||||
Folder remoteFolder = remoteStore.getFolder(message.getFolder().getName());
|
||||
|
@ -1238,7 +1241,7 @@ public class MessagingController implements Runnable {
|
|||
final Message message,
|
||||
MessagingListener listener) {
|
||||
try {
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
LocalFolder localFolder =
|
||||
(LocalFolder) localStore.getFolder(account.getOutboxFolderName());
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
@ -1278,9 +1281,7 @@ public class MessagingController implements Runnable {
|
|||
*/
|
||||
public void sendPendingMessagesSynchronous(final Account account) {
|
||||
try {
|
||||
Store localStore = Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
mApplication);
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
Folder localFolder = localStore.getFolder(
|
||||
account.getOutboxFolderName());
|
||||
if (!localFolder.exists()) {
|
||||
|
@ -1364,7 +1365,7 @@ public class MessagingController implements Runnable {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
Folder localFolder = localStore.getFolder(folder);
|
||||
Folder localTrashFolder = localStore.getFolder(account.getTrashFolderName());
|
||||
|
||||
|
@ -1389,7 +1390,8 @@ public class MessagingController implements Runnable {
|
|||
public void run() {
|
||||
// TODO IMAP
|
||||
try {
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Store localStore = Store.getInstance(
|
||||
account.getLocalStoreUri(), mApplication, null);
|
||||
Folder localFolder = localStore.getFolder(account.getTrashFolderName());
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
Message[] messages = localFolder.getMessages(null);
|
||||
|
@ -1446,7 +1448,7 @@ public class MessagingController implements Runnable {
|
|||
|
||||
public void saveDraft(final Account account, final Message message) {
|
||||
try {
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication, null);
|
||||
LocalFolder localFolder =
|
||||
(LocalFolder) localStore.getFolder(account.getDraftsFolderName());
|
||||
localFolder.open(OpenMode.READ_WRITE);
|
||||
|
|
|
@ -124,8 +124,7 @@ public class AccountShortcutPicker extends ListActivity implements OnItemClickLi
|
|||
int unreadMessageCount = 0;
|
||||
try {
|
||||
LocalStore localStore = (LocalStore) Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
getApplication());
|
||||
account.getLocalStoreUri(), getApplication(), null);
|
||||
LocalFolder localFolder = (LocalFolder) localStore.getFolder(Email.INBOX);
|
||||
if (localFolder.exists()) {
|
||||
unreadMessageCount = localFolder.getUnreadMessageCount();
|
||||
|
|
|
@ -174,11 +174,13 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
|
|||
// Delete Remote store at first.
|
||||
Store.getInstance(
|
||||
mSelectedContextAccount.getStoreUri(),
|
||||
getApplication()).delete();
|
||||
getApplication(),
|
||||
mSelectedContextAccount.getStoreCallbacks()).delete();
|
||||
// If no error, then delete LocalStore
|
||||
Store.getInstance(
|
||||
mSelectedContextAccount.getLocalStoreUri(),
|
||||
getApplication()).delete();
|
||||
getApplication(),
|
||||
null).delete();
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
|
@ -299,7 +301,8 @@ public class Accounts extends ListActivity implements OnItemClickListener, OnCli
|
|||
try {
|
||||
LocalStore localStore = (LocalStore) Store.getInstance(
|
||||
account.getLocalStoreUri(),
|
||||
getApplication());
|
||||
getApplication(),
|
||||
null);
|
||||
LocalFolder localFolder = (LocalFolder) localStore.getFolder(Email.INBOX);
|
||||
if (localFolder.exists()) {
|
||||
unreadMessageCount = localFolder.getUnreadMessageCount();
|
||||
|
|
|
@ -195,7 +195,8 @@ public class AccountSettings extends PreferenceActivity {
|
|||
|
||||
private void onIncomingSettings() {
|
||||
try {
|
||||
Store store = Store.getInstance(mAccount.getStoreUri(), getApplication());
|
||||
Store store = Store.getInstance(mAccount.getStoreUri(), getApplication(),
|
||||
mAccount.getStoreCallbacks());
|
||||
if (store != null) {
|
||||
Class<? extends android.app.Activity> setting = store.getSettingActivityClass();
|
||||
if (setting != null) {
|
||||
|
|
|
@ -141,7 +141,7 @@ public class AccountSetupAccountType extends Activity implements OnClickListener
|
|||
try {
|
||||
URI uri = new URI(mAccount.getStoreUri());
|
||||
uri = new URI("eas", uri.getUserInfo(), uri.getHost(), uri.getPort(), null, null, null);
|
||||
Store store = Store.getInstance(uri.toString(), this);
|
||||
Store store = Store.getInstance(uri.toString(), this, mAccount.getStoreCallbacks());
|
||||
return (store != null);
|
||||
} catch (URISyntaxException e) {
|
||||
return false;
|
||||
|
|
|
@ -104,7 +104,8 @@ public class AccountSetupCheckSettings extends Activity implements OnClickListen
|
|||
}
|
||||
if (mCheckIncoming) {
|
||||
setMessage(R.string.account_setup_check_settings_check_incoming_msg);
|
||||
Store store = Store.getInstance(mAccount.getStoreUri(), getApplication());
|
||||
Store store = Store.getInstance(mAccount.getStoreUri(), getApplication(),
|
||||
mAccount.getStoreCallbacks());
|
||||
store.checkSettings();
|
||||
}
|
||||
if (mDestroyed) {
|
||||
|
|
|
@ -57,20 +57,22 @@ public abstract class Store {
|
|||
* Static named constructor. It should be overrode by extending class.
|
||||
* Because this method will be called through reflection, it can not be protected.
|
||||
*/
|
||||
public static Store newInstance(String uri, Context context)
|
||||
public static Store newInstance(String uri, Context context, PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
throw new MessagingException("Store.newInstance: Unknown scheme in " + uri);
|
||||
}
|
||||
|
||||
private static Store instantiateStore(String className, String uri, Context context)
|
||||
private static Store instantiateStore(String className, String uri, Context context,
|
||||
PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
Object o = null;
|
||||
try {
|
||||
Class<?> c = Class.forName(className);
|
||||
// and invoke "newInstance" class method and instantiate store object.
|
||||
java.lang.reflect.Method m =
|
||||
c.getMethod("newInstance", String.class, Context.class);
|
||||
o = m.invoke(null, uri, context);
|
||||
c.getMethod("newInstance", String.class, Context.class,
|
||||
PersistentDataCallbacks.class);
|
||||
o = m.invoke(null, uri, context, callbacks);
|
||||
} catch (Exception e) {
|
||||
Log.d(Email.LOG_TAG, String.format(
|
||||
"exception %s invoking %s.newInstance.(String, Context) method for %s",
|
||||
|
@ -149,13 +151,14 @@ public abstract class Store {
|
|||
* @return an initialized store of the appropriate class
|
||||
* @throws MessagingException
|
||||
*/
|
||||
public synchronized static Store getInstance(String uri, Context context)
|
||||
public synchronized static Store getInstance(String uri, Context context,
|
||||
PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
Store store = mStores.get(uri);
|
||||
if (store == null) {
|
||||
StoreInfo info = StoreInfo.getStoreInfo(uri, context);
|
||||
if (info != null) {
|
||||
store = instantiateStore(info.mClassName, uri, context);
|
||||
store = instantiateStore(info.mClassName, uri, context, callbacks);
|
||||
}
|
||||
|
||||
if (store != null) {
|
||||
|
@ -212,4 +215,23 @@ public abstract class Store {
|
|||
*/
|
||||
public void delete() throws MessagingException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface by which a Store can read and write persistent data.
|
||||
* TODO This needs to be made more generic & flexible
|
||||
*/
|
||||
public interface PersistentDataCallbacks {
|
||||
|
||||
/**
|
||||
* Provides a small place for Stores to store persistent data.
|
||||
* @param storeData Data to persist. All data must be encoded into a string,
|
||||
* so use base64 or some other encoding if necessary.
|
||||
*/
|
||||
public void setPersistentString(String storeData);
|
||||
|
||||
/**
|
||||
* @return the data saved by the Store, or null if never set.
|
||||
*/
|
||||
public String getPersistentString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ public class ExchangeStoreExample extends Store {
|
|||
|
||||
private final Context mContext;
|
||||
private URI mUri;
|
||||
private PersistentDataCallbacks mCallbacks;
|
||||
|
||||
private final ExchangeTransportExample mTransport;
|
||||
private final HashMap<String, Folder> mFolders = new HashMap<String, Folder>();
|
||||
|
@ -52,9 +53,9 @@ public class ExchangeStoreExample extends Store {
|
|||
/**
|
||||
* Factory method.
|
||||
*/
|
||||
public static Store newInstance(String uri, Context context)
|
||||
public static Store newInstance(String uri, Context context, PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
return new ExchangeStoreExample(uri, context);
|
||||
return new ExchangeStoreExample(uri, context, callbacks);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -64,13 +65,15 @@ public class ExchangeStoreExample extends Store {
|
|||
* @param application
|
||||
* @throws MessagingException
|
||||
*/
|
||||
private ExchangeStoreExample(String _uri, Context context) throws MessagingException {
|
||||
private ExchangeStoreExample(String _uri, Context context, PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
mContext = context;
|
||||
try {
|
||||
mUri = new URI(_uri);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new MessagingException("Invalid uri for ExchangeStoreExample");
|
||||
}
|
||||
mCallbacks = callbacks;
|
||||
|
||||
String scheme = mUri.getScheme();
|
||||
int connectionSecurity;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package com.android.email.mail.store;
|
||||
|
||||
import com.android.email.Email;
|
||||
import com.android.email.PeekableInputStream;
|
||||
import com.android.email.Utility;
|
||||
import com.android.email.mail.AuthenticationFailedException;
|
||||
import com.android.email.mail.CertificateValidationException;
|
||||
|
@ -112,7 +111,8 @@ public class ImapStore extends Store {
|
|||
/**
|
||||
* Static named constructor.
|
||||
*/
|
||||
public static Store newInstance(String uri, Context context) throws MessagingException {
|
||||
public static Store newInstance(String uri, Context context, PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
return new ImapStore(uri);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,7 +85,8 @@ public class Pop3Store extends Store {
|
|||
/**
|
||||
* Static named constructor.
|
||||
*/
|
||||
public static Store newInstance(String uri, Context context) throws MessagingException {
|
||||
public static Store newInstance(String uri, Context context, PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
return new Pop3Store(uri);
|
||||
}
|
||||
|
||||
|
|
|
@ -283,7 +283,8 @@ public class MailService extends Service {
|
|||
try {
|
||||
String storeUri = account.getStoreUri();
|
||||
if (storeUri != null) {
|
||||
Store store = Store.getInstance(storeUri, this.getBaseContext());
|
||||
Store store = Store.getInstance(storeUri, this.getBaseContext(),
|
||||
account.getStoreCallbacks());
|
||||
if (store != null) {
|
||||
store.enablePushModeDelivery(enable);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package com.android.email;
|
||||
|
||||
import com.android.email.mail.Store;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
@ -135,6 +137,59 @@ public class AccountUnitTests extends AndroidTestCase {
|
|||
assertEquals(Account.DELETE_POLICY_ON_DELETE, storedPolicy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the new store persistent data code.
|
||||
*
|
||||
* This test, and the underlying code, reflect the essential error in the Account class. The
|
||||
* account objects should have been singletons-per-account. As it stands there are lots of
|
||||
* them floating around, which is very expensive (we waste a lot of effort creating them)
|
||||
* and forces slow sync hacks for dynamic data like the store's persistent data.
|
||||
*/
|
||||
public void testStorePersistentData() {
|
||||
|
||||
final String TEST_STRING = "This is the store's persistent data.";
|
||||
final String TEST_STRING_2 = "Rewrite the store data.";
|
||||
|
||||
// create a dummy account
|
||||
createTestAccount();
|
||||
|
||||
// confirm null on new account
|
||||
assertNull(mAccount.getPersistentString());
|
||||
|
||||
// test write/readback
|
||||
mAccount.setPersistentString(TEST_STRING);
|
||||
mAccount.save(mPreferences);
|
||||
mAccount.refresh(mPreferences);
|
||||
assertEquals(TEST_STRING, mAccount.getPersistentString());
|
||||
|
||||
// test that the data is shared across multiple account instantiations
|
||||
Account account2 = new Account(mPreferences, mUuid);
|
||||
assertEquals(TEST_STRING, account2.getPersistentString());
|
||||
mAccount.setPersistentString(TEST_STRING_2);
|
||||
assertEquals(TEST_STRING_2, account2.getPersistentString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the callbacks for setting & getting persistent data
|
||||
*/
|
||||
public void testStorePersistentCallbacks() {
|
||||
|
||||
final String TEST_STRING = "This is the store's persistent data.";
|
||||
final String TEST_STRING_2 = "Rewrite the store data.";
|
||||
|
||||
// create a dummy account
|
||||
createTestAccount();
|
||||
Store.PersistentDataCallbacks callbacks = mAccount.getStoreCallbacks();
|
||||
|
||||
// push some data through the interfaces
|
||||
assertNull(callbacks.getPersistentString());
|
||||
callbacks.setPersistentString(TEST_STRING);
|
||||
assertEquals(TEST_STRING, mAccount.getPersistentString());
|
||||
|
||||
mAccount.setPersistentString(TEST_STRING_2);
|
||||
assertEquals(TEST_STRING_2, callbacks.getPersistentString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dummy account with minimal fields
|
||||
*/
|
||||
|
|
|
@ -38,7 +38,7 @@ public class StoreTests extends AndroidTestCase {
|
|||
assertFalse(info.mPushSupported);
|
||||
|
||||
// This will throw MessagingException if the result would have been null
|
||||
Store store = Store.getInstance(storeUri, getContext());
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,11 +54,12 @@ public class StoreTests extends AndroidTestCase {
|
|||
assertFalse(info.mPushSupported);
|
||||
|
||||
// This will throw MessagingException if the result would have been null
|
||||
Store store = Store.getInstance(storeUri, getContext());
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test StoreInfo & Store lookup for EAS accounts
|
||||
* TODO: EAS store will probably require implementation of Store.PersistentDataCallbacks
|
||||
*/
|
||||
public void testStoreLookupEAS() throws MessagingException {
|
||||
final String storeUri = "eas://user:password@server.com";
|
||||
|
@ -69,10 +70,10 @@ public class StoreTests extends AndroidTestCase {
|
|||
assertTrue(info.mPushSupported);
|
||||
|
||||
// This will throw MessagingException if the result would have been null
|
||||
Store store = Store.getInstance(storeUri, getContext());
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
} else {
|
||||
try {
|
||||
Store store = Store.getInstance(storeUri, getContext());
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
fail("MessagingException expected when EAS not supported");
|
||||
} catch (MessagingException me) {
|
||||
// expected - fall through
|
||||
|
@ -89,7 +90,7 @@ public class StoreTests extends AndroidTestCase {
|
|||
assertNull(info);
|
||||
|
||||
try {
|
||||
Store store = Store.getInstance(storeUri, getContext());
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
fail("MessagingException expected from bogus URI scheme");
|
||||
} catch (MessagingException me) {
|
||||
// expected - fall through
|
||||
|
|
|
@ -50,7 +50,7 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
|||
|
||||
// These are needed so we can get at the inner classes
|
||||
mStore = (ImapStore) ImapStore.newInstance("imap://user:password@server:999",
|
||||
getContext());
|
||||
getContext(), null);
|
||||
mFolder = (ImapStore.ImapFolder) mStore.getFolder("INBOX");
|
||||
|
||||
// This is needed for parsing mime messages
|
||||
|
|
|
@ -57,7 +57,7 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
|
||||
// These are needed so we can get at the inner classes
|
||||
mStore = (Pop3Store) Pop3Store.newInstance("pop3://user:password@server:999",
|
||||
getContext());
|
||||
getContext(), null);
|
||||
mFolder = (Pop3Store.Pop3Folder) mStore.getFolder("INBOX");
|
||||
|
||||
// This is needed for parsing mime messages
|
||||
|
|
Loading…
Reference in New Issue