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