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