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