EmailPreferenceActivity.java revision 7b9f7ff76fd9812d7e3ae4dd42c1ba97b6e347e7
12ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler/*
22ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler * Copyright (C) 2010 The Android Open Source Project
32ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler *
42ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler * Licensed under the Apache License, Version 2.0 (the "License");
52ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler * you may not use this file except in compliance with the License.
62ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler * You may obtain a copy of the License at
72ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler *
82ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler *      http://www.apache.org/licenses/LICENSE-2.0
92ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler *
102ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler * Unless required by applicable law or agreed to in writing, software
112ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler * distributed under the License is distributed on an "AS IS" BASIS,
122ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler * See the License for the specific language governing permissions and
142ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler * limitations under the License.
152ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler */
162ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
172ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerpackage com.android.email.activity.setup;
182ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1938089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onukiimport android.app.ActionBar;
201a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.app.AlertDialog;
211a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.app.Dialog;
221a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.app.DialogFragment;
232ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.app.Fragment;
24464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadlerimport android.content.Context;
251a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.content.DialogInterface;
262ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.content.Intent;
27f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadlerimport android.content.res.Resources;
28b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komaloimport android.database.ContentObserver;
292ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.database.Cursor;
30308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onukiimport android.net.Uri;
312ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.os.AsyncTask;
322ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.os.Bundle;
331bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blankimport android.text.SpannableString;
340dffe3afd7a2fdfb394573aa0d8d06dd90e9fe12James Lemieuximport android.text.TextUtils;
351bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blankimport android.text.method.LinkMovementMethod;
361bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blankimport android.text.util.Linkify;
3757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadlerimport android.view.KeyEvent;
3897874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadlerimport android.view.Menu;
3997874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadlerimport android.view.MenuItem;
401bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blankimport android.widget.TextView;
412ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
4235b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.email.R;
43f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.email.provider.EmailProvider;
4435b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.Logging;
4535b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.provider.Account;
4635b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.provider.EmailContent.AccountColumns;
470e6a521747970d5427f10c25cdc070d2341dc93aBen Komaloimport com.android.emailcommon.utility.IntentUtilities;
4835b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.utility.Utility;
49f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.mail.providers.Folder;
50f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.mail.providers.UIProvider.EditSettingsExtras;
517b9f7ff76fd9812d7e3ae4dd42c1ba97b6e347e7Tony Mantlerimport com.android.mail.ui.settings.MailPreferenceActivity;
52560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedyimport com.android.mail.utils.LogUtils;
5338f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrookimport com.android.mail.utils.Utils;
54c83366c88770f336a8e9976af42389c616de0b62Tony Mantlerimport com.google.common.annotations.VisibleForTesting;
5535b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blank
562ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport java.util.List;
572ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
582ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler/**
59fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * Handles account preferences, using multi-pane arrangement when possible.
60fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *
61fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * This activity uses the following fragments:
62fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *   AccountSettingsFragment
63f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank *   Account{Incoming/Outgoing}Fragment
64fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *   AccountCheckSettingsFragment
65fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *   GeneralPreferences
66fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *   DebugFragment
672ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler *
68464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler * TODO: Delete account - on single-pane view (phone UX) the account list doesn't update properly
69464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler * TODO: Handle dynamic changes to the account list (exit if necessary).  It probably makes
70464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler *       sense to use a loader for the accounts list, because it would provide better support for
71464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler *       dealing with accounts being added/deleted and triggering the header reload.
722ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler */
737b9f7ff76fd9812d7e3ae4dd42c1ba97b6e347e7Tony Mantlerpublic class AccountSettings extends MailPreferenceActivity implements
7476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        SetupDataFragment.SetupDataContainer, SecurityRequiredDialogFragment.Callback,
7576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        CheckSettingsErrorDialogFragment.Callback, AccountCheckSettingsFragment.Callback,
761c594b8050abda5c1859f80cb3a7cea690c21632Tony Mantler        AccountServerBaseFragment.Callback, CheckSettingsProgressDialogFragment.Callback {
77308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki    /*
78308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki     * Intent to open account settings for account=1
79308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki        adb shell am start -a android.intent.action.EDIT \
80308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki            -d '"content://ui.email.android.com/settings?ACCOUNT_ID=1"'
81308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki     */
82308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki
839c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // Intent extras for our internal activity launch
843955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    private static final String EXTRA_ENABLE_DEBUG = "AccountSettings.enable_debug";
853955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    private static final String EXTRA_LOGIN_WARNING_FOR_ACCOUNT = "AccountSettings.for_account";
86dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank    private static final String EXTRA_LOGIN_WARNING_REASON_FOR_ACCOUNT =
87dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            "AccountSettings.for_account_reason";
883955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    private static final String EXTRA_TITLE = "AccountSettings.title";
892c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon    // STOPSHIP: Do not ship with the debug menu allowed.
902c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon    private static final boolean DEBUG_MENU_ALLOWED = false;
91f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    public static final String EXTRA_NO_ACCOUNTS = "AccountSettings.no_account";
920dffe3afd7a2fdfb394573aa0d8d06dd90e9fe12James Lemieux    public static final String EXTRA_ACCOUNT = "AccountSettings.account";
9357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler
949c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // Intent extras for launch directly from system account manager
959c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // NOTE: This string must match the one in res/xml/account_preferences.xml
96fb9deb96c3af56bf422e28e8ae3b7b838f343155Tony Mantler    private static String INTENT_ACCOUNT_MANAGER_ENTRY;
979c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // NOTE: This constant should eventually be defined in android.accounts.Constants
989c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    private static final String EXTRA_ACCOUNT_MANAGER_ACCOUNT = "account";
999c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
1005a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo    // Key for arguments bundle for QuickResponse editing
1015a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo    private static final String QUICK_RESPONSE_ACCOUNT_KEY = "account";
1025a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo
10357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    // Key codes used to open a debug settings fragment.
10457f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private static final int[] SECRET_KEY_CODES = {
10557f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            KeyEvent.KEYCODE_D, KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_B, KeyEvent.KEYCODE_U,
10657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            KeyEvent.KEYCODE_G
10757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            };
10857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private int mSecretKeyCodeIndex = 0;
10957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler
1109c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // Support for account-by-name lookup
1119c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    private static final String SELECTION_ACCOUNT_EMAIL_ADDRESS =
1129c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        AccountColumns.EMAIL_ADDRESS + "=?";
1139c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
1149c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // When the user taps "Email Preferences" 10 times in a row, we'll enable the debug settings.
11557f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private int mNumGeneralHeaderClicked = 0;
1162ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
11751224176259b1b3126087c69814ccf652cb398b9Andrew Stadler    private long mRequestedAccountId;
118a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn    private Header[] mAccountListHeaders;
1192ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    private Header mAppPreferencesHeader;
12091ad26315a8769f92af469b06e24033ffd9e6cafTony Mantler    private AccountSettingsFragment mAccountSettingsFragment;
12191ad26315a8769f92af469b06e24033ffd9e6cafTony Mantler    private AccountServerBaseFragment mAccountServerFragment;
122a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    private long mDeletingAccountId = -1;
12357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private boolean mShowDebugMenu;
1241a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    private List<Header> mGeneratedHeaders;
125dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    private Uri mFeedbackUri;
126dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    private MenuItem mFeedbackMenuItem;
1272ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1289c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler    private SetupDataFragment mSetupData;
12926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler
1302ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    // Async Tasks
1312ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    private LoadAccountListTask mLoadAccountListTask;
1329c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    private GetAccountIdFromAccountTask mGetAccountIdFromAccountTask;
133b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo    private ContentObserver mAccountObserver;
1342ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1352ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    // Specific callbacks used by settings fragments
1361a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    private final AccountSettingsFragmentCallback mAccountSettingsFragmentCallback
1372ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            = new AccountSettingsFragmentCallback();
1382ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1392ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
140d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank     * Create and return an intent to display (and edit) settings for a specific account, or -1
141f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * for any/all accounts.  If an account name string is provided, a warning dialog will be
142f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * displayed as well.
143d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank     */
1444ce1fc7669a0a9ecf104fe1a48df6a2bb6675c59Tony Mantler    public static Intent createAccountSettingsIntent(final Context context, final long accountId,
1454ce1fc7669a0a9ecf104fe1a48df6a2bb6675c59Tony Mantler            final String loginWarningAccountName, final String loginWarningReason) {
146c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder(
147c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert                IntentUtilities.PATH_SETTINGS);
148308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki        IntentUtilities.setAccountId(b, accountId);
14926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        final Intent i = new Intent(Intent.ACTION_EDIT, b.build());
1504ce1fc7669a0a9ecf104fe1a48df6a2bb6675c59Tony Mantler        i.setPackage(context.getPackageName());
151308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki        if (loginWarningAccountName != null) {
152308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki            i.putExtra(EXTRA_LOGIN_WARNING_FOR_ACCOUNT, loginWarningAccountName);
153308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki        }
154dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank        if (loginWarningReason != null) {
155dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            i.putExtra(EXTRA_LOGIN_WARNING_REASON_FOR_ACCOUNT, loginWarningReason);
156dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank        }
157d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank        return i;
158d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank    }
159d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank
160c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert    @Override
161c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert    public Intent getIntent() {
162c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        final Intent intent = super.getIntent();
163c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        final long accountId = IntentUtilities.getAccountIdFromIntent(intent);
164c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        if (accountId < 0) {
165c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert            return intent;
166c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        }
167c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        Intent modIntent = new Intent(intent);
168c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, AccountSettingsFragment.class.getCanonicalName());
169c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        modIntent.putExtra(
170c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert                EXTRA_SHOW_FRAGMENT_ARGUMENTS,
171c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert                AccountSettingsFragment.buildArguments(
172c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert                        accountId, IntentUtilities.getAccountNameFromIntent(intent)));
173c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        modIntent.putExtra(EXTRA_NO_HEADERS, true);
174c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert        return modIntent;
175c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert    }
176c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert
177c4d139c4f4d924eae0307e8349ae977441dabbedAlon Albert
178d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank    /**
17957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler     * Launch generic settings and pre-enable the debug preferences
1802ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
18157f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    public static void actionSettingsWithDebug(Context fromContext) {
18226cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        final Intent i = new Intent(fromContext, AccountSettings.class);
18357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
18457f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        i.putExtra(EXTRA_ENABLE_DEBUG, true);
18557f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        fromContext.startActivity(i);
18657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    }
1872ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1882ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    @Override
1892ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onCreate(Bundle savedInstanceState) {
1902ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        super.onCreate(savedInstanceState);
1912ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
192f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        final Intent i = getIntent();
193a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn        if (savedInstanceState == null) {
194a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            // If we are not restarting from a previous instance, we need to
195a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            // figure out the initial prefs to show.  (Otherwise, we want to
196a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            // continue showing whatever the user last selected.)
197fb9deb96c3af56bf422e28e8ae3b7b838f343155Tony Mantler            if (INTENT_ACCOUNT_MANAGER_ENTRY == null) {
198fb9deb96c3af56bf422e28e8ae3b7b838f343155Tony Mantler                INTENT_ACCOUNT_MANAGER_ENTRY = getString(R.string.intent_account_manager_entry);
19974c79a50432fcbf127fbfeadc1a461263ea92135Marc Blank            }
200fb9deb96c3af56bf422e28e8ae3b7b838f343155Tony Mantler            if (INTENT_ACCOUNT_MANAGER_ENTRY.equals(i.getAction())) {
201a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                // This case occurs if we're changing account settings from Settings -> Accounts
202a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                mGetAccountIdFromAccountTask =
203bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki                        (GetAccountIdFromAccountTask) new GetAccountIdFromAccountTask()
204bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki                        .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, i);
205f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            } else if (i.hasExtra(EditSettingsExtras.EXTRA_FOLDER)) {
206f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                launchMailboxSettings(i);
207f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                return;
208f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            } else if (i.hasExtra(EXTRA_NO_ACCOUNTS)) {
20976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                final Intent setupIntent = AccountSetupFinal.actionNewAccountWithResultIntent(this);
21076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                startActivity(setupIntent);
211f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                finish();
212f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                return;
2130dffe3afd7a2fdfb394573aa0d8d06dd90e9fe12James Lemieux            } else if (i.hasExtra(EXTRA_ACCOUNT)) {
2140dffe3afd7a2fdfb394573aa0d8d06dd90e9fe12James Lemieux                final Account account = i.getParcelableExtra(EXTRA_ACCOUNT);
2150dffe3afd7a2fdfb394573aa0d8d06dd90e9fe12James Lemieux                mSetupData = new SetupDataFragment(SetupDataFragment.FLOW_MODE_EDIT, account);
216a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            } else {
217f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                // Otherwise, we're called from within the Email app and look for our extras
218308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki                mRequestedAccountId = IntentUtilities.getAccountIdFromIntent(i);
219f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                String loginWarningAccount = i.getStringExtra(EXTRA_LOGIN_WARNING_FOR_ACCOUNT);
220dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                String loginWarningReason =
221dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                        i.getStringExtra(EXTRA_LOGIN_WARNING_REASON_FOR_ACCOUNT);
222f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                if (loginWarningAccount != null) {
223f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                    // Show dialog (first time only - don't re-show on a rotation)
224dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                    LoginWarningDialog dialog =
225dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                            LoginWarningDialog.newInstance(loginWarningAccount, loginWarningReason);
226f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                    dialog.show(getFragmentManager(), "loginwarning");
227f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                }
228a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            }
22926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        } else {
2309c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler            mSetupData = savedInstanceState.getParcelable(SetupDataFragment.EXTRA_SETUP_DATA);
2319c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        }
23257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        mShowDebugMenu = i.getBooleanExtra(EXTRA_ENABLE_DEBUG, false);
23338089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki
23426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        final String title = i.getStringExtra(EXTRA_TITLE);
2353955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        if (title != null) {
2363955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            setTitle(title);
2373955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        }
2383955f6794f23c1380749d4470b5f2264d2109adcBen Komalo
23938089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki        getActionBar().setDisplayOptions(
24038089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
241b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo
242b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        mAccountObserver = new ContentObserver(Utility.getMainThreadHandler()) {
243b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo            @Override
244b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo            public void onChange(boolean selfChange) {
245b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo                updateAccounts();
246b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo            }
247b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        };
248dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
249dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        mFeedbackUri = Utils.getValidUri(getString(R.string.email_feedback_uri));
2502ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
2512ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
2522ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    @Override
25326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler    protected void onSaveInstanceState(Bundle outState) {
25426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        super.onSaveInstanceState(
25526cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                outState);
2569c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler        // TODO: use the fragment manager to persist this
2579c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler        outState.putParcelable(SetupDataFragment.EXTRA_SETUP_DATA, mSetupData);
25826cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler    }
25926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler
26026cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler    @Override
2612ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onResume() {
2622ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        super.onResume();
263b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        getContentResolver().registerContentObserver(Account.NOTIFIER_URI, true, mAccountObserver);
2642ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        updateAccounts();
2658ec0dcfe0d241cdac946a8c131472913c7349492Andy Stadler    }
2668ec0dcfe0d241cdac946a8c131472913c7349492Andy Stadler
2678ec0dcfe0d241cdac946a8c131472913c7349492Andy Stadler    @Override
268b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo    public void onPause() {
269b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        super.onPause();
270b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        getContentResolver().unregisterContentObserver(mAccountObserver);
271b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo    }
272b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo
273b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo    @Override
2742ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    protected void onDestroy() {
2752ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        super.onDestroy();
2762ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        Utility.cancelTaskInterrupt(mLoadAccountListTask);
2772ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        mLoadAccountListTask = null;
2789c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        Utility.cancelTaskInterrupt(mGetAccountIdFromAccountTask);
2799c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        mGetAccountIdFromAccountTask = null;
2802ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
2812ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
2822ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
28357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler     * Listen for secret sequence and, if heard, enable debug menu
28457f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler     */
28557f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    @Override
28657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    public boolean onKeyDown(int keyCode, KeyEvent event) {
28757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        if (event.getKeyCode() == SECRET_KEY_CODES[mSecretKeyCodeIndex]) {
28857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            mSecretKeyCodeIndex++;
28957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            if (mSecretKeyCodeIndex == SECRET_KEY_CODES.length) {
29057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler                mSecretKeyCodeIndex = 0;
29157f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler                enableDebugMenu();
29257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            }
29357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        } else {
29457f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            mSecretKeyCodeIndex = 0;
29557f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        }
29657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        return super.onKeyDown(keyCode, event);
29757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    }
29857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler
299b387560384d38e3280090176a0f3b2cf8b1f9ab5Andrew Stadler    @Override
30097874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler    public boolean onCreateOptionsMenu(Menu menu) {
30197874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler        super.onCreateOptionsMenu(menu);
302525e8ad321967b3f4b15cadf63efb3deafc216abPaul Westbrook        getMenuInflater().inflate(R.menu.settings_menu, menu);
303dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
304dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        mFeedbackMenuItem = menu.findItem(R.id.feedback_menu_item);
30597874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler        return true;
30697874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler    }
30797874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler
30897874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler    @Override
309dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    public boolean onPrepareOptionsMenu(Menu menu) {
310dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        super.onPrepareOptionsMenu(menu);
311dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
312dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        if (mFeedbackMenuItem != null) {
313dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook            // We only want to enable the feedback menu item, if there is a valid feedback uri
314dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook            mFeedbackMenuItem.setVisible(!Uri.EMPTY.equals(mFeedbackUri));
315dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        }
316dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        return true;
317dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    }
318dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
319dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
320dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    @Override
32197874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler    public boolean onOptionsItemSelected(MenuItem item) {
32297874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler        switch (item.getItemId()) {
32338089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki            case android.R.id.home:
32438089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                // The app icon on the action bar is pressed.  Just emulate a back press.
32538089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                // TODO: this should navigate to the main screen, even if a sub-setting is open.
32638089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                // But we shouldn't just finish(), as we want to show "discard changes?" dialog
32738089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                // when necessary.
32838089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                onBackPressed();
32938089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                break;
3306cf15e66bc46d211882fe903ec55fe748fc87bfcTony Mantler            case R.id.add_new_account:
3316cf15e66bc46d211882fe903ec55fe748fc87bfcTony Mantler                onAddNewAccount();
3326cf15e66bc46d211882fe903ec55fe748fc87bfcTony Mantler                break;
33338f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook            case R.id.feedback_menu_item:
334dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook                Utils.sendFeedback(this, mFeedbackUri, false /* reportingProblem */);
33538f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook                break;
33697874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler            default:
33797874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler                return super.onOptionsItemSelected(item);
338b387560384d38e3280090176a0f3b2cf8b1f9ab5Andrew Stadler        }
33997874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler        return true;
340b387560384d38e3280090176a0f3b2cf8b1f9ab5Andrew Stadler    }
341b387560384d38e3280090176a0f3b2cf8b1f9ab5Andrew Stadler
34215b06c208082c41542e1b1a323a8e4bd2d2d5d9fMartin Hibdon    public boolean isValidFragment(String fragmentName) {
34315b06c208082c41542e1b1a323a8e4bd2d2d5d9fMartin Hibdon        // We need to make sure that a fragment about to be attached is valid. This corrects
34415b06c208082c41542e1b1a323a8e4bd2d2d5d9fMartin Hibdon        // a security vulnerability.
34515b06c208082c41542e1b1a323a8e4bd2d2d5d9fMartin Hibdon        return (TextUtils.equals(AccountSettingsFragment.class.getName(), fragmentName) ||
34678d168c19d9079512bcc769dc1c9bb1a8d013df1Martin Hibdon                TextUtils.equals(GeneralPreferences.class.getName(), fragmentName) ||
3470dffe3afd7a2fdfb394573aa0d8d06dd90e9fe12James Lemieux                TextUtils.equals(AccountSetupIncomingFragment.class.getName(), fragmentName) ||
3480c7ff00df4a74f92545650d3ee8bccdc42e5b94cMartin Hibdon                TextUtils.equals(AccountSettingsEditQuickResponsesFragment.class.getName(),
3490c7ff00df4a74f92545650d3ee8bccdc42e5b94cMartin Hibdon                        fragmentName) ||
3507b9f7ff76fd9812d7e3ae4dd42c1ba97b6e347e7Tony Mantler                TextUtils.equals(DebugFragment.class.getName(), fragmentName) ||
3517b9f7ff76fd9812d7e3ae4dd42c1ba97b6e347e7Tony Mantler                super.isValidFragment(fragmentName));
35215b06c208082c41542e1b1a323a8e4bd2d2d5d9fMartin Hibdon    }
35315b06c208082c41542e1b1a323a8e4bd2d2d5d9fMartin Hibdon
3543955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    @Override
3553955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,
3563955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            int titleRes, int shortTitleRes) {
35726cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        final Intent intent = super.onBuildStartFragmentIntent(
3583955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                fragmentName, args, titleRes, shortTitleRes);
3593955f6794f23c1380749d4470b5f2264d2109adcBen Komalo
3603955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        // When opening a sub-settings page (e.g. account specific page), see if we want to modify
3613955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        // the activity title.
3623955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        String title = AccountSettingsFragment.getTitleFromArgs(args);
3633955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        if ((titleRes == 0) && (title != null)) {
36426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            intent.putExtra(EXTRA_TITLE, title);
3653955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        }
36626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        return intent;
3673955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    }
3683955f6794f23c1380749d4470b5f2264d2109adcBen Komalo
3699c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    /**
370c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy     * Any time we exit via this pathway, and we are showing a server settings fragment,
371c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy     * we put up the exit-save-changes dialog.  This will work for the following cases:
372983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Cancel button
373983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Back button
374983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Up arrow in application icon
375983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     * It will *not* apply in the following cases:
376983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Click the parent breadcrumb - need to find a hook for this
377983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Click in the header list (e.g. another account) - handled elsewhere
378983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     */
379983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler    @Override
380983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler    public void onBackPressed() {
381c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        final AccountServerBaseFragment accountServerFragment = getAccountServerFragment();
382c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        if (accountServerFragment != null) {
383c83366c88770f336a8e9976af42389c616de0b62Tony Mantler            if (accountServerFragment.haveSettingsChanged()) {
384c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                UnsavedChangesDialogFragment dialogFragment =
3853955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                        UnsavedChangesDialogFragment.newInstanceForBack();
386c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                dialogFragment.show(getFragmentManager(), UnsavedChangesDialogFragment.TAG);
387c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                return; // Prevent "back" from being handled
388c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            }
389c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        }
390983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler        super.onBackPressed();
391983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler    }
392983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler
3939195a1202483053606f43e871915a5405e955306Martin Hibdon
394f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    private void launchMailboxSettings(Intent intent) {
39526cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        final Folder folder = intent.getParcelableExtra(EditSettingsExtras.EXTRA_FOLDER);
396f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
397f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        // TODO: determine from the account if we should navigate to the mailbox settings.
398f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        // See bug 6242668
399f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
400f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        // Get the mailbox id from the folder
401281c6365fb95037ca284dd8c910538639e8b3dcbScott Kennedy        final long mailboxId =
402281c6365fb95037ca284dd8c910538639e8b3dcbScott Kennedy                Long.parseLong(folder.folderUri.fullUri.getPathSegments().get(1));
403f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
404f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        MailboxSettings.start(this, mailboxId);
405f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        finish();
40603cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank    }
40703cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank
40857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private void enableDebugMenu() {
40957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        mShowDebugMenu = true;
41057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        invalidateHeaders();
41157f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    }
41257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler
413a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    private void onAddNewAccount() {
41476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        final Intent setupIntent = AccountSetupFinal.actionNewAccountIntent(this);
41576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        startActivity(setupIntent);
416a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    }
417a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler
418a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    /**
4192ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * Start the async reload of the accounts list (if the headers are being displayed)
4202ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
4212ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    private void updateAccounts() {
4222ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        if (hasHeaders()) {
4232ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            Utility.cancelTaskInterrupt(mLoadAccountListTask);
424bd3e7777c58d4ffef41922b1e7e0d3ccbbb78ca3Makoto Onuki            mLoadAccountListTask = (LoadAccountListTask)
425bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki                    new LoadAccountListTask().executeOnExecutor(
426bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki                            AsyncTask.THREAD_POOL_EXECUTOR, mDeletingAccountId);
4272ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
4282ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
4292ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
4302ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
4312ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * Write the current header (accounts) array into the one provided by the PreferenceActivity.
432464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler     * Skip any headers that match mDeletingAccountId (this is a quick-hide algorithm while a
4339c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * background thread works on deleting the account).  Also sets mRequestedAccountHeader if
4349c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * we find the requested account (by id).
4352ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
4362ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    @Override
4372ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onBuildHeaders(List<Header> target) {
438464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        // Always add app preferences as first header
439464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        target.clear();
440464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        target.add(getAppPreferencesHeader());
4419c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
442464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        // Then add zero or more account headers as necessary
443464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        if (mAccountListHeaders != null) {
44426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final int headerCount = mAccountListHeaders.length;
445464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            for (int index = 0; index < headerCount; index++) {
446a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                Header header = mAccountListHeaders[index];
44704c4ae864fb0df88b9bc41e85a72062c12540d81Andy Stadler                if (header != null && header.id != HEADER_ID_UNDEFINED) {
448a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                    if (header.id != mDeletingAccountId) {
449a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                        target.add(header);
450a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                        if (header.id == mRequestedAccountId) {
451a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                            mRequestedAccountId = -1;
452a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                        }
4539c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler                    }
454464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler                }
455464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            }
456464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        }
4579c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
45857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        // finally, if debug header is enabled, show it
4592c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon        if (DEBUG_MENU_ALLOWED) {
4602c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon            if (mShowDebugMenu) {
4612c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon                // setup lightweight header for debugging
4622c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon                final Header debugHeader = new Header();
4632c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon                debugHeader.title = getText(R.string.debug_title);
4642c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon                debugHeader.summary = null;
4652c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon                debugHeader.iconRes = 0;
4662c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon                debugHeader.fragment = DebugFragment.class.getCanonicalName();
4672c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon                debugHeader.fragmentArguments = null;
4682c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon                target.add(debugHeader);
4692c26bb3b09700ce2531eedbe66d389d21107a416Martin Hibdon            }
47057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        }
4711a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
4721a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // Save for later use (see forceSwitch)
4731a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        mGeneratedHeaders = target;
474464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    }
475464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler
476464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    /**
477464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler     * Generate and return the first header, for app preferences
478464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler     */
479464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    private Header getAppPreferencesHeader() {
4802ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        // Set up fixed header for general settings
4812ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        if (mAppPreferencesHeader == null) {
4822ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader = new Header();
4832ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader.title = getText(R.string.header_label_general_preferences);
4842ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader.summary = null;
4852ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader.iconRes = 0;
4867b9f7ff76fd9812d7e3ae4dd42c1ba97b6e347e7Tony Mantler            mAppPreferencesHeader.fragment = GeneralPreferences.class.getName();
4872ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader.fragmentArguments = null;
4882ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
489464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        return mAppPreferencesHeader;
490464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    }
491464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler
492464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    /**
4932ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * This AsyncTask reads the accounts list and generates the headers.  When the headers are
4942ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * ready, we'll trigger PreferenceActivity to refresh the account list with them.
4952ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     *
49604c4ae864fb0df88b9bc41e85a72062c12540d81Andy Stadler     * The array generated and stored in mAccountListHeaders may be sparse so any readers should
49704c4ae864fb0df88b9bc41e85a72062c12540d81Andy Stadler     * check for and skip over null entries, and should not assume array length is # of accounts.
49804c4ae864fb0df88b9bc41e85a72062c12540d81Andy Stadler     *
4992ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * TODO: Smaller projection
5002ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * TODO: Convert to Loader
501a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler     * TODO: Write a test, including operation of deletingAccountId param
5022ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
503464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    private class LoadAccountListTask extends AsyncTask<Long, Void, Object[]> {
5042ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5052ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        @Override
506464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        protected Object[] doInBackground(Long... params) {
507a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            Header[] result = null;
508464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            Boolean deletingAccountFound = false;
50926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final long deletingAccountId = params[0];
5102ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5112ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            Cursor c = getContentResolver().query(
512f5418f1f93b02e7fab9f15eb201800b65510998eMarc Blank                    Account.CONTENT_URI,
513f5418f1f93b02e7fab9f15eb201800b65510998eMarc Blank                    Account.CONTENT_PROJECTION, null, null, null);
5142ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            try {
5152ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                int index = 0;
51626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                result = new Header[c.getCount()];
5172ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5182ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                while (c.moveToNext()) {
51926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                    final long accountId = c.getLong(Account.CONTENT_ID_COLUMN);
520a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler                    if (accountId == deletingAccountId) {
521464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler                        deletingAccountFound = true;
522a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler                        continue;
523a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler                    }
52426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                    final String name = c.getString(Account.CONTENT_DISPLAY_NAME_COLUMN);
52526cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                    final String email = c.getString(Account.CONTENT_EMAIL_ADDRESS_COLUMN);
52626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                    final Header newHeader = new Header();
527a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                    newHeader.id = accountId;
5283955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                    newHeader.title = name;
5293955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                    newHeader.summary = email;
530a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                    newHeader.fragment = AccountSettingsFragment.class.getCanonicalName();
5313955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                    newHeader.fragmentArguments =
5323955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                            AccountSettingsFragment.buildArguments(accountId, email);
533a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn
5342ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                    result[index++] = newHeader;
5352ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                }
5362ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            } finally {
5372ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                if (c != null) {
5382ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                    c.close();
5392ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                }
5402ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            }
541464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            return new Object[] { result, deletingAccountFound };
5422ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
5432ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5442ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        @Override
545464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        protected void onPostExecute(Object[] result) {
5462866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            if (isCancelled() || result == null) return;
547464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            // Extract the results
54826cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final Header[] headers = (Header[]) result[0];
54926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final boolean deletingAccountFound = (Boolean) result[1];
550a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            // report the settings
5512ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAccountListHeaders = headers;
5522866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            invalidateHeaders();
553464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            if (!deletingAccountFound) {
554464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler                mDeletingAccountId = -1;
555464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            }
5562ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
5572ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
5582ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5592ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
5602ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * Called when the user selects an item in the header list.  Handles save-data cases as needed
5612ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     *
5622ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * @param header The header that was selected.
5632ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * @param position The header's position in the list.
5642ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
5652ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    @Override
5662ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onHeaderClick(Header header, int position) {
5671a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // special case when exiting the server settings fragments
568c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        final AccountServerBaseFragment accountServerFragment = getAccountServerFragment();
569c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        if ((accountServerFragment != null) && accountServerFragment.haveSettingsChanged()) {
57026cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            UnsavedChangesDialogFragment dialogFragment =
57126cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                UnsavedChangesDialogFragment.newInstanceForHeader(position);
57226cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            dialogFragment.show(getFragmentManager(), UnsavedChangesDialogFragment.TAG);
57326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            return;
5741a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
5751a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
5761a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // Secret keys:  Click 10x to enable debug settings
57757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        if (position == 0) {
57857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            mNumGeneralHeaderClicked++;
57957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            if (mNumGeneralHeaderClicked == 10) {
58057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler                enableDebugMenu();
58157f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            }
58257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        } else {
58357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            mNumGeneralHeaderClicked = 0;
58457f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        }
5851a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
5861a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // Process header click normally
5872ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        super.onHeaderClick(header, position);
5882ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
5892ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5902ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
5911a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * Switch to a specific header without checking for server settings fragments as done
5921a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * in {@link #onHeaderClick(Header, int)}.  Called after we interrupted a header switch
5931a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * with a dialog, and the user OK'd it.
5941a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     */
595c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy    private void forceSwitchHeader(int position) {
596c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        // Ensure the UI visually shows the correct header selected
597c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        setSelection(position);
59826cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        switchToHeader(mGeneratedHeaders.get(position));
599c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy    }
600c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy
601c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy    /**
602c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy     * Forcefully go backward in the stack. This may potentially discard unsaved settings.
603c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy     */
604c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy    private void forceBack() {
605294593c5f592f4eec6994909cca60450936a0812Tony Mantler        super.onBackPressed();
6061a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    }
6071a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
6083955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    @Override
6093955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    public void onAttachFragment(Fragment f) {
6103955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        super.onAttachFragment(f);
6113955f6794f23c1380749d4470b5f2264d2109adcBen Komalo
6122ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        if (f instanceof AccountSettingsFragment) {
61326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final AccountSettingsFragment asf = (AccountSettingsFragment) f;
61491ad26315a8769f92af469b06e24033ffd9e6cafTony Mantler            mAccountSettingsFragment = asf;
6152ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            asf.setCallback(mAccountSettingsFragmentCallback);
616c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        } else if (f instanceof AccountServerBaseFragment) {
61791ad26315a8769f92af469b06e24033ffd9e6cafTony Mantler            mAccountServerFragment = (AccountServerBaseFragment) f;
618c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        } else {
6193955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            // Possibly uninteresting fragment, such as a dialog.
6203955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            return;
6211a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
6221a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // When we're changing fragments, enable/disable the add account button
62372a24f12a2a0a48528cf0f826397e2348fe8ace2Ben Komalo        invalidateOptionsMenu();
6242ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
6252ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
626c83366c88770f336a8e9976af42389c616de0b62Tony Mantler    @VisibleForTesting
627c83366c88770f336a8e9976af42389c616de0b62Tony Mantler    protected AccountSettingsFragment getSettingsFragment() {
62834c2e1619d47d8140efd212c7bb037b935eb5d18Tony Mantler        return mAccountSettingsFragment != null && mAccountSettingsFragment.isAdded() ?
62934c2e1619d47d8140efd212c7bb037b935eb5d18Tony Mantler                mAccountSettingsFragment : null;
630c83366c88770f336a8e9976af42389c616de0b62Tony Mantler    }
631c83366c88770f336a8e9976af42389c616de0b62Tony Mantler
632c83366c88770f336a8e9976af42389c616de0b62Tony Mantler    protected AccountServerBaseFragment getAccountServerFragment() {
63334c2e1619d47d8140efd212c7bb037b935eb5d18Tony Mantler        return mAccountServerFragment != null && mAccountServerFragment.isAdded() ?
63434c2e1619d47d8140efd212c7bb037b935eb5d18Tony Mantler                mAccountServerFragment : null;
63576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
63676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
6372ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
6382ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * Callbacks for AccountSettingsFragment
6392ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
6402ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    private class AccountSettingsFragmentCallback implements AccountSettingsFragment.Callback {
6412866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo        @Override
642062f27fa370564d494260889c8141df50c07572fTony Mantler        public void onSettingsChanged(long accountId, String preference, Object value) {
643062f27fa370564d494260889c8141df50c07572fTony Mantler            AccountSettings.this.onSettingsChanged(accountId, preference, value);
64434704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy        }
6452866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo        @Override
646c6953b77552d4cb71776cf0537dc226029381628Tony Mantler        public void onEditQuickResponses(com.android.mail.providers.Account account) {
6475a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo            AccountSettings.this.onEditQuickResponses(account);
6485a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        }
6495a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        @Override
6502ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        public void onIncomingSettings(Account account) {
6512866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            AccountSettings.this.onIncomingSettings(account);
6522ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
6532866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo        @Override
6542ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        public void onOutgoingSettings(Account account) {
6552866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            AccountSettings.this.onOutgoingSettings(account);
6562ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
6572866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo        @Override
6582ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        public void abandonEdit() {
6592ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            finish();
6602ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
6612ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
6622ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
66376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
664ae980cd685a867b3fecfd38c876fd18d98b7c86bTony Mantler    public void onNextButton() {}
66576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
6662ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
66776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler     * Save process is done, dismiss the fragment.
6681a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     */
66976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
67076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public void onAccountServerSaveComplete() {
67128dd431c2377655775a1f07e4365776ccc1b03a7Tony Mantler        super.onBackPressed();
67276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
673fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler
67476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
67576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public void onAccountServerUIComplete(int checkMode) {
67676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        Fragment checkerDialog = CheckSettingsProgressDialogFragment.newInstance(checkMode);
67776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        Fragment checkerFragment = AccountCheckSettingsFragment.newInstance(checkMode);
67876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        getFragmentManager().beginTransaction()
67976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                .add(checkerDialog, CheckSettingsProgressDialogFragment.TAG)
68076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                .add(checkerFragment, AccountCheckSettingsFragment.TAG)
68176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                .commit();
68276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
68376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
6841c594b8050abda5c1859f80cb3a7cea690c21632Tony Mantler    @Override
6851c594b8050abda5c1859f80cb3a7cea690c21632Tony Mantler    public void onCheckSettingsProgressDialogCancel() {
6861c594b8050abda5c1859f80cb3a7cea690c21632Tony Mantler        dismissCheckSettingsFragment();
6871c594b8050abda5c1859f80cb3a7cea690c21632Tony Mantler    }
6881c594b8050abda5c1859f80cb3a7cea690c21632Tony Mantler
68976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    /**
69076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler     * After verifying a new server configuration as OK, we return here and continue. This kicks
69176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler     * off the save process.
69276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler     */
69376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
69476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public void onCheckSettingsComplete() {
69576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        dismissCheckSettingsFragment();
696c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        final AccountServerBaseFragment f = getAccountServerFragment();
697c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        if (f != null) {
698c83366c88770f336a8e9976af42389c616de0b62Tony Mantler            f.saveSettings();
699c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        }
70076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
70176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
70276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
70376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public void onCheckSettingsSecurityRequired(String hostName) {
70476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        dismissCheckSettingsFragment();
70576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        SecurityRequiredDialogFragment.newInstance(hostName)
70676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                .show(getFragmentManager(), SecurityRequiredDialogFragment.TAG);
70776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
70876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
70976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
71076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public void onCheckSettingsError(int reason, String message) {
71176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        dismissCheckSettingsFragment();
71276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        CheckSettingsErrorDialogFragment.newInstance(reason, message)
71376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                .show(getFragmentManager(), CheckSettingsErrorDialogFragment.TAG);
71476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
71576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
71676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
71776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public void onCheckSettingsAutoDiscoverComplete(int result) {
71876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        throw new IllegalStateException();
71976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
72076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
72176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    private void dismissCheckSettingsFragment() {
72276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        final Fragment f =
72376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                getFragmentManager().findFragmentByTag(AccountCheckSettingsFragment.TAG);
72476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        final Fragment d =
72576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                getFragmentManager().findFragmentByTag(CheckSettingsProgressDialogFragment.TAG);
72676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        getFragmentManager().beginTransaction()
72776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                .remove(f)
72876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                .remove(d)
72976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                .commit();
73076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
73176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
73276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
73376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public void onSecurityRequiredDialogResult(boolean ok) {
73476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        if (ok) {
735c83366c88770f336a8e9976af42389c616de0b62Tony Mantler            final AccountServerBaseFragment f = getAccountServerFragment();
736c83366c88770f336a8e9976af42389c616de0b62Tony Mantler            if (f != null) {
737c83366c88770f336a8e9976af42389c616de0b62Tony Mantler                f.saveSettings();
738c83366c88770f336a8e9976af42389c616de0b62Tony Mantler            }
739fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler        }
74076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        // else just stay here
74176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
742fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler
74376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
74476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public void onCheckSettingsErrorDialogEditSettings() {
74576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        // Just stay here
74676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    }
74776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
74876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    @Override
74976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public void onCheckSettingsErrorDialogEditCertificate() {
750c83366c88770f336a8e9976af42389c616de0b62Tony Mantler        final AccountServerBaseFragment f = getAccountServerFragment();
75176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        if (f instanceof AccountSetupIncomingFragment) {
75276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            AccountSetupIncomingFragment asif = (AccountSetupIncomingFragment) f;
75376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            asif.onCertificateRequested();
75476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        } else {
75576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            LogUtils.wtf(LogUtils.TAG, "Tried to change cert on non-incoming screen?");
7561a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
7571a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    }
7581a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
7591a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    /**
76034704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy     * Some of the settings have changed. Update internal state as necessary.
76134704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy     */
762062f27fa370564d494260889c8141df50c07572fTony Mantler    public void onSettingsChanged(long accountId, String preference, Object value) {
76334704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy        if (AccountSettingsFragment.PREFERENCE_DESCRIPTION.equals(preference)) {
76434704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy            for (Header header : mAccountListHeaders) {
765062f27fa370564d494260889c8141df50c07572fTony Mantler                if (header.id == accountId) {
76634704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    // Manually tweak the header title. We cannot rebuild the header list from
76734704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    // an account cursor as the account database has not been saved yet.
76834704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    header.title = value.toString();
76934704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    invalidateHeaders();
77034704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    break;
77134704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                }
77234704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy            }
77334704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy        }
77434704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy    }
77534704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy
77634704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy    /**
7775a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo     * Dispatch to edit quick responses.
7785a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo     */
779c6953b77552d4cb71776cf0537dc226029381628Tony Mantler    public void onEditQuickResponses(com.android.mail.providers.Account account) {
7805a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        try {
78126cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final Bundle args = new Bundle(1);
7825a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo            args.putParcelable(QUICK_RESPONSE_ACCOUNT_KEY, account);
7835a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo            startPreferencePanel(AccountSettingsEditQuickResponsesFragment.class.getName(), args,
7845a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo                    R.string.account_settings_edit_quick_responses_label, null, null, 0);
7855a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        } catch (Exception e) {
786560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy            LogUtils.d(Logging.LOG_TAG, "Error while trying to invoke edit quick responses.", e);
7875a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        }
7885a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo    }
7895a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo
7905a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo    /**
7911a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * Dispatch to edit incoming settings.
7922ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
7932ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onIncomingSettings(Account account) {
7942ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        try {
7959c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler            mSetupData = new SetupDataFragment(SetupDataFragment.FLOW_MODE_EDIT, account);
79676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            final Fragment f = AccountSetupIncomingFragment.newInstance(true);
79726cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            // Use startPreferenceFragment here because we need to keep this activity instance
79826cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            startPreferenceFragment(f, true);
7992ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        } catch (Exception e) {
800560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy            LogUtils.d(Logging.LOG_TAG, "Error while trying to invoke store settings.", e);
8012ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
8022ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
8032ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
8042ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
8051a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * Dispatch to edit outgoing settings.
8062ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
8072ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onOutgoingSettings(Account account) {
8082ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        try {
8099c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler            mSetupData = new SetupDataFragment(SetupDataFragment.FLOW_MODE_EDIT, account);
81076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            final Fragment f = AccountSetupOutgoingFragment.newInstance(true);
81126cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            // Use startPreferenceFragment here because we need to keep this activity instance
81226cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            startPreferenceFragment(f, true);
8132ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        } catch (Exception e) {
814560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy            LogUtils.d(Logging.LOG_TAG, "Error while trying to invoke sender settings.", e);
8152ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
8162ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
8172ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
8182ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
819a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler     * Delete the selected account
820a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler     */
821f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    public void deleteAccount(final Account account) {
822464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        // Kick off the work to actually delete the account
823f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        new Thread(new Runnable() {
824f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
825f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            public void run() {
82626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                final Uri uri = EmailProvider.uiUri("uiaccount", account.mId);
827f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                getContentResolver().delete(uri, null, null);
828f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            }}).start();
829464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler
830f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        // TODO: Remove ui glue for unified
831464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        // Then update the UI as appropriate:
832a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler        // If single pane, return to the header list.  If multi, rebuild header list
83372a24f12a2a0a48528cf0f826397e2348fe8ace2Ben Komalo        if (onIsMultiPane()) {
83426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final Header prefsHeader = getAppPreferencesHeader();
835464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            this.switchToHeader(prefsHeader.fragment, prefsHeader.fragmentArguments);
836a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            mDeletingAccountId = account.mId;
83709aae75f4e37c3197c6f8d3f046b15c71534d1f0Andy Stadler            updateAccounts();
838a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler        } else {
839a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            // We should only be calling this while showing AccountSettingsFragment,
840a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            // so a finish() should bring us back to headers.  No point hiding the deleted account.
841a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            finish();
842a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler        }
843a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    }
844a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler
845a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    /**
8469c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * This AsyncTask looks up an account based on its email address (which is what we get from
8479c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * the Account Manager).  When the account id is determined, we refresh the header list,
8489c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * which will select the preferences for that account.
8499c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     */
8509c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    private class GetAccountIdFromAccountTask extends AsyncTask<Intent, Void, Long> {
8519c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
8529c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        @Override
8539c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        protected Long doInBackground(Intent... params) {
85426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final Intent intent = params[0];
8559c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler            android.accounts.Account acct =
85626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                intent.getParcelableExtra(EXTRA_ACCOUNT_MANAGER_ACCOUNT);
8572866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            return Utility.getFirstRowLong(AccountSettings.this, Account.CONTENT_URI,
8582866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo                    Account.ID_PROJECTION, SELECTION_ACCOUNT_EMAIL_ADDRESS,
8592866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo                    new String[] {acct.name}, null, Account.ID_PROJECTION_COLUMN, -1L);
8609c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        }
8619c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
8629c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        @Override
8639c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        protected void onPostExecute(Long accountId) {
8649c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler            if (accountId != -1 && !isCancelled()) {
8659c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler                mRequestedAccountId = accountId;
8662866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo                invalidateHeaders();
8679c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler            }
8689c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        }
8699c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    }
8709c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
8719c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    /**
8721a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * Dialog fragment to show "exit with unsaved changes?" dialog
8731a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     */
8746f3a94cca18c67f19c093f3178476055e60370d3Tony Mantler    public static class UnsavedChangesDialogFragment extends DialogFragment {
875f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        final static String TAG = "UnsavedChangesDialogFragment";
8761a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
8771a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // Argument bundle keys
878c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        private final static String BUNDLE_KEY_HEADER = "UnsavedChangesDialogFragment.Header";
879c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        private final static String BUNDLE_KEY_BACK = "UnsavedChangesDialogFragment.Back";
8801a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
8811a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        /**
882c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         * Creates a save changes dialog when the user selects a new header
883c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         * @param position The new header index to make active if the user accepts the dialog. This
884c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         * must be a valid header index although there is no error checking.
8851a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler         */
886c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        public static UnsavedChangesDialogFragment newInstanceForHeader(int position) {
88726cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final UnsavedChangesDialogFragment f = new UnsavedChangesDialogFragment();
88826cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final Bundle b = new Bundle(1);
889c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            b.putInt(BUNDLE_KEY_HEADER, position);
8901a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            f.setArguments(b);
8911a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            return f;
8921a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
8931a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
894c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        /**
895c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         * Creates a save changes dialog when the user navigates "back".
8962866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo         * {@link #onBackPressed()} defines in which case this may be triggered.
897c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         */
898c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        public static UnsavedChangesDialogFragment newInstanceForBack() {
89926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final UnsavedChangesDialogFragment f = new UnsavedChangesDialogFragment();
90026cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final Bundle b = new Bundle(1);
901c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            b.putBoolean(BUNDLE_KEY_BACK, true);
902c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            f.setArguments(b);
903c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            return f;
904c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        }
905c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy
906c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        // Force usage of newInstance()
9077985b43ab7310f76c170266da346f993d2f86051Paul Westbrook        public UnsavedChangesDialogFragment() {}
908c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy
9091a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        @Override
9101a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        public Dialog onCreateDialog(Bundle savedInstanceState) {
9112866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            final AccountSettings activity = (AccountSettings) getActivity();
912c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            final int position = getArguments().getInt(BUNDLE_KEY_HEADER);
913c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            final boolean isBack = getArguments().getBoolean(BUNDLE_KEY_BACK);
9141a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
9151a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            return new AlertDialog.Builder(activity)
91649518bb3605d6c8e3cc4801c452e4f8f63220f44Makoto Onuki                .setIconAttribute(android.R.attr.alertDialogIcon)
9171a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .setTitle(android.R.string.dialog_alert_title)
9181a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .setMessage(R.string.account_settings_exit_server_settings)
9191a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .setPositiveButton(
920254dde761f1cfed028ba258ec56f6b239eb2fb02Tony Mantler                        android.R.string.ok,
9211a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                        new DialogInterface.OnClickListener() {
922f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                            @Override
9231a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                            public void onClick(DialogInterface dialog, int which) {
924c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                if (isBack) {
925c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                    activity.forceBack();
926c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                } else {
927c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                    activity.forceSwitchHeader(position);
928c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                }
9291a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                                dismiss();
9301a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                            }
9311a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                        })
9321a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .setNegativeButton(
933254dde761f1cfed028ba258ec56f6b239eb2fb02Tony Mantler                        activity.getString(android.R.string.cancel), null)
9341a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .create();
9351a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
9361a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    }
9371a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
938f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler    /**
939f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * Dialog briefly shown in some cases, to indicate the user that login failed.  If the user
940f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * clicks OK, we simply dismiss the dialog, leaving the user in the account settings for
941f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * that account;  If the user clicks "cancel", we exit account settings.
942f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     */
943f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler    public static class LoginWarningDialog extends DialogFragment
944f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            implements DialogInterface.OnClickListener {
945f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name";
946dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank        private String mReason;
947f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler
9487985b43ab7310f76c170266da346f993d2f86051Paul Westbrook        // Public no-args constructor needed for fragment re-instantiation
9497985b43ab7310f76c170266da346f993d2f86051Paul Westbrook        public LoginWarningDialog() {}
9507985b43ab7310f76c170266da346f993d2f86051Paul Westbrook
951f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        /**
952f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler         * Create a new dialog.
953f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler         */
954dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank        public static LoginWarningDialog newInstance(String accountName, String reason) {
955f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final LoginWarningDialog dialog = new LoginWarningDialog();
95626cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler            final Bundle b = new Bundle(1);
957f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName);
958f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            dialog.setArguments(b);
959dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            dialog.mReason = reason;
960f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            return dialog;
961f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        }
962f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler
963f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        @Override
964f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        public Dialog onCreateDialog(Bundle savedInstanceState) {
965f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME);
966f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler
967f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final Context context = getActivity();
968f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final Resources res = context.getResources();
969f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final AlertDialog.Builder b = new AlertDialog.Builder(context);
970f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            b.setTitle(R.string.account_settings_login_dialog_title);
971f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            b.setIconAttribute(android.R.attr.alertDialogIcon);
972dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            if (mReason != null) {
9731bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                final TextView message = new TextView(context);
97426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                final String alert = res.getString(
9751bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                        R.string.account_settings_login_dialog_reason_fmt, accountName, mReason);
9761bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                SpannableString spannableAlertString = new SpannableString(alert);
9771bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                Linkify.addLinks(spannableAlertString, Linkify.WEB_URLS);
9781bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                message.setText(spannableAlertString);
9791bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                // There must be a better way than specifying size/padding this way
9801bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                // It does work and look right, though
98126cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                final int textSize = res.getDimensionPixelSize(R.dimen.dialog_text_size);
9821bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                message.setTextSize(textSize);
98326cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                final int paddingLeft = res.getDimensionPixelSize(R.dimen.dialog_padding_left);
98426cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                final int paddingOther = res.getDimensionPixelSize(R.dimen.dialog_padding_other);
9851bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                message.setPadding(paddingLeft, paddingOther, paddingOther, paddingOther);
9861bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                message.setMovementMethod(LinkMovementMethod.getInstance());
9871bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                b.setView(message);
988dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            } else {
989dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                b.setMessage(res.getString(R.string.account_settings_login_dialog_content_fmt,
990dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                        accountName));
991dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            }
992254dde761f1cfed028ba258ec56f6b239eb2fb02Tony Mantler            b.setPositiveButton(android.R.string.ok, this);
993254dde761f1cfed028ba258ec56f6b239eb2fb02Tony Mantler            b.setNegativeButton(android.R.string.cancel, this);
994f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            return b.create();
995f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        }
996f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler
997f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        @Override
998f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        public void onClick(DialogInterface dialog, int which) {
999f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            dismiss();
1000f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            if (which == DialogInterface.BUTTON_NEGATIVE) {
1001f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                getActivity().finish();
1002f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            }
1003f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        }
1004f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler    }
100538f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook
100638f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook    @Override
10079c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler    public SetupDataFragment getSetupData() {
100826cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler        return mSetupData;
100926cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler    }
10102ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler}
1011