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;