Welcome.java revision 844bf745044b4564f42a68f8b7d40105c4def294
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 * Parse the {@link #EXTRA_DEBUG_PANE_MODE} extra and return 1 or 2, if it's set to "1" or "2". 139 * Return 0 otherwise. 140 */ 141 private static int getDebugPaneMode(Intent i) { 142 Bundle extras = i.getExtras(); 143 if (extras != null) { 144 String s = extras.getString(EXTRA_DEBUG_PANE_MODE); 145 if ("1".equals(s)) { 146 return 1; 147 } else if ("2".equals(s)) { 148 return 2; 149 } 150 } 151 return 0; 152 } 153 154 @Override 155 public void onCreate(Bundle icicle) { 156 super.onCreate(icicle); 157 ActivityHelper.debugSetWindowFlags(this); 158 159 // Reset the "accounts changed" notification, now that we're here 160 Email.setNotifyUiAccountsChanged(false); 161 162 // Restore accounts, if it has not happened already 163 // NOTE: This is blocking, which it should not be (in the UI thread) 164 // We're going to live with this for the short term and replace with something 165 // smarter. Long-term fix: Move this, and most of the code below, to an AsyncTask 166 // and do the DB work in a thread. Then post handler to finish() as appropriate. 167 AccountBackupRestore.restoreIfNeeded(this); 168 169 // Because the app could be reloaded (for debugging, etc.), we need to make sure that 170 // ExchangeService gets a chance to start. There is no harm to starting it if it has 171 // already been started 172 // When the service starts, it reconciles EAS accounts. 173 // TODO More completely separate ExchangeService from Email app 174 ExchangeUtils.startExchangeService(this); 175 176 new MainActivityLauncher(this, getIntent()).executeParallel(); 177 } 178 179 @Override 180 public void onDestroy() { 181 mTaskTracker.cancellAllInterrupt(); 182 super.onDestroy(); 183 } 184 185 /** 186 * Open an account with the Activity appropriate to the current configuration. 187 * If there's no accounts set up, open the "add account" screen. 188 * 189 * if {@code account} is -1, open the default account. 190 */ 191 @VisibleForTesting 192 static class MainActivityLauncher extends EmailAsyncTask<Void, Void, Void> { 193 private final Welcome mFromActivity; 194 private final int mDebugPaneMode; 195 private final long mAccountId; 196 private final long mMailboxId; 197 private final long mMessageId; 198 private final String mAccountUuid; 199 200 public MainActivityLauncher(Welcome fromActivity, Intent intent) { 201 super(fromActivity.mTaskTracker); 202 mFromActivity = fromActivity; 203 204 mAccountId = IntentUtilities.getAccountIdFromIntent(intent); 205 mMailboxId = IntentUtilities.getMailboxIdFromIntent(intent); 206 mMessageId = IntentUtilities.getMessageIdFromIntent(intent); 207 mAccountUuid = IntentUtilities.getAccountUuidFromIntent(intent); 208 mDebugPaneMode = getDebugPaneMode(intent); 209 } 210 211 private boolean isMailboxSelected() { 212 return mMailboxId != -1; 213 } 214 215 private boolean isMessageSelected() { 216 return mMessageId != -1; 217 } 218 219 @VisibleForTesting 220 static long resolveAccountId(Context context, long inputAccountId, String uuid) { 221 final long accountId; 222 223 if (!TextUtils.isEmpty(uuid)) { 224 accountId = Account.getAccountIdFromUuid(context, uuid); 225 // accountId will be NO_ACCOUNT if the UUID is invalid. 226 227 } else if (inputAccountId != Account.NO_ACCOUNT) { 228 // TODO if we add meta-mailboxes/accounts to the database, remove this special case 229 if (inputAccountId == Account.ACCOUNT_ID_COMBINED_VIEW 230 || Account.isValidId(context, inputAccountId)) { 231 accountId = inputAccountId; 232 } else { 233 accountId = Account.NO_ACCOUNT; 234 } 235 } else { 236 // Use the default (without showing the toast) 237 accountId = EmailContent.Account.getDefaultAccountId(context); 238 } 239 if (accountId != Account.NO_ACCOUNT) { 240 // Okay, the given account is valid. 241 return accountId; 242 } else { 243 // No, it's invalid. Show the warning toast and use the default. 244 Utility.showToast(context, R.string.toast_account_not_found); 245 return EmailContent.Account.getDefaultAccountId(context); 246 } 247 } 248 249 @Override 250 protected Void doInBackground(Void... params) { 251 // Reconcile POP/IMAP accounts. EAS accounts are taken care of by ExchangeService. 252 MailService.reconcilePopImapAccountsSync(mFromActivity); 253 254 final int numAccount = 255 EmailContent.count(mFromActivity, EmailContent.Account.CONTENT_URI); 256 if (numAccount == 0) { 257 AccountSetupBasics.actionNewAccount(mFromActivity); 258 } else { 259 final long accountId = resolveAccountId(mFromActivity, mAccountId, mAccountUuid); 260 261 final Intent i; 262 if (isMessageSelected()) { 263 i = EmailActivity.createOpenMessageIntent(mFromActivity, accountId, 264 mMailboxId, mMessageId); 265 } else if (isMailboxSelected()) { 266 i = EmailActivity.createOpenMailboxIntent(mFromActivity, accountId, 267 mMailboxId); 268 } else { 269 i = EmailActivity.createOpenAccountIntent(mFromActivity, accountId); 270 } 271 if (mDebugPaneMode != 0) { 272 EmailActivity.forcePaneMode(i, mDebugPaneMode == 2); 273 } 274 mFromActivity.startActivity(i); 275 } 276 return null; 277 } 278 279 @Override 280 protected void onPostExecute(Void result) { 281 mFromActivity.finish(); 282 } 283 } 284} 285