diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 345575cc9..54d5f25bb 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -213,12 +213,6 @@
-
-
-
+
+
+
+
+
+
+
%s.
IMAP
POP3
- Picky, picky, picky!
+ Folder picker
- Select server trash folder
+ Select server trash folder for %s
- Select server sent items folder
+ Select server sent items folder for %s
Create folder
-
-
-
+ Loading folder list…
+
\ No newline at end of file
diff --git a/src/com/android/email/imap2/Imap2SyncManager.java b/src/com/android/email/imap2/Imap2SyncManager.java
index 7b8fddc58..d708f95f4 100644
--- a/src/com/android/email/imap2/Imap2SyncManager.java
+++ b/src/com/android/email/imap2/Imap2SyncManager.java
@@ -274,17 +274,6 @@ public class Imap2SyncManager extends SyncManager {
inbox.save(getContext());
log("Creating inbox for account: " + acct.mDisplayName);
Imap2SyncManager.kick("New account");
- // Need to sync folder list first; sigh
- Imap2SyncService svc = new Imap2SyncService(Imap2SyncManager.this, acct);
- try {
- svc.loadFolderList();
- mResolver.update(
- ContentUris.withAppendedId(EmailContent.PICK_TRASH_FOLDER_URI, acctId),
- new ContentValues(), null, null);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
}
};
}
diff --git a/src/com/android/email/imap2/Imap2SyncService.java b/src/com/android/email/imap2/Imap2SyncService.java
index 871f0722f..3b20dcf26 100644
--- a/src/com/android/email/imap2/Imap2SyncService.java
+++ b/src/com/android/email/imap2/Imap2SyncService.java
@@ -1379,6 +1379,17 @@ public class Imap2SyncService extends AbstractSyncService {
}
applyBatch(ops);
+
+ // Set folder list loaded flag, if it hasn't already been
+ if ((mAccount.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) == 0) {
+ userLog("Notify initial folder list loaded...");
+ mAccount.mFlags |= Account.FLAGS_INITIAL_FOLDER_LIST_LOADED;
+ ContentValues values = new ContentValues();
+ values.put(AccountColumns.FLAGS, mAccount.mFlags);
+ mResolver.update(ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId),
+ values, null, null);
+ }
+
// Fixup parent stuff, flags...
MailboxUtilities.fixupUninitializedParentKeys(mContext,
Mailbox.ACCOUNT_KEY + "=" + mAccountId);
@@ -2173,7 +2184,8 @@ public class Imap2SyncService extends AbstractSyncService {
idle();
}
-
+ } catch (Exception e) {
+ userLog("Exception in imap2 sync", e);
} finally {
// Don't kill the connection until mBodyThread is done...
if (mBodyThread != null) {
@@ -2253,6 +2265,7 @@ public class Imap2SyncService extends AbstractSyncService {
public void run() {
try {
TAG = Thread.currentThread().getName();
+ userLog("Starting imap sync thread...");
// Check for Outbox (special "sync") and stopped
if (mMailbox.mType == Mailbox.TYPE_OUTBOX) {
diff --git a/src/com/android/email/provider/EmailProvider.java b/src/com/android/email/provider/EmailProvider.java
index 49707d8c7..3859af03a 100644
--- a/src/com/android/email/provider/EmailProvider.java
+++ b/src/com/android/email/provider/EmailProvider.java
@@ -2820,6 +2820,15 @@ outer:
// Email doesn't support priority inbox, so always state priority arrows disabled.
values.put(UIProvider.AccountColumns.SettingsColumns.PRIORITY_ARROWS_ENABLED, "0");
}
+ if (projectionColumns.contains(
+ UIProvider.AccountColumns.SettingsColumns.SETUP_INTENT_URI)) {
+ // Use this if needed
+ long trashId = Mailbox.findMailboxOfType(context, accountId, Mailbox.TYPE_TRASH);
+ if (trashId == Mailbox.NO_MAILBOX) {
+ values.put(UIProvider.AccountColumns.SettingsColumns.SETUP_INTENT_URI,
+ getExternalUriString("setup", id));
+ }
+ }
final StringBuilder sb = genSelect(getAccountListMap(), uiProjection, values);
sb.append(" FROM " + Account.TABLE_NAME + " WHERE " + AccountColumns.ID + "=?");
diff --git a/src/com/android/email/provider/FolderPickerActivity.java b/src/com/android/email/provider/FolderPickerActivity.java
index f00966ebe..bb3b494ef 100644
--- a/src/com/android/email/provider/FolderPickerActivity.java
+++ b/src/com/android/email/provider/FolderPickerActivity.java
@@ -18,32 +18,147 @@
package com.android.email.provider;
import android.app.Activity;
+import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.ContentValues;
+import android.content.Context;
import android.content.Intent;
+import android.database.ContentObserver;
+import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import com.android.email.R;
+import com.android.emailcommon.provider.Account;
+import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.Mailbox;
+import com.android.emailcommon.provider.EmailContent.AccountColumns;
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
import com.android.mail.providers.Folder;
public class FolderPickerActivity extends Activity implements FolderPickerCallback {
+ private static final String TAG = "FolderPickerActivity";
private long mAccountId;
private int mMailboxType;
+ private AccountObserver mAccountObserver;
+ private String mAccountName;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
Intent i = getIntent();
- com.android.mail.providers.Account account =
- i.getParcelableExtra(EmailProvider.PICKER_UI_ACCOUNT);
- mAccountId = Long.parseLong(account.uri.getLastPathSegment());
- mMailboxType = i.getIntExtra(EmailProvider.PICKER_MAILBOX_TYPE, -1);
- int headerId = i.getIntExtra(EmailProvider.PICKER_HEADER_ID, 0);
- if (headerId == 0) {
- finish();
- return;
+ Uri uri = i.getData();
+ int headerId;
+ com.android.mail.providers.Account uiAccount = null;
+ // If we've gotten a Uri, then this is a call from the UI in response to setupIntentUri
+ // in an account (meaning the account requires setup)
+ if (uri != null) {
+ String id = uri.getQueryParameter("account");
+ if (id == null) {
+ Log.w(TAG, "No account # in Uri?");
+ finish();
+ return;
+ }
+ try {
+ mAccountId = Long.parseLong(id);
+ } catch (NumberFormatException e) {
+ Log.w(TAG, "Invalid account # in Uri?");
+ finish();
+ return;
+ }
+ mMailboxType = Mailbox.TYPE_TRASH;
+ Account account = Account.restoreAccountWithId(this, mAccountId);
+ if (account == null) {
+ Log.w(TAG, "No account?");
+ finish();
+ } else {
+ mAccountName = account.mDisplayName;
+ // Two possibilities here; either we have our folder list, or we don't
+ if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0) {
+ // If we've got them, just start up the picker dialog
+ startPickerForAccount();
+ } else {
+ // Otherwise, wait for the folders to show up
+ waitForFolders();
+ }
+ }
+ } else {
+ // In this case, we're coming from Settings
+ uiAccount = i.getParcelableExtra(EmailProvider.PICKER_UI_ACCOUNT);
+ mAccountName = uiAccount.name;
+ mAccountId = Long.parseLong(uiAccount.uri.getLastPathSegment());
+ mMailboxType = i.getIntExtra(EmailProvider.PICKER_MAILBOX_TYPE, -1);
+ headerId = i.getIntExtra(EmailProvider.PICKER_HEADER_ID, 0);
+ if (headerId == 0) {
+ finish();
+ return;
+ }
+ startPicker(uiAccount.folderListUri, headerId);
}
- new FolderSelectionDialog(this, account, this, headerId).show();
+ }
+
+ public void onDestroy() {
+ super.onDestroy();
+ // Clean up
+ if (mAccountObserver != null) {
+ getContentResolver().unregisterContentObserver(mAccountObserver);
+ mAccountObserver = null;
+ }
+ if (mWaitingForFoldersDialog != null) {
+ mWaitingForFoldersDialog.dismiss();
+ mWaitingForFoldersDialog = null;
+ }
+ }
+
+ private class AccountObserver extends ContentObserver {
+ private final Context mContext;
+
+ public AccountObserver(Context context, Handler handler) {
+ super(handler);
+ mContext = context;
+ }
+
+ public void onChange(boolean selfChange) {
+ Account account = Account.restoreAccountWithId(mContext, mAccountId);
+ // All we care about is whether the folder list is now loaded
+ if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0) {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ mAccountObserver = null;
+ // Bring down the ProgressDialog and show the picker
+ if (mWaitingForFoldersDialog != null) {
+ mWaitingForFoldersDialog.dismiss();
+ mWaitingForFoldersDialog = null;
+ }
+ startPickerForAccount();
+ }
+ }
+ }
+
+ private ProgressDialog mWaitingForFoldersDialog;
+
+ private void waitForFolders() {
+ /// Show "Waiting for folders..." dialog
+ mWaitingForFoldersDialog = new ProgressDialog(this);
+ mWaitingForFoldersDialog.setIndeterminate(true);
+ mWaitingForFoldersDialog.setMessage(getString(R.string.account_waiting_for_folders_msg));
+ mWaitingForFoldersDialog.show();
+
+ // Listen for account changes
+ mAccountObserver = new AccountObserver(this, new Handler());
+ Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId);
+ getContentResolver().registerContentObserver(uri, false, mAccountObserver);
+ }
+
+ private void startPickerForAccount() {
+ int headerId = R.string.trash_folder_selection_title;
+ Uri uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/uiallfolders/" + mAccountId);
+ startPicker(uri, headerId);
+ }
+
+ private void startPicker(Uri uri, int headerId) {
+ String header = getString(headerId, mAccountName);
+ FolderSelectionDialog dialog = new FolderSelectionDialog(this, uri, this, header);
+ dialog.show();
}
@Override
@@ -68,13 +183,14 @@ public class FolderPickerActivity extends Activity implements FolderPickerCallba
getContentResolver().update(
ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailbox.mId), values,
null, null);
+ values.clear();
+ // Touch the account so that UI won't bring up this picker again
+ Account account = Account.restoreAccountWithId(this, mAccountId);
+ values.put(AccountColumns.FLAGS, account.mFlags);
+ getContentResolver().update(
+ ContentUris.withAppendedId(Account.CONTENT_URI, account.mId), values,
+ null, null);
}
finish();
}
-
- @Override
- public void create() {
- // TODO: Not sure about this...
- finish();
- }
}
diff --git a/src/com/android/email/provider/FolderPickerCallback.java b/src/com/android/email/provider/FolderPickerCallback.java
index b84d13801..52f82c66b 100644
--- a/src/com/android/email/provider/FolderPickerCallback.java
+++ b/src/com/android/email/provider/FolderPickerCallback.java
@@ -21,5 +21,4 @@ import com.android.mail.providers.Folder;
public interface FolderPickerCallback {
public void select(Folder folder);
- public void create();
}
diff --git a/src/com/android/email/provider/FolderSelectionDialog.java b/src/com/android/email/provider/FolderSelectionDialog.java
index 31ae5ca5d..37be18699 100644
--- a/src/com/android/email/provider/FolderSelectionDialog.java
+++ b/src/com/android/email/provider/FolderSelectionDialog.java
@@ -20,15 +20,16 @@ package com.android.email.provider;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.database.Cursor;
+import android.net.Uri;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import com.android.mail.R;
-import com.android.mail.providers.Account;
import com.android.mail.providers.Folder;
import com.android.mail.providers.UIProvider;
import com.android.mail.ui.FolderSelectorAdapter;
@@ -46,18 +47,18 @@ public class FolderSelectionDialog implements OnClickListener, OnMultiChoiceClic
private final SeparatedFolderListAdapter mAdapter;
private final FolderPickerCallback mCallback;
- public FolderSelectionDialog(final Context context, Account account,
- FolderPickerCallback callback, int headerId) {
+ public FolderSelectionDialog(final Context context, Uri uri,
+ FolderPickerCallback callback, String header) {
mCallback = callback;
// Mapping of a folder's uri to its checked state
mCheckedState = new HashMap();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(headerId);
+ builder.setTitle(header);
builder.setPositiveButton(R.string.ok, this);
- builder.setNegativeButton(R.string.create_new_folder, this);
+ builder.setCancelable(false);
+ // TODO: Do this on a background thread
final Cursor foldersCursor = context.getContentResolver().query(
- account.fullFolderListUri != null ? account.fullFolderListUri
- : account.folderListUri, UIProvider.FOLDERS_PROJECTION, null, null, null);
+ uri, UIProvider.FOLDERS_PROJECTION, null, null, null);
try {
mAdapter = new SeparatedFolderListAdapter(context);
String[] headers = context.getResources()
@@ -135,9 +136,6 @@ public class FolderSelectionDialog implements OnClickListener, OnMultiChoiceClic
}
mCallback.select(folder);
break;
- case DialogInterface.BUTTON_NEGATIVE:
- mCallback.create();
- break;
default:
onClick(dialog, which, true);
break;