Welcome.java revision af6079c823d045bb14abb601cc9c7fd48261313f
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.AccountBackupRestore; 20import com.android.email.Email; 21import com.android.email.ExchangeUtils; 22import com.android.email.activity.setup.AccountSetupBasics; 23import com.android.email.service.MailService; 24import com.android.emailcommon.provider.EmailContent; 25import com.android.emailcommon.provider.EmailContent.Account; 26import com.android.emailcommon.provider.EmailContent.Mailbox; 27import com.android.emailcommon.utility.EmailAsyncTask; 28 29import android.app.Activity; 30import android.content.Context; 31import android.content.Intent; 32import android.content.res.Configuration; 33import android.net.Uri; 34import android.os.Bundle; 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 * @return true if the two-pane activity should be used on the current configuration. 80 */ 81 public static boolean useTwoPane(Context context) { 82 final int screenLayout = context.getResources().getConfiguration().screenLayout; 83 return (screenLayout & Configuration.SCREENLAYOUT_SIZE_XLARGE) != 0; 84 } 85 86 /** 87 * Launch this activity. Note: It's assumed that this activity is only called as a means to 88 * 'reset' the UI state; Because of this, it is always launched with FLAG_ACTIVITY_CLEAR_TOP, 89 * which will drop any other activities on the stack (e.g. AccountFolderList or MessageList). 90 */ 91 public static void actionStart(Activity fromActivity) { 92 Intent i = IntentUtilities.createRestartAppIntent(fromActivity, Welcome.class); 93 fromActivity.startActivity(i); 94 } 95 96 /** 97 * Create an Intent to open email activity. If <code>accountId</code> is not -1, the 98 * specified account will be automatically be opened when the activity starts. 99 */ 100 public static Intent createOpenAccountInboxIntent(Context context, long accountId) { 101 final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder( 102 VIEW_MAILBOX_INTENT_URL_PATH); 103 IntentUtilities.setAccountId(b, accountId); 104 return IntentUtilities.createRestartAppIntent(b.build()); 105 } 106 107 /** 108 * Create an Intent to open a message. 109 */ 110 public static Intent createOpenMessageIntent(Context context, long accountId, 111 long mailboxId, long messageId) { 112 final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder( 113 VIEW_MAILBOX_INTENT_URL_PATH); 114 IntentUtilities.setAccountId(b, accountId); 115 IntentUtilities.setMailboxId(b, mailboxId); 116 IntentUtilities.setMessageId(b, messageId); 117 return IntentUtilities.createRestartAppIntent(b.build()); 118 } 119 120 /** 121 * Open account's inbox. 122 */ 123 public static void actionOpenAccountInbox(Activity fromActivity, long accountId) { 124 fromActivity.startActivity(createOpenAccountInboxIntent(fromActivity, accountId)); 125 } 126 127 /** 128 * Parse the {@link #EXTRA_DEBUG_PANE_MODE} extra and return 1 or 2, if it's set to "1" or "2". 129 * Return 0 otherwise. 130 */ 131 private static int getDebugPaneMode(Intent i) { 132 Bundle extras = i.getExtras(); 133 if (extras != null) { 134 String s = extras.getString(EXTRA_DEBUG_PANE_MODE); 135 if ("1".equals(s)) { 136 return 1; 137 } else if ("2".equals(s)) { 138 return 2; 139 } 140 } 141 return 0; 142 } 143 144 @Override 145 public void onCreate(Bundle icicle) { 146 super.onCreate(icicle); 147 ActivityHelper.debugSetWindowFlags(this); 148 149 // Reset the "accounts changed" notification, now that we're here 150 Email.setNotifyUiAccountsChanged(false); 151 152 // Restore accounts, if it has not happened already 153 // NOTE: This is blocking, which it should not be (in the UI thread) 154 // We're going to live with this for the short term and replace with something 155 // smarter. Long-term fix: Move this, and most of the code below, to an AsyncTask 156 // and do the DB work in a thread. Then post handler to finish() as appropriate. 157 AccountBackupRestore.restoreAccountsIfNeeded(this); 158 159 // Because the app could be reloaded (for debugging, etc.), we need to make sure that 160 // ExchangeService gets a chance to start. There is no harm to starting it if it has 161 // already been started 162 // When the service starts, it reconciles EAS accounts. 163 // TODO More completely separate ExchangeService from Email app 164 ExchangeUtils.startExchangeService(this); 165 166 final Intent intent = getIntent(); 167 final long accountId = IntentUtilities.getAccountIdFromIntent(intent); 168 final long mailboxId = IntentUtilities.getMailboxIdFromIntent(intent); 169 final long messageId = IntentUtilities.getMessageIdFromIntent(intent); 170 final int debugPaneMode = getDebugPaneMode(getIntent()); 171 new MainActivityLauncher(this, accountId, mailboxId, messageId, debugPaneMode) 172 .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 private static class MainActivityLauncher extends EmailAsyncTask<Void, Void, Void> { 188 private final Welcome mFromActivity; 189 private final int mDebugPaneMode; 190 private final long mAccountId; 191 private final long mMailboxId; 192 private final long mMessageId; 193 194 public MainActivityLauncher(Welcome fromActivity, long accountId, long mailboxId, 195 long messageId, int debugPaneMode) { 196 super(fromActivity.mTaskTracker); 197 mFromActivity = fromActivity; 198 mAccountId = accountId; 199 mMailboxId = mailboxId; 200 mMessageId = messageId; 201 mDebugPaneMode = debugPaneMode; 202 } 203 204 private boolean isMailboxSelected() { 205 return mMailboxId != -1; 206 } 207 208 private boolean isMessageSelected() { 209 return mMessageId != -1; 210 } 211 212 @Override 213 protected Void doInBackground(Void... params) { 214 // Reconcile POP/IMAP accounts. EAS accounts are taken care of by ExchangeService. 215 MailService.reconcilePopImapAccountsSync(mFromActivity); 216 217 final int numAccount = 218 EmailContent.count(mFromActivity, EmailContent.Account.CONTENT_URI); 219 if (numAccount == 0) { 220 AccountSetupBasics.actionNewAccount(mFromActivity); 221 } else { 222 long accountId = mAccountId; 223 if (accountId == -1 || !Account.isValidId(mFromActivity, accountId)) { 224 accountId = EmailContent.Account.getDefaultAccountId(mFromActivity); 225 } 226 227 final boolean useTwoPane = (mDebugPaneMode == 2) 228 || (useTwoPane(mFromActivity) && mDebugPaneMode == 0); 229 230 if (useTwoPane) { 231 if (isMessageSelected()) { 232 MessageListXL.actionOpenMessage(mFromActivity, accountId, mMailboxId, 233 mMessageId); 234 } else if (isMailboxSelected()) { 235 MessageListXL.actionOpenMailbox(mFromActivity, accountId, mMailboxId); 236 } else { 237 MessageListXL.actionOpenAccount(mFromActivity, accountId); 238 } 239 } else { 240 if (isMessageSelected()) { 241 MessageView.actionView(mFromActivity, mMessageId, mMailboxId); 242 } else if (isMailboxSelected()) { 243 MessageList.actionHandleMailbox(mFromActivity, mMailboxId); 244 } else { 245 MessageList.actionHandleAccount( 246 mFromActivity, accountId, Mailbox.TYPE_INBOX); 247 } 248 } 249 } 250 return null; 251 } 252 253 @Override 254 protected void onPostExecute(Void result) { 255 mFromActivity.finish(); 256 } 257 } 258} 259