AccountSettingsFragment.java revision 55110ca1ad8ce48a5429f9f351d013691c10b806
1/*
2 * Copyright (C) 2010 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.R;
21import com.android.email.Utility;
22import com.android.email.mail.MessagingException;
23import com.android.email.mail.Sender;
24import com.android.email.mail.Store;
25import com.android.email.provider.EmailContent.Account;
26import com.android.email.provider.EmailContent.HostAuth;
27
28import android.app.Activity;
29import android.app.AlertDialog;
30import android.app.Dialog;
31import android.app.DialogFragment;
32import android.app.Fragment;
33import android.content.ContentResolver;
34import android.content.Context;
35import android.content.DialogInterface;
36import android.content.SharedPreferences;
37import android.os.AsyncTask;
38import android.os.Bundle;
39import android.preference.CheckBoxPreference;
40import android.preference.EditTextPreference;
41import android.preference.ListPreference;
42import android.preference.Preference;
43import android.preference.PreferenceCategory;
44import android.preference.PreferenceFragment;
45import android.preference.RingtonePreference;
46import android.provider.Calendar;
47import android.provider.ContactsContract;
48import android.util.Log;
49
50/**
51 * Fragment containing the main logic for account settings.  This also calls out to other
52 * fragments for server settings.
53 *
54 * TODO: Move all "Restore" ops & other queries out of lifecycle methods and out of UI thread
55 * TODO: Can we defer calling addPreferencesFromResource() until after we load the account?  This
56 *       could reduce flicker.
57 *
58 * STOPSHIP: Find a permanent home for delete account
59 *
60 * STOPSHIP: Remove fragment lifecycle logging
61 */
62public class AccountSettingsFragment extends PreferenceFragment {
63
64    // Keys used for arguments bundle
65    private static final String BUNDLE_KEY_ACCOUNT_ID = "AccountSettingsFragment.AccountId";
66
67    private static final String PREFERENCE_TOP_CATEGORY = "account_settings";
68    private static final String PREFERENCE_DESCRIPTION = "account_description";
69    private static final String PREFERENCE_NAME = "account_name";
70    private static final String PREFERENCE_SIGNATURE = "account_signature";
71    private static final String PREFERENCE_FREQUENCY = "account_check_frequency";
72    private static final String PREFERENCE_DEFAULT = "account_default";
73    private static final String PREFERENCE_NOTIFY = "account_notify";
74    private static final String PREFERENCE_VIBRATE_WHEN = "account_settings_vibrate_when";
75    private static final String PREFERENCE_RINGTONE = "account_ringtone";
76    private static final String PREFERENCE_SERVER_CATEGORY = "account_servers";
77    private static final String PREFERENCE_INCOMING = "incoming";
78    private static final String PREFERENCE_OUTGOING = "outgoing";
79    private static final String PREFERENCE_SYNC_CONTACTS = "account_sync_contacts";
80    private static final String PREFERENCE_SYNC_CALENDAR = "account_sync_calendar";
81    private static final String PREFERENCE_DELETE_ACCOUNT_CATEGORY = "category_delete_account";
82    private static final String PREFERENCE_DELETE_ACCOUNT = "delete_account";
83
84    // These strings must match account_settings_vibrate_when_* strings in strings.xml
85    private static final String PREFERENCE_VALUE_VIBRATE_WHEN_ALWAYS = "always";
86    private static final String PREFERENCE_VALUE_VIBRATE_WHEN_SILENT = "silent";
87    private static final String PREFERENCE_VALUE_VIBRATE_WHEN_NEVER = "never";
88
89    private EditTextPreference mAccountDescription;
90    private EditTextPreference mAccountName;
91    private EditTextPreference mAccountSignature;
92    private ListPreference mCheckFrequency;
93    private ListPreference mSyncWindow;
94    private CheckBoxPreference mAccountDefault;
95    private CheckBoxPreference mAccountNotify;
96    private ListPreference mAccountVibrateWhen;
97    private RingtonePreference mAccountRingtone;
98    private CheckBoxPreference mSyncContacts;
99    private CheckBoxPreference mSyncCalendar;
100
101    private Context mContext;
102    private Account mAccount;
103    private boolean mAccountDirty;
104    private Callback mCallback = EmptyCallback.INSTANCE;
105    private boolean mStarted;
106    private boolean mLoaded;
107    private boolean mSaveOnExit;
108
109    // Async Tasks
110    private AsyncTask<?,?,?> mLoadAccountTask;
111
112    /**
113     * Callback interface that owning activities must provide
114     */
115    public interface Callback {
116        public void onIncomingSettings(Account account);
117        public void onOutgoingSettings(Account account);
118        public void abandonEdit();
119        public void deleteAccount(Account account);
120    }
121
122    private static class EmptyCallback implements Callback {
123        public static final Callback INSTANCE = new EmptyCallback();
124        @Override public void onIncomingSettings(Account account) { }
125        @Override public void onOutgoingSettings(Account account) { }
126        @Override public void abandonEdit() { }
127        @Override public void deleteAccount(Account account) { };
128    }
129
130    /**
131     * If launching with an arguments bundle, use this method to build the arguments.
132     * @param accountId The account being modified
133     */
134    public static Bundle buildArguments(long accountId) {
135        Bundle b = new Bundle();
136        b.putLong(BUNDLE_KEY_ACCOUNT_ID, accountId);
137        return b;
138    }
139
140    /**
141     * Called when a fragment is first attached to its activity.
142     * {@link #onCreate(Bundle)} will be called after this.
143     */
144    public void onAttach(Activity activity) {
145        super.onAttach(activity);
146
147        mContext = activity;
148
149        // Notify the activity that we're here.
150        if (activity instanceof AccountSettingsXL) {
151            ((AccountSettingsXL)activity).onAttach(this);
152        }
153    }
154
155    /**
156     * Called to do initial creation of a fragment.  This is called after
157     * {@link #onAttach(Activity)} and before {@link #onActivityCreated(Bundle)}.
158     */
159    @Override
160    public void onCreate(Bundle savedInstanceState) {
161        if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
162            Log.d(Email.LOG_TAG, "MailboxListFragment onCreate");
163        }
164        super.onCreate(savedInstanceState);
165
166        // Load the preferences from an XML resource
167        addPreferencesFromResource(R.xml.account_settings_preferences);
168
169        // Start loading the account data, if provided in the arguments
170        // If not, activity must call startLoadingAccount() directly
171        Bundle b = getArguments();
172        if (b != null) {
173            long accountId = b.getLong(BUNDLE_KEY_ACCOUNT_ID, -1);
174            if (accountId >= 0 && !mLoaded) {
175                startLoadingAccount(accountId);
176            }
177        }
178
179        mAccountDirty = false;
180    }
181
182    @Override
183    public void onActivityCreated(Bundle savedInstanceState) {
184        if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
185            Log.d(Email.LOG_TAG, "MailboxListFragment onActivityCreated");
186        }
187        super.onActivityCreated(savedInstanceState);
188    }
189
190    /**
191     * Called when the Fragment is visible to the user.
192     */
193    @Override
194    public void onStart() {
195        if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
196            Log.d(Email.LOG_TAG, "MailboxListFragment onStart");
197        }
198        super.onStart();
199        mStarted = true;
200
201        // If the loaded account is ready now, load the UI
202        if (mAccount != null && !mLoaded) {
203            loadSettings();
204        }
205    }
206
207    /**
208     * Called when the fragment is visible to the user and actively running.
209     */
210    @Override
211    public void onResume() {
212        if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
213            Log.d(Email.LOG_TAG, "MailboxListFragment onResume");
214        }
215        super.onResume();
216
217        if (mAccountDirty) {
218            // if we are coming back from editing incoming or outgoing settings,
219            // we need to refresh them here so we don't accidentally overwrite the
220            // old values we're still holding here
221            mAccount.mHostAuthRecv =
222                HostAuth.restoreHostAuthWithId(mContext, mAccount.mHostAuthKeyRecv);
223            mAccount.mHostAuthSend =
224                HostAuth.restoreHostAuthWithId(mContext, mAccount.mHostAuthKeySend);
225            // Because "delete policy" UI is on edit incoming settings, we have
226            // to refresh that as well.
227            Account refreshedAccount = Account.restoreAccountWithId(mContext, mAccount.mId);
228            if (refreshedAccount == null || mAccount.mHostAuthRecv == null
229                    || mAccount.mHostAuthSend == null) {
230                mSaveOnExit = false;
231                mCallback.abandonEdit();
232                return;
233            }
234            mAccount.setDeletePolicy(refreshedAccount.getDeletePolicy());
235            mAccountDirty = false;
236        }
237    }
238
239    @Override
240    public void onPause() {
241        if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
242            Log.d(Email.LOG_TAG, "MailboxListFragment onPause");
243        }
244        super.onPause();
245    }
246
247    /**
248     * Called when the Fragment is no longer started.
249     */
250    @Override
251    public void onStop() {
252        if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
253            Log.d(Email.LOG_TAG, "MailboxListFragment onStop");
254        }
255        super.onStop();
256        mStarted = false;
257    }
258
259    /**
260     * Called when the fragment is no longer in use.
261     */
262    @Override
263    public void onDestroy() {
264        if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
265            Log.d(Email.LOG_TAG, "MailboxListFragment onDestroy");
266        }
267        super.onDestroy();
268
269        Utility.cancelTaskInterrupt(mLoadAccountTask);
270        mLoadAccountTask = null;
271
272        // If there is good account data and we have not abandoned it, save it now
273        if (mSaveOnExit) {
274            saveSettings();
275            mSaveOnExit = false;
276        }
277    }
278
279    @Override
280    public void onSaveInstanceState(Bundle outState) {
281        if (Email.DEBUG_LIFECYCLE && Email.DEBUG) {
282            Log.d(Email.LOG_TAG, "MailboxListFragment onSaveInstanceState");
283        }
284        super.onSaveInstanceState(outState);
285    }
286
287    /**
288     * Activity provides callbacks here
289     */
290    public void setCallback(Callback callback) {
291        mCallback = (callback == null) ? EmptyCallback.INSTANCE : callback;
292    }
293
294    /**
295     * Start loading a single account in preparation for editing it
296     */
297    public void startLoadingAccount(long accountId) {
298        Utility.cancelTaskInterrupt(mLoadAccountTask);
299        mLoadAccountTask = new LoadAccountTask().execute(accountId);
300    }
301
302    /**
303     * Async task to load account in order to view/edit it
304     */
305    private class LoadAccountTask extends AsyncTask<Long, Void, Account> {
306        @Override
307        protected Account doInBackground(Long... params) {
308            long accountId = params[0];
309            Account account = Account.restoreAccountWithId(mContext, accountId);
310            if (account != null) {
311                account.mHostAuthRecv =
312                    HostAuth.restoreHostAuthWithId(mContext, account.mHostAuthKeyRecv);
313                account.mHostAuthSend =
314                    HostAuth.restoreHostAuthWithId(mContext, account.mHostAuthKeySend);
315                if (account.mHostAuthRecv == null || account.mHostAuthSend == null) {
316                    account = null;
317                }
318            }
319            return account;
320        }
321
322        @Override
323        protected void onPostExecute(Account account) {
324            if (!isCancelled()) {
325                if (account == null) {
326                    mSaveOnExit = false;
327                    mCallback.abandonEdit();
328                } else {
329                    mAccount = account;
330                    if (mStarted && !mLoaded) {
331                        loadSettings();
332                    }
333                }
334            }
335        }
336    }
337
338    /**
339     * Load account data into preference UI
340     */
341    private void loadSettings() {
342        // We can only do this once, so prevent repeat
343        mLoaded = true;
344        // Once loaded the data is ready to be saved, as well
345        mSaveOnExit = true;
346
347        PreferenceCategory topCategory =
348            (PreferenceCategory) findPreference(PREFERENCE_TOP_CATEGORY);
349        topCategory.setTitle(mContext.getString(R.string.account_settings_title_fmt));
350
351        mAccountDescription = (EditTextPreference) findPreference(PREFERENCE_DESCRIPTION);
352        mAccountDescription.setSummary(mAccount.getDisplayName());
353        mAccountDescription.setText(mAccount.getDisplayName());
354        mAccountDescription.setOnPreferenceChangeListener(
355            new Preference.OnPreferenceChangeListener() {
356                public boolean onPreferenceChange(Preference preference, Object newValue) {
357                    final String summary = newValue.toString();
358                    mAccountDescription.setSummary(summary);
359                    mAccountDescription.setText(summary);
360                    return false;
361                }
362            }
363        );
364
365        mAccountName = (EditTextPreference) findPreference(PREFERENCE_NAME);
366        mAccountName.setSummary(mAccount.getSenderName());
367        mAccountName.setText(mAccount.getSenderName());
368        mAccountName.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
369            public boolean onPreferenceChange(Preference preference, Object newValue) {
370                final String summary = newValue.toString();
371                mAccountName.setSummary(summary);
372                mAccountName.setText(summary);
373                return false;
374            }
375        });
376
377        mAccountSignature = (EditTextPreference) findPreference(PREFERENCE_SIGNATURE);
378        mAccountSignature.setSummary(mAccount.getSignature());
379        mAccountSignature.setText(mAccount.getSignature());
380        mAccountSignature.setOnPreferenceChangeListener(
381                new Preference.OnPreferenceChangeListener() {
382                    public boolean onPreferenceChange(Preference preference, Object newValue) {
383                        String summary = newValue.toString();
384                        if (summary == null || summary.length() == 0) {
385                            mAccountSignature.setSummary(R.string.account_settings_signature_hint);
386                        } else {
387                            mAccountSignature.setSummary(summary);
388                        }
389                        mAccountSignature.setText(summary);
390                        return false;
391                    }
392                });
393
394        mCheckFrequency = (ListPreference) findPreference(PREFERENCE_FREQUENCY);
395
396        // Before setting value, we may need to adjust the lists
397        Store.StoreInfo info = Store.StoreInfo.getStoreInfo(mAccount.getStoreUri(mContext),
398                mContext);
399        if (info.mPushSupported) {
400            mCheckFrequency.setEntries(R.array.account_settings_check_frequency_entries_push);
401            mCheckFrequency.setEntryValues(R.array.account_settings_check_frequency_values_push);
402        }
403
404        mCheckFrequency.setValue(String.valueOf(mAccount.getSyncInterval()));
405        mCheckFrequency.setSummary(mCheckFrequency.getEntry());
406        mCheckFrequency.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
407            public boolean onPreferenceChange(Preference preference, Object newValue) {
408                final String summary = newValue.toString();
409                int index = mCheckFrequency.findIndexOfValue(summary);
410                mCheckFrequency.setSummary(mCheckFrequency.getEntries()[index]);
411                mCheckFrequency.setValue(summary);
412                return false;
413            }
414        });
415
416        // Add check window preference
417        mSyncWindow = null;
418        if (info.mVisibleLimitDefault == -1) {
419            mSyncWindow = new ListPreference(mContext);
420            mSyncWindow.setTitle(R.string.account_setup_options_mail_window_label);
421            mSyncWindow.setEntries(R.array.account_settings_mail_window_entries);
422            mSyncWindow.setEntryValues(R.array.account_settings_mail_window_values);
423            mSyncWindow.setValue(String.valueOf(mAccount.getSyncLookback()));
424            mSyncWindow.setSummary(mSyncWindow.getEntry());
425            mSyncWindow.setOrder(4);
426            mSyncWindow.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
427                public boolean onPreferenceChange(Preference preference, Object newValue) {
428                    final String summary = newValue.toString();
429                    int index = mSyncWindow.findIndexOfValue(summary);
430                    mSyncWindow.setSummary(mSyncWindow.getEntries()[index]);
431                    mSyncWindow.setValue(summary);
432                    return false;
433                }
434            });
435            topCategory.addPreference(mSyncWindow);
436        }
437
438        mAccountDefault = (CheckBoxPreference) findPreference(PREFERENCE_DEFAULT);
439        mAccountDefault.setChecked(mAccount.mId == Account.getDefaultAccountId(mContext));
440
441        mAccountNotify = (CheckBoxPreference) findPreference(PREFERENCE_NOTIFY);
442        mAccountNotify.setChecked(0 != (mAccount.getFlags() & Account.FLAGS_NOTIFY_NEW_MAIL));
443
444        mAccountRingtone = (RingtonePreference) findPreference(PREFERENCE_RINGTONE);
445
446        // The following two lines act as a workaround for the RingtonePreference
447        // which does not let us set/get the value programmatically
448        SharedPreferences prefs = mAccountRingtone.getPreferenceManager().getSharedPreferences();
449        prefs.edit().putString(PREFERENCE_RINGTONE, mAccount.getRingtone()).commit();
450
451        mAccountVibrateWhen = (ListPreference) findPreference(PREFERENCE_VIBRATE_WHEN);
452        boolean flagsVibrate = 0 != (mAccount.getFlags() & Account.FLAGS_VIBRATE_ALWAYS);
453        boolean flagsVibrateSilent = 0 != (mAccount.getFlags() & Account.FLAGS_VIBRATE_WHEN_SILENT);
454        mAccountVibrateWhen.setValue(
455                flagsVibrate ? PREFERENCE_VALUE_VIBRATE_WHEN_ALWAYS :
456                flagsVibrateSilent ? PREFERENCE_VALUE_VIBRATE_WHEN_SILENT :
457                    PREFERENCE_VALUE_VIBRATE_WHEN_NEVER);
458
459        findPreference(PREFERENCE_INCOMING).setOnPreferenceClickListener(
460                new Preference.OnPreferenceClickListener() {
461                    public boolean onPreferenceClick(Preference preference) {
462                        mAccountDirty = true;
463                        mCallback.onIncomingSettings(mAccount);
464                        return true;
465                    }
466                });
467
468        // Hide the outgoing account setup link if it's not activated
469        Preference prefOutgoing = findPreference(PREFERENCE_OUTGOING);
470        boolean showOutgoing = true;
471        try {
472            Sender sender = Sender.getInstance(mContext, mAccount.getSenderUri(mContext));
473            if (sender != null) {
474                Class<? extends android.app.Activity> setting = sender.getSettingActivityClass();
475                showOutgoing = (setting != null);
476            }
477        } catch (MessagingException me) {
478            // just leave showOutgoing as true - bias towards showing it, so user can fix it
479        }
480        if (showOutgoing) {
481            prefOutgoing.setOnPreferenceClickListener(
482                    new Preference.OnPreferenceClickListener() {
483                        public boolean onPreferenceClick(Preference preference) {
484                            mAccountDirty = true;
485                            mCallback.onOutgoingSettings(mAccount);
486                            return true;
487                        }
488                    });
489        } else {
490            PreferenceCategory serverCategory = (PreferenceCategory) findPreference(
491                    PREFERENCE_SERVER_CATEGORY);
492            serverCategory.removePreference(prefOutgoing);
493        }
494
495        mSyncContacts = (CheckBoxPreference) findPreference(PREFERENCE_SYNC_CONTACTS);
496        mSyncCalendar = (CheckBoxPreference) findPreference(PREFERENCE_SYNC_CALENDAR);
497        if (mAccount.mHostAuthRecv.mProtocol.equals("eas")) {
498            android.accounts.Account acct = new android.accounts.Account(mAccount.mEmailAddress,
499                    Email.EXCHANGE_ACCOUNT_MANAGER_TYPE);
500            mSyncContacts.setChecked(ContentResolver
501                    .getSyncAutomatically(acct, ContactsContract.AUTHORITY));
502            mSyncCalendar.setChecked(ContentResolver
503                    .getSyncAutomatically(acct, Calendar.AUTHORITY));
504        } else {
505            PreferenceCategory serverCategory = (PreferenceCategory) findPreference(
506                    PREFERENCE_SERVER_CATEGORY);
507            serverCategory.removePreference(mSyncContacts);
508            serverCategory.removePreference(mSyncCalendar);
509        }
510
511        // Temporary home for delete account
512        Preference prefDeleteAccount = findPreference(PREFERENCE_DELETE_ACCOUNT);
513        prefDeleteAccount.setOnPreferenceClickListener(
514                new Preference.OnPreferenceClickListener() {
515                    public boolean onPreferenceClick(Preference preference) {
516                        DeleteAccountFragment dialogFragment = DeleteAccountFragment.newInstance(
517                                mAccount, AccountSettingsFragment.this);
518                        dialogFragment.show(getActivity(), DeleteAccountFragment.TAG);
519                        return true;
520                    }
521                });
522    }
523
524    /*
525     * TODO: Should collect the data in the UI thread, but should spin out a thread to write
526     * to sync settings, provider, and service enabler.
527     */
528    public void saveSettings() {
529        int newFlags = mAccount.getFlags() &
530                ~(Account.FLAGS_NOTIFY_NEW_MAIL |
531                        Account.FLAGS_VIBRATE_ALWAYS | Account.FLAGS_VIBRATE_WHEN_SILENT);
532
533        mAccount.setDefaultAccount(mAccountDefault.isChecked());
534        mAccount.setDisplayName(mAccountDescription.getText());
535        mAccount.setSenderName(mAccountName.getText());
536        mAccount.setSignature(mAccountSignature.getText());
537        newFlags |= mAccountNotify.isChecked() ? Account.FLAGS_NOTIFY_NEW_MAIL : 0;
538        mAccount.setSyncInterval(Integer.parseInt(mCheckFrequency.getValue()));
539        if (mSyncWindow != null) {
540            mAccount.setSyncLookback(Integer.parseInt(mSyncWindow.getValue()));
541        }
542        if (mAccountVibrateWhen.getValue().equals(PREFERENCE_VALUE_VIBRATE_WHEN_ALWAYS)) {
543            newFlags |= Account.FLAGS_VIBRATE_ALWAYS;
544        } else if (mAccountVibrateWhen.getValue().equals(PREFERENCE_VALUE_VIBRATE_WHEN_SILENT)) {
545            newFlags |= Account.FLAGS_VIBRATE_WHEN_SILENT;
546        }
547        SharedPreferences prefs = mAccountRingtone.getPreferenceManager().getSharedPreferences();
548        mAccount.setRingtone(prefs.getString(PREFERENCE_RINGTONE, null));
549        mAccount.setFlags(newFlags);
550
551        if (mAccount.mHostAuthRecv.mProtocol.equals("eas")) {
552            android.accounts.Account acct = new android.accounts.Account(mAccount.mEmailAddress,
553                    Email.EXCHANGE_ACCOUNT_MANAGER_TYPE);
554            ContentResolver.setSyncAutomatically(acct, ContactsContract.AUTHORITY,
555                    mSyncContacts.isChecked());
556            ContentResolver.setSyncAutomatically(acct, Calendar.AUTHORITY,
557                    mSyncCalendar.isChecked());
558
559        }
560        AccountSettingsUtils.commitSettings(mContext, mAccount);
561        Email.setServicesEnabled(mContext);
562    }
563
564    /**
565     * Dialog fragment to show "remove account?" dialog
566     */
567    public static class DeleteAccountFragment extends DialogFragment {
568        private final static String TAG = "DeleteAccountFragment";
569
570        // Argument bundle keys
571        private final static String BUNDLE_KEY_ACCOUNT_NAME = "DeleteAccountFragment.Name";
572
573        /**
574         * Create the dialog with parameters
575         */
576        public static DeleteAccountFragment newInstance(Account account, Fragment parentFragment) {
577            DeleteAccountFragment f = new DeleteAccountFragment();
578            Bundle b = new Bundle();
579            b.putString(BUNDLE_KEY_ACCOUNT_NAME, account.getDisplayName());
580            f.setArguments(b);
581            f.setTargetFragment(parentFragment, 0);
582            return f;
583        }
584
585        @Override
586        public Dialog onCreateDialog(Bundle savedInstanceState) {
587            Context context = getActivity();
588            final String name = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME);
589
590            return new AlertDialog.Builder(context)
591                .setIcon(android.R.drawable.ic_dialog_alert)
592                .setTitle(R.string.account_delete_dlg_title)
593                .setMessage(context.getString(R.string.account_delete_dlg_instructions_fmt, name))
594                .setPositiveButton(
595                        R.string.okay_action,
596                        new DialogInterface.OnClickListener() {
597                            public void onClick(DialogInterface dialog, int whichButton) {
598                                Fragment f = getTargetFragment();
599                                if (f instanceof AccountSettingsFragment) {
600                                    ((AccountSettingsFragment)f).finishDeleteAccount();
601                                }
602                                dismiss();
603                            }
604                        })
605                .setNegativeButton(
606                        R.string.cancel_action,
607                        new DialogInterface.OnClickListener() {
608                            public void onClick(DialogInterface dialog, int whichButton) {
609                                dismiss();
610                            }
611                        })
612                .create();
613        }
614    }
615
616    /**
617     * Callback from delete account dialog - passes the delete command up to the activity
618     */
619    private void finishDeleteAccount() {
620        mSaveOnExit = false;
621        mCallback.deleteAccount(mAccount);
622    }
623}
624