Welcome.java revision 9dad9ad973ccf8255228a41acc0ee78af989a651
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.Account; 26import com.android.emailcommon.provider.EmailContent; 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 // Because the app could be reloaded (for debugging, etc.), we need to make sure that 166 // ExchangeService gets a chance to start. There is no harm to starting it if it has 167 // already been started 168 // When the service starts, it reconciles EAS accounts. 169 // TODO More completely separate ExchangeService from Email app 170 ExchangeUtils.startExchangeService(this); 171 172 new MainActivityLauncher(this, getIntent()).executeParallel(); 173 } 174 175 @Override 176 public void onDestroy() { 177 mTaskTracker.cancellAllInterrupt(); 178 super.onDestroy(); 179 } 180 181 /** 182 * Open an account with the Activity appropriate to the current configuration. 183 * If there's no accounts set up, open the "add account" screen. 184 * 185 * if {@code account} is -1, open the default account. 186 */ 187 @VisibleForTesting 188 static class MainActivityLauncher extends EmailAsyncTask<Void, Void, Void> { 189 private final Welcome mFromActivity; 190 private final long mAccountId; 191 private final long mMailboxId; 192 private final long mMessageId; 193 private final String mAccountUuid; 194 195 public MainActivityLauncher(Welcome fromActivity, Intent intent) { 196 super(fromActivity.mTaskTracker); 197 mFromActivity = fromActivity; 198 199 mAccountId = IntentUtilities.getAccountIdFromIntent(intent); 200 mMailboxId = IntentUtilities.getMailboxIdFromIntent(intent); 201 mMessageId = IntentUtilities.getMessageIdFromIntent(intent); 202 mAccountUuid = IntentUtilities.getAccountUuidFromIntent(intent); 203 UiUtilities.setDebugPaneMode(getDebugPaneMode(intent)); 204 } 205 206 private boolean isMailboxSelected() { 207 return mMailboxId != -1; 208 } 209 210 private boolean isMessageSelected() { 211 return mMessageId != -1; 212 } 213 214 @VisibleForTesting 215 static long resolveAccountId(Context context, long inputAccountId, String uuid) { 216 final long accountId; 217 218 if (!TextUtils.isEmpty(uuid)) { 219 accountId = Account.getAccountIdFromUuid(context, uuid); 220 // accountId will be NO_ACCOUNT if the UUID is invalid. 221 222 } else if (inputAccountId != Account.NO_ACCOUNT) { 223 // TODO if we add meta-mailboxes/accounts to the database, remove this special case 224 if (inputAccountId == Account.ACCOUNT_ID_COMBINED_VIEW 225 || Account.isValidId(context, inputAccountId)) { 226 accountId = inputAccountId; 227 } else { 228 accountId = Account.NO_ACCOUNT; 229 } 230 } else { 231 // Use the default (without showing the toast) 232 accountId = Account.getDefaultAccountId(context); 233 } 234 if (accountId != Account.NO_ACCOUNT) { 235 // Okay, the given account is valid. 236 return accountId; 237 } else { 238 // No, it's invalid. Show the warning toast and use the default. 239 Utility.showToast(context, R.string.toast_account_not_found); 240 return Account.getDefaultAccountId(context); 241 } 242 } 243 244 @Override 245 protected Void doInBackground(Void... params) { 246 // Reconcile POP/IMAP accounts. EAS accounts are taken care of by ExchangeService. 247 MailService.reconcilePopImapAccountsSync(mFromActivity); 248 249 final int numAccount = 250 EmailContent.count(mFromActivity, Account.CONTENT_URI); 251 if (numAccount == 0) { 252 AccountSetupBasics.actionNewAccount(mFromActivity); 253 } else { 254 final long accountId = resolveAccountId(mFromActivity, mAccountId, mAccountUuid); 255 256 final Intent i; 257 if (isMessageSelected()) { 258 i = EmailActivity.createOpenMessageIntent(mFromActivity, accountId, 259 mMailboxId, mMessageId); 260 } else if (isMailboxSelected()) { 261 i = EmailActivity.createOpenMailboxIntent(mFromActivity, accountId, 262 mMailboxId); 263 } else { 264 i = EmailActivity.createOpenAccountIntent(mFromActivity, accountId); 265 } 266 mFromActivity.startActivity(i); 267 } 268 return null; 269 } 270 271 @Override 272 protected void onPostExecute(Void result) { 273 mFromActivity.finish(); 274 } 275 } 276} 277