Welcome.java revision d111cc70aa555b0cfb7cc58f6413de458e9ae9ec
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 * If no accounts are configured the user is taken to the AccountSetupBasics Activity where they 43 * can configure an account. 44 * If a single account is configured the user is taken directly to the MessageList for 45 * the INBOX of that account. 46 * If more than one account is configured the user is taken to the AccountFolderList Activity so 47 * they can select an account. 48 */ 49public class Welcome extends Activity { 50 private static final String EXTRA_ACCOUNT_ID = "com.android.email.activity._ACCOUNT_ID"; 51 52 /** 53 * Extra for debugging. Set 1 to force one-pane. Set 2 to force two-pane. 54 */ 55 private static final String EXTRA_DEBUG_PANE_MODE = "DEBUG_PANE_MODE"; 56 57 private AccountsUpdatedListener mAccountsUpdatedListener; 58 private Handler mHandler = new Handler(); 59 60 /** 61 * @return true if the two-pane activity should be used on the current configuration. 62 */ 63 public static boolean useTwoPane(Context context) { 64 final int screenLayout = context.getResources().getConfiguration().screenLayout; 65 return (screenLayout & Configuration.SCREENLAYOUT_SIZE_XLARGE) != 0; 66 } 67 68 /** 69 * Launch this activity. Note: It's assumed that this activity is only called as a means to 70 * 'reset' the UI state; Because of this, it is always launched with FLAG_ACTIVITY_CLEAR_TOP, 71 * which will drop any other activities on the stack (e.g. AccountFolderList or MessageList). 72 */ 73 public static void actionStart(Activity fromActivity) { 74 Intent i = new Intent(fromActivity, Welcome.class); 75 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 76 fromActivity.startActivity(i); 77 } 78 79 /** 80 * Create an Intent to open account's inbox. 81 */ 82 public static Intent createOpenAccountInboxIntent(Activity fromActivity, long accountId) { 83 Intent i = new Intent(fromActivity, Welcome.class); 84 if (accountId != -1) { 85 i.putExtra(EXTRA_ACCOUNT_ID, accountId); 86 } 87 return i; 88 } 89 90 /** 91 * Open account's inbox. 92 */ 93 public static void actionOpenAccountInbox(Activity fromActivity, long accountId) { 94 fromActivity.startActivity(createOpenAccountInboxIntent(fromActivity, accountId)); 95 } 96 97 /** 98 * Parse the {@link #EXTRA_DEBUG_PANE_MODE} extra and return 1 or 2, if it's set to "1" or "2". 99 * Return 0 otherwise. 100 */ 101 private static int getDebugPaneMode(Intent i) { 102 Bundle extras = i.getExtras(); 103 if (extras != null) { 104 String s = extras.getString(EXTRA_DEBUG_PANE_MODE); 105 if ("1".equals(s)) { 106 return 1; 107 } else if ("2".equals(s)) { 108 return 2; 109 } 110 } 111 return 0; 112 } 113 114 @Override 115 public void onCreate(Bundle icicle) { 116 super.onCreate(icicle); 117 118 // Reset the "accounts changed" notification, now that we're here 119 Email.setNotifyUiAccountsChanged(false); 120 121 // Quickly check for bulk upgrades (from older app versions) and switch to the 122 // upgrade activity if necessary 123 if (UpgradeAccounts.doBulkUpgradeIfNecessary(this)) { 124 finish(); 125 return; 126 } 127 128 // Restore accounts, if it has not happened already 129 // NOTE: This is blocking, which it should not be (in the UI thread) 130 // We're going to live with this for the short term and replace with something 131 // smarter. Long-term fix: Move this, and most of the code below, to an AsyncTask 132 // and do the DB work in a thread. Then post handler to finish() as appropriate. 133 AccountBackupRestore.restoreAccountsIfNeeded(this); 134 135 // Because the app could be reloaded (for debugging, etc.), we need to make sure that 136 // SyncManager gets a chance to start. There is no harm to starting it if it has already 137 // been started 138 // TODO More completely separate SyncManager from Email app 139 ExchangeUtils.startExchangeService(this); 140 141 // TODO Move this listener code to a more central location 142 // Set up our observer for AccountManager 143 mAccountsUpdatedListener = new AccountsUpdatedListener(); 144 AccountManager.get(getApplication()).addOnAccountsUpdatedListener( 145 mAccountsUpdatedListener, mHandler, true); 146 // Run reconciliation to make sure we're up-to-date on account status 147 mAccountsUpdatedListener.onAccountsUpdated(null); 148 149 final long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1); 150 final int debugPaneMode = getDebugPaneMode(getIntent()); 151 new MainActivityLauncher(this, accountId, debugPaneMode).execute(); 152 } 153 154 @Override 155 public void onDestroy() { 156 super.onDestroy(); 157 if (mAccountsUpdatedListener != null) { 158 AccountManager.get(this).removeOnAccountsUpdatedListener(mAccountsUpdatedListener); 159 } 160 } 161 162 /** 163 * Reconcile accounts when accounts are added/removed from AccountManager 164 */ 165 public class AccountsUpdatedListener implements OnAccountsUpdateListener { 166 public void onAccountsUpdated(android.accounts.Account[] accounts) { 167 Utility.runAsync(new Runnable() { 168 public void run() { 169 MailService.reconcilePopImapAccounts(Welcome.this); 170 } 171 }); 172 } 173 } 174 175 /** 176 * Open an account with the Activity appropriate to the current configuration. 177 * If there's no accounts set up, open the "add account" screen. 178 * 179 * if {@code account} is -1, open the default account. 180 */ 181 private static class MainActivityLauncher extends AsyncTask<Void, Void, Void> { 182 private final Activity mFromActivity; 183 private final int mDebugPaneMode; 184 private final long mAccountId; 185 186 public MainActivityLauncher(Activity fromActivity, long accountId, int debugPaneMode) { 187 mFromActivity = fromActivity; 188 mAccountId = accountId; 189 mDebugPaneMode = debugPaneMode; 190 } 191 192 @Override 193 protected Void doInBackground(Void... params) { 194 final int numAccount = 195 EmailContent.count(mFromActivity, EmailContent.Account.CONTENT_URI); 196 if (numAccount == 0) { 197 AccountSetupBasics.actionNewAccount(mFromActivity); 198 } else { 199 long accountId = mAccountId; 200 if (accountId == -1 || !Account.isValidId(mFromActivity, accountId)) { 201 accountId = EmailContent.Account.getDefaultAccountId(mFromActivity); 202 } 203 204 final boolean useTwoPane = (mDebugPaneMode == 2) 205 || (useTwoPane(mFromActivity) && mDebugPaneMode == 0); 206 207 if (useTwoPane) { 208 MessageListXL.actionStart(mFromActivity, accountId); 209 } else { 210 MessageList.actionHandleAccount(mFromActivity, accountId, Mailbox.TYPE_INBOX); 211 } 212 } 213 return null; 214 } 215 216 @Override 217 protected void onPostExecute(Void result) { 218 mFromActivity.finish(); 219 } 220 } 221} 222