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