Welcome.java revision 347ae23b6932fe994b03909bf90854888c438517
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.email.activity; 18 19import com.android.email.Email; 20import com.android.email.ExchangeUtils; 21import com.android.email.R; 22import com.android.email.activity.setup.AccountSetupBasics; 23import com.android.email.provider.AccountBackupRestore; 24import com.android.email.service.MailService; 25import com.android.emailcommon.provider.EmailContent; 26import com.android.emailcommon.provider.EmailContent.Account; 27import com.android.emailcommon.utility.EmailAsyncTask; 28import com.android.emailcommon.utility.Utility; 29import com.google.common.annotations.VisibleForTesting; 30 31import android.app.Activity; 32import android.content.Context; 33import android.content.Intent; 34import android.net.Uri; 35import android.os.Bundle; 36import android.text.TextUtils; 37 38/** 39 * The Welcome activity initializes the application and decides what Activity 40 * the user should start with. 41 * 42 * This class knows which activity should be launched under the current configuration (screen size) 43 * and the number of accounts configured. So if you want to open an account or a mailbox, 44 * you should always do so via its static methods, such as {@link #actionOpenAccountInbox}. 45 */ 46public class Welcome extends Activity { 47 /* 48 * Commands for testing... 49 * Open 1 pane 50 adb shell am start -a android.intent.action.MAIN \ 51 -d '"content://ui.email.android.com/view/mailbox"' \ 52 -e DEBUG_PANE_MODE 1 53 54 * Open 2 pane 55 adb shell am start -a android.intent.action.MAIN \ 56 -d '"content://ui.email.android.com/view/mailbox"' \ 57 -e DEBUG_PANE_MODE 2 58 59 * Open an account (ID=1) in 2 pane 60 adb shell am start -a android.intent.action.MAIN \ 61 -d '"content://ui.email.android.com/view/mailbox?ACCOUNT_ID=1"' \ 62 -e DEBUG_PANE_MODE 2 63 64 * Open a message (account id=1, mailbox id=2, message id=3) 65 adb shell am start -a android.intent.action.MAIN \ 66 -d '"content://ui.email.android.com/view/mailbox?ACCOUNT_ID=1&MAILBOX_ID=2&MESSAGE_ID=3"' \ 67 -e DEBUG_PANE_MODE 2 68 69 * Open the combined starred on the combined view 70 adb shell am start -a android.intent.action.MAIN \ 71 -d '"content://ui.email.android.com/view/mailbox?ACCOUNT_ID=1152921504606846976&MAILBOX_ID=-4"' \ 72 -e DEBUG_PANE_MODE 2 73 */ 74 75 /** 76 * Extra for debugging. Set 1 to force one-pane. Set 2 to force two-pane. 77 */ 78 private static final String EXTRA_DEBUG_PANE_MODE = "DEBUG_PANE_MODE"; 79 80 private static final String VIEW_MAILBOX_INTENT_URL_PATH = "/view/mailbox"; 81 82 private final EmailAsyncTask.Tracker mTaskTracker = new EmailAsyncTask.Tracker(); 83 84 /** 85 * Launch this activity. Note: It's assumed that this activity is only called as a means to 86 * 'reset' the UI state; Because of this, it is always launched with FLAG_ACTIVITY_CLEAR_TOP, 87 * which will drop any other activities on the stack (e.g. AccountFolderList or MessageList). 88 */ 89 public static void actionStart(Activity fromActivity) { 90 Intent i = IntentUtilities.createRestartAppIntent(fromActivity, Welcome.class); 91 fromActivity.startActivity(i); 92 } 93 94 /** 95 * Create an Intent to open email activity. If <code>accountId</code> is not -1, the 96 * specified account will be automatically be opened when the activity starts. 97 */ 98 public static Intent createOpenAccountInboxIntent(Context context, long accountId) { 99 final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder( 100 VIEW_MAILBOX_INTENT_URL_PATH); 101 IntentUtilities.setAccountId(b, accountId); 102 return IntentUtilities.createRestartAppIntent(b.build()); 103 } 104 105 /** 106 * Create an Intent to open a message. 107 */ 108 public static Intent createOpenMessageIntent(Context context, long accountId, 109 long mailboxId, long messageId) { 110 final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder( 111 VIEW_MAILBOX_INTENT_URL_PATH); 112 IntentUtilities.setAccountId(b, accountId); 113 IntentUtilities.setMailboxId(b, mailboxId); 114 IntentUtilities.setMessageId(b, messageId); 115 return IntentUtilities.createRestartAppIntent(b.build()); 116 } 117 118 /** 119 * Open account's inbox. 120 */ 121 public static void actionOpenAccountInbox(Activity fromActivity, long accountId) { 122 fromActivity.startActivity(createOpenAccountInboxIntent(fromActivity, accountId)); 123 } 124 125 /** 126 * Create an {@link Intent} for account shortcuts. The returned intent stores the account's 127 * UUID rather than the account ID, which will be changed after account restore. 128 */ 129 public static Intent createAccountShortcutIntent(Context context, String uuid, long mailboxId) { 130 final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder( 131 VIEW_MAILBOX_INTENT_URL_PATH); 132 IntentUtilities.setAccountUuid(b, uuid); 133 IntentUtilities.setMailboxId(b, mailboxId); 134 return IntentUtilities.createRestartAppIntent(b.build()); 135 } 136 137 /** 138 * If the {@link #EXTRA_DEBUG_PANE_MODE} extra is "1" or "2", return 1 or 2 respectively. 139 * Otherwise return 0. 140 * 141 * @see UiUtilities#setDebugPaneMode(int) 142 * @see UiUtilities#useTwoPane(Context) 143 */ 144 private static int getDebugPaneMode(Intent i) { 145 Bundle extras = i.getExtras(); 146 if (extras != null) { 147 String s = extras.getString(EXTRA_DEBUG_PANE_MODE); 148 if ("1".equals(s)) { 149 return 1; 150 } else if ("2".equals(s)) { 151 return 2; 152 } 153 } 154 return 0; 155 } 156 157 @Override 158 public void onCreate(Bundle icicle) { 159 super.onCreate(icicle); 160 ActivityHelper.debugSetWindowFlags(this); 161 162 // Reset the "accounts changed" notification, now that we're here 163 Email.setNotifyUiAccountsChanged(false); 164 165 // Restore accounts, if it has not happened already 166 // NOTE: This is blocking, which it should not be (in the UI thread) 167 // We're going to live with this for the short term and replace with something 168 // smarter. Long-term fix: Move this, and most of the code below, to an AsyncTask 169 // and do the DB work in a thread. Then post handler to finish() as appropriate. 170 AccountBackupRestore.restoreIfNeeded(this); 171 172 // Because the app could be reloaded (for debugging, etc.), we need to make sure that 173 // ExchangeService gets a chance to start. There is no harm to starting it if it has 174 // already been started 175 // When the service starts, it reconciles EAS accounts. 176 // TODO More completely separate ExchangeService from Email app 177 ExchangeUtils.startExchangeService(this); 178 179 new MainActivityLauncher(this, getIntent()).executeParallel(); 180 } 181 182 @Override 183 public void onDestroy() { 184 mTaskTracker.cancellAllInterrupt(); 185 super.onDestroy(); 186 } 187 188 /** 189 * Open an account with the Activity appropriate to the current configuration. 190 * If there's no accounts set up, open the "add account" screen. 191 * 192 * if {@code account} is -1, open the default account. 193 */ 194 @VisibleForTesting 195 static class MainActivityLauncher extends EmailAsyncTask<Void, Void, Void> { 196 private final Welcome mFromActivity; 197 private final long mAccountId; 198 private final long mMailboxId; 199 private final long mMessageId; 200 private final String mAccountUuid; 201 202 public MainActivityLauncher(Welcome fromActivity, Intent intent) { 203 super(fromActivity.mTaskTracker); 204 mFromActivity = fromActivity; 205 206 mAccountId = IntentUtilities.getAccountIdFromIntent(intent); 207 mMailboxId = IntentUtilities.getMailboxIdFromIntent(intent); 208 mMessageId = IntentUtilities.getMessageIdFromIntent(intent); 209 mAccountUuid = IntentUtilities.getAccountUuidFromIntent(intent); 210 UiUtilities.setDebugPaneMode(getDebugPaneMode(intent)); 211 } 212 213 private boolean isMailboxSelected() { 214 return mMailboxId != -1; 215 } 216 217 private boolean isMessageSelected() { 218 return mMessageId != -1; 219 } 220 221 @VisibleForTesting 222 static long resolveAccountId(Context context, long inputAccountId, String uuid) { 223 final long accountId; 224 225 if (!TextUtils.isEmpty(uuid)) { 226 accountId = Account.getAccountIdFromUuid(context, uuid); 227 // accountId will be NO_ACCOUNT if the UUID is invalid. 228 229 } else if (inputAccountId != Account.NO_ACCOUNT) { 230 // TODO if we add meta-mailboxes/accounts to the database, remove this special case 231 if (inputAccountId == Account.ACCOUNT_ID_COMBINED_VIEW 232 || Account.isValidId(context, inputAccountId)) { 233 accountId = inputAccountId; 234 } else { 235 accountId = Account.NO_ACCOUNT; 236 } 237 } else { 238 // Use the default (without showing the toast) 239 accountId = EmailContent.Account.getDefaultAccountId(context); 240 } 241 if (accountId != Account.NO_ACCOUNT) { 242 // Okay, the given account is valid. 243 return accountId; 244 } else { 245 // No, it's invalid. Show the warning toast and use the default. 246 Utility.showToast(context, R.string.toast_account_not_found); 247 return EmailContent.Account.getDefaultAccountId(context); 248 } 249 } 250 251 @Override 252 protected Void doInBackground(Void... params) { 253 // Reconcile POP/IMAP accounts. EAS accounts are taken care of by ExchangeService. 254 MailService.reconcilePopImapAccountsSync(mFromActivity); 255 256 final int numAccount = 257 EmailContent.count(mFromActivity, EmailContent.Account.CONTENT_URI); 258 if (numAccount == 0) { 259 AccountSetupBasics.actionNewAccount(mFromActivity); 260 } else { 261 final long accountId = resolveAccountId(mFromActivity, mAccountId, mAccountUuid); 262 263 final Intent i; 264 if (isMessageSelected()) { 265 i = EmailActivity.createOpenMessageIntent(mFromActivity, accountId, 266 mMailboxId, mMessageId); 267 } else if (isMailboxSelected()) { 268 i = EmailActivity.createOpenMailboxIntent(mFromActivity, accountId, 269 mMailboxId); 270 } else { 271 i = EmailActivity.createOpenAccountIntent(mFromActivity, accountId); 272 } 273 mFromActivity.startActivity(i); 274 } 275 return null; 276 } 277 278 @Override 279 protected void onPostExecute(Void result) { 280 mFromActivity.finish(); 281 } 282 } 283} 284