/* * Copyright (C) 2012 Google Inc. * Licensed to The Android Open Source Project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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 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; import com.android.mail.utils.LogUtils; public class FolderPickerActivity extends Activity implements FolderPickerCallback { private static final String TAG = "FolderPickerActivity"; public static final String MAILBOX_TYPE_EXTRA = "mailbox_type"; private long mAccountId; private int mMailboxType; private AccountObserver mAccountObserver; private String mAccountName; private boolean mInSetup = true; @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); Intent i = getIntent(); Uri uri = i.getData(); int headerId; final com.android.mail.providers.Account uiAccount; // 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) { LogUtils.w(TAG, "No account # in Uri?"); finish(); return; } try { mAccountId = Long.parseLong(id); } catch (NumberFormatException e) { LogUtils.w(TAG, "Invalid account # in Uri?"); finish(); return; } // We act a bit differently if we're coming to set up the trash after account creation mInSetup = !i.hasExtra(MAILBOX_TYPE_EXTRA); mMailboxType = i.getIntExtra(MAILBOX_TYPE_EXTRA, Mailbox.TYPE_TRASH); long trashMailboxId = Mailbox.findMailboxOfType(this, mAccountId, Mailbox.TYPE_TRASH); // If we already have a trash mailbox, we're done (if in setup; a race?) if (trashMailboxId != Mailbox.NO_MAILBOX && mInSetup) { LogUtils.w(TAG, "Trash folder already exists"); finish(); return; } Account account = Account.restoreAccountWithId(this, mAccountId); if (account == null) { LogUtils.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.getDisplayName(); 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); } } @Override 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; } @Override 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 && (mAccountObserver != null)) { mContext.getContentResolver().unregisterContentObserver(mAccountObserver); 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 + "/uifullfolders/" + mAccountId); startPicker(uri, headerId); } private void startPicker(Uri uri, int headerId) { String header = getString(headerId, mAccountName); FolderPickerDialog dialog = new FolderPickerDialog(this, uri, this, header, !mInSetup); dialog.show(); } @Override public void select(Folder folder) { String folderId = folder.folderUri.fullUri.getLastPathSegment(); Long id = Long.parseLong(folderId); ContentValues values = new ContentValues(); // If we already have a mailbox of this type, change it back to generic mail type Mailbox ofType = Mailbox.restoreMailboxOfType(this, mAccountId, mMailboxType); if (ofType != null) { values.put(MailboxColumns.TYPE, Mailbox.TYPE_MAIL); getContentResolver().update( ContentUris.withAppendedId(Mailbox.CONTENT_URI, ofType.mId), values, null, null); } // Change this mailbox to be of the desired type Mailbox mailbox = Mailbox.restoreMailboxWithId(this, id); if (mailbox != null) { values.put(MailboxColumns.TYPE, mMailboxType); 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 cancel() { finish(); } }