FolderPickerActivity.java revision fdb1635868e9591c3bcaf107360a7eae2e09fe18
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    private long mAccountId;
43    private int mMailboxType;
44    private AccountObserver mAccountObserver;
45    private String mAccountName;
46
47    public void onCreate(Bundle bundle) {
48        super.onCreate(bundle);
49        Intent i = getIntent();
50        Uri uri = i.getData();
51        int headerId;
52        com.android.mail.providers.Account uiAccount = null;
53        // If we've gotten a Uri, then this is a call from the UI in response to setupIntentUri
54        // in an account (meaning the account requires setup)
55        if (uri != null) {
56            String id = uri.getQueryParameter("account");
57            if (id == null) {
58                Log.w(TAG, "No account # in Uri?");
59                finish();
60                return;
61            }
62            try {
63                mAccountId = Long.parseLong(id);
64            } catch (NumberFormatException e) {
65                Log.w(TAG, "Invalid account # in Uri?");
66                finish();
67                return;
68            }
69            mMailboxType = Mailbox.TYPE_TRASH;
70            long trashMailboxId = Mailbox.findMailboxOfType(this, mAccountId, Mailbox.TYPE_TRASH);
71            // If we already have a trash mailbox, we're done (race?)
72            if (trashMailboxId != Mailbox.NO_MAILBOX) {
73                Log.w(TAG, "Trash folder already exists");
74                finish();
75                return;
76            }
77            Account account = Account.restoreAccountWithId(this, mAccountId);
78            if (account == null) {
79                Log.w(TAG, "No account?");
80                finish();
81            } else {
82                mAccountName = account.mDisplayName;
83                // Two possibilities here; either we have our folder list, or we don't
84                if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0) {
85                    // If we've got them, just start up the picker dialog
86                    startPickerForAccount();
87                } else {
88                    // Otherwise, wait for the folders to show up
89                    waitForFolders();
90                }
91            }
92        } else {
93            // In this case, we're coming from Settings
94            uiAccount = i.getParcelableExtra(EmailProvider.PICKER_UI_ACCOUNT);
95            mAccountName = uiAccount.name;
96            mAccountId = Long.parseLong(uiAccount.uri.getLastPathSegment());
97            mMailboxType = i.getIntExtra(EmailProvider.PICKER_MAILBOX_TYPE, -1);
98            headerId = i.getIntExtra(EmailProvider.PICKER_HEADER_ID, 0);
99            if (headerId == 0) {
100                finish();
101                return;
102            }
103            startPicker(uiAccount.folderListUri, headerId);
104        }
105    }
106
107    public void onDestroy() {
108        super.onDestroy();
109        // Clean up
110        if (mAccountObserver != null) {
111            getContentResolver().unregisterContentObserver(mAccountObserver);
112            mAccountObserver = null;
113        }
114        if (mWaitingForFoldersDialog != null) {
115            mWaitingForFoldersDialog.dismiss();
116            mWaitingForFoldersDialog = null;
117        }
118    }
119
120    private class AccountObserver extends ContentObserver {
121        private final Context mContext;
122
123        public AccountObserver(Context context, Handler handler) {
124            super(handler);
125            mContext = context;
126        }
127
128        public void onChange(boolean selfChange) {
129            Account account = Account.restoreAccountWithId(mContext, mAccountId);
130            // All we care about is whether the folder list is now loaded
131            if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0 &&
132                    (mAccountObserver != null)) {
133                mContext.getContentResolver().unregisterContentObserver(mAccountObserver);
134                mAccountObserver = null;
135                // Bring down the ProgressDialog and show the picker
136                if (mWaitingForFoldersDialog != null) {
137                    mWaitingForFoldersDialog.dismiss();
138                    mWaitingForFoldersDialog = null;
139                }
140                startPickerForAccount();
141            }
142        }
143    }
144
145    private ProgressDialog mWaitingForFoldersDialog;
146
147    private void waitForFolders() {
148        /// Show "Waiting for folders..." dialog
149        mWaitingForFoldersDialog = new ProgressDialog(this);
150        mWaitingForFoldersDialog.setIndeterminate(true);
151        mWaitingForFoldersDialog.setMessage(getString(R.string.account_waiting_for_folders_msg));
152        mWaitingForFoldersDialog.show();
153
154        // Listen for account changes
155        mAccountObserver = new AccountObserver(this, new Handler());
156        Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId);
157        getContentResolver().registerContentObserver(uri, false, mAccountObserver);
158    }
159
160    private void startPickerForAccount() {
161        int headerId = R.string.trash_folder_selection_title;
162        Uri uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/uiallfolders/" + mAccountId);
163        startPicker(uri, headerId);
164    }
165
166    private void startPicker(Uri uri, int headerId) {
167        String header = getString(headerId, mAccountName);
168        FolderSelectionDialog dialog = new FolderSelectionDialog(this, uri, this, header);
169        dialog.show();
170    }
171
172    @Override
173    public void select(Folder folder) {
174        String folderId = folder.uri.getLastPathSegment();
175        Long id = Long.parseLong(folderId);
176        ContentValues values = new ContentValues();
177
178        // If we already have a mailbox of this type, change it back to generic mail type
179        Mailbox ofType = Mailbox.restoreMailboxOfType(this, mAccountId, mMailboxType);
180        if (ofType != null) {
181            values.put(MailboxColumns.TYPE, Mailbox.TYPE_MAIL);
182            getContentResolver().update(
183                    ContentUris.withAppendedId(Mailbox.CONTENT_URI, ofType.mId), values,
184                    null, null);
185        }
186
187        // Change this mailbox to be of the desired type
188        Mailbox mailbox = Mailbox.restoreMailboxWithId(this, id);
189        if (mailbox != null) {
190            values.put(MailboxColumns.TYPE, mMailboxType);
191            getContentResolver().update(
192                    ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailbox.mId), values,
193                    null, null);
194            values.clear();
195            // Touch the account so that UI won't bring up this picker again
196            Account account = Account.restoreAccountWithId(this, mAccountId);
197            values.put(AccountColumns.FLAGS, account.mFlags);
198            getContentResolver().update(
199                    ContentUris.withAppendedId(Account.CONTENT_URI, account.mId), values,
200                    null, null);
201        }
202        finish();
203    }
204}
205