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