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