AccountSetupExchange.java revision 8bcb572ccfdac6974c111fe6dfc753a5e0d4e7ca
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.SecurityPolicy.PolicySet; 21import com.android.email.provider.EmailContent.Account; 22import com.android.email.provider.EmailContent.HostAuth; 23import com.android.email.service.EmailServiceProxy; 24 25import android.app.Activity; 26import android.content.Intent; 27import android.os.Bundle; 28import android.os.Parcelable; 29 30/** 31 * Provides generic setup for Exchange accounts. The following fields are supported: 32 * 33 * Email Address (from previous setup screen) 34 * Server 35 * Domain 36 * Requires SSL? 37 * User (login) 38 * Password 39 * 40 * There are two primary paths through this activity: 41 * Edit existing: 42 * Load existing values from account into fields 43 * When user clicks 'next': 44 * Confirm not a duplicate account 45 * Try new values (check settings) 46 * If new values are OK: 47 * Write new values (save to provider) 48 * finish() (pop to previous) 49 * 50 * Creating New: 51 * Try Auto-discover to get details from server 52 * If Auto-discover reports an authentication failure: 53 * finish() (pop to previous, to re-enter username & password) 54 * If Auto-discover succeeds: 55 * write server's account details into account 56 * Load values from account into fields 57 * Confirm not a duplicate account 58 * Try new values (check settings) 59 * If new values are OK: 60 * Write new values (save to provider) 61 * Proceed to options screen 62 * finish() (removes self from back stack) 63 * 64 * TODO: The manifest for this activity has it ignore config changes, because 65 * we don't want to restart on every orientation - this would launch autodiscover again. 66 * Do not attempt to define orientation-specific resources, they won't be loaded. 67 * What we really need here is a more "sticky" way to prevent that problem. 68 */ 69public class AccountSetupExchange extends AccountSetupActivity 70 implements AccountSetupExchangeFragment.Callback { 71 72 /* package */ AccountSetupExchangeFragment mFragment; 73 private boolean mNextButtonEnabled; 74 75 public static void actionIncomingSettings(Activity fromActivity, int mode, Account acct) { 76 SetupData.init(mode, acct); 77 fromActivity.startActivity(new Intent(fromActivity, AccountSetupExchange.class)); 78 } 79 80 public static void actionEditIncomingSettings(Activity fromActivity, int mode, Account acct) { 81 actionIncomingSettings(fromActivity, mode, acct); 82 } 83 84 /** 85 * For now, we'll simply replicate outgoing, for the purpose of satisfying the 86 * account settings flow. 87 */ 88 public static void actionEditOutgoingSettings(Activity fromActivity, int mode, Account acct) { 89 actionIncomingSettings(fromActivity, mode, acct); 90 } 91 92 @Override 93 public void onCreate(Bundle savedInstanceState) { 94 super.onCreate(savedInstanceState); 95 setContentView(R.layout.account_setup_exchange); 96 97 mFragment = (AccountSetupExchangeFragment) 98 getFragmentManager().findFragmentById(R.id.setup_fragment); 99 mFragment.setCallback(this); 100 101 startAutoDiscover(); 102 } 103 104 /** 105 * If the conditions are right, launch the autodiscover activity. If it succeeds (even 106 * partially) it will prefill the setup fields and we can proceed as if the user entered them. 107 * 108 * Conditions for skipping: 109 * Editing existing account 110 * AutoDiscover blocked (used for unit testing only) 111 * Username or password not entered yet 112 */ 113 private void startAutoDiscover() { 114 if (SetupData.getFlowMode() == SetupData.FLOW_MODE_EDIT 115 || !SetupData.isAllowAutodiscover()) { 116 return; 117 } 118 119 Account account = SetupData.getAccount(); 120 // If we've got a username and password and we're NOT editing, try autodiscover 121 String username = account.mHostAuthRecv.mLogin; 122 String password = account.mHostAuthRecv.mPassword; 123 if (username != null && password != null) { 124 AccountSetupCheckSettings.actionAutoDiscover(this, account.mEmailAddress, password); 125 } 126 } 127 128 /** 129 * There are three cases handled here, so we split out into separate sections. 130 * 1. Validate existing account (edit) 131 * 2. Validate new account 132 * 3. Autodiscover for new account 133 * 134 * For each case, there are two or more paths for success or failure. 135 */ 136 @Override 137 public void onActivityResult(int requestCode, int resultCode, Intent data) { 138 if (requestCode == AccountSetupCheckSettings.REQUEST_CODE_VALIDATE) { 139 if (SetupData.getFlowMode() == SetupData.FLOW_MODE_EDIT) { 140 doActivityResultValidateExistingAccount(resultCode, data); 141 } else { 142 doActivityResultValidateNewAccount(resultCode, data); 143 } 144 } else if (requestCode == AccountSetupCheckSettings.REQUEST_CODE_AUTO_DISCOVER) { 145 doActivityResultAutoDiscoverNewAccount(resultCode, data); 146 } 147 } 148 149 /** 150 * Process activity result when validating existing account. If OK, save and finish; 151 * otherwise simply remain in activity for further editing. 152 */ 153 private void doActivityResultValidateExistingAccount(int resultCode, Intent data) { 154 if (resultCode == RESULT_OK) { 155 mFragment.saveSettingsAfterEdit(); 156 finish(); 157 } 158 } 159 160 /** 161 * Process activity result when validating new account 162 */ 163 private void doActivityResultValidateNewAccount(int resultCode, Intent data) { 164 if (resultCode == RESULT_OK) { 165 // Go directly to next screen 166 PolicySet ps = null; 167 if ((data != null) && data.hasExtra(EmailServiceProxy.VALIDATE_BUNDLE_POLICY_SET)) { 168 ps = (PolicySet)data.getParcelableExtra( 169 EmailServiceProxy.VALIDATE_BUNDLE_POLICY_SET); 170 } 171 AccountSetupOptions.actionOptions(this); 172 finish(); 173 } else if (resultCode == AccountSetupCheckSettings.RESULT_SECURITY_REQUIRED_USER_CANCEL) { 174 finish(); 175 } 176 // else (resultCode not OK) - just return into this activity for further editing 177 } 178 179 /** 180 * Process activity result when provisioning new account via autodiscovery 181 */ 182 private void doActivityResultAutoDiscoverNewAccount(int resultCode, Intent data) { 183 // If authentication failed, exit immediately (to re-enter credentials) 184 if (resultCode == AccountSetupCheckSettings.RESULT_AUTO_DISCOVER_AUTH_FAILED) { 185 finish(); 186 return; 187 } 188 189 // If data was returned, populate the account & populate the UI fields and validate it 190 if (data != null) { 191 Parcelable p = data.getParcelableExtra("HostAuth"); 192 if (p != null) { 193 HostAuth hostAuth = (HostAuth)p; 194 boolean valid = mFragment.setHostAuthFromAutodiscover(hostAuth); 195 if (valid) { 196 // "click" next to launch server verification 197 mFragment.onNext(); 198 } 199 } 200 } 201 // Otherwise, proceed into this activity for manual setup 202 } 203 204 /** 205 * Implements AccountServerBaseFragment.Callback 206 */ 207 public void onEnableProceedButtons(boolean enabled) { 208 boolean wasEnabled = mNextButtonEnabled; 209 mNextButtonEnabled = enabled; 210 211 if (enabled != wasEnabled) { 212 invalidateOptionsMenu(); 213 } 214 } 215 216 /** 217 * Implements AccountServerBaseFragment.Callback 218 */ 219 public void onProceedNext(int checkMode) { 220 AccountSetupCheckSettings.actionCheckSettings(this, checkMode); 221 } 222} 223