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