1c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank/* 2c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * Copyright (C) 2012 Google Inc. 3c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * Licensed to The Android Open Source Project. 4c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * 5c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * Licensed under the Apache License, Version 2.0 (the "License"); 6c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * you may not use this file except in compliance with the License. 7c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * You may obtain a copy of the License at 8c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * 9c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * http://www.apache.org/licenses/LICENSE-2.0 10c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * 11c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * Unless required by applicable law or agreed to in writing, software 12c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * distributed under the License is distributed on an "AS IS" BASIS, 13c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * See the License for the specific language governing permissions and 15c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank * limitations under the License. 16c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank */ 17c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 18c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankpackage com.android.email.provider; 19c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 20c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport android.app.Activity; 2126164054710375519ba7468987971a7a3340ba7eMarc Blankimport android.app.ProgressDialog; 22c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport android.content.ContentUris; 23c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport android.content.ContentValues; 2426164054710375519ba7468987971a7a3340ba7eMarc Blankimport android.content.Context; 25c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport android.content.Intent; 2626164054710375519ba7468987971a7a3340ba7eMarc Blankimport android.database.ContentObserver; 2726164054710375519ba7468987971a7a3340ba7eMarc Blankimport android.net.Uri; 28c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport android.os.Bundle; 2926164054710375519ba7468987971a7a3340ba7eMarc Blankimport android.os.Handler; 30c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 3126164054710375519ba7468987971a7a3340ba7eMarc Blankimport com.android.email.R; 3226164054710375519ba7468987971a7a3340ba7eMarc Blankimport com.android.emailcommon.provider.Account; 3326164054710375519ba7468987971a7a3340ba7eMarc Blankimport com.android.emailcommon.provider.EmailContent; 34c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport com.android.emailcommon.provider.Mailbox; 3526164054710375519ba7468987971a7a3340ba7eMarc Blankimport com.android.emailcommon.provider.EmailContent.AccountColumns; 36c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport com.android.emailcommon.provider.EmailContent.MailboxColumns; 37c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankimport com.android.mail.providers.Folder; 38560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedyimport com.android.mail.utils.LogUtils; 39c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 40c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blankpublic class FolderPickerActivity extends Activity implements FolderPickerCallback { 4126164054710375519ba7468987971a7a3340ba7eMarc Blank private static final String TAG = "FolderPickerActivity"; 42266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank public static final String MAILBOX_TYPE_EXTRA = "mailbox_type"; 43266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank 44c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank private long mAccountId; 45c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank private int mMailboxType; 4626164054710375519ba7468987971a7a3340ba7eMarc Blank private AccountObserver mAccountObserver; 4726164054710375519ba7468987971a7a3340ba7eMarc Blank private String mAccountName; 48266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank private boolean mInSetup = true; 49c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 50560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy @Override 51c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public void onCreate(Bundle bundle) { 52c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank super.onCreate(bundle); 53c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank Intent i = getIntent(); 5426164054710375519ba7468987971a7a3340ba7eMarc Blank Uri uri = i.getData(); 5526164054710375519ba7468987971a7a3340ba7eMarc Blank int headerId; 5696192ef342f182deadcfe8a245306f7f155e4a79Tony Mantler final com.android.mail.providers.Account uiAccount; 5726164054710375519ba7468987971a7a3340ba7eMarc Blank // If we've gotten a Uri, then this is a call from the UI in response to setupIntentUri 5826164054710375519ba7468987971a7a3340ba7eMarc Blank // in an account (meaning the account requires setup) 5926164054710375519ba7468987971a7a3340ba7eMarc Blank if (uri != null) { 6026164054710375519ba7468987971a7a3340ba7eMarc Blank String id = uri.getQueryParameter("account"); 6126164054710375519ba7468987971a7a3340ba7eMarc Blank if (id == null) { 62560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(TAG, "No account # in Uri?"); 6326164054710375519ba7468987971a7a3340ba7eMarc Blank finish(); 6426164054710375519ba7468987971a7a3340ba7eMarc Blank return; 6526164054710375519ba7468987971a7a3340ba7eMarc Blank } 6626164054710375519ba7468987971a7a3340ba7eMarc Blank try { 6726164054710375519ba7468987971a7a3340ba7eMarc Blank mAccountId = Long.parseLong(id); 6826164054710375519ba7468987971a7a3340ba7eMarc Blank } catch (NumberFormatException e) { 69560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(TAG, "Invalid account # in Uri?"); 7026164054710375519ba7468987971a7a3340ba7eMarc Blank finish(); 7126164054710375519ba7468987971a7a3340ba7eMarc Blank return; 7226164054710375519ba7468987971a7a3340ba7eMarc Blank } 73266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank // We act a bit differently if we're coming to set up the trash after account creation 74266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank mInSetup = !i.hasExtra(MAILBOX_TYPE_EXTRA); 75266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank mMailboxType = i.getIntExtra(MAILBOX_TYPE_EXTRA, Mailbox.TYPE_TRASH); 76fdb1635868e9591c3bcaf107360a7eae2e09fe18Marc Blank long trashMailboxId = Mailbox.findMailboxOfType(this, mAccountId, Mailbox.TYPE_TRASH); 77266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank // If we already have a trash mailbox, we're done (if in setup; a race?) 78266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank if (trashMailboxId != Mailbox.NO_MAILBOX && mInSetup) { 79560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(TAG, "Trash folder already exists"); 80fdb1635868e9591c3bcaf107360a7eae2e09fe18Marc Blank finish(); 81fdb1635868e9591c3bcaf107360a7eae2e09fe18Marc Blank return; 82fdb1635868e9591c3bcaf107360a7eae2e09fe18Marc Blank } 8326164054710375519ba7468987971a7a3340ba7eMarc Blank Account account = Account.restoreAccountWithId(this, mAccountId); 8426164054710375519ba7468987971a7a3340ba7eMarc Blank if (account == null) { 85560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy LogUtils.w(TAG, "No account?"); 8626164054710375519ba7468987971a7a3340ba7eMarc Blank finish(); 8726164054710375519ba7468987971a7a3340ba7eMarc Blank } else { 8826164054710375519ba7468987971a7a3340ba7eMarc Blank mAccountName = account.mDisplayName; 8926164054710375519ba7468987971a7a3340ba7eMarc Blank // Two possibilities here; either we have our folder list, or we don't 9026164054710375519ba7468987971a7a3340ba7eMarc Blank if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0) { 9126164054710375519ba7468987971a7a3340ba7eMarc Blank // If we've got them, just start up the picker dialog 9226164054710375519ba7468987971a7a3340ba7eMarc Blank startPickerForAccount(); 9326164054710375519ba7468987971a7a3340ba7eMarc Blank } else { 9426164054710375519ba7468987971a7a3340ba7eMarc Blank // Otherwise, wait for the folders to show up 9526164054710375519ba7468987971a7a3340ba7eMarc Blank waitForFolders(); 9626164054710375519ba7468987971a7a3340ba7eMarc Blank } 9726164054710375519ba7468987971a7a3340ba7eMarc Blank } 9826164054710375519ba7468987971a7a3340ba7eMarc Blank } else { 9926164054710375519ba7468987971a7a3340ba7eMarc Blank // In this case, we're coming from Settings 10026164054710375519ba7468987971a7a3340ba7eMarc Blank uiAccount = i.getParcelableExtra(EmailProvider.PICKER_UI_ACCOUNT); 101531b3630592c1d830c1c64ca3c2579020d771c2fTony Mantler mAccountName = uiAccount.getDisplayName(); 10226164054710375519ba7468987971a7a3340ba7eMarc Blank mAccountId = Long.parseLong(uiAccount.uri.getLastPathSegment()); 10326164054710375519ba7468987971a7a3340ba7eMarc Blank mMailboxType = i.getIntExtra(EmailProvider.PICKER_MAILBOX_TYPE, -1); 10426164054710375519ba7468987971a7a3340ba7eMarc Blank headerId = i.getIntExtra(EmailProvider.PICKER_HEADER_ID, 0); 10526164054710375519ba7468987971a7a3340ba7eMarc Blank if (headerId == 0) { 10626164054710375519ba7468987971a7a3340ba7eMarc Blank finish(); 10726164054710375519ba7468987971a7a3340ba7eMarc Blank return; 10826164054710375519ba7468987971a7a3340ba7eMarc Blank } 10926164054710375519ba7468987971a7a3340ba7eMarc Blank startPicker(uiAccount.folderListUri, headerId); 110a8b683cf3f2efe726220c0235368cf6ea899e3baMarc Blank } 11126164054710375519ba7468987971a7a3340ba7eMarc Blank } 11226164054710375519ba7468987971a7a3340ba7eMarc Blank 113560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy @Override 11426164054710375519ba7468987971a7a3340ba7eMarc Blank public void onDestroy() { 11526164054710375519ba7468987971a7a3340ba7eMarc Blank super.onDestroy(); 11626164054710375519ba7468987971a7a3340ba7eMarc Blank // Clean up 11726164054710375519ba7468987971a7a3340ba7eMarc Blank if (mAccountObserver != null) { 11826164054710375519ba7468987971a7a3340ba7eMarc Blank getContentResolver().unregisterContentObserver(mAccountObserver); 11926164054710375519ba7468987971a7a3340ba7eMarc Blank mAccountObserver = null; 12026164054710375519ba7468987971a7a3340ba7eMarc Blank } 12126164054710375519ba7468987971a7a3340ba7eMarc Blank if (mWaitingForFoldersDialog != null) { 12226164054710375519ba7468987971a7a3340ba7eMarc Blank mWaitingForFoldersDialog.dismiss(); 12326164054710375519ba7468987971a7a3340ba7eMarc Blank mWaitingForFoldersDialog = null; 12426164054710375519ba7468987971a7a3340ba7eMarc Blank } 12526164054710375519ba7468987971a7a3340ba7eMarc Blank } 12626164054710375519ba7468987971a7a3340ba7eMarc Blank 12726164054710375519ba7468987971a7a3340ba7eMarc Blank private class AccountObserver extends ContentObserver { 12826164054710375519ba7468987971a7a3340ba7eMarc Blank private final Context mContext; 12926164054710375519ba7468987971a7a3340ba7eMarc Blank 13026164054710375519ba7468987971a7a3340ba7eMarc Blank public AccountObserver(Context context, Handler handler) { 13126164054710375519ba7468987971a7a3340ba7eMarc Blank super(handler); 13226164054710375519ba7468987971a7a3340ba7eMarc Blank mContext = context; 13326164054710375519ba7468987971a7a3340ba7eMarc Blank } 13426164054710375519ba7468987971a7a3340ba7eMarc Blank 135560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy @Override 13626164054710375519ba7468987971a7a3340ba7eMarc Blank public void onChange(boolean selfChange) { 13726164054710375519ba7468987971a7a3340ba7eMarc Blank Account account = Account.restoreAccountWithId(mContext, mAccountId); 13826164054710375519ba7468987971a7a3340ba7eMarc Blank // All we care about is whether the folder list is now loaded 139fdb1635868e9591c3bcaf107360a7eae2e09fe18Marc Blank if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0 && 140fdb1635868e9591c3bcaf107360a7eae2e09fe18Marc Blank (mAccountObserver != null)) { 141fdb1635868e9591c3bcaf107360a7eae2e09fe18Marc Blank mContext.getContentResolver().unregisterContentObserver(mAccountObserver); 14226164054710375519ba7468987971a7a3340ba7eMarc Blank mAccountObserver = null; 14326164054710375519ba7468987971a7a3340ba7eMarc Blank // Bring down the ProgressDialog and show the picker 14426164054710375519ba7468987971a7a3340ba7eMarc Blank if (mWaitingForFoldersDialog != null) { 14526164054710375519ba7468987971a7a3340ba7eMarc Blank mWaitingForFoldersDialog.dismiss(); 14626164054710375519ba7468987971a7a3340ba7eMarc Blank mWaitingForFoldersDialog = null; 14726164054710375519ba7468987971a7a3340ba7eMarc Blank } 14826164054710375519ba7468987971a7a3340ba7eMarc Blank startPickerForAccount(); 14926164054710375519ba7468987971a7a3340ba7eMarc Blank } 15026164054710375519ba7468987971a7a3340ba7eMarc Blank } 15126164054710375519ba7468987971a7a3340ba7eMarc Blank } 15226164054710375519ba7468987971a7a3340ba7eMarc Blank 15326164054710375519ba7468987971a7a3340ba7eMarc Blank private ProgressDialog mWaitingForFoldersDialog; 15426164054710375519ba7468987971a7a3340ba7eMarc Blank 15526164054710375519ba7468987971a7a3340ba7eMarc Blank private void waitForFolders() { 15626164054710375519ba7468987971a7a3340ba7eMarc Blank /// Show "Waiting for folders..." dialog 15726164054710375519ba7468987971a7a3340ba7eMarc Blank mWaitingForFoldersDialog = new ProgressDialog(this); 15826164054710375519ba7468987971a7a3340ba7eMarc Blank mWaitingForFoldersDialog.setIndeterminate(true); 15926164054710375519ba7468987971a7a3340ba7eMarc Blank mWaitingForFoldersDialog.setMessage(getString(R.string.account_waiting_for_folders_msg)); 16026164054710375519ba7468987971a7a3340ba7eMarc Blank mWaitingForFoldersDialog.show(); 16126164054710375519ba7468987971a7a3340ba7eMarc Blank 16226164054710375519ba7468987971a7a3340ba7eMarc Blank // Listen for account changes 16326164054710375519ba7468987971a7a3340ba7eMarc Blank mAccountObserver = new AccountObserver(this, new Handler()); 16426164054710375519ba7468987971a7a3340ba7eMarc Blank Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId); 16526164054710375519ba7468987971a7a3340ba7eMarc Blank getContentResolver().registerContentObserver(uri, false, mAccountObserver); 16626164054710375519ba7468987971a7a3340ba7eMarc Blank } 16726164054710375519ba7468987971a7a3340ba7eMarc Blank 16826164054710375519ba7468987971a7a3340ba7eMarc Blank private void startPickerForAccount() { 16926164054710375519ba7468987971a7a3340ba7eMarc Blank int headerId = R.string.trash_folder_selection_title; 17096192ef342f182deadcfe8a245306f7f155e4a79Tony Mantler Uri uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/uifullfolders/" + mAccountId); 17126164054710375519ba7468987971a7a3340ba7eMarc Blank startPicker(uri, headerId); 17226164054710375519ba7468987971a7a3340ba7eMarc Blank } 17326164054710375519ba7468987971a7a3340ba7eMarc Blank 17426164054710375519ba7468987971a7a3340ba7eMarc Blank private void startPicker(Uri uri, int headerId) { 17526164054710375519ba7468987971a7a3340ba7eMarc Blank String header = getString(headerId, mAccountName); 176266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank FolderPickerDialog dialog = 177266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank new FolderPickerDialog(this, uri, this, header, !mInSetup); 17826164054710375519ba7468987971a7a3340ba7eMarc Blank dialog.show(); 179c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank } 180c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 181c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank @Override 182c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank public void select(Folder folder) { 183281c6365fb95037ca284dd8c910538639e8b3dcbScott Kennedy String folderId = folder.folderUri.fullUri.getLastPathSegment(); 184c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank Long id = Long.parseLong(folderId); 185c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank ContentValues values = new ContentValues(); 186c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 187c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank // If we already have a mailbox of this type, change it back to generic mail type 188c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank Mailbox ofType = Mailbox.restoreMailboxOfType(this, mAccountId, mMailboxType); 189c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank if (ofType != null) { 190c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank values.put(MailboxColumns.TYPE, Mailbox.TYPE_MAIL); 191c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank getContentResolver().update( 192c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank ContentUris.withAppendedId(Mailbox.CONTENT_URI, ofType.mId), values, 193c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank null, null); 194c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank } 195c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank 196c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank // Change this mailbox to be of the desired type 197c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank Mailbox mailbox = Mailbox.restoreMailboxWithId(this, id); 198c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank if (mailbox != null) { 199c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank values.put(MailboxColumns.TYPE, mMailboxType); 200c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank getContentResolver().update( 201c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailbox.mId), values, 202c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank null, null); 20326164054710375519ba7468987971a7a3340ba7eMarc Blank values.clear(); 20426164054710375519ba7468987971a7a3340ba7eMarc Blank // Touch the account so that UI won't bring up this picker again 20526164054710375519ba7468987971a7a3340ba7eMarc Blank Account account = Account.restoreAccountWithId(this, mAccountId); 20626164054710375519ba7468987971a7a3340ba7eMarc Blank values.put(AccountColumns.FLAGS, account.mFlags); 20726164054710375519ba7468987971a7a3340ba7eMarc Blank getContentResolver().update( 20826164054710375519ba7468987971a7a3340ba7eMarc Blank ContentUris.withAppendedId(Account.CONTENT_URI, account.mId), values, 20926164054710375519ba7468987971a7a3340ba7eMarc Blank null, null); 210c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank } 211c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank finish(); 212c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank } 213266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank 214560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy @Override 215266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank public void cancel() { 216266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank finish(); 217266064bcc7c6ed7318a284d59bb83d53edbf1921Marc Blank } 218c6089bc01f2ae49fb11904a4b4f222811358254fMarc Blank} 219