155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler/*
255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * Copyright (C) 2010 The Android Open Source Project
355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler *
455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * Licensed under the Apache License, Version 2.0 (the "License");
555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * you may not use this file except in compliance with the License.
655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * You may obtain a copy of the License at
755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler *
855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler *      http://www.apache.org/licenses/LICENSE-2.0
955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler *
1055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * Unless required by applicable law or agreed to in writing, software
1155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * distributed under the License is distributed on an "AS IS" BASIS,
1255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * See the License for the specific language governing permissions and
1455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * limitations under the License.
1555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler */
1655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
1755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadlerpackage com.android.email.activity.setup;
1855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
19fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadlerimport android.app.Activity;
2055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadlerimport android.app.Fragment;
2155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadlerimport android.app.FragmentManager;
2255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadlerimport android.content.Context;
2355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadlerimport android.os.AsyncTask;
2455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadlerimport android.os.Bundle;
2555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
2635b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.email.R;
2735b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.email.mail.Sender;
2835b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.email.mail.Store;
29e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blankimport com.android.email.service.EmailServiceUtils;
30e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blankimport com.android.email.service.EmailServiceUtils.EmailServiceInfo;
3135b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.Logging;
3235b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.mail.MessagingException;
3335b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.provider.Account;
3435b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.provider.HostAuth;
3535b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.provider.Policy;
3635b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.service.EmailServiceProxy;
371d8fd9c05449863ac6a151a6db87c267c4f55ac2Martin Hibdonimport com.android.emailcommon.service.HostAuthCompat;
3835b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blankimport com.android.emailcommon.utility.Utility;
39560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedyimport com.android.mail.utils.LogUtils;
4035b0e95ca795e17b6dc8dd98c7ab847d65d9aa0cMarc Blank
4155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler/**
4255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * Check incoming or outgoing settings, or perform autodiscovery.
4355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler *
4455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * There are three components that work together.  1. This fragment is retained and non-displayed,
4555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * and controls the overall process.  2. An AsyncTask that works with the stores/services to
4655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * check the accounts settings.  3. A stateless progress dialog (which will be recreated on
4755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * orientation changes).
4855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler *
4955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * There are also two lightweight error dialogs which are used for notification of terminal
5055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler * conditions.
5155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler */
5255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadlerpublic class AccountCheckSettingsFragment extends Fragment {
5349518bb3605d6c8e3cc4801c452e4f8f63220f44Makoto Onuki
54fead9986c1ce920e669aadddb0b993ff4cff56b8Martin Hibdon    public final static String TAG = "AccountCheckStgFrag";
5555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
5655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    // State
5755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    private final static int STATE_START = 0;
5855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    private final static int STATE_CHECK_AUTODISCOVER = 1;
5955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    private final static int STATE_CHECK_INCOMING = 2;
6055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    private final static int STATE_CHECK_OUTGOING = 3;
612731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    private final static int STATE_CHECK_OK = 4;                    // terminal
622731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    private final static int STATE_CHECK_SHOW_SECURITY = 5;         // terminal
632731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    private final static int STATE_CHECK_ERROR = 6;                 // terminal
642731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    private final static int STATE_AUTODISCOVER_AUTH_DIALOG = 7;    // terminal
652731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    private final static int STATE_AUTODISCOVER_RESULT = 8;         // terminal
6655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    private int mState = STATE_START;
6776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
6876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    // Args
6976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    private final static String ARGS_MODE = "mode";
7076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
7176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    private int mMode;
7255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
7355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    // Support for UI
7455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    private boolean mAttached;
75f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    private boolean mPaused = false;
76715ee4ec4c5a7893b89c28b8569a7a109a5be970Ben Komalo    private MessagingException mProgressException;
77fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler
7855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    // Support for AsyncTask and account checking
7955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    AccountCheckTask mAccountCheckTask;
802731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler
8176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    // Result codes returned by onCheckSettingsAutoDiscoverComplete.
822731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    /** AutoDiscover completed successfully with server setup data */
832731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    public final static int AUTODISCOVER_OK = 0;
842731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    /** AutoDiscover completed with no data (no server or AD not supported) */
852731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    public final static int AUTODISCOVER_NO_DATA = 1;
862731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    /** AutoDiscover reported authentication error */
872731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    public final static int AUTODISCOVER_AUTHENTICATION = 2;
882731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler
8955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    /**
90fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler     * Callback interface for any target or activity doing account check settings
91fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler     */
9276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public interface Callback {
93fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler        /**
942731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         * Called when CheckSettings completed
95fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler         */
9676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        void onCheckSettingsComplete();
9776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
9876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        /**
9976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         * Called when we determine that a security policy will need to be installed
10076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         * @param hostName Passed back from the MessagingException
10176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         */
10276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        void onCheckSettingsSecurityRequired(String hostName);
10376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler
10476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        /**
10576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         * Called when we receive an error while validating the account
10676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         * @param reason from
10776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         *      {@link CheckSettingsErrorDialogFragment#getReasonFromException(MessagingException)}
10876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         * @param message from
10976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         *      {@link CheckSettingsErrorDialogFragment#getErrorString(Context, MessagingException)}
11076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         */
11176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        void onCheckSettingsError(int reason, String message);
1122731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler
1132731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler        /**
1142731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         * Called when autodiscovery completes.
1152731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         * @param result autodiscovery result code - success is AUTODISCOVER_OK
1162731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         */
11776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        void onCheckSettingsAutoDiscoverComplete(int result);
118fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler    }
1192731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler
1207985b43ab7310f76c170266da346f993d2f86051Paul Westbrook    // Public no-args constructor needed for fragment re-instantiation
1217985b43ab7310f76c170266da346f993d2f86051Paul Westbrook    public AccountCheckSettingsFragment() {}
1227985b43ab7310f76c170266da346f993d2f86051Paul Westbrook
123fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler    /**
12455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * Create a retained, invisible fragment that checks accounts
12555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     *
12655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * @param mode incoming or outgoing
12755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     */
12876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    public static AccountCheckSettingsFragment newInstance(int mode) {
129ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler        final AccountCheckSettingsFragment f = new AccountCheckSettingsFragment();
13076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        final Bundle b = new Bundle(1);
13176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        b.putInt(ARGS_MODE, mode);
13276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        f.setArguments(b);
13355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        return f;
13455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    }
13555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
13655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    /**
13755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * Fragment initialization.  Because we never implement onCreateView, and call
13855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * setRetainInstance here, this creates an invisible, persistent, "worker" fragment.
13955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     */
14055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    @Override
14155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    public void onCreate(Bundle savedInstanceState) {
14255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        super.onCreate(savedInstanceState);
14355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        setRetainInstance(true);
14476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        mMode = getArguments().getInt(ARGS_MODE);
14555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    }
14655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
14755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    /**
14855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * This is called when the Fragment's Activity is ready to go, after
14955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * its content view has been installed; it is called both after
15055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * the initial fragment creation and after the fragment is re-attached
15155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * to a new activity.
15255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     */
15355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    @Override
15455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    public void onActivityCreated(Bundle savedInstanceState) {
15555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        super.onActivityCreated(savedInstanceState);
15655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        mAttached = true;
15755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
15855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        // If this is the first time, start the AsyncTask
15955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        if (mAccountCheckTask == null) {
1609c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler            final SetupDataFragment.SetupDataContainer container =
1619c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler                    (SetupDataFragment.SetupDataContainer) getActivity();
16276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            // TODO: don't pass in the whole SetupDataFragment
16355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            mAccountCheckTask = (AccountCheckTask)
16476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    new AccountCheckTask(getActivity().getApplicationContext(), this, mMode,
16576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                            container.getSetupData())
166bc2eaadde987044027b57d241e635de014bdb8baMakoto Onuki                    .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
16755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        }
168f946ff001914abce9ea06b1ceecd29cdb7e10ef3Andy Stadler    }
169f946ff001914abce9ea06b1ceecd29cdb7e10ef3Andy Stadler
170f946ff001914abce9ea06b1ceecd29cdb7e10ef3Andy Stadler    /**
171f946ff001914abce9ea06b1ceecd29cdb7e10ef3Andy Stadler     * When resuming, restart the progress/error UI if necessary by re-reporting previous values
172f946ff001914abce9ea06b1ceecd29cdb7e10ef3Andy Stadler     */
173f946ff001914abce9ea06b1ceecd29cdb7e10ef3Andy Stadler    @Override
174f946ff001914abce9ea06b1ceecd29cdb7e10ef3Andy Stadler    public void onResume() {
175f946ff001914abce9ea06b1ceecd29cdb7e10ef3Andy Stadler        super.onResume();
176f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        mPaused = false;
17755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
17855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        if (mState != STATE_START) {
179715ee4ec4c5a7893b89c28b8569a7a109a5be970Ben Komalo            reportProgress(mState, mProgressException);
18055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        }
18155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    }
18255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
183f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    @Override
184f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    public void onPause() {
185f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        super.onPause();
186f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        mPaused = true;
187f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank    }
188f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank
18955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    /**
19055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * This is called when the fragment is going away.  It is NOT called
19155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * when the fragment is being propagated between activity instances.
19255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     */
19355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    @Override
19455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    public void onDestroy() {
19555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        super.onDestroy();
196f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        if (mAccountCheckTask != null) {
197f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            Utility.cancelTaskInterrupt(mAccountCheckTask);
198f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank            mAccountCheckTask = null;
199f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        }
20055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    }
20155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
20255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    /**
20355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * This is called right before the fragment is detached from its current activity instance.
20455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * All reporting and callbacks are halted until we reattach.
20555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     */
20655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    @Override
20755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    public void onDetach() {
20855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        super.onDetach();
20955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        mAttached = false;
21055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    }
21155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
21255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    /**
21355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * The worker (AsyncTask) will call this (in the UI thread) to report progress.  If we are
21455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * attached to an activity, update the progress immediately;  If not, simply hold the
21555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * progress for later.
21655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * @param newState The new progress state being reported
21755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     */
218715ee4ec4c5a7893b89c28b8569a7a109a5be970Ben Komalo    private void reportProgress(int newState, MessagingException ex) {
21955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        mState = newState;
220715ee4ec4c5a7893b89c28b8569a7a109a5be970Ben Komalo        mProgressException = ex;
22155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
22255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        // If we are attached, create, recover, and/or update the dialog
223f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank        if (mAttached && !mPaused) {
224ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler            final FragmentManager fm = getFragmentManager();
22555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
2262731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler            switch (newState) {
2272731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                case STATE_CHECK_OK:
2282731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    // immediately terminate, clean up, and report back
22976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    getCallbackTarget().onCheckSettingsComplete();
2302731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    break;
2312731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                case STATE_CHECK_SHOW_SECURITY:
23276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    // report that we need to accept a security policy
23376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    String hostName = ex.getMessage();
23476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    if (hostName != null) {
23576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                        hostName = hostName.trim();
236f946ff001914abce9ea06b1ceecd29cdb7e10ef3Andy Stadler                    }
23776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    getCallbackTarget().onCheckSettingsSecurityRequired(hostName);
2382731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    break;
2392731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                case STATE_CHECK_ERROR:
2402731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                case STATE_AUTODISCOVER_AUTH_DIALOG:
24176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    // report that we had an error
24276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    final int reason =
24376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                            CheckSettingsErrorDialogFragment.getReasonFromException(ex);
24476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    final String errorMessage =
24576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                            CheckSettingsErrorDialogFragment.getErrorString(getActivity(), ex);
24676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    getCallbackTarget().onCheckSettingsError(reason, errorMessage);
2472731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    break;
2482731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                case STATE_AUTODISCOVER_RESULT:
249ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    final HostAuth autoDiscoverResult = ((AutoDiscoverResults) ex).mHostAuth;
25076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    // report autodiscover results back to target fragment or activity
25176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    getCallbackTarget().onCheckSettingsAutoDiscoverComplete(
25276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                            (autoDiscoverResult != null) ? AUTODISCOVER_OK : AUTODISCOVER_NO_DATA);
2532731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    break;
2542731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                default:
2552731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    // Display a normal progress message
25676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    CheckSettingsProgressDialogFragment checkingDialog =
25776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                            (CheckSettingsProgressDialogFragment)
25876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                                    fm.findFragmentByTag(CheckSettingsProgressDialogFragment.TAG);
2592731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler
26076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                    if (checkingDialog != null) {
26176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                        checkingDialog.updateProgress(mState);
2622731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    }
2632731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    break;
26455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            }
26555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        }
26655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    }
26755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
26855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    /**
269fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler     * Find the callback target, either a target fragment or the activity
270fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler     */
27176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    private Callback getCallbackTarget() {
272ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler        final Fragment target = getTargetFragment();
27376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        if (target instanceof Callback) {
27476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            return (Callback) target;
275fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler        }
276fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler        Activity activity = getActivity();
27776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        if (activity instanceof Callback) {
27876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            return (Callback) activity;
279fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler        }
280fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler        throw new IllegalStateException();
2812731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    }
282fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler
283fd14496c494a0d38c35c3788c9cc55f1984592e4Andrew Stadler    /**
2842731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler     * This exception class is used to report autodiscover results via the reporting mechanism.
2852731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler     */
2862731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    public static class AutoDiscoverResults extends MessagingException {
2872731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler        public final HostAuth mHostAuth;
2882731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler
2892731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler        /**
2902731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         * @param authenticationError true if auth failure, false for result (or no response)
2912731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         * @param hostAuth null for "no autodiscover", non-null for server info to return
2922731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         */
2932731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler        public AutoDiscoverResults(boolean authenticationError, HostAuth hostAuth) {
2942731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler            super(null);
2952731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler            if (authenticationError) {
2962731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                mExceptionType = AUTODISCOVER_AUTHENTICATION_FAILED;
2972731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler            } else {
2982731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                mExceptionType = AUTODISCOVER_AUTHENTICATION_RESULT;
2992731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler            }
3002731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler            mHostAuth = hostAuth;
3012731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler        }
3022731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    }
3032731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler
3042731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler    /**
30555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * This AsyncTask does the actual account checking
30655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     *
30755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * TODO: It would be better to remove the UI complete from here (the exception->string
30855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     * conversions).
30955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     */
31076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    private static class AccountCheckTask extends AsyncTask<Void, Integer, MessagingException> {
31155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        final Context mContext;
31276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        final AccountCheckSettingsFragment mCallback;
31355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        final int mMode;
31476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        final SetupDataFragment mSetupData;
315a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        final Account mAccount;
31655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        final String mStoreHost;
3172731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler        final String mCheckPassword;
318d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler        final String mCheckEmail;
31955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
32055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        /**
32155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler         * Create task and parameterize it
32276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         * @param context application context object
32355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler         * @param mode bits request operations
32476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler         * @param setupData {@link SetupDataFragment} holding values to be checked
32555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler         */
32676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        public AccountCheckTask(Context context, AccountCheckSettingsFragment callback, int mode,
32776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                SetupDataFragment setupData) {
32876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            mContext = context;
32976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            mCallback = callback;
33055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            mMode = mode;
33176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            mSetupData = setupData;
33276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            mAccount = setupData.getAccount();
333d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler            if (mAccount.mHostAuthRecv != null) {
334d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                mStoreHost = mAccount.mHostAuthRecv.mAddress;
335d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                mCheckPassword = mAccount.mHostAuthRecv.mPassword;
336d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler            } else {
337d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                mStoreHost = null;
338d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                mCheckPassword = null;
339d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler            }
34076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            mCheckEmail = mAccount.mEmailAddress;
34155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        }
34255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
34355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        @Override
34455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        protected MessagingException doInBackground(Void... params) {
34555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            try {
3469c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler                if ((mMode & SetupDataFragment.CHECK_AUTODISCOVER) != 0) {
34755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    if (isCancelled()) return null;
34887de90282bc7f00c154be460c66cef999072b555Martin Hibdon                    LogUtils.d(Logging.LOG_TAG, "Begin auto-discover for %s", mCheckEmail);
34955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    publishProgress(STATE_CHECK_AUTODISCOVER);
350ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    final Store store = Store.getInstance(mAccount, mContext);
351ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    final Bundle result = store.autoDiscover(mContext, mCheckEmail, mCheckPassword);
3522731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    // Result will be one of:
3532731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    //  null: remote exception - proceed to manual setup
3542731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    //  MessagingException.AUTHENTICATION_FAILED: username/password rejected
3552731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    //  Other error: proceed to manual setup
3562731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    //  No error: return autodiscover results
3572731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    if (result == null) {
3582731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        return new AutoDiscoverResults(false, null);
3592731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    }
3602731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    int errorCode =
3612731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                            result.getInt(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_ERROR_CODE);
362c196e05ee15ba72ed993bf498897c2be121ccad1Marc Blank                    if (errorCode == MessagingException.AUTODISCOVER_AUTHENTICATION_FAILED) {
3632731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        return new AutoDiscoverResults(true, null);
3642731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    } else if (errorCode != MessagingException.NO_ERROR) {
3652731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        return new AutoDiscoverResults(false, null);
3662731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    } else {
3671d8fd9c05449863ac6a151a6db87c267c4f55ac2Martin Hibdon                        final HostAuthCompat hostAuthCompat =
3682731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                            result.getParcelable(EmailServiceProxy.AUTO_DISCOVER_BUNDLE_HOST_AUTH);
3691d8fd9c05449863ac6a151a6db87c267c4f55ac2Martin Hibdon                        HostAuth serverInfo = null;
3701d8fd9c05449863ac6a151a6db87c267c4f55ac2Martin Hibdon                        if (hostAuthCompat != null) {
3711d8fd9c05449863ac6a151a6db87c267c4f55ac2Martin Hibdon                            serverInfo = hostAuthCompat.toHostAuth();
3721d8fd9c05449863ac6a151a6db87c267c4f55ac2Martin Hibdon                        }
3732731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        return new AutoDiscoverResults(false, serverInfo);
3742731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    }
37555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                }
37655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
37755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                // Check Incoming Settings
3789c8c471f971f9c8e40002503a0799ce56c5bfd76Tony Mantler                if ((mMode & SetupDataFragment.CHECK_INCOMING) != 0) {
37955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    if (isCancelled()) return null;
380560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy                    LogUtils.d(Logging.LOG_TAG, "Begin check of incoming email settings");
38155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    publishProgress(STATE_CHECK_INCOMING);
382ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    final Store store = Store.getInstance(mAccount, mContext);
383ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    final Bundle bundle = store.checkSettings();
384ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    if (bundle == null) {
385ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                        return new MessagingException(MessagingException.UNSPECIFIED_EXCEPTION);
386ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    }
387ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    mAccount.mProtocolVersion = bundle.getString(
388ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                            EmailServiceProxy.VALIDATE_BUNDLE_PROTOCOL_VERSION);
389ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    int resultCode = bundle.getInt(EmailServiceProxy.VALIDATE_BUNDLE_RESULT_CODE);
390ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    final String redirectAddress = bundle.getString(
391ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                            EmailServiceProxy.VALIDATE_BUNDLE_REDIRECT_ADDRESS, null);
392ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    if (redirectAddress != null) {
393ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                        mAccount.mHostAuthRecv.mAddress = redirectAddress;
394ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    }
395ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    // Only show "policies required" if this is a new account setup
396ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    if (resultCode == MessagingException.SECURITY_POLICIES_REQUIRED &&
397ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                            mAccount.isSaved()) {
398ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                        resultCode = MessagingException.NO_ERROR;
39955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    }
40055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    if (resultCode == MessagingException.SECURITY_POLICIES_REQUIRED) {
40126cd5e024c6af8ff9c8558325dd0930c9aacb370Tony Mantler                        mSetupData.setPolicy((Policy)bundle.getParcelable(
40255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                                EmailServiceProxy.VALIDATE_BUNDLE_POLICY_SET));
403265530723b8c008f6bc23b1723f4de706a3e9556Marc Blank                        return new MessagingException(resultCode, mStoreHost);
404265530723b8c008f6bc23b1723f4de706a3e9556Marc Blank                    } else if (resultCode == MessagingException.SECURITY_POLICIES_UNSUPPORTED) {
405ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                        final Policy policy = bundle.getParcelable(
406f419287f22ae44f25e1ba1f757ec33c7941bbfa8Marc Blank                                EmailServiceProxy.VALIDATE_BUNDLE_POLICY_SET);
407ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                        final String unsupported = policy.mProtocolPoliciesUnsupported;
408ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                        final String[] data =
409ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                                unsupported.split("" + Policy.POLICY_STRING_DELIMITER);
410265530723b8c008f6bc23b1723f4de706a3e9556Marc Blank                        return new MessagingException(resultCode, mStoreHost, data);
411265530723b8c008f6bc23b1723f4de706a3e9556Marc Blank                    } else if (resultCode != MessagingException.NO_ERROR) {
412ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                        final String errorMessage;
413ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                        errorMessage = bundle.getString(
414ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                                EmailServiceProxy.VALIDATE_BUNDLE_ERROR_MESSAGE);
41555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                        return new MessagingException(resultCode, errorMessage);
41655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    }
41755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                }
41855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
419d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                final EmailServiceInfo info;
420d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                if (mAccount.mHostAuthRecv != null) {
421d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                    final String protocol = mAccount.mHostAuthRecv.mProtocol;
422d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                    info = EmailServiceUtils
423d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                            .getServiceInfo(mContext, protocol);
424d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                } else {
425d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                    info = null;
426d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                }
427e714bb9d153cfe13a7f0932e7d67ea08fa5a1d98Marc Blank
42855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                // Check Outgoing Settings
429d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                if ((info == null || info.usesSmtp) &&
430d716d89459f736402e74f3cfb2f20a71e50768f0Tony Mantler                        (mMode & SetupDataFragment.CHECK_OUTGOING) != 0) {
43155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    if (isCancelled()) return null;
432560bfadc3151f7a06f3b06e9a6c92cfa534c63ecScott Kennedy                    LogUtils.d(Logging.LOG_TAG, "Begin check of outgoing email settings");
43355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    publishProgress(STATE_CHECK_OUTGOING);
434ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                    final Sender sender = Sender.getInstance(mContext, mAccount);
43555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    sender.close();
43655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    sender.open();
43755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    sender.close();
43855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                }
43955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
44055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                // If we reached the end, we completed the check(s) successfully
44155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                return null;
44255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            } catch (final MessagingException me) {
44355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                // Some of the legacy account checkers return errors by throwing MessagingException,
44455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                // which we catch and return here.
44555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                return me;
44655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            }
44755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        }
44855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
44955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        /**
45055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler         * Progress reports (runs in UI thread).  This should be used for real progress only
45155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler         * (not for errors).
45255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler         */
45355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        @Override
45455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        protected void onProgressUpdate(Integer... progress) {
45555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            if (isCancelled()) return;
45676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            mCallback.reportProgress(progress[0], null);
45755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        }
45855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
45955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        /**
4602731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         * Result handler (runs in UI thread).
4612731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         *
4622731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         * AutoDiscover authentication errors are handled a bit differently than the
4632731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         * other errors;  If encountered, we display the error dialog, but we return with
4642731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         * a different callback used only for AutoDiscover.
4652731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler         *
46655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler         * @param result null for a successful check;  exception for various errors
46755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler         */
46855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        @Override
46955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        protected void onPostExecute(MessagingException result) {
47055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            if (isCancelled()) return;
47155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            if (result == null) {
47276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                mCallback.reportProgress(STATE_CHECK_OK, null);
47355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            } else {
4742731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                int progressState = STATE_CHECK_ERROR;
475ed4accb24facd1324948abc61b0791eb3dc97cc4Tony Mantler                final int exceptionType = result.getExceptionType();
4762731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler
47755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                switch (exceptionType) {
4782731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    // NOTE: AutoDiscover reports have their own reporting state, handle differently
4792731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    // from the other exception types
4802731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    case MessagingException.AUTODISCOVER_AUTHENTICATION_FAILED:
4812731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        progressState = STATE_AUTODISCOVER_AUTH_DIALOG;
4822731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        break;
4832731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                    case MessagingException.AUTODISCOVER_AUTHENTICATION_RESULT:
4842731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        progressState = STATE_AUTODISCOVER_RESULT;
4852731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        break;
48655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    // NOTE: Security policies required has its own report state, handle it a bit
48755110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    // differently from the other exception types.
48855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                    case MessagingException.SECURITY_POLICIES_REQUIRED:
4892731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        progressState = STATE_CHECK_SHOW_SECURITY;
4902731aef45c6f2f9792ae698ebf7d65ca6338a02cAndrew Stadler                        break;
49155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler                }
49276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                mCallback.reportProgress(progressState, result);
49355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler            }
49455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        }
49555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    }
49655110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
49776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    /**
49876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler     * Convert progress to message
49976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler     */
50076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    protected static String getProgressString(Context context, int progress) {
50176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        int stringId = 0;
50276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        switch (progress) {
50376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            case STATE_CHECK_AUTODISCOVER:
50476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                stringId = R.string.account_setup_check_settings_retr_info_msg;
505715ee4ec4c5a7893b89c28b8569a7a109a5be970Ben Komalo                break;
50676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            case STATE_START:
50776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            case STATE_CHECK_INCOMING:
50876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                stringId = R.string.account_setup_check_settings_check_incoming_msg;
509715ee4ec4c5a7893b89c28b8569a7a109a5be970Ben Komalo                break;
51076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            case STATE_CHECK_OUTGOING:
51176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                stringId = R.string.account_setup_check_settings_check_outgoing_msg;
512715ee4ec4c5a7893b89c28b8569a7a109a5be970Ben Komalo                break;
513715ee4ec4c5a7893b89c28b8569a7a109a5be970Ben Komalo        }
51476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        if (stringId != 0) {
51576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            return context.getString(stringId);
51676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        } else {
51776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            return null;
51855110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        }
51955110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    }
52055110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler
52155110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    /**
52276472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler     * Convert mode to initial progress
52355110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler     */
52476472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler    protected static int getProgressForMode(int checkMode) {
52576472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        switch (checkMode) {
52676472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            case SetupDataFragment.CHECK_INCOMING:
52776472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                return STATE_CHECK_INCOMING;
52876472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            case SetupDataFragment.CHECK_OUTGOING:
52976472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                return STATE_CHECK_OUTGOING;
53076472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler            case SetupDataFragment.CHECK_AUTODISCOVER:
53176472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler                return STATE_CHECK_AUTODISCOVER;
53255110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler        }
53376472ae40cd55d17edb0420e8fc2a7bae60c50deTony Mantler        return STATE_START;
53455110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler    }
53555110ca1ad8ce48a5429f9f351d013691c10b806Andrew Stadler}
536