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 17 package com.android.email.activity.setup; 18 19 import com.android.email.R; 20 import com.android.email.activity.ActivityHelper; 21 import com.android.email.activity.UiUtilities; 22 import com.android.emailcommon.provider.Account; 23 import com.android.emailcommon.provider.HostAuth; 24 25 import android.app.Activity; 26 import android.app.FragmentTransaction; 27 import android.content.Intent; 28 import android.os.Bundle; 29 import android.view.View; 30 import android.view.View.OnClickListener; 31 import 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 */ 67 public 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