AccountSetupOptions.java revision 2959a7e073c87e2fa5fab42ec543b352a91cf187
1/* 2 * Copyright (C) 2008 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.Email; 20import com.android.email.ExchangeUtils; 21import com.android.email.R; 22import com.android.email.SecurityPolicy.PolicySet; 23import com.android.email.activity.ActivityHelper; 24import com.android.email.mail.Store; 25import com.android.email.provider.EmailContent; 26import com.android.email.provider.EmailContent.Account; 27import com.android.email.service.MailService; 28 29import android.accounts.AccountManagerCallback; 30import android.accounts.AccountManagerFuture; 31import android.accounts.AuthenticatorException; 32import android.accounts.OperationCanceledException; 33import android.app.Activity; 34import android.app.AlertDialog; 35import android.content.DialogInterface; 36import android.content.Intent; 37import android.os.Bundle; 38import android.os.Handler; 39import android.util.Log; 40import android.view.View; 41import android.view.View.OnClickListener; 42import android.widget.ArrayAdapter; 43import android.widget.CheckBox; 44import android.widget.Spinner; 45 46import java.io.IOException; 47 48public class AccountSetupOptions extends AccountSetupActivity implements OnClickListener { 49 50 private Spinner mCheckFrequencyView; 51 private Spinner mSyncWindowView; 52 private CheckBox mDefaultView; 53 private CheckBox mNotifyView; 54 private CheckBox mSyncContactsView; 55 private CheckBox mSyncCalendarView; 56 private CheckBox mSyncEmailView; 57 private Handler mHandler = new Handler(); 58 private boolean mDonePressed = false; 59 60 public static final int REQUEST_CODE_ACCEPT_POLICIES = 1; 61 62 /** Default sync window for new EAS accounts */ 63 private static final int SYNC_WINDOW_EAS_DEFAULT = com.android.email.Account.SYNC_WINDOW_3_DAYS; 64 65 public static void actionOptions(Activity fromActivity) { 66 fromActivity.startActivity(new Intent(fromActivity, AccountSetupOptions.class)); 67 } 68 69 @Override 70 public void onCreate(Bundle savedInstanceState) { 71 super.onCreate(savedInstanceState); 72 ActivityHelper.debugSetWindowFlags(this); 73 setContentView(R.layout.account_setup_options); 74 75 mCheckFrequencyView = (Spinner)findViewById(R.id.account_check_frequency); 76 mSyncWindowView = (Spinner) findViewById(R.id.account_sync_window); 77 mDefaultView = (CheckBox)findViewById(R.id.account_default); 78 mNotifyView = (CheckBox)findViewById(R.id.account_notify); 79 mSyncContactsView = (CheckBox) findViewById(R.id.account_sync_contacts); 80 mSyncCalendarView = (CheckBox) findViewById(R.id.account_sync_calendar); 81 mSyncEmailView = (CheckBox) findViewById(R.id.account_sync_email); 82 mSyncEmailView.setChecked(true); 83 findViewById(R.id.previous).setOnClickListener(this); 84 findViewById(R.id.next).setOnClickListener(this); 85 86 // Generate spinner entries using XML arrays used by the preferences 87 int frequencyValuesId; 88 int frequencyEntriesId; 89 Account account = SetupData.getAccount(); 90 Store.StoreInfo info = Store.StoreInfo.getStoreInfo(account.getStoreUri(this), this); 91 if (info.mPushSupported) { 92 frequencyValuesId = R.array.account_settings_check_frequency_values_push; 93 frequencyEntriesId = R.array.account_settings_check_frequency_entries_push; 94 } else { 95 frequencyValuesId = R.array.account_settings_check_frequency_values; 96 frequencyEntriesId = R.array.account_settings_check_frequency_entries; 97 } 98 CharSequence[] frequencyValues = getResources().getTextArray(frequencyValuesId); 99 CharSequence[] frequencyEntries = getResources().getTextArray(frequencyEntriesId); 100 101 // Now create the array used by the Spinner 102 SpinnerOption[] checkFrequencies = new SpinnerOption[frequencyEntries.length]; 103 for (int i = 0; i < frequencyEntries.length; i++) { 104 checkFrequencies[i] = new SpinnerOption( 105 Integer.valueOf(frequencyValues[i].toString()), frequencyEntries[i].toString()); 106 } 107 108 ArrayAdapter<SpinnerOption> checkFrequenciesAdapter = new ArrayAdapter<SpinnerOption>(this, 109 android.R.layout.simple_spinner_item, checkFrequencies); 110 checkFrequenciesAdapter 111 .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 112 mCheckFrequencyView.setAdapter(checkFrequenciesAdapter); 113 114 if (info.mVisibleLimitDefault == -1) { 115 enableEASSyncWindowSpinner(); 116 } 117 118 // Note: It is OK to use mAccount.mIsDefault here *only* because the account 119 // has not been written to the DB yet. Ordinarily, call Account.getDefaultAccountId(). 120 if (account.mIsDefault || SetupData.isDefault()) { 121 mDefaultView.setChecked(true); 122 } 123 mNotifyView.setChecked( 124 (account.getFlags() & EmailContent.Account.FLAGS_NOTIFY_NEW_MAIL) != 0); 125 SpinnerOption.setSpinnerOptionValue(mCheckFrequencyView, account.getSyncInterval()); 126 127 // Setup any additional items to support EAS & EAS flow mode 128 if ("eas".equals(info.mScheme)) { 129 // "also sync contacts" == "true" 130 mSyncContactsView.setVisibility(View.VISIBLE); 131 mSyncContactsView.setChecked(true); 132 mSyncCalendarView.setVisibility(View.VISIBLE); 133 mSyncCalendarView.setChecked(true); 134 // Show the associated dividers 135 findViewById(R.id.account_sync_contacts_divider).setVisibility(View.VISIBLE); 136 findViewById(R.id.account_sync_calendar_divider).setVisibility(View.VISIBLE); 137 } 138 139 // If we are just visiting here to fill in details, exit immediately 140 if (SetupData.isAutoSetup() || 141 SetupData.getFlowMode() == SetupData.FLOW_MODE_FORCE_CREATE) { 142 onDone(); 143 } 144 } 145 146 /** 147 * Respond to clicks in the "Next" or "Previous" buttons 148 */ 149 @Override 150 public void onClick(View view) { 151 switch (view.getId()) { 152 case R.id.next: 153 // Don't allow this more than once (Exchange accounts call an async method 154 // before finish()'ing the Activity, which allows this code to potentially be 155 // executed multiple times 156 if (!mDonePressed) { 157 onDone(); 158 mDonePressed = true; 159 } 160 break; 161 case R.id.previous: 162 onBackPressed(); 163 break; 164 } 165 } 166 167 AccountManagerCallback<Bundle> mAccountManagerCallback = new AccountManagerCallback<Bundle>() { 168 public void run(AccountManagerFuture<Bundle> future) { 169 try { 170 Bundle bundle = future.getResult(); 171 bundle.keySet(); 172 mHandler.post(new Runnable() { 173 public void run() { 174 optionsComplete(); 175 } 176 }); 177 return; 178 } catch (OperationCanceledException e) { 179 Log.d(Email.LOG_TAG, "addAccount was canceled"); 180 } catch (IOException e) { 181 Log.d(Email.LOG_TAG, "addAccount failed: " + e); 182 } catch (AuthenticatorException e) { 183 Log.d(Email.LOG_TAG, "addAccount failed: " + e); 184 } 185 showErrorDialog(R.string.account_setup_failed_dlg_auth_message, 186 R.string.system_account_create_failed); 187 } 188 }; 189 190 private void showErrorDialog(final int msgResId, final Object... args) { 191 mHandler.post(new Runnable() { 192 public void run() { 193 new AlertDialog.Builder(AccountSetupOptions.this) 194 .setIcon(android.R.drawable.ic_dialog_alert) 195 .setTitle(getString(R.string.account_setup_failed_dlg_title)) 196 .setMessage(getString(msgResId, args)) 197 .setCancelable(true) 198 .setPositiveButton( 199 getString(R.string.account_setup_failed_dlg_edit_details_action), 200 new DialogInterface.OnClickListener() { 201 public void onClick(DialogInterface dialog, int which) { 202 finish(); 203 } 204 }) 205 .show(); 206 } 207 }); 208 } 209 210 @Override 211 public void onActivityResult(int requestCode, int resultCode, Intent data) { 212 saveAccountAndFinish(); 213 } 214 215 private void optionsComplete() { 216 // If we've got policies for this account, ask the user to accept. 217 Account account = SetupData.getAccount(); 218 if ((account.mFlags & Account.FLAGS_SECURITY_HOLD) != 0) { 219 Intent intent = AccountSecurity.actionUpdateSecurityIntent(this, account.mId); 220 startActivityForResult(intent, AccountSetupOptions.REQUEST_CODE_ACCEPT_POLICIES); 221 return; 222 } 223 saveAccountAndFinish(); 224 } 225 226 /** 227 * STOPSHIP most of this work needs to be async 228 */ 229 private void saveAccountAndFinish() { 230 // Clear the incomplete/security hold flag now 231 Account account = SetupData.getAccount(); 232 account.mFlags &= ~(Account.FLAGS_INCOMPLETE | Account.FLAGS_SECURITY_HOLD); 233 AccountSettingsUtils.commitSettings(this, account); 234 Email.setServicesEnabledSync(this); 235 AccountSetupNames.actionSetNames(this); 236 // Start up ExchangeService (if it isn't already running) 237 ExchangeUtils.startExchangeService(this); 238 finish(); 239 } 240 241 private void onDone() { 242 Account account = SetupData.getAccount(); 243 account.setDisplayName(account.getEmailAddress()); 244 int newFlags = account.getFlags() & ~(EmailContent.Account.FLAGS_NOTIFY_NEW_MAIL); 245 if (mNotifyView.isChecked()) { 246 newFlags |= EmailContent.Account.FLAGS_NOTIFY_NEW_MAIL; 247 } 248 account.setFlags(newFlags); 249 account.setSyncInterval((Integer)((SpinnerOption)mCheckFrequencyView 250 .getSelectedItem()).value); 251 if (findViewById(R.id.account_sync_window_row).getVisibility() == View.VISIBLE) { 252 int window = (Integer)((SpinnerOption)mSyncWindowView.getSelectedItem()).value; 253 account.setSyncLookback(window); 254 } 255 account.setDefaultAccount(mDefaultView.isChecked()); 256 257 // Setup up the AccountManager account 258 if (!account.isSaved() && account.mHostAuthRecv != null) { 259 // Set the incomplete flag here to avoid reconciliation issues in ExchangeService 260 account.mFlags |= Account.FLAGS_INCOMPLETE; 261 boolean calendar = false; 262 boolean contacts = false; 263 boolean email = mSyncEmailView.isChecked(); 264 if (account.mHostAuthRecv.mProtocol.equals("eas")) { 265 // Set security hold if necessary to prevent sync until policies are accepted 266 PolicySet policySet = SetupData.getPolicySet(); 267 if (policySet != null && policySet.getSecurityCode() != 0) { 268 account.mSecurityFlags = policySet.getSecurityCode(); 269 account.mFlags |= Account.FLAGS_SECURITY_HOLD; 270 } 271 // Get flags for contacts/calendar sync 272 contacts = mSyncContactsView.isChecked(); 273 calendar = mSyncCalendarView.isChecked(); 274 } 275 AccountSettingsUtils.commitSettings(this, account); 276 MailService.setupAccountManagerAccount(this, account, email, calendar, contacts, 277 mAccountManagerCallback); 278 } else { 279 optionsComplete(); 280 } 281 } 282 283 /** 284 * Enable an additional spinner using the arrays normally handled by preferences 285 */ 286 private void enableEASSyncWindowSpinner() { 287 // Show everything 288 findViewById(R.id.account_sync_window_row).setVisibility(View.VISIBLE); 289 290 // Generate spinner entries using XML arrays used by the preferences 291 CharSequence[] windowValues = getResources().getTextArray( 292 R.array.account_settings_mail_window_values); 293 CharSequence[] windowEntries = getResources().getTextArray( 294 R.array.account_settings_mail_window_entries); 295 296 // Now create the array used by the Spinner 297 SpinnerOption[] windowOptions = new SpinnerOption[windowEntries.length]; 298 int defaultIndex = -1; 299 for (int i = 0; i < windowEntries.length; i++) { 300 final int value = Integer.valueOf(windowValues[i].toString()); 301 windowOptions[i] = new SpinnerOption(value, windowEntries[i].toString()); 302 if (value == SYNC_WINDOW_EAS_DEFAULT) { 303 defaultIndex = i; 304 } 305 } 306 307 ArrayAdapter<SpinnerOption> windowOptionsAdapter = new ArrayAdapter<SpinnerOption>(this, 308 android.R.layout.simple_spinner_item, windowOptions); 309 windowOptionsAdapter 310 .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 311 mSyncWindowView.setAdapter(windowOptionsAdapter); 312 313 SpinnerOption.setSpinnerOptionValue(mSyncWindowView, 314 SetupData.getAccount().getSyncLookback()); 315 if (defaultIndex >= 0) { 316 mSyncWindowView.setSelection(defaultIndex); 317 } 318 } 319} 320