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