FolderPickerActivity.java revision 266064bcc7c6ed7318a284d59bb83d53edbf1921
1/*
2 * Copyright (C) 2012 Google Inc.
3 * Licensed to The Android Open Source Project.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.email.provider;
19
20import android.app.Activity;
21import android.app.ProgressDialog;
22import android.content.ContentUris;
23import android.content.ContentValues;
24import android.content.Context;
25import android.content.Intent;
26import android.database.ContentObserver;
27import android.net.Uri;
28import android.os.Bundle;
29import android.os.Handler;
30import android.util.Log;
31
32import com.android.email.R;
33import com.android.emailcommon.provider.Account;
34import com.android.emailcommon.provider.EmailContent;
35import com.android.emailcommon.provider.Mailbox;
36import com.android.emailcommon.provider.EmailContent.AccountColumns;
37import com.android.emailcommon.provider.EmailContent.MailboxColumns;
38import com.android.mail.providers.Folder;
39
40public class FolderPickerActivity extends Activity implements FolderPickerCallback {
41    private static final String TAG = "FolderPickerActivity";
42    public static final String MAILBOX_TYPE_EXTRA = "mailbox_type";
43
44    private long mAccountId;
45    private int mMailboxType;
46    private AccountObserver mAccountObserver;
47    private String mAccountName;
48    private boolean mInSetup = true;
49
50    public void onCreate(Bundle bundle) {
51        super.onCreate(bundle);
52        Intent i = getIntent();
53        Uri uri = i.getData();
54        int headerId;
55        com.android.mail.providers.Account uiAccount = null;
56        // If we've gotten a Uri, then this is a call from the UI in response to setupIntentUri
57        // in an account (meaning the account requires setup)
58        if (uri != null) {
59            String id = uri.getQueryParameter("account");
60            if (id == null) {
61                Log.w(TAG, "No account # in Uri?");
62                finish();
63                return;
64            }
65            try {
66                mAccountId = Long.parseLong(id);
67            } catch (NumberFormatException e) {
68                Log.w(TAG, "Invalid account # in Uri?");
69                finish();
70                return;
71            }
72            // We act a bit differently if we're coming to set up the trash after account creation
73            mInSetup = !i.hasExtra(MAILBOX_TYPE_EXTRA);
74            mMailboxType = i.getIntExtra(MAILBOX_TYPE_EXTRA, Mailbox.TYPE_TRASH);
75            long trashMailboxId = Mailbox.findMailboxOfType(this, mAccountId, Mailbox.TYPE_TRASH);
76            // If we already have a trash mailbox, we're done (if in setup; a race?)
77            if (trashMailboxId != Mailbox.NO_MAILBOX && mInSetup) {
78                Log.w(TAG, "Trash folder already exists");
79                finish();
80                return;
81            }
82            Account account = Account.restoreAccountWithId(this, mAccountId);
83            if (account == null) {
84                Log.w(TAG, "No account?");
85                finish();
86            } else {
87                mAccountName = account.mDisplayName;
88                // Two possibilities here; either we have our folder list, or we don't
89                if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0) {
90                    // If we've got them, just start up the picker dialog
91                    startPickerForAccount();
92                } else {
93                    // Otherwise, wait for the folders to show up
94                    waitForFolders();
95                }
96            }
97        } else {
98            // In this case, we're coming from Settings
99            uiAccount = i.getParcelableExtra(EmailProvider.PICKER_UI_ACCOUNT);
100            mAccountName = uiAccount.name;
101            mAccountId = Long.parseLong(uiAccount.uri.getLastPathSegment());
102            mMailboxType = i.getIntExtra(EmailProvider.PICKER_MAILBOX_TYPE, -1);
103            headerId = i.getIntExtra(EmailProvider.PICKER_HEADER_ID, 0);
104            if (headerId == 0) {
105                finish();
106                return;
107            }
108            startPicker(uiAccount.folderListUri, headerId);
109        }
110    }
111
112    public void onDestroy() {
113        super.onDestroy();
114        // Clean up
115        if (mAccountObserver != null) {
116            getContentResolver().unregisterContentObserver(mAccountObserver);
117            mAccountObserver = null;
118        }
119        if (mWaitingForFoldersDialog != null) {
120            mWaitingForFoldersDialog.dismiss();
121            mWaitingForFoldersDialog = null;
122        }
123    }
124
125    private class AccountObserver extends ContentObserver {
126        private final Context mContext;
127
128        public AccountObserver(Context context, Handler handler) {
129            super(handler);
130            mContext = context;
131        }
132
133        public void onChange(boolean selfChange) {
134            Account account = Account.restoreAccountWithId(mContext, mAccountId);
135            // All we care about is whether the folder list is now loaded
136            if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0 &&
137                    (mAccountObserver != null)) {
138                mContext.getContentResolver().unregisterContentObserver(mAccountObserver);
139                mAccountObserver = null;
140                // Bring down the ProgressDialog and show the picker
141                if (mWaitingForFoldersDialog != null) {
142                    mWaitingForFoldersDialog.dismiss();
143                    mWaitingForFoldersDialog = null;
144                }
145                startPickerForAccount();
146            }
147        }
148    }
149
150    private ProgressDialog mWaitingForFoldersDialog;
151
152    private void waitForFolders() {
153        /// Show "Waiting for folders..." dialog
154        mWaitingForFoldersDialog = new ProgressDialog(this);
155        mWaitingForFoldersDialog.setIndeterminate(true);
156        mWaitingForFoldersDialog.setMessage(getString(R.string.account_waiting_for_folders_msg));
157        mWaitingForFoldersDialog.show();
158
159        // Listen for account changes
160        mAccountObserver = new AccountObserver(this, new Handler());
161        Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId);
162        getContentResolver().registerContentObserver(uri, false, mAccountObserver);
163    }
164
165    private void startPickerForAccount() {
166        int headerId = R.string.trash_folder_selection_title;
167        Uri uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/uiallfolders/" + mAccountId);
168        startPicker(uri, headerId);
169    }
170
171    private void startPicker(Uri uri, int headerId) {
172        String header = getString(headerId, mAccountName);
173        FolderPickerDialog dialog =
174                new FolderPickerDialog(this, uri, this, header, !mInSetup);
175        dialog.show();
176    }
177
178    @Override
179    public void select(Folder folder) {
180        String folderId = folder.uri.getLastPathSegment();
181        Long id = Long.parseLong(folderId);
182        ContentValues values = new ContentValues();
183
184        // If we already have a mailbox of this type, change it back to generic mail type
185        Mailbox ofType = Mailbox.restoreMailboxOfType(this, mAccountId, mMailboxType);
186        if (ofType != null) {
187            values.put(MailboxColumns.TYPE, Mailbox.TYPE_MAIL);
188            getContentResolver().update(
189                    ContentUris.withAppendedId(Mailbox.CONTENT_URI, ofType.mId), values,
190                    null, null);
191        }
192
193        // Change this mailbox to be of the desired type
194        Mailbox mailbox = Mailbox.restoreMailboxWithId(this, id);
195        if (mailbox != null) {
196            values.put(MailboxColumns.TYPE, mMailboxType);
197            getContentResolver().update(
198                    ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailbox.mId), values,
199                    null, null);
200            values.clear();
201            // Touch the account so that UI won't bring up this picker again
202            Account account = Account.restoreAccountWithId(this, mAccountId);
203            values.put(AccountColumns.FLAGS, account.mFlags);
204            getContentResolver().update(
205                    ContentUris.withAppendedId(Account.CONTENT_URI, account.mId), values,
206                    null, null);
207        }
208        finish();
209    }
210
211    public void cancel() {
212        finish();
213    }
214}
215