Welcome.java revision 0be2d85bb8e4ca177a52aebeb0dc5e869f1c96b4
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.Utility; 23import com.android.email.activity.setup.AccountSetupBasics; 24import com.android.email.provider.EmailContent; 25import com.android.email.provider.EmailContent.Account; 26import com.android.email.provider.EmailContent.Mailbox; 27import com.android.email.service.MailService; 28 29import android.accounts.AccountManager; 30import android.accounts.OnAccountsUpdateListener; 31import android.app.Activity; 32import android.content.Context; 33import android.content.Intent; 34import android.content.res.Configuration; 35import android.os.AsyncTask; 36import android.os.Bundle; 37import android.os.Handler; 38 39/** 40 * The Welcome activity initializes the application and decides what Activity 41 * the user should start with. 42 * 43 * This class knows which activity should be launched under the current configuration (screen size) 44 * and the number of accounts configured. So if you want to open an account or a mailbox, 45 * you should alawys do so via its static methods, such as {@link #actionOpenAccountInbox}. 46 */ 47public class Welcome extends Activity { 48 /* 49 * Commands for testing... 50 * Open 1 pane 51 adb shell am start -a android.intent.action.MAIN \ 52 -n com.google.android.email/com.android.email.activity.Welcome \ 53 -e DEBUG_PANE_MODE 1 54 55 * Open 2 pane 56 adb shell am start -a android.intent.action.MAIN \ 57 -n com.google.android.email/com.android.email.activity.Welcome \ 58 -e DEBUG_PANE_MODE 2 59 60 * Open an account (ID=2) in 2 pane 61 adb shell am start -a android.intent.action.MAIN \ 62 -n com.google.android.email/com.android.email.activity.Welcome \ 63 -e DEBUG_PANE_MODE 2 --el ACCOUNT_ID 2 64 65 * Open Combined Inbox (ID=-2) in 2 pane 66 adb shell am start -a android.intent.action.MAIN \ 67 -n com.google.android.email/com.android.email.activity.Welcome \ 68 -e DEBUG_PANE_MODE 2 --el MAILBOX_ID -2 69 70 */ 71 private static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID"; 72 private static final String EXTRA_MAILBOX_ID = "MAILBOX_ID"; 73 74 /** 75 * Extra for debugging. Set 1 to force one-pane. Set 2 to force two-pane. 76 */ 77 private static final String EXTRA_DEBUG_PANE_MODE = "DEBUG_PANE_MODE"; 78 79 private AccountsUpdatedListener mAccountsUpdatedListener; 80 private Handler mHandler = new Handler(); 81 82 /** 83 * @return true if the two-pane activity should be used on the current configuration. 84 */ 85 public static boolean useTwoPane(Context context) { 86 final int screenLayout = context.getResources().getConfiguration().screenLayout; 87 return (screenLayout & Configuration.SCREENLAYOUT_SIZE_XLARGE) != 0; 88 } 89 90 /** 91 * Launch this activity. Note: It's assumed that this activity is only called as a means to 92 * 'reset' the UI state; Because of this, it is always launched with FLAG_ACTIVITY_CLEAR_TOP, 93 * which will drop any other activities on the stack (e.g. AccountFolderList or MessageList). 94 */ 95 public static void actionStart(Activity fromActivity) { 96 Intent i = new Intent(fromActivity, Welcome.class); 97 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 98 fromActivity.startActivity(i); 99 } 100 101 /** 102 * Create an Intent to open account's inbox. 103 */ 104 public static Intent createOpenAccountInboxIntent(Context context, long accountId) { 105 Intent i = new Intent(context, Welcome.class); 106 if (accountId != -1) { 107 i.putExtra(EXTRA_ACCOUNT_ID, accountId); 108 } 109 return i; 110 } 111 112 /** 113 * Create an Intent to open "Combined Inbox". 114 */ 115 public static Intent createOpenCombinedInboxIntent(Context context) { 116 Intent i = new Intent(context, Welcome.class); 117 i.putExtra(EXTRA_MAILBOX_ID, Mailbox.QUERY_ALL_INBOXES); 118 return i; 119 } 120 121 /** 122 * Open account's inbox. 123 */ 124 public static void actionOpenAccountInbox(Activity fromActivity, long accountId) { 125 fromActivity.startActivity(createOpenAccountInboxIntent(fromActivity, accountId)); 126 } 127 128 /** 129 * Parse the {@link #EXTRA_DEBUG_PANE_MODE} extra and return 1 or 2, if it's set to "1" or "2". 130 * Return 0 otherwise. 131 */ 132 private static int getDebugPaneMode(Intent i) { 133 Bundle extras = i.getExtras(); 134 if (extras != null) { 135 String s = extras.getString(EXTRA_DEBUG_PANE_MODE); 136 if ("1".equals(s)) { 137 return 1; 138 } else if ("2".equals(s)) { 139 return 2; 140 } 141 } 142 return 0; 143 } 144 145 @Override 146 public void onCreate(Bundle icicle) { 147 super.onCreate(icicle); 148 149 // Reset the "accounts changed" notification, now that we're here 150 Email.setNotifyUiAccountsChanged(false); 151 152 // Quickly check for bulk upgrades (from older app versions) and switch to the 153 // upgrade activity if necessary 154 if (UpgradeAccounts.doBulkUpgradeIfNecessary(this)) { 155 finish(); 156 return; 157 } 158 159 // Restore accounts, if it has not happened already 160 // NOTE: This is blocking, which it should not be (in the UI thread) 161 // We're going to live with this for the short term and replace with something 162 // smarter. Long-term fix: Move this, and most of the code below, to an AsyncTask 163 // and do the DB work in a thread. Then post handler to finish() as appropriate. 164 AccountBackupRestore.restoreAccountsIfNeeded(this); 165 166 // Because the app could be reloaded (for debugging, etc.), we need to make sure that 167 // SyncManager gets a chance to start. There is no harm to starting it if it has already 168 // been started 169 // TODO More completely separate SyncManager from Email app 170 ExchangeUtils.startExchangeService(this); 171 172 // TODO Move this listener code to a more central location 173 // Set up our observer for AccountManager 174 mAccountsUpdatedListener = new AccountsUpdatedListener(); 175 AccountManager.get(getApplication()).addOnAccountsUpdatedListener( 176 mAccountsUpdatedListener, mHandler, true); 177 // Run reconciliation to make sure we're up-to-date on account status 178 mAccountsUpdatedListener.onAccountsUpdated(null); 179 180 final long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1); 181 final long mailboxId = getIntent().getLongExtra(EXTRA_MAILBOX_ID, -1); 182 final int debugPaneMode = getDebugPaneMode(getIntent()); 183 new MainActivityLauncher(this, accountId, mailboxId, debugPaneMode).execute(); 184 } 185 186 @Override 187 public void onDestroy() { 188 super.onDestroy(); 189 if (mAccountsUpdatedListener != null) { 190 AccountManager.get(this).removeOnAccountsUpdatedListener(mAccountsUpdatedListener); 191 } 192 } 193 194 /** 195 * Reconcile accounts when accounts are added/removed from AccountManager 196 */ 197 public class AccountsUpdatedListener implements OnAccountsUpdateListener { 198 public void onAccountsUpdated(android.accounts.Account[] accounts) { 199 Utility.runAsync(new Runnable() { 200 public void run() { 201 MailService.reconcilePopImapAccounts(Welcome.this); 202 } 203 }); 204 } 205 } 206 207 /** 208 * Open an account with the Activity appropriate to the current configuration. 209 * If there's no accounts set up, open the "add account" screen. 210 * 211 * if {@code account} is -1, open the default account. 212 */ 213 private static class MainActivityLauncher extends AsyncTask<Void, Void, Void> { 214 private final Activity mFromActivity; 215 private final int mDebugPaneMode; 216 private final long mAccountId; 217 private final long mMailboxId; 218 219 public MainActivityLauncher(Activity fromActivity, long accountId, long mailboxId, 220 int debugPaneMode) { 221 mFromActivity = fromActivity; 222 mAccountId = accountId; 223 mMailboxId = mailboxId; 224 mDebugPaneMode = debugPaneMode; 225 } 226 227 private boolean isMailboxSelected() { 228 return mMailboxId != -1; 229 } 230 231 @Override 232 protected Void doInBackground(Void... params) { 233 final int numAccount = 234 EmailContent.count(mFromActivity, EmailContent.Account.CONTENT_URI); 235 if (numAccount == 0) { 236 AccountSetupBasics.actionNewAccount(mFromActivity); 237 } else { 238 long accountId = mAccountId; 239 if (accountId == -1 || !Account.isValidId(mFromActivity, accountId)) { 240 accountId = EmailContent.Account.getDefaultAccountId(mFromActivity); 241 } 242 243 final boolean useTwoPane = (mDebugPaneMode == 2) 244 || (useTwoPane(mFromActivity) && mDebugPaneMode == 0); 245 246 if (useTwoPane) { 247 if (isMailboxSelected()) { 248 MessageListXL.actionOpenMailbox(mFromActivity, accountId, mMailboxId); 249 } else { 250 MessageListXL.actionOpenAccount(mFromActivity, accountId); 251 } 252 } else { 253 if (isMailboxSelected()) { 254 MessageList.actionHandleMailbox(mFromActivity, mMailboxId); 255 } else { 256 MessageList.actionHandleAccount( 257 mFromActivity, accountId, Mailbox.TYPE_INBOX); 258 } 259 } 260 } 261 return null; 262 } 263 264 @Override 265 protected void onPostExecute(Void result) { 266 mFromActivity.finish(); 267 } 268 } 269} 270