AccountSetupExchange.java revision f5418f1f93b02e7fab9f15eb201800b65510998e
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.email.activity.setup;
18
19import com.android.email.R;
20import com.android.email.activity.ActivityHelper;
21import com.android.email.activity.UiUtilities;
22import com.android.emailcommon.provider.Account;
23import com.android.emailcommon.provider.HostAuth;
24
25import android.app.Activity;
26import android.app.FragmentTransaction;
27import android.content.Intent;
28import android.os.Bundle;
29import android.view.View;
30import android.view.View.OnClickListener;
31import android.widget.Button;
32
33/**
34 * Provides generic setup for Exchange accounts.  The following fields are supported:
35 *
36 *  Email Address   (from previous setup screen)
37 *  Server
38 *  Domain
39 *  Requires SSL?
40 *  User (login)
41 *  Password
42 *
43 * There are two primary paths through this activity:
44 *   Edit existing:
45 *     Load existing values from account into fields
46 *     When user clicks 'next':
47 *       Confirm not a duplicate account
48 *       Try new values (check settings)
49 *       If new values are OK:
50 *         Write new values (save to provider)
51 *         finish() (pop to previous)
52 *
53 *   Creating New:
54 *     Try Auto-discover to get details from server
55 *     If Auto-discover reports an authentication failure:
56 *       finish() (pop to previous, to re-enter username & password)
57 *     If Auto-discover succeeds:
58 *       write server's account details into account
59 *     Load values from account into fields
60 *     Confirm not a duplicate account
61 *     Try new values (check settings)
62 *     If new values are OK:
63 *       Write new values (save to provider)
64 *       Proceed to options screen
65 *       finish() (removes self from back stack)
66 */
67public class AccountSetupExchange extends AccountSetupActivity
68        implements AccountSetupExchangeFragment.Callback, OnClickListener {
69
70    // Keys for savedInstanceState
71    private final static String STATE_STARTED_AUTODISCOVERY =
72            "AccountSetupExchange.StartedAutoDiscovery";
73
74    boolean mStartedAutoDiscovery;
75    /* package */ AccountSetupExchangeFragment mFragment;
76    private Button mNextButton;
77    /* package */ boolean mNextButtonEnabled;
78
79    public static void actionIncomingSettings(Activity fromActivity, int mode, Account account) {
80        SetupData.setFlowMode(mode);
81        SetupData.setAccount(account);
82        fromActivity.startActivity(new Intent(fromActivity, AccountSetupExchange.class));
83    }
84
85    @Override
86    public void onCreate(Bundle savedInstanceState) {
87        super.onCreate(savedInstanceState);
88        ActivityHelper.debugSetWindowFlags(this);
89        setContentView(R.layout.account_setup_exchange);
90
91        mFragment = (AccountSetupExchangeFragment)
92                getFragmentManager().findFragmentById(R.id.setup_fragment);
93        mFragment.setCallback(this);
94
95        mNextButton = (Button) UiUtilities.getView(this, R.id.next);
96        mNextButton.setOnClickListener(this);
97        UiUtilities.getView(this, R.id.previous).setOnClickListener(this);
98
99        // One-shot to launch autodiscovery at the entry to this activity (but not if it restarts)
100        mStartedAutoDiscovery = false;
101        if (savedInstanceState != null) {
102            mStartedAutoDiscovery = savedInstanceState.getBoolean(STATE_STARTED_AUTODISCOVERY);
103        }
104        if (!mStartedAutoDiscovery) {
105            startAutoDiscover();
106        }
107    }
108
109    /**
110     * Implements View.OnClickListener
111     */
112    @Override
113    public void onClick(View view) {
114        switch (view.getId()) {
115            case R.id.next:
116                mFragment.onNext();
117                break;
118            case R.id.previous:
119                onBackPressed();
120                break;
121        }
122    }
123
124    @Override
125    public void onSaveInstanceState(Bundle outState) {
126        super.onSaveInstanceState(outState);
127        outState.putBoolean(STATE_STARTED_AUTODISCOVERY, mStartedAutoDiscovery);
128    }
129
130    /**
131     * If the conditions are right, launch the autodiscover fragment.  If it succeeds (even
132     * partially) it will prefill the setup fields and we can proceed as if the user entered them.
133     *
134     * Conditions for skipping:
135     *  Editing existing account
136     *  AutoDiscover blocked (used for unit testing only)
137     *  Username or password not entered yet
138     */
139    private void startAutoDiscover() {
140        // Note that we've started autodiscovery - even if we decide not to do it,
141        // this prevents repeating.
142        mStartedAutoDiscovery = true;
143
144        if (!SetupData.isAllowAutodiscover()) {
145            return;
146        }
147
148        Account account = SetupData.getAccount();
149        // If we've got a username and password and we're NOT editing, try autodiscover
150        String username = account.mHostAuthRecv.mLogin;
151        String password = account.mHostAuthRecv.mPassword;
152        if (username != null && password != null) {
153            onProceedNext(SetupData.CHECK_AUTODISCOVER, mFragment);
154        }
155    }
156
157    /**
158     * Implements AccountCheckSettingsFragment.Callbacks
159     *
160     * @param result configuration data returned by AD server, or null if no data available
161     */
162    public void onAutoDiscoverComplete(int result, HostAuth hostAuth) {
163        // If authentication failed, exit immediately (to re-enter credentials)
164        if (result == AccountCheckSettingsFragment.AUTODISCOVER_AUTHENTICATION) {
165            finish();
166            return;
167        }
168
169        // If data was returned, populate the account & populate the UI fields and validate it
170        if (result == AccountCheckSettingsFragment.AUTODISCOVER_OK) {
171            boolean valid = mFragment.setHostAuthFromAutodiscover(hostAuth);
172            if (valid) {
173                // "click" next to launch server verification
174                mFragment.onNext();
175            }
176        }
177        // Otherwise, proceed into this activity for manual setup
178    }
179
180    /**
181     * Implements AccountServerBaseFragment.Callback
182     */
183    public void onProceedNext(int checkMode, AccountServerBaseFragment target) {
184        AccountCheckSettingsFragment checkerFragment =
185            AccountCheckSettingsFragment.newInstance(checkMode, target);
186        FragmentTransaction transaction = getFragmentManager().beginTransaction();
187        transaction.add(checkerFragment, AccountCheckSettingsFragment.TAG);
188        transaction.addToBackStack("back");
189        transaction.commit();
190    }
191
192    /**
193     * Implements AccountServerBaseFragment.Callback
194     */
195    public void onEnableProceedButtons(boolean enable) {
196        mNextButtonEnabled = enable;
197        mNextButton.setEnabled(enable);
198    }
199
200    /**
201     * Implements AccountServerBaseFragment.Callback
202     *
203     * If the checked settings are OK, proceed to options screen.  If the user rejects security,
204     * exit this screen.  For all other errors, remain here for editing.
205     */
206    public void onCheckSettingsComplete(int result, int setupMode) {
207        switch (result) {
208            case AccountCheckSettingsFragment.CHECK_SETTINGS_OK:
209                AccountSetupOptions.actionOptions(this);
210                finish();
211                break;
212            case AccountCheckSettingsFragment.CHECK_SETTINGS_SECURITY_USER_DENY:
213                finish();
214                break;
215            default:
216            case AccountCheckSettingsFragment.CHECK_SETTINGS_SERVER_ERROR:
217                // Do nothing - remain in this screen
218                break;
219        }
220    }
221}
222