Home | History | Annotate | Download | only in setup
      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