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