EmailPreferenceActivity.java revision dbb8b75a4bd201f8472a511ef77ca2ed05bd808b
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;
202ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.app.Activity;
211a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.app.AlertDialog;
221a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.app.Dialog;
231a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.app.DialogFragment;
242ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.app.Fragment;
25464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadlerimport android.content.Context;
261a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadlerimport android.content.DialogInterface;
272ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.content.Intent;
28f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadlerimport android.content.res.Resources;
29b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komaloimport android.database.ContentObserver;
302ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.database.Cursor;
31308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onukiimport android.net.Uri;
322ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.os.AsyncTask;
332ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.os.Bundle;
342ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport android.preference.PreferenceActivity;
351bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blankimport android.text.SpannableString;
361bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blankimport android.text.method.LinkMovementMethod;
371bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blankimport android.text.util.Linkify;
3857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadlerimport android.view.KeyEvent;
3997874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadlerimport android.view.Menu;
4097874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadlerimport android.view.MenuItem;
411bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blankimport android.widget.TextView;
422ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
4335b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.email.R;
4435b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.email.activity.ActivityHelper;
4535b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.email.mail.Sender;
46f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.email.provider.EmailProvider;
4735b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.Logging;
4835b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.provider.Account;
4935b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.provider.EmailContent.AccountColumns;
5074c79a50432fcbf127fbfeadc1a461263ea92135Marc Blankimport com.android.emailcommon.service.ServiceProxy;
510e6a521747970d5427f10c25cdc070d2341dc93aBen Komaloimport com.android.emailcommon.utility.IntentUtilities;
5235b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.utility.Utility;
53f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.mail.providers.Folder;
54f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blankimport com.android.mail.providers.UIProvider.EditSettingsExtras;
5538f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrookimport com.android.mail.ui.FeedbackEnabledActivity;
56560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedyimport com.android.mail.utils.LogUtils;
5738f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrookimport com.android.mail.utils.Utils;
5835b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blank
592ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadlerimport java.util.List;
602ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
612ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler/**
62fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * Handles account preferences, using multi-pane arrangement when possible.
63fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *
64fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler * This activity uses the following fragments:
65fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *   AccountSettingsFragment
66f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank *   Account{Incoming/Outgoing}Fragment
67fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *   AccountCheckSettingsFragment
68fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *   GeneralPreferences
69fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler *   DebugFragment
702ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler *
71464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler * TODO: Delete account - on single-pane view (phone UX) the account list doesn't update properly
72464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler * TODO: Handle dynamic changes to the account list (exit if necessary).  It probably makes
73464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler *       sense to use a loader for the accounts list, because it would provide better support for
74464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler *       dealing with accounts being added/deleted and triggering the header reload.
752ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler */
7638f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrookpublic class AccountSettings extends PreferenceActivity implements FeedbackEnabledActivity {
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";
89f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    public static final String EXTRA_NO_ACCOUNTS = "AccountSettings.no_account";
9057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler
919c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // Intent extras for launch directly from system account manager
929c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // NOTE: This string must match the one in res/xml/account_preferences.xml
9374c79a50432fcbf127fbfeadc1a461263ea92135Marc Blank    private static String ACTION_ACCOUNT_MANAGER_ENTRY;
949c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // NOTE: This constant should eventually be defined in android.accounts.Constants
959c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    private static final String EXTRA_ACCOUNT_MANAGER_ACCOUNT = "account";
969c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
975a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo    // Key for arguments bundle for QuickResponse editing
985a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo    private static final String QUICK_RESPONSE_ACCOUNT_KEY = "account";
995a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo
10057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    // Key codes used to open a debug settings fragment.
10157f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private static final int[] SECRET_KEY_CODES = {
10257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            KeyEvent.KEYCODE_D, KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_B, KeyEvent.KEYCODE_U,
10357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            KeyEvent.KEYCODE_G
10457f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            };
10557f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private int mSecretKeyCodeIndex = 0;
10657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler
1079c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // Support for account-by-name lookup
1089c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    private static final String SELECTION_ACCOUNT_EMAIL_ADDRESS =
1099c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        AccountColumns.EMAIL_ADDRESS + "=?";
1109c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
1119c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    // When the user taps "Email Preferences" 10 times in a row, we'll enable the debug settings.
11257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private int mNumGeneralHeaderClicked = 0;
1132ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
11451224176259b1b3126087c69814ccf652cb398b9Andrew Stadler    private long mRequestedAccountId;
115a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn    private Header[] mAccountListHeaders;
1162ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    private Header mAppPreferencesHeader;
1179c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    /* package */ Fragment mCurrentFragment;
118a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    private long mDeletingAccountId = -1;
11957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private boolean mShowDebugMenu;
1201a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    private List<Header> mGeneratedHeaders;
121dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    private Uri mFeedbackUri;
122dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    private MenuItem mFeedbackMenuItem;
1232ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1242ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    // Async Tasks
1252ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    private LoadAccountListTask mLoadAccountListTask;
1269c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    private GetAccountIdFromAccountTask mGetAccountIdFromAccountTask;
127b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo    private ContentObserver mAccountObserver;
1282ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1292ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    // Specific callbacks used by settings fragments
1301a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    private final AccountSettingsFragmentCallback mAccountSettingsFragmentCallback
1312ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            = new AccountSettingsFragmentCallback();
1321a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    private final AccountServerSettingsFragmentCallback mAccountServerSettingsFragmentCallback
1331a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            = new AccountServerSettingsFragmentCallback();
1342ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1352ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
1362ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * Display (and edit) settings for a specific account, or -1 for any/all accounts
1372ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
1382ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public static void actionSettings(Activity fromActivity, long accountId) {
1391b8e0fa23f6e9957f0b8753dd3f5b95d3f5d98eaScott Kennedy        fromActivity.startActivity(createAccountSettingsIntent(accountId, null, null));
1402ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
1412ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1422ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
143d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank     * Create and return an intent to display (and edit) settings for a specific account, or -1
144f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * for any/all accounts.  If an account name string is provided, a warning dialog will be
145f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * displayed as well.
146d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank     */
1471b8e0fa23f6e9957f0b8753dd3f5b95d3f5d98eaScott Kennedy    public static Intent createAccountSettingsIntent(long accountId,
148dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            String loginWarningAccountName, String loginWarningReason) {
149308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki        final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder("settings");
150308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki        IntentUtilities.setAccountId(b, accountId);
151308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki        Intent i = new Intent(Intent.ACTION_EDIT, b.build());
152308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki        if (loginWarningAccountName != null) {
153308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki            i.putExtra(EXTRA_LOGIN_WARNING_FOR_ACCOUNT, loginWarningAccountName);
154308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki        }
155dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank        if (loginWarningReason != null) {
156dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            i.putExtra(EXTRA_LOGIN_WARNING_REASON_FOR_ACCOUNT, loginWarningReason);
157dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank        }
158d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank        return i;
159d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank    }
160d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank
161d3e4f3ca7e43fb7ebaa140f93a44a1fb96a0577eMarc Blank    /**
16257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler     * Launch generic settings and pre-enable the debug preferences
1632ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
16457f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    public static void actionSettingsWithDebug(Context fromContext) {
1652866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo        Intent i = new Intent(fromContext, AccountSettings.class);
16657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
16757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        i.putExtra(EXTRA_ENABLE_DEBUG, true);
16857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        fromContext.startActivity(i);
16957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    }
1702ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
1712ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    @Override
1722ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onCreate(Bundle savedInstanceState) {
1732ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        super.onCreate(savedInstanceState);
174cd09545b87979fa6b4337f17b5a001f0ef7b5269Andrew Stadler        ActivityHelper.debugSetWindowFlags(this);
1752ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
176f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        final Intent i = getIntent();
177a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn        if (savedInstanceState == null) {
178a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            // If we are not restarting from a previous instance, we need to
179a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            // figure out the initial prefs to show.  (Otherwise, we want to
180a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            // continue showing whatever the user last selected.)
18174c79a50432fcbf127fbfeadc1a461263ea92135Marc Blank            if (ACTION_ACCOUNT_MANAGER_ENTRY == null) {
18274c79a50432fcbf127fbfeadc1a461263ea92135Marc Blank                ACTION_ACCOUNT_MANAGER_ENTRY =
18374c79a50432fcbf127fbfeadc1a461263ea92135Marc Blank                        ServiceProxy.getIntentStringForEmailPackage(this,
18474c79a50432fcbf127fbfeadc1a461263ea92135Marc Blank                                getString(R.string.intent_account_manager_entry));
18574c79a50432fcbf127fbfeadc1a461263ea92135Marc Blank            }
186a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            if (ACTION_ACCOUNT_MANAGER_ENTRY.equals(i.getAction())) {
187a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                // This case occurs if we're changing account settings from Settings -> Accounts
188a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                mGetAccountIdFromAccountTask =
189bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki                        (GetAccountIdFromAccountTask) new GetAccountIdFromAccountTask()
190bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki                        .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, i);
191f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            } else if (i.hasExtra(EditSettingsExtras.EXTRA_FOLDER)) {
192f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                launchMailboxSettings(i);
193f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                return;
194f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            } else if (i.hasExtra(EXTRA_NO_ACCOUNTS)) {
195f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                AccountSetupBasics.actionNewAccountWithResult(this);
196f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                finish();
197f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                return;
198a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            } else {
199f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                // Otherwise, we're called from within the Email app and look for our extras
200308ce9284793b597797994dfb1fb25155cbe0b20Makoto Onuki                mRequestedAccountId = IntentUtilities.getAccountIdFromIntent(i);
201f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                String loginWarningAccount = i.getStringExtra(EXTRA_LOGIN_WARNING_FOR_ACCOUNT);
202dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                String loginWarningReason =
203dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                        i.getStringExtra(EXTRA_LOGIN_WARNING_REASON_FOR_ACCOUNT);
204f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                if (loginWarningAccount != null) {
205f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                    // Show dialog (first time only - don't re-show on a rotation)
206dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                    LoginWarningDialog dialog =
207dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                            LoginWarningDialog.newInstance(loginWarningAccount, loginWarningReason);
208f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                    dialog.show(getFragmentManager(), "loginwarning");
209f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                }
210a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            }
2119c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        }
21257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        mShowDebugMenu = i.getBooleanExtra(EXTRA_ENABLE_DEBUG, false);
21338089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki
2143955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        String title = i.getStringExtra(EXTRA_TITLE);
2153955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        if (title != null) {
2163955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            setTitle(title);
2173955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        }
2183955f6794f23c1380749d4470b5f2264d2109adcBen Komalo
21938089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki        getActionBar().setDisplayOptions(
22038089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
221b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo
222b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        mAccountObserver = new ContentObserver(Utility.getMainThreadHandler()) {
223b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo            @Override
224b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo            public void onChange(boolean selfChange) {
225b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo                updateAccounts();
226b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo            }
227b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        };
228dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
229dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        mFeedbackUri = Utils.getValidUri(getString(R.string.email_feedback_uri));
2302ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
2312ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
2322ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    @Override
2332ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onResume() {
2342ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        super.onResume();
235b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        getContentResolver().registerContentObserver(Account.NOTIFIER_URI, true, mAccountObserver);
2362ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        updateAccounts();
2378ec0dcfe0d241cdac946a8c131472913c7349492Andy Stadler    }
2388ec0dcfe0d241cdac946a8c131472913c7349492Andy Stadler
2398ec0dcfe0d241cdac946a8c131472913c7349492Andy Stadler    @Override
240b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo    public void onPause() {
241b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        super.onPause();
242b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo        getContentResolver().unregisterContentObserver(mAccountObserver);
243b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo    }
244b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo
245b7d137bfb6b59b1a4da4b14eb6022ce0df7cf637Ben Komalo    @Override
2462ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    protected void onDestroy() {
2472ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        super.onDestroy();
2482ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        Utility.cancelTaskInterrupt(mLoadAccountListTask);
2492ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        mLoadAccountListTask = null;
2509c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        Utility.cancelTaskInterrupt(mGetAccountIdFromAccountTask);
2519c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        mGetAccountIdFromAccountTask = null;
2522ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
2532ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
2542ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
25557f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler     * Listen for secret sequence and, if heard, enable debug menu
25657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler     */
25757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    @Override
25857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    public boolean onKeyDown(int keyCode, KeyEvent event) {
25957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        if (event.getKeyCode() == SECRET_KEY_CODES[mSecretKeyCodeIndex]) {
26057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            mSecretKeyCodeIndex++;
26157f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            if (mSecretKeyCodeIndex == SECRET_KEY_CODES.length) {
26257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler                mSecretKeyCodeIndex = 0;
26357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler                enableDebugMenu();
26457f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            }
26557f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        } else {
26657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            mSecretKeyCodeIndex = 0;
26757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        }
26857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        return super.onKeyDown(keyCode, event);
26957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    }
27057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler
271b387560384d38e3280090176a0f3b2cf8b1f9ab5Andrew Stadler    @Override
27297874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler    public boolean onCreateOptionsMenu(Menu menu) {
27397874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler        super.onCreateOptionsMenu(menu);
274525e8ad321967b3f4b15cadf63efb3deafc216abPaul Westbrook        getMenuInflater().inflate(R.menu.settings_menu, menu);
275dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
276dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        mFeedbackMenuItem = menu.findItem(R.id.feedback_menu_item);
27797874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler        return true;
27897874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler    }
27997874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler
28097874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler    @Override
281dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    public boolean onPrepareOptionsMenu(Menu menu) {
282dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        super.onPrepareOptionsMenu(menu);
283dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
284dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        if (mFeedbackMenuItem != null) {
285dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook            // We only want to enable the feedback menu item, if there is a valid feedback uri
286dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook            mFeedbackMenuItem.setVisible(!Uri.EMPTY.equals(mFeedbackUri));
287dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        }
288dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook        return true;
289dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    }
290dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
291dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook
292dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook    @Override
29397874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler    public boolean onOptionsItemSelected(MenuItem item) {
29497874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler        switch (item.getItemId()) {
29538089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki            case android.R.id.home:
29638089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                // The app icon on the action bar is pressed.  Just emulate a back press.
29738089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                // TODO: this should navigate to the main screen, even if a sub-setting is open.
29838089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                // But we shouldn't just finish(), as we want to show "discard changes?" dialog
29938089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                // when necessary.
30038089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                onBackPressed();
30138089f6c4222ab56582899f1f228966c5ebf75e8Makoto Onuki                break;
30297874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler            case R.id.add_new_account:
30397874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler                onAddNewAccount();
30497874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler                break;
30538f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook            case R.id.feedback_menu_item:
306dbb8b75a4bd201f8472a511ef77ca2ed05bd808bPaul Westbrook                Utils.sendFeedback(this, mFeedbackUri, false /* reportingProblem */);
30738f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook                break;
30897874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler            default:
30997874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler                return super.onOptionsItemSelected(item);
310b387560384d38e3280090176a0f3b2cf8b1f9ab5Andrew Stadler        }
31197874770fc7cbe6a89a6ea706658fb42dff77a95Andy Stadler        return true;
312b387560384d38e3280090176a0f3b2cf8b1f9ab5Andrew Stadler    }
313b387560384d38e3280090176a0f3b2cf8b1f9ab5Andrew Stadler
3143955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    @Override
3153955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,
3163955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            int titleRes, int shortTitleRes) {
3173955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        Intent result = super.onBuildStartFragmentIntent(
3183955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                fragmentName, args, titleRes, shortTitleRes);
3193955f6794f23c1380749d4470b5f2264d2109adcBen Komalo
3203955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        // When opening a sub-settings page (e.g. account specific page), see if we want to modify
3213955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        // the activity title.
3223955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        String title = AccountSettingsFragment.getTitleFromArgs(args);
3233955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        if ((titleRes == 0) && (title != null)) {
3243955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            result.putExtra(EXTRA_TITLE, title);
3253955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        }
3263955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        return result;
3273955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    }
3283955f6794f23c1380749d4470b5f2264d2109adcBen Komalo
3299c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    /**
330c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy     * Any time we exit via this pathway, and we are showing a server settings fragment,
331c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy     * we put up the exit-save-changes dialog.  This will work for the following cases:
332983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Cancel button
333983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Back button
334983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Up arrow in application icon
335983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     * It will *not* apply in the following cases:
336983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Click the parent breadcrumb - need to find a hook for this
337983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     *   Click in the header list (e.g. another account) - handled elsewhere
338983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler     */
339983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler    @Override
340983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler    public void onBackPressed() {
341c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        if (mCurrentFragment instanceof AccountServerBaseFragment) {
3423955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            boolean changed = ((AccountServerBaseFragment) mCurrentFragment).haveSettingsChanged();
343c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            if (changed) {
344c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                UnsavedChangesDialogFragment dialogFragment =
3453955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                        UnsavedChangesDialogFragment.newInstanceForBack();
346c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                dialogFragment.show(getFragmentManager(), UnsavedChangesDialogFragment.TAG);
347c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                return; // Prevent "back" from being handled
348c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            }
349c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        }
350983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler        super.onBackPressed();
351983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler    }
352983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler
353f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    private void launchMailboxSettings(Intent intent) {
354f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        final Folder folder = (Folder)intent.getParcelableExtra(EditSettingsExtras.EXTRA_FOLDER);
355f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
356f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        // TODO: determine from the account if we should navigate to the mailbox settings.
357f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        // See bug 6242668
358f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
359f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        // Get the mailbox id from the folder
360f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        final long mailboxId = Long.parseLong(folder.uri.getPathSegments().get(1));
361f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
362f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        MailboxSettings.start(this, mailboxId);
363f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        finish();
36403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank    }
36503cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank
366f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
36757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    private void enableDebugMenu() {
36857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        mShowDebugMenu = true;
36957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        invalidateHeaders();
37057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler    }
37157f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler
372a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    private void onAddNewAccount() {
373a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler        AccountSetupBasics.actionNewAccount(this);
374a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    }
375a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler
376a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    /**
3772ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * Start the async reload of the accounts list (if the headers are being displayed)
3782ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
3792ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    private void updateAccounts() {
3802ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        if (hasHeaders()) {
3812ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            Utility.cancelTaskInterrupt(mLoadAccountListTask);
382bd3e7777c58d4ffef41922b1e7e0d3ccbbb78ca3Makoto Onuki            mLoadAccountListTask = (LoadAccountListTask)
383bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki                    new LoadAccountListTask().executeOnExecutor(
384bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki                            AsyncTask.THREAD_POOL_EXECUTOR, mDeletingAccountId);
3852ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
3862ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
3872ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
3882ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
3892ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * Write the current header (accounts) array into the one provided by the PreferenceActivity.
390464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler     * Skip any headers that match mDeletingAccountId (this is a quick-hide algorithm while a
3919c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * background thread works on deleting the account).  Also sets mRequestedAccountHeader if
3929c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * we find the requested account (by id).
3932ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
3942ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    @Override
3952ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onBuildHeaders(List<Header> target) {
396464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        // Always add app preferences as first header
397464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        target.clear();
398464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        target.add(getAppPreferencesHeader());
3999c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
400464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        // Then add zero or more account headers as necessary
401464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        if (mAccountListHeaders != null) {
402464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            int headerCount = mAccountListHeaders.length;
403464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            for (int index = 0; index < headerCount; index++) {
404a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                Header header = mAccountListHeaders[index];
40504c4ae864fb0df88b9bc41e85a72062c12540d81Andy Stadler                if (header != null && header.id != HEADER_ID_UNDEFINED) {
406a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                    if (header.id != mDeletingAccountId) {
407a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                        target.add(header);
408a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                        if (header.id == mRequestedAccountId) {
409a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                            mRequestedAccountId = -1;
410a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                        }
4119c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler                    }
412464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler                }
413464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            }
414464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        }
4159c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
41657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        // finally, if debug header is enabled, show it
41757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        if (mShowDebugMenu) {
41857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            // setup lightweight header for debugging
41957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            Header debugHeader = new Header();
42057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            debugHeader.title = getText(R.string.debug_title);
42157f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            debugHeader.summary = null;
42257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            debugHeader.iconRes = 0;
42357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            debugHeader.fragment = DebugFragment.class.getCanonicalName();
42457f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            debugHeader.fragmentArguments = null;
42557f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            target.add(debugHeader);
42657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        }
4271a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
4281a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // Save for later use (see forceSwitch)
4291a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        mGeneratedHeaders = target;
430464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    }
431464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler
432464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    /**
433464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler     * Generate and return the first header, for app preferences
434464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler     */
435464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    private Header getAppPreferencesHeader() {
4362ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        // Set up fixed header for general settings
4372ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        if (mAppPreferencesHeader == null) {
4382ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader = new Header();
4392ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader.title = getText(R.string.header_label_general_preferences);
4402ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader.summary = null;
4412ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader.iconRes = 0;
4420f52e546ef662e126b7360ad69c8c8f838789ef3Makoto Onuki            mAppPreferencesHeader.fragment = GeneralPreferences.class.getCanonicalName();
4432ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAppPreferencesHeader.fragmentArguments = null;
4442ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
445464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        return mAppPreferencesHeader;
446464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    }
447464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler
448464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    /**
4492ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * This AsyncTask reads the accounts list and generates the headers.  When the headers are
4502ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * ready, we'll trigger PreferenceActivity to refresh the account list with them.
4512ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     *
45204c4ae864fb0df88b9bc41e85a72062c12540d81Andy Stadler     * The array generated and stored in mAccountListHeaders may be sparse so any readers should
45304c4ae864fb0df88b9bc41e85a72062c12540d81Andy Stadler     * check for and skip over null entries, and should not assume array length is # of accounts.
45404c4ae864fb0df88b9bc41e85a72062c12540d81Andy Stadler     *
4552ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * TODO: Smaller projection
4562ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * TODO: Convert to Loader
457a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler     * TODO: Write a test, including operation of deletingAccountId param
4582ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
459464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler    private class LoadAccountListTask extends AsyncTask<Long, Void, Object[]> {
4602ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
4612ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        @Override
462464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        protected Object[] doInBackground(Long... params) {
463a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            Header[] result = null;
464464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            Boolean deletingAccountFound = false;
465a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            long deletingAccountId = params[0];
4662ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
4672ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            Cursor c = getContentResolver().query(
468f5418f1f93b02e7fab9f15eb201800b65510998eMarc Blank                    Account.CONTENT_URI,
469f5418f1f93b02e7fab9f15eb201800b65510998eMarc Blank                    Account.CONTENT_PROJECTION, null, null, null);
4702ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            try {
4712ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                int index = 0;
4722ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                int headerCount = c.getCount();
473a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                result = new Header[headerCount];
4742ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
4752ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                while (c.moveToNext()) {
476a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler                    long accountId = c.getLong(Account.CONTENT_ID_COLUMN);
477a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler                    if (accountId == deletingAccountId) {
478464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler                        deletingAccountFound = true;
479a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler                        continue;
480a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler                    }
4813955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                    String name = c.getString(Account.CONTENT_DISPLAY_NAME_COLUMN);
4823955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                    String email = c.getString(Account.CONTENT_EMAIL_ADDRESS_COLUMN);
483a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                    Header newHeader = new Header();
484a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                    newHeader.id = accountId;
4853955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                    newHeader.title = name;
4863955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                    newHeader.summary = email;
487a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn                    newHeader.fragment = AccountSettingsFragment.class.getCanonicalName();
4883955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                    newHeader.fragmentArguments =
4893955f6794f23c1380749d4470b5f2264d2109adcBen Komalo                            AccountSettingsFragment.buildArguments(accountId, email);
490a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn
4912ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                    result[index++] = newHeader;
4922ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                }
4932ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            } finally {
4942ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                if (c != null) {
4952ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                    c.close();
4962ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                }
4972ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            }
498464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            return new Object[] { result, deletingAccountFound };
4992ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
5002ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5012ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        @Override
502464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        protected void onPostExecute(Object[] result) {
5032866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            if (isCancelled() || result == null) return;
504464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            // Extract the results
505a2cc46c810eb802c172a4af8ecc67fca53dd584fDianne Hackborn            Header[] headers = (Header[]) result[0];
506464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            boolean deletingAccountFound = (Boolean) result[1];
507a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            // report the settings
5082ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            mAccountListHeaders = headers;
5092866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            invalidateHeaders();
510464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            if (!deletingAccountFound) {
511464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler                mDeletingAccountId = -1;
512464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            }
5132ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
5142ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
5152ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5162ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
5172ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * Called when the user selects an item in the header list.  Handles save-data cases as needed
5182ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     *
5192ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * @param header The header that was selected.
5202ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * @param position The header's position in the list.
5212ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
5222ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    @Override
5232ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onHeaderClick(Header header, int position) {
5241a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // special case when exiting the server settings fragments
5251a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        if (mCurrentFragment instanceof AccountServerBaseFragment) {
526c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            boolean changed = ((AccountServerBaseFragment)mCurrentFragment).haveSettingsChanged();
527c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            if (changed) {
5281a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                UnsavedChangesDialogFragment dialogFragment =
529c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                    UnsavedChangesDialogFragment.newInstanceForHeader(position);
5301a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                dialogFragment.show(getFragmentManager(), UnsavedChangesDialogFragment.TAG);
531c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                return;
5321a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            }
5331a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
5341a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
5351a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // Secret keys:  Click 10x to enable debug settings
53657f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        if (position == 0) {
53757f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            mNumGeneralHeaderClicked++;
53857f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            if (mNumGeneralHeaderClicked == 10) {
53957f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler                enableDebugMenu();
54057f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            }
54157f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        } else {
54257f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler            mNumGeneralHeaderClicked = 0;
54357f125a01b5fbb5860b144b3057153a50d07ddd1Andrew Stadler        }
5441a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
5451a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // Process header click normally
5462ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        super.onHeaderClick(header, position);
5472ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
5482ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5492ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
5501a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * Switch to a specific header without checking for server settings fragments as done
5511a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * in {@link #onHeaderClick(Header, int)}.  Called after we interrupted a header switch
5521a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * with a dialog, and the user OK'd it.
5531a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     */
554c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy    private void forceSwitchHeader(int position) {
555c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        // Clear the current fragment; we're navigating away
556c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        mCurrentFragment = null;
557c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        // Ensure the UI visually shows the correct header selected
558c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        setSelection(position);
559c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        Header header = mGeneratedHeaders.get(position);
560c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        switchToHeader(header);
561c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy    }
562c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy
563c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy    /**
564c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy     * Forcefully go backward in the stack. This may potentially discard unsaved settings.
565c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy     */
566c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy    private void forceBack() {
567c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        // Clear the current fragment; we're navigating away
568c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        mCurrentFragment = null;
569c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        onBackPressed();
5701a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    }
5711a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
5723955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    @Override
5733955f6794f23c1380749d4470b5f2264d2109adcBen Komalo    public void onAttachFragment(Fragment f) {
5743955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        super.onAttachFragment(f);
5753955f6794f23c1380749d4470b5f2264d2109adcBen Komalo
5762ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        if (f instanceof AccountSettingsFragment) {
5772ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            AccountSettingsFragment asf = (AccountSettingsFragment) f;
5782ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            asf.setCallback(mAccountSettingsFragmentCallback);
5793955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        } else if (f instanceof AccountServerBaseFragment) {
580ee97468feb73f0ed040485292687b764027d7d31Ben Komalo            AccountServerBaseFragment asbf = (AccountServerBaseFragment) f;
5811a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            asbf.setCallback(mAccountServerSettingsFragmentCallback);
5823955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        } else {
5833955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            // Possibly uninteresting fragment, such as a dialog.
5843955f6794f23c1380749d4470b5f2264d2109adcBen Komalo            return;
5851a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
5863955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        mCurrentFragment = f;
5871a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
5881a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // When we're changing fragments, enable/disable the add account button
58972a24f12a2a0a48528cf0f826397e2348fe8ace2Ben Komalo        invalidateOptionsMenu();
5902ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
5912ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
5922ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
5932ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     * Callbacks for AccountSettingsFragment
5942ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
5952ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    private class AccountSettingsFragmentCallback implements AccountSettingsFragment.Callback {
5962866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo        @Override
59734704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy        public void onSettingsChanged(Account account, String preference, Object value) {
5982866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            AccountSettings.this.onSettingsChanged(account, preference, value);
59934704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy        }
6002866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo        @Override
6015a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        public void onEditQuickResponses(Account account) {
6025a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo            AccountSettings.this.onEditQuickResponses(account);
6035a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        }
6045a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        @Override
6052ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        public void onIncomingSettings(Account account) {
6062866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            AccountSettings.this.onIncomingSettings(account);
6072ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
6082866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo        @Override
6092ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        public void onOutgoingSettings(Account account) {
6102866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            AccountSettings.this.onOutgoingSettings(account);
6112ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
6122866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo        @Override
6132ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        public void abandonEdit() {
6142ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            finish();
6152ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
6162ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
6172ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
6182ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
6191a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * Callbacks for AccountServerSettingsFragmentCallback
6201a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     */
6211a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    private class AccountServerSettingsFragmentCallback
6221a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            implements AccountServerBaseFragment.Callback {
6231a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        @Override
6241a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        public void onEnableProceedButtons(boolean enable) {
6251a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            // This is not used - it's a callback for the legacy activities
6261a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
627fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler
6281a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        @Override
629fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler        public void onProceedNext(int checkMode, AccountServerBaseFragment target) {
630fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler            AccountCheckSettingsFragment checkerFragment =
631fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler                AccountCheckSettingsFragment.newInstance(checkMode, target);
632fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler            startPreferenceFragment(checkerFragment, true);
633fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler        }
634fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler
635fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler        /**
636fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler         * After verifying a new server configuration as OK, we return here and continue.  This
637fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler         * simply does a "back" to exit the settings screen.
638fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler         */
6393955f6794f23c1380749d4470b5f2264d2109adcBen Komalo        @Override
6402731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler        public void onCheckSettingsComplete(int result, int setupMode) {
6412731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler            if (result == AccountCheckSettingsFragment.CHECK_SETTINGS_OK) {
642c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                // Settings checked & saved; clear current fragment
643c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                mCurrentFragment = null;
6442731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                onBackPressed();
6452731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler            }
6461a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
6471a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    }
6481a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
6491a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    /**
65034704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy     * Some of the settings have changed. Update internal state as necessary.
65134704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy     */
65234704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy    public void onSettingsChanged(Account account, String preference, Object value) {
65334704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy        if (AccountSettingsFragment.PREFERENCE_DESCRIPTION.equals(preference)) {
65434704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy            for (Header header : mAccountListHeaders) {
65534704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                if (header.id == account.mId) {
65634704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    // Manually tweak the header title. We cannot rebuild the header list from
65734704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    // an account cursor as the account database has not been saved yet.
65834704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    header.title = value.toString();
65934704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    invalidateHeaders();
66034704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                    break;
66134704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy                }
66234704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy            }
66334704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy        }
66434704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy    }
66534704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy
66634704851e96dcc139d6833adb3bd139f57fa497cTodd Kennedy    /**
6675a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo     * Dispatch to edit quick responses.
6685a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo     */
6695a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo    public void onEditQuickResponses(Account account) {
6705a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        try {
6715a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo            Bundle args = new Bundle();
6725a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo            args.putParcelable(QUICK_RESPONSE_ACCOUNT_KEY, account);
6735a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo            startPreferencePanel(AccountSettingsEditQuickResponsesFragment.class.getName(), args,
6745a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo                    R.string.account_settings_edit_quick_responses_label, null, null, 0);
6755a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        } catch (Exception e) {
676560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy            LogUtils.d(Logging.LOG_TAG, "Error while trying to invoke edit quick responses.", e);
6775a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo        }
6785a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo    }
6795a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo
6805a3888f35b669ffb3cc785d7dfe4862879a3896cJorge Lugo    /**
6811a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * Dispatch to edit incoming settings.
6822ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
6832ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onIncomingSettings(Account account) {
6842ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        try {
685f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            SetupData.init(SetupData.FLOW_MODE_EDIT, account);
686f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            startPreferencePanel(AccountSetupIncomingFragment.class.getName(),
687f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                    AccountSetupIncomingFragment.getSettingsModeArgs(),
688f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                    R.string.account_settings_incoming_label, null, null, 0);
6892ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        } catch (Exception e) {
690560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy            LogUtils.d(Logging.LOG_TAG, "Error while trying to invoke store settings.", e);
6912ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
6922ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
6932ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
6942ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
6951a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * Dispatch to edit outgoing settings.
6961a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     *
6971a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * TODO: Make things less hardwired
6982ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler     */
6992ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    public void onOutgoingSettings(Account account) {
7002ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        try {
701daf869cf60de75bc91ed3aef6ac0bff1fe371733Todd Kennedy            Sender sender = Sender.getInstance(getApplication(), account);
7022ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            if (sender != null) {
7032ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                Class<? extends android.app.Activity> setting = sender.getSettingActivityClass();
7042ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                if (setting != null) {
7051a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                    SetupData.init(SetupData.FLOW_MODE_EDIT, account);
7061a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                    if (setting.equals(AccountSetupOutgoing.class)) {
707983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler                        startPreferencePanel(AccountSetupOutgoingFragment.class.getName(),
708983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler                                AccountSetupOutgoingFragment.getSettingsModeArgs(),
709983e1ad53b3ca3105655bf6d961713c61060a7f8Andy Stadler                                R.string.account_settings_outgoing_label, null, null, 0);
7101a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                    }
7112ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler                }
7122ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler            }
7132ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        } catch (Exception e) {
714560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy            LogUtils.d(Logging.LOG_TAG, "Error while trying to invoke sender settings.", e);
7152ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler        }
7162ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    }
7172ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler
7182ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler    /**
719a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler     * Delete the selected account
720a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler     */
721f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    public void deleteAccount(final Account account) {
722464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        // Kick off the work to actually delete the account
723f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        new Thread(new Runnable() {
724f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            @Override
725f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            public void run() {
726f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                Uri uri = EmailProvider.uiUri("uiaccount", account.mId);
727f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                getContentResolver().delete(uri, null, null);
728f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            }}).start();
729464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler
730f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        // TODO: Remove ui glue for unified
731464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler        // Then update the UI as appropriate:
732a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler        // If single pane, return to the header list.  If multi, rebuild header list
73372a24f12a2a0a48528cf0f826397e2348fe8ace2Ben Komalo        if (onIsMultiPane()) {
734464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            Header prefsHeader = getAppPreferencesHeader();
735464d1f95b725fb22d701bd7b55d6d682ad4d3cbfAndrew Stadler            this.switchToHeader(prefsHeader.fragment, prefsHeader.fragmentArguments);
736a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            mDeletingAccountId = account.mId;
73709aae75f4e37c3197c6f8d3f046b15c71534d1f0Andy Stadler            updateAccounts();
738a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler        } else {
739a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            // We should only be calling this while showing AccountSettingsFragment,
740a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            // so a finish() should bring us back to headers.  No point hiding the deleted account.
741a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler            finish();
742a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler        }
743a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    }
744a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler
745a14a24a5bc2ffa426f7ef8e5e6938cffe3f35829Andrew Stadler    /**
7469c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * This AsyncTask looks up an account based on its email address (which is what we get from
7479c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * the Account Manager).  When the account id is determined, we refresh the header list,
7489c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     * which will select the preferences for that account.
7499c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler     */
7509c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    private class GetAccountIdFromAccountTask extends AsyncTask<Intent, Void, Long> {
7519c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
7529c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        @Override
7539c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        protected Long doInBackground(Intent... params) {
7549c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler            Intent intent = params[0];
7559c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler            android.accounts.Account acct =
7569c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler                (android.accounts.Account) intent.getParcelableExtra(EXTRA_ACCOUNT_MANAGER_ACCOUNT);
7572866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            return Utility.getFirstRowLong(AccountSettings.this, Account.CONTENT_URI,
7582866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo                    Account.ID_PROJECTION, SELECTION_ACCOUNT_EMAIL_ADDRESS,
7592866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo                    new String[] {acct.name}, null, Account.ID_PROJECTION_COLUMN, -1L);
7609c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        }
7619c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
7629c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        @Override
7639c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        protected void onPostExecute(Long accountId) {
7649c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler            if (accountId != -1 && !isCancelled()) {
7659c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler                mRequestedAccountId = accountId;
7662866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo                invalidateHeaders();
7679c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler            }
7689c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler        }
7699c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    }
7709c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler
7719c65c146f3d8e60f35f46c815d4121749ad13abdAndrew Stadler    /**
7721a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     * Dialog fragment to show "exit with unsaved changes?" dialog
7731a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler     */
774c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy    /* package */ static class UnsavedChangesDialogFragment extends DialogFragment {
775f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        final static String TAG = "UnsavedChangesDialogFragment";
7761a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
7771a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        // Argument bundle keys
778c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        private final static String BUNDLE_KEY_HEADER = "UnsavedChangesDialogFragment.Header";
779c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        private final static String BUNDLE_KEY_BACK = "UnsavedChangesDialogFragment.Back";
7801a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
7811a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        /**
782c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         * Creates a save changes dialog when the user selects a new header
783c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         * @param position The new header index to make active if the user accepts the dialog. This
784c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         * must be a valid header index although there is no error checking.
7851a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler         */
786c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        public static UnsavedChangesDialogFragment newInstanceForHeader(int position) {
7871a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            UnsavedChangesDialogFragment f = new UnsavedChangesDialogFragment();
7881a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            Bundle b = new Bundle();
789c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            b.putInt(BUNDLE_KEY_HEADER, position);
7901a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            f.setArguments(b);
7911a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            return f;
7921a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
7931a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
794c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        /**
795c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         * Creates a save changes dialog when the user navigates "back".
7962866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo         * {@link #onBackPressed()} defines in which case this may be triggered.
797c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy         */
798c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        public static UnsavedChangesDialogFragment newInstanceForBack() {
799c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            UnsavedChangesDialogFragment f = new UnsavedChangesDialogFragment();
800c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            Bundle b = new Bundle();
801c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            b.putBoolean(BUNDLE_KEY_BACK, true);
802c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            f.setArguments(b);
803c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            return f;
804c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        }
805c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy
806c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        // Force usage of newInstance()
807c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        private UnsavedChangesDialogFragment() {
808c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy        }
809c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy
8101a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        @Override
8111a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        public Dialog onCreateDialog(Bundle savedInstanceState) {
8122866284a6d4ee4b368fcaf412c540b21d457e065Ben Komalo            final AccountSettings activity = (AccountSettings) getActivity();
813c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            final int position = getArguments().getInt(BUNDLE_KEY_HEADER);
814c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy            final boolean isBack = getArguments().getBoolean(BUNDLE_KEY_BACK);
8151a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
8161a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler            return new AlertDialog.Builder(activity)
81749518bb3605d6c8e3cc4801c452e4f8f63220f44Makoto Onuki                .setIconAttribute(android.R.attr.alertDialogIcon)
8181a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .setTitle(android.R.string.dialog_alert_title)
8191a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .setMessage(R.string.account_settings_exit_server_settings)
8201a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .setPositiveButton(
8211a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                        R.string.okay_action,
8221a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                        new DialogInterface.OnClickListener() {
823f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                            @Override
8241a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                            public void onClick(DialogInterface dialog, int which) {
825c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                if (isBack) {
826c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                    activity.forceBack();
827c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                } else {
828c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                    activity.forceSwitchHeader(position);
829c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                                }
8301a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                                dismiss();
8311a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                            }
8321a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                        })
8331a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .setNegativeButton(
834c890a4e4a2cbb489aea4847cf25368a723586530Todd Kennedy                        activity.getString(R.string.cancel_action), null)
8351a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler                .create();
8361a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler        }
8371a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler    }
8381a5e1e159352f6e21bde878eebca3e3a1896045cAndrew Stadler
839f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler    /**
840f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * Dialog briefly shown in some cases, to indicate the user that login failed.  If the user
841f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * clicks OK, we simply dismiss the dialog, leaving the user in the account settings for
842f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     * that account;  If the user clicks "cancel", we exit account settings.
843f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler     */
844f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler    public static class LoginWarningDialog extends DialogFragment
845f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            implements DialogInterface.OnClickListener {
846f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name";
847dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank        private String mReason;
848f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler
849f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        /**
850f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler         * Create a new dialog.
851f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler         */
852dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank        public static LoginWarningDialog newInstance(String accountName, String reason) {
853f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final LoginWarningDialog dialog = new LoginWarningDialog();
854f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            Bundle b = new Bundle();
855f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName);
856f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            dialog.setArguments(b);
857dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            dialog.mReason = reason;
858f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            return dialog;
859f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        }
860f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler
861f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        @Override
862f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        public Dialog onCreateDialog(Bundle savedInstanceState) {
863f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME);
864f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler
865f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final Context context = getActivity();
866f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final Resources res = context.getResources();
867f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            final AlertDialog.Builder b = new AlertDialog.Builder(context);
868f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            b.setTitle(R.string.account_settings_login_dialog_title);
869f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            b.setIconAttribute(android.R.attr.alertDialogIcon);
870dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            if (mReason != null) {
8711bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                final TextView message = new TextView(context);
8721bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                String alert = res.getString(
8731bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                        R.string.account_settings_login_dialog_reason_fmt, accountName, mReason);
8741bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                SpannableString spannableAlertString = new SpannableString(alert);
8751bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                Linkify.addLinks(spannableAlertString, Linkify.WEB_URLS);
8761bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                message.setText(spannableAlertString);
8771bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                // There must be a better way than specifying size/padding this way
8781bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                // It does work and look right, though
8791bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                int textSize = res.getDimensionPixelSize(R.dimen.dialog_text_size);
8801bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                message.setTextSize(textSize);
8811bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                int paddingLeft = res.getDimensionPixelSize(R.dimen.dialog_padding_left);
8821bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                int paddingOther = res.getDimensionPixelSize(R.dimen.dialog_padding_other);
8831bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                message.setPadding(paddingLeft, paddingOther, paddingOther, paddingOther);
8841bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                message.setMovementMethod(LinkMovementMethod.getInstance());
8851bd4630d3d7e4ea309a126b05b00fb1ccab283b8Marc Blank                b.setView(message);
886dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            } else {
887dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                b.setMessage(res.getString(R.string.account_settings_login_dialog_content_fmt,
888dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank                        accountName));
889dba0b20d955d88831ce94d96dbdadc49dba4761aMarc Blank            }
890f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            b.setPositiveButton(R.string.okay_action, this);
891f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            b.setNegativeButton(R.string.cancel_action, this);
892f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            return b.create();
893f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        }
894f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler
895f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        @Override
896f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        public void onClick(DialogInterface dialog, int which) {
897f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            dismiss();
898f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            if (which == DialogInterface.BUTTON_NEGATIVE) {
899f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler                getActivity().finish();
900f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler            }
901f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler        }
902f4894131427ec7562fcb05388b9f3aa094e388bcAndy Stadler    }
90338f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook
90438f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook    @Override
90538f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook    public Context getActivityContext() {
90638f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook        return this;
90738f22dbf08664b885b4cf063ea665c02edfb1c32Paul Westbrook    }
9082ae2a12d6b049a4347c0781bd4daa17229bf1340Andrew Stadler}
909