Merge "Unify settings activity" into ub-mail-master
This commit is contained in:
commit
88580cd5e0
|
@ -272,30 +272,40 @@
|
|||
android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Must be exported in order for the AccountManager to launch it -->
|
||||
<activity
|
||||
android:name=".activity.setup.AccountSettings"
|
||||
android:label="@string/settings_activity_title"
|
||||
android:exported="true"
|
||||
>
|
||||
android:exported="false" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.EDIT" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data
|
||||
android:scheme="content"
|
||||
android:host="ui.email.android.com"
|
||||
android:pathPrefix="/settings"
|
||||
/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.android.mail.ui.settings.PublicPreferenceActivity"
|
||||
android:label="@string/settings_activity_title"
|
||||
android:exported="true"
|
||||
android:theme="@android:style/Theme.NoDisplay" >
|
||||
<!-- Must be exported in order for the AccountManager to launch it -->
|
||||
<intent-filter>
|
||||
<action android:name="com.android.email.activity.setup.ACCOUNT_MANAGER_ENTRY" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.EDIT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data
|
||||
android:scheme="content"
|
||||
android:host="ui.email.android.com"
|
||||
android:pathPrefix="/settings"
|
||||
/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".activity.setup.AccountServerSettingsActivity"
|
||||
android:label="@string/mailbox_settings_activity_title"
|
||||
android:exported="false">
|
||||
</activity>
|
||||
<!-- a Headless Activity to load the account from the account id before navigating to the
|
||||
Incoming Account Settings fragment -->
|
||||
<activity
|
||||
|
|
|
@ -215,6 +215,23 @@ public final class Account extends EmailContent implements Parcelable {
|
|||
Account.CONTENT_URI, Account.CONTENT_PROJECTION, id, observer);
|
||||
}
|
||||
|
||||
public static Account restoreAccountWithAddress(Context context, String emailAddress) {
|
||||
return restoreAccountWithAddress(context, emailAddress, null);
|
||||
}
|
||||
|
||||
public static Account restoreAccountWithAddress(Context context, String emailAddress,
|
||||
ContentObserver observer) {
|
||||
final Cursor c = context.getContentResolver().query(CONTENT_URI,
|
||||
new String[] {AccountColumns._ID},
|
||||
AccountColumns.EMAIL_ADDRESS + "=?", new String[] {emailAddress},
|
||||
null);
|
||||
if (c == null || !c.moveToFirst()) {
|
||||
return null;
|
||||
}
|
||||
final long id = c.getLong(c.getColumnIndex(AccountColumns._ID));
|
||||
return restoreAccountWithId(context, id, observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getContentNotificationUri() {
|
||||
return Account.CONTENT_URI;
|
||||
|
@ -323,6 +340,7 @@ public final class Account extends EmailContent implements Parcelable {
|
|||
return mSignature;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setSignature(String signature) {
|
||||
mSignature = signature;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/account_server_settings_container">
|
||||
|
||||
</ScrollView>
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.email.activity.setup;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.email.R;
|
||||
import com.android.emailcommon.provider.Account;
|
||||
import com.android.mail.utils.LogUtils;
|
||||
|
||||
public class AccountServerSettingsActivity extends AccountSetupActivity implements
|
||||
SecurityRequiredDialogFragment.Callback, CheckSettingsErrorDialogFragment.Callback,
|
||||
AccountCheckSettingsFragment.Callback, AccountServerBaseFragment.Callback,
|
||||
CheckSettingsProgressDialogFragment.Callback {
|
||||
|
||||
/**
|
||||
* {@link com.android.emailcommon.provider.Account}
|
||||
*/
|
||||
private static final String EXTRA_ACCOUNT = "account";
|
||||
/**
|
||||
* Incoming or Outgoing settings?
|
||||
*/
|
||||
private static final String EXTRA_WHICH_SETTINGS = "whichSettings";
|
||||
private static final String INCOMING_SETTINGS = "incoming";
|
||||
private static final String OUTGOING_SETTINGS = "outgoing";
|
||||
|
||||
private AccountServerBaseFragment mAccountServerFragment;
|
||||
|
||||
public static Intent getIntentForIncoming(final Context context, final Account account) {
|
||||
final Intent intent = new Intent(context, AccountServerSettingsActivity.class);
|
||||
intent.putExtra(EXTRA_ACCOUNT, account);
|
||||
intent.putExtra(EXTRA_WHICH_SETTINGS, INCOMING_SETTINGS);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent getIntentForOutgoing(final Context context, final Account account) {
|
||||
final Intent intent = new Intent(context, AccountServerSettingsActivity.class);
|
||||
intent.putExtra(EXTRA_ACCOUNT, account);
|
||||
intent.putExtra(EXTRA_WHICH_SETTINGS, OUTGOING_SETTINGS);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mSetupData.setFlowMode(SetupDataFragment.FLOW_MODE_EDIT);
|
||||
|
||||
// TODO: this activity is ugly as sin
|
||||
setContentView(R.layout.account_server_settings);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
final Account account = getIntent().getParcelableExtra(EXTRA_ACCOUNT);
|
||||
if (account == null) {
|
||||
throw new IllegalArgumentException("No account present in intent");
|
||||
}
|
||||
mSetupData.setAccount(account);
|
||||
final String whichSettings = getIntent().getStringExtra(EXTRA_WHICH_SETTINGS);
|
||||
final AccountServerBaseFragment f;
|
||||
if (OUTGOING_SETTINGS.equals(whichSettings)) {
|
||||
f = AccountSetupOutgoingFragment.newInstance(true);
|
||||
} else {
|
||||
f = AccountSetupIncomingFragment.newInstance(true);
|
||||
}
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(R.id.account_server_settings_container, f)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachFragment(Fragment fragment) {
|
||||
super.onAttachFragment(fragment);
|
||||
if (fragment instanceof AccountServerBaseFragment) {
|
||||
mAccountServerFragment = (AccountServerBaseFragment) fragment;
|
||||
}
|
||||
}
|
||||
|
||||
public AccountServerBaseFragment getAccountServerFragment() {
|
||||
return mAccountServerFragment;
|
||||
}
|
||||
|
||||
private void forceBack() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Any time we exit via this pathway we put up the exit-save-changes dialog.
|
||||
*/
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
final AccountServerBaseFragment accountServerFragment = getAccountServerFragment();
|
||||
if (accountServerFragment != null) {
|
||||
if (accountServerFragment.haveSettingsChanged()) {
|
||||
UnsavedChangesDialogFragment dialogFragment =
|
||||
UnsavedChangesDialogFragment.newInstanceForBack();
|
||||
dialogFragment.show(getFragmentManager(), UnsavedChangesDialogFragment.TAG);
|
||||
return; // Prevent "back" from being handled
|
||||
}
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextButton() {}
|
||||
|
||||
/**
|
||||
* Save process is done, dismiss the fragment.
|
||||
*/
|
||||
@Override
|
||||
public void onAccountServerSaveComplete() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountServerUIComplete(int checkMode) {
|
||||
final Fragment checkerDialog = CheckSettingsProgressDialogFragment.newInstance(checkMode);
|
||||
final Fragment checkerFragment = AccountCheckSettingsFragment.newInstance(checkMode);
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(checkerDialog, CheckSettingsProgressDialogFragment.TAG)
|
||||
.add(checkerFragment, AccountCheckSettingsFragment.TAG)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsProgressDialogCancel() {
|
||||
dismissCheckSettingsFragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* After verifying a new server configuration as OK, we return here and continue. This kicks
|
||||
* off the save process.
|
||||
*/
|
||||
@Override
|
||||
public void onCheckSettingsComplete() {
|
||||
dismissCheckSettingsFragment();
|
||||
final AccountServerBaseFragment f = getAccountServerFragment();
|
||||
if (f != null) {
|
||||
f.saveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsSecurityRequired(String hostName) {
|
||||
dismissCheckSettingsFragment();
|
||||
SecurityRequiredDialogFragment.newInstance(hostName)
|
||||
.show(getFragmentManager(), SecurityRequiredDialogFragment.TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsError(int reason, String message) {
|
||||
dismissCheckSettingsFragment();
|
||||
CheckSettingsErrorDialogFragment.newInstance(reason, message)
|
||||
.show(getFragmentManager(), CheckSettingsErrorDialogFragment.TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsAutoDiscoverComplete(int result) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
private void dismissCheckSettingsFragment() {
|
||||
final Fragment f =
|
||||
getFragmentManager().findFragmentByTag(AccountCheckSettingsFragment.TAG);
|
||||
final Fragment d =
|
||||
getFragmentManager().findFragmentByTag(CheckSettingsProgressDialogFragment.TAG);
|
||||
getFragmentManager().beginTransaction()
|
||||
.remove(f)
|
||||
.remove(d)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSecurityRequiredDialogResult(boolean ok) {
|
||||
if (ok) {
|
||||
final AccountServerBaseFragment f = getAccountServerFragment();
|
||||
if (f != null) {
|
||||
f.saveSettings();
|
||||
}
|
||||
}
|
||||
// else just stay here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsErrorDialogEditSettings() {
|
||||
// Just stay here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsErrorDialogEditCertificate() {
|
||||
final AccountServerBaseFragment f = getAccountServerFragment();
|
||||
if (f instanceof AccountSetupIncomingFragment) {
|
||||
AccountSetupIncomingFragment asif = (AccountSetupIncomingFragment) f;
|
||||
asif.onCertificateRequested();
|
||||
} else {
|
||||
LogUtils.wtf(LogUtils.TAG, "Tried to change cert on non-incoming screen?");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog fragment to show "exit with unsaved changes?" dialog
|
||||
*/
|
||||
public static class UnsavedChangesDialogFragment extends DialogFragment {
|
||||
final static String TAG = "UnsavedChangesDialogFragment";
|
||||
|
||||
/**
|
||||
* Creates a save changes dialog when the user navigates "back".
|
||||
* {@link #onBackPressed()} defines in which case this may be triggered.
|
||||
*/
|
||||
public static UnsavedChangesDialogFragment newInstanceForBack() {
|
||||
return new UnsavedChangesDialogFragment();
|
||||
}
|
||||
|
||||
// Force usage of newInstance()
|
||||
public UnsavedChangesDialogFragment() {}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final AccountServerSettingsActivity activity =
|
||||
(AccountServerSettingsActivity) getActivity();
|
||||
|
||||
return new AlertDialog.Builder(activity)
|
||||
.setIconAttribute(android.R.attr.alertDialogIcon)
|
||||
.setTitle(android.R.string.dialog_alert_title)
|
||||
.setMessage(R.string.account_settings_exit_server_settings)
|
||||
.setPositiveButton(
|
||||
android.R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
activity.forceBack();
|
||||
dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(
|
||||
activity.getString(android.R.string.cancel), null)
|
||||
.create();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,41 +17,21 @@
|
|||
package com.android.email.activity.setup;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.util.Linkify;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.email.R;
|
||||
import com.android.email.provider.EmailProvider;
|
||||
import com.android.emailcommon.Logging;
|
||||
import com.android.emailcommon.provider.Account;
|
||||
import com.android.emailcommon.provider.EmailContent.AccountColumns;
|
||||
import com.android.emailcommon.utility.IntentUtilities;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
import com.android.mail.providers.Folder;
|
||||
import com.android.mail.providers.UIProvider.EditSettingsExtras;
|
||||
import com.android.mail.ui.settings.MailPreferenceActivity;
|
||||
import com.android.mail.utils.LogUtils;
|
||||
import com.android.mail.utils.Utils;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -60,20 +40,11 @@ import java.util.List;
|
|||
*
|
||||
* This activity uses the following fragments:
|
||||
* AccountSettingsFragment
|
||||
* Account{Incoming/Outgoing}Fragment
|
||||
* AccountCheckSettingsFragment
|
||||
* GeneralPreferences
|
||||
* DebugFragment
|
||||
*
|
||||
* TODO: Delete account - on single-pane view (phone UX) the account list doesn't update properly
|
||||
* TODO: Handle dynamic changes to the account list (exit if necessary). It probably makes
|
||||
* sense to use a loader for the accounts list, because it would provide better support for
|
||||
* dealing with accounts being added/deleted and triggering the header reload.
|
||||
*/
|
||||
public class AccountSettings extends MailPreferenceActivity implements
|
||||
SetupDataFragment.SetupDataContainer, SecurityRequiredDialogFragment.Callback,
|
||||
CheckSettingsErrorDialogFragment.Callback, AccountCheckSettingsFragment.Callback,
|
||||
AccountServerBaseFragment.Callback, CheckSettingsProgressDialogFragment.Callback {
|
||||
public class AccountSettings extends MailPreferenceActivity {
|
||||
/*
|
||||
* Intent to open account settings for account=1
|
||||
adb shell am start -a android.intent.action.EDIT \
|
||||
|
@ -85,20 +56,13 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
private static final String EXTRA_LOGIN_WARNING_FOR_ACCOUNT = "AccountSettings.for_account";
|
||||
private static final String EXTRA_LOGIN_WARNING_REASON_FOR_ACCOUNT =
|
||||
"AccountSettings.for_account_reason";
|
||||
private static final String EXTRA_TITLE = "AccountSettings.title";
|
||||
// STOPSHIP: Do not ship with the debug menu allowed.
|
||||
private static final boolean DEBUG_MENU_ALLOWED = false;
|
||||
public static final String EXTRA_NO_ACCOUNTS = "AccountSettings.no_account";
|
||||
public static final String EXTRA_ACCOUNT = "AccountSettings.account";
|
||||
|
||||
// Intent extras for launch directly from system account manager
|
||||
// NOTE: This string must match the one in res/xml/account_preferences.xml
|
||||
private static String INTENT_ACCOUNT_MANAGER_ENTRY;
|
||||
// NOTE: This constant should eventually be defined in android.accounts.Constants
|
||||
private static final String EXTRA_ACCOUNT_MANAGER_ACCOUNT = "account";
|
||||
|
||||
// Key for arguments bundle for QuickResponse editing
|
||||
private static final String QUICK_RESPONSE_ACCOUNT_KEY = "account";
|
||||
|
||||
// Key codes used to open a debug settings fragment.
|
||||
private static final int[] SECRET_KEY_CODES = {
|
||||
|
@ -107,35 +71,13 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
};
|
||||
private int mSecretKeyCodeIndex = 0;
|
||||
|
||||
// Support for account-by-name lookup
|
||||
private static final String SELECTION_ACCOUNT_EMAIL_ADDRESS =
|
||||
AccountColumns.EMAIL_ADDRESS + "=?";
|
||||
|
||||
// When the user taps "Email Preferences" 10 times in a row, we'll enable the debug settings.
|
||||
private int mNumGeneralHeaderClicked = 0;
|
||||
|
||||
private long mRequestedAccountId;
|
||||
private Header[] mAccountListHeaders;
|
||||
private Header mAppPreferencesHeader;
|
||||
private AccountSettingsFragment mAccountSettingsFragment;
|
||||
private AccountServerBaseFragment mAccountServerFragment;
|
||||
private long mDeletingAccountId = -1;
|
||||
private boolean mShowDebugMenu;
|
||||
private List<Header> mGeneratedHeaders;
|
||||
private Uri mFeedbackUri;
|
||||
private MenuItem mFeedbackMenuItem;
|
||||
|
||||
private SetupDataFragment mSetupData;
|
||||
|
||||
// Async Tasks
|
||||
private LoadAccountListTask mLoadAccountListTask;
|
||||
private GetAccountIdFromAccountTask mGetAccountIdFromAccountTask;
|
||||
private ContentObserver mAccountObserver;
|
||||
|
||||
// Specific callbacks used by settings fragments
|
||||
private final AccountSettingsFragmentCallback mAccountSettingsFragmentCallback
|
||||
= new AccountSettingsFragmentCallback();
|
||||
|
||||
/**
|
||||
* Create and return an intent to display (and edit) settings for a specific account, or -1
|
||||
* for any/all accounts. If an account name string is provided, a warning dialog will be
|
||||
|
@ -169,7 +111,7 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
modIntent.putExtra(
|
||||
EXTRA_SHOW_FRAGMENT_ARGUMENTS,
|
||||
AccountSettingsFragment.buildArguments(
|
||||
accountId, IntentUtilities.getAccountNameFromIntent(intent)));
|
||||
IntentUtilities.getAccountNameFromIntent(intent)));
|
||||
modIntent.putExtra(EXTRA_NO_HEADERS, true);
|
||||
return modIntent;
|
||||
}
|
||||
|
@ -198,10 +140,12 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
INTENT_ACCOUNT_MANAGER_ENTRY = getString(R.string.intent_account_manager_entry);
|
||||
}
|
||||
if (INTENT_ACCOUNT_MANAGER_ENTRY.equals(i.getAction())) {
|
||||
// This case occurs if we're changing account settings from Settings -> Accounts
|
||||
mGetAccountIdFromAccountTask =
|
||||
(GetAccountIdFromAccountTask) new GetAccountIdFromAccountTask()
|
||||
.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, i);
|
||||
// This case occurs if we're changing account settings from Settings -> Accounts.
|
||||
// We get an account object in the intent, but it's not actually useful to us since
|
||||
// it's always just the first account of that type. The user can't specify which
|
||||
// account they wish to view from within the settings UI, so just dump them at the
|
||||
// main screen.
|
||||
// android.accounts.Account acct = i.getParcelableExtra("account");
|
||||
} else if (i.hasExtra(EditSettingsExtras.EXTRA_FOLDER)) {
|
||||
launchMailboxSettings(i);
|
||||
return;
|
||||
|
@ -210,75 +154,28 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
startActivity(setupIntent);
|
||||
finish();
|
||||
return;
|
||||
} else if (i.hasExtra(EXTRA_ACCOUNT)) {
|
||||
final Account account = i.getParcelableExtra(EXTRA_ACCOUNT);
|
||||
mSetupData = new SetupDataFragment(SetupDataFragment.FLOW_MODE_EDIT, account);
|
||||
} else {
|
||||
// Otherwise, we're called from within the Email app and look for our extras
|
||||
mRequestedAccountId = IntentUtilities.getAccountIdFromIntent(i);
|
||||
String loginWarningAccount = i.getStringExtra(EXTRA_LOGIN_WARNING_FOR_ACCOUNT);
|
||||
String loginWarningReason =
|
||||
i.getStringExtra(EXTRA_LOGIN_WARNING_REASON_FOR_ACCOUNT);
|
||||
if (loginWarningAccount != null) {
|
||||
// Show dialog (first time only - don't re-show on a rotation)
|
||||
LoginWarningDialog dialog =
|
||||
LoginWarningDialog.newInstance(loginWarningAccount, loginWarningReason);
|
||||
dialog.show(getFragmentManager(), "loginwarning");
|
||||
final long accountId = IntentUtilities.getAccountIdFromIntent(i);
|
||||
if (accountId != -1) {
|
||||
String loginWarningAccount = i.getStringExtra(EXTRA_LOGIN_WARNING_FOR_ACCOUNT);
|
||||
String loginWarningReason =
|
||||
i.getStringExtra(EXTRA_LOGIN_WARNING_REASON_FOR_ACCOUNT);
|
||||
final Bundle args = AccountSettingsFragment.buildArguments(accountId,
|
||||
loginWarningAccount, loginWarningReason);
|
||||
startPreferencePanel(AccountSettingsFragment.class.getName(), args,
|
||||
0, null, null, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mSetupData = savedInstanceState.getParcelable(SetupDataFragment.EXTRA_SETUP_DATA);
|
||||
}
|
||||
mShowDebugMenu = i.getBooleanExtra(EXTRA_ENABLE_DEBUG, false);
|
||||
|
||||
final String title = i.getStringExtra(EXTRA_TITLE);
|
||||
if (title != null) {
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
getActionBar().setDisplayOptions(
|
||||
ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
|
||||
|
||||
mAccountObserver = new ContentObserver(Utility.getMainThreadHandler()) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
updateAccounts();
|
||||
}
|
||||
};
|
||||
|
||||
mFeedbackUri = Utils.getValidUri(getString(R.string.email_feedback_uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(
|
||||
outState);
|
||||
// TODO: use the fragment manager to persist this
|
||||
outState.putParcelable(SetupDataFragment.EXTRA_SETUP_DATA, mSetupData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
getContentResolver().registerContentObserver(Account.NOTIFIER_URI, true, mAccountObserver);
|
||||
updateAccounts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
getContentResolver().unregisterContentObserver(mAccountObserver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
Utility.cancelTaskInterrupt(mLoadAccountListTask);
|
||||
mLoadAccountListTask = null;
|
||||
Utility.cancelTaskInterrupt(mGetAccountIdFromAccountTask);
|
||||
mGetAccountIdFromAccountTask = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for secret sequence and, if heard, enable debug menu
|
||||
*/
|
||||
|
@ -339,55 +236,10 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidFragment(String fragmentName) {
|
||||
// We need to make sure that a fragment about to be attached is valid. This corrects
|
||||
// a security vulnerability.
|
||||
return (TextUtils.equals(AccountSettingsFragment.class.getName(), fragmentName) ||
|
||||
TextUtils.equals(GeneralPreferences.class.getName(), fragmentName) ||
|
||||
TextUtils.equals(AccountSetupIncomingFragment.class.getName(), fragmentName) ||
|
||||
TextUtils.equals(AccountSettingsEditQuickResponsesFragment.class.getName(),
|
||||
fragmentName) ||
|
||||
TextUtils.equals(DebugFragment.class.getName(), fragmentName) ||
|
||||
super.isValidFragment(fragmentName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,
|
||||
int titleRes, int shortTitleRes) {
|
||||
final Intent intent = super.onBuildStartFragmentIntent(
|
||||
fragmentName, args, titleRes, shortTitleRes);
|
||||
|
||||
// When opening a sub-settings page (e.g. account specific page), see if we want to modify
|
||||
// the activity title.
|
||||
String title = AccountSettingsFragment.getTitleFromArgs(args);
|
||||
if ((titleRes == 0) && (title != null)) {
|
||||
intent.putExtra(EXTRA_TITLE, title);
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any time we exit via this pathway, and we are showing a server settings fragment,
|
||||
* we put up the exit-save-changes dialog. This will work for the following cases:
|
||||
* Cancel button
|
||||
* Back button
|
||||
* Up arrow in application icon
|
||||
* It will *not* apply in the following cases:
|
||||
* Click the parent breadcrumb - need to find a hook for this
|
||||
* Click in the header list (e.g. another account) - handled elsewhere
|
||||
*/
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
final AccountServerBaseFragment accountServerFragment = getAccountServerFragment();
|
||||
if (accountServerFragment != null) {
|
||||
if (accountServerFragment.haveSettingsChanged()) {
|
||||
UnsavedChangesDialogFragment dialogFragment =
|
||||
UnsavedChangesDialogFragment.newInstanceForBack();
|
||||
dialogFragment.show(getFragmentManager(), UnsavedChangesDialogFragment.TAG);
|
||||
return; // Prevent "back" from being handled
|
||||
}
|
||||
}
|
||||
super.onBackPressed();
|
||||
// This activity is not exported, so we can allow any fragment
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -415,46 +267,9 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
startActivity(setupIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the async reload of the accounts list (if the headers are being displayed)
|
||||
*/
|
||||
private void updateAccounts() {
|
||||
if (hasHeaders()) {
|
||||
Utility.cancelTaskInterrupt(mLoadAccountListTask);
|
||||
mLoadAccountListTask = (LoadAccountListTask)
|
||||
new LoadAccountListTask().executeOnExecutor(
|
||||
AsyncTask.THREAD_POOL_EXECUTOR, mDeletingAccountId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the current header (accounts) array into the one provided by the PreferenceActivity.
|
||||
* Skip any headers that match mDeletingAccountId (this is a quick-hide algorithm while a
|
||||
* background thread works on deleting the account). Also sets mRequestedAccountHeader if
|
||||
* we find the requested account (by id).
|
||||
*/
|
||||
@Override
|
||||
public void onBuildHeaders(List<Header> target) {
|
||||
// Always add app preferences as first header
|
||||
target.clear();
|
||||
target.add(getAppPreferencesHeader());
|
||||
|
||||
// Then add zero or more account headers as necessary
|
||||
if (mAccountListHeaders != null) {
|
||||
final int headerCount = mAccountListHeaders.length;
|
||||
for (int index = 0; index < headerCount; index++) {
|
||||
Header header = mAccountListHeaders[index];
|
||||
if (header != null && header.id != HEADER_ID_UNDEFINED) {
|
||||
if (header.id != mDeletingAccountId) {
|
||||
target.add(header);
|
||||
if (header.id == mRequestedAccountId) {
|
||||
mRequestedAccountId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onBuildExtraHeaders(List<Header> target) {
|
||||
super.onBuildExtraHeaders(target);
|
||||
// finally, if debug header is enabled, show it
|
||||
if (DEBUG_MENU_ALLOWED) {
|
||||
if (mShowDebugMenu) {
|
||||
|
@ -468,92 +283,6 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
target.add(debugHeader);
|
||||
}
|
||||
}
|
||||
|
||||
// Save for later use (see forceSwitch)
|
||||
mGeneratedHeaders = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and return the first header, for app preferences
|
||||
*/
|
||||
private Header getAppPreferencesHeader() {
|
||||
// Set up fixed header for general settings
|
||||
if (mAppPreferencesHeader == null) {
|
||||
mAppPreferencesHeader = new Header();
|
||||
mAppPreferencesHeader.title = getText(R.string.header_label_general_preferences);
|
||||
mAppPreferencesHeader.summary = null;
|
||||
mAppPreferencesHeader.iconRes = 0;
|
||||
mAppPreferencesHeader.fragment = GeneralPreferences.class.getName();
|
||||
mAppPreferencesHeader.fragmentArguments = null;
|
||||
}
|
||||
return mAppPreferencesHeader;
|
||||
}
|
||||
|
||||
/**
|
||||
* This AsyncTask reads the accounts list and generates the headers. When the headers are
|
||||
* ready, we'll trigger PreferenceActivity to refresh the account list with them.
|
||||
*
|
||||
* The array generated and stored in mAccountListHeaders may be sparse so any readers should
|
||||
* check for and skip over null entries, and should not assume array length is # of accounts.
|
||||
*
|
||||
* TODO: Smaller projection
|
||||
* TODO: Convert to Loader
|
||||
* TODO: Write a test, including operation of deletingAccountId param
|
||||
*/
|
||||
private class LoadAccountListTask extends AsyncTask<Long, Void, Object[]> {
|
||||
|
||||
@Override
|
||||
protected Object[] doInBackground(Long... params) {
|
||||
Header[] result = null;
|
||||
Boolean deletingAccountFound = false;
|
||||
final long deletingAccountId = params[0];
|
||||
|
||||
Cursor c = getContentResolver().query(
|
||||
Account.CONTENT_URI,
|
||||
Account.CONTENT_PROJECTION, null, null, null);
|
||||
try {
|
||||
int index = 0;
|
||||
result = new Header[c.getCount()];
|
||||
|
||||
while (c.moveToNext()) {
|
||||
final long accountId = c.getLong(Account.CONTENT_ID_COLUMN);
|
||||
if (accountId == deletingAccountId) {
|
||||
deletingAccountFound = true;
|
||||
continue;
|
||||
}
|
||||
final String name = c.getString(Account.CONTENT_DISPLAY_NAME_COLUMN);
|
||||
final String email = c.getString(Account.CONTENT_EMAIL_ADDRESS_COLUMN);
|
||||
final Header newHeader = new Header();
|
||||
newHeader.id = accountId;
|
||||
newHeader.title = name;
|
||||
newHeader.summary = email;
|
||||
newHeader.fragment = AccountSettingsFragment.class.getCanonicalName();
|
||||
newHeader.fragmentArguments =
|
||||
AccountSettingsFragment.buildArguments(accountId, email);
|
||||
|
||||
result[index++] = newHeader;
|
||||
}
|
||||
} finally {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
return new Object[] { result, deletingAccountFound };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Object[] result) {
|
||||
if (isCancelled() || result == null) return;
|
||||
// Extract the results
|
||||
final Header[] headers = (Header[]) result[0];
|
||||
final boolean deletingAccountFound = (Boolean) result[1];
|
||||
// report the settings
|
||||
mAccountListHeaders = headers;
|
||||
invalidateHeaders();
|
||||
if (!deletingAccountFound) {
|
||||
mDeletingAccountId = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -564,15 +293,6 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
*/
|
||||
@Override
|
||||
public void onHeaderClick(Header header, int position) {
|
||||
// special case when exiting the server settings fragments
|
||||
final AccountServerBaseFragment accountServerFragment = getAccountServerFragment();
|
||||
if ((accountServerFragment != null) && accountServerFragment.haveSettingsChanged()) {
|
||||
UnsavedChangesDialogFragment dialogFragment =
|
||||
UnsavedChangesDialogFragment.newInstanceForHeader(position);
|
||||
dialogFragment.show(getFragmentManager(), UnsavedChangesDialogFragment.TAG);
|
||||
return;
|
||||
}
|
||||
|
||||
// Secret keys: Click 10x to enable debug settings
|
||||
if (position == 0) {
|
||||
mNumGeneralHeaderClicked++;
|
||||
|
@ -587,424 +307,10 @@ public class AccountSettings extends MailPreferenceActivity implements
|
|||
super.onHeaderClick(header, position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to a specific header without checking for server settings fragments as done
|
||||
* in {@link #onHeaderClick(Header, int)}. Called after we interrupted a header switch
|
||||
* with a dialog, and the user OK'd it.
|
||||
*/
|
||||
private void forceSwitchHeader(int position) {
|
||||
// Ensure the UI visually shows the correct header selected
|
||||
setSelection(position);
|
||||
switchToHeader(mGeneratedHeaders.get(position));
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcefully go backward in the stack. This may potentially discard unsaved settings.
|
||||
*/
|
||||
private void forceBack() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachFragment(Fragment f) {
|
||||
super.onAttachFragment(f);
|
||||
|
||||
if (f instanceof AccountSettingsFragment) {
|
||||
final AccountSettingsFragment asf = (AccountSettingsFragment) f;
|
||||
mAccountSettingsFragment = asf;
|
||||
asf.setCallback(mAccountSettingsFragmentCallback);
|
||||
} else if (f instanceof AccountServerBaseFragment) {
|
||||
mAccountServerFragment = (AccountServerBaseFragment) f;
|
||||
} else {
|
||||
// Possibly uninteresting fragment, such as a dialog.
|
||||
return;
|
||||
}
|
||||
// When we're changing fragments, enable/disable the add account button
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected AccountSettingsFragment getSettingsFragment() {
|
||||
return mAccountSettingsFragment != null && mAccountSettingsFragment.isAdded() ?
|
||||
mAccountSettingsFragment : null;
|
||||
}
|
||||
|
||||
protected AccountServerBaseFragment getAccountServerFragment() {
|
||||
return mAccountServerFragment != null && mAccountServerFragment.isAdded() ?
|
||||
mAccountServerFragment : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callbacks for AccountSettingsFragment
|
||||
*/
|
||||
private class AccountSettingsFragmentCallback implements AccountSettingsFragment.Callback {
|
||||
@Override
|
||||
public void onSettingsChanged(long accountId, String preference, Object value) {
|
||||
AccountSettings.this.onSettingsChanged(accountId, preference, value);
|
||||
}
|
||||
@Override
|
||||
public void onEditQuickResponses(com.android.mail.providers.Account account) {
|
||||
AccountSettings.this.onEditQuickResponses(account);
|
||||
}
|
||||
@Override
|
||||
public void onIncomingSettings(Account account) {
|
||||
AccountSettings.this.onIncomingSettings(account);
|
||||
}
|
||||
@Override
|
||||
public void onOutgoingSettings(Account account) {
|
||||
AccountSettings.this.onOutgoingSettings(account);
|
||||
}
|
||||
@Override
|
||||
public void abandonEdit() {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNextButton() {}
|
||||
|
||||
/**
|
||||
* Save process is done, dismiss the fragment.
|
||||
*/
|
||||
@Override
|
||||
public void onAccountServerSaveComplete() {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountServerUIComplete(int checkMode) {
|
||||
Fragment checkerDialog = CheckSettingsProgressDialogFragment.newInstance(checkMode);
|
||||
Fragment checkerFragment = AccountCheckSettingsFragment.newInstance(checkMode);
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(checkerDialog, CheckSettingsProgressDialogFragment.TAG)
|
||||
.add(checkerFragment, AccountCheckSettingsFragment.TAG)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsProgressDialogCancel() {
|
||||
dismissCheckSettingsFragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* After verifying a new server configuration as OK, we return here and continue. This kicks
|
||||
* off the save process.
|
||||
*/
|
||||
@Override
|
||||
public void onCheckSettingsComplete() {
|
||||
dismissCheckSettingsFragment();
|
||||
final AccountServerBaseFragment f = getAccountServerFragment();
|
||||
if (f != null) {
|
||||
f.saveSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsSecurityRequired(String hostName) {
|
||||
dismissCheckSettingsFragment();
|
||||
SecurityRequiredDialogFragment.newInstance(hostName)
|
||||
.show(getFragmentManager(), SecurityRequiredDialogFragment.TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsError(int reason, String message) {
|
||||
dismissCheckSettingsFragment();
|
||||
CheckSettingsErrorDialogFragment.newInstance(reason, message)
|
||||
.show(getFragmentManager(), CheckSettingsErrorDialogFragment.TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsAutoDiscoverComplete(int result) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
private void dismissCheckSettingsFragment() {
|
||||
final Fragment f =
|
||||
getFragmentManager().findFragmentByTag(AccountCheckSettingsFragment.TAG);
|
||||
final Fragment d =
|
||||
getFragmentManager().findFragmentByTag(CheckSettingsProgressDialogFragment.TAG);
|
||||
getFragmentManager().beginTransaction()
|
||||
.remove(f)
|
||||
.remove(d)
|
||||
.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSecurityRequiredDialogResult(boolean ok) {
|
||||
if (ok) {
|
||||
final AccountServerBaseFragment f = getAccountServerFragment();
|
||||
if (f != null) {
|
||||
f.saveSettings();
|
||||
}
|
||||
}
|
||||
// else just stay here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsErrorDialogEditSettings() {
|
||||
// Just stay here
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckSettingsErrorDialogEditCertificate() {
|
||||
final AccountServerBaseFragment f = getAccountServerFragment();
|
||||
if (f instanceof AccountSetupIncomingFragment) {
|
||||
AccountSetupIncomingFragment asif = (AccountSetupIncomingFragment) f;
|
||||
asif.onCertificateRequested();
|
||||
} else {
|
||||
LogUtils.wtf(LogUtils.TAG, "Tried to change cert on non-incoming screen?");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Some of the settings have changed. Update internal state as necessary.
|
||||
*/
|
||||
public void onSettingsChanged(long accountId, String preference, Object value) {
|
||||
if (AccountSettingsFragment.PREFERENCE_DESCRIPTION.equals(preference)) {
|
||||
for (Header header : mAccountListHeaders) {
|
||||
if (header.id == accountId) {
|
||||
// Manually tweak the header title. We cannot rebuild the header list from
|
||||
// an account cursor as the account database has not been saved yet.
|
||||
header.title = value.toString();
|
||||
invalidateHeaders();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch to edit quick responses.
|
||||
*/
|
||||
public void onEditQuickResponses(com.android.mail.providers.Account account) {
|
||||
try {
|
||||
final Bundle args = new Bundle(1);
|
||||
args.putParcelable(QUICK_RESPONSE_ACCOUNT_KEY, account);
|
||||
startPreferencePanel(AccountSettingsEditQuickResponsesFragment.class.getName(), args,
|
||||
R.string.account_settings_edit_quick_responses_label, null, null, 0);
|
||||
} catch (Exception e) {
|
||||
LogUtils.d(Logging.LOG_TAG, "Error while trying to invoke edit quick responses.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch to edit incoming settings.
|
||||
*/
|
||||
public void onIncomingSettings(Account account) {
|
||||
try {
|
||||
mSetupData = new SetupDataFragment(SetupDataFragment.FLOW_MODE_EDIT, account);
|
||||
final Fragment f = AccountSetupIncomingFragment.newInstance(true);
|
||||
// Use startPreferenceFragment here because we need to keep this activity instance
|
||||
startPreferenceFragment(f, true);
|
||||
} catch (Exception e) {
|
||||
LogUtils.d(Logging.LOG_TAG, "Error while trying to invoke store settings.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch to edit outgoing settings.
|
||||
*/
|
||||
public void onOutgoingSettings(Account account) {
|
||||
try {
|
||||
mSetupData = new SetupDataFragment(SetupDataFragment.FLOW_MODE_EDIT, account);
|
||||
final Fragment f = AccountSetupOutgoingFragment.newInstance(true);
|
||||
// Use startPreferenceFragment here because we need to keep this activity instance
|
||||
startPreferenceFragment(f, true);
|
||||
} catch (Exception e) {
|
||||
LogUtils.d(Logging.LOG_TAG, "Error while trying to invoke sender settings.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the selected account
|
||||
*/
|
||||
public void deleteAccount(final Account account) {
|
||||
// Kick off the work to actually delete the account
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Uri uri = EmailProvider.uiUri("uiaccount", account.mId);
|
||||
getContentResolver().delete(uri, null, null);
|
||||
}}).start();
|
||||
|
||||
// TODO: Remove ui glue for unified
|
||||
// Then update the UI as appropriate:
|
||||
// If single pane, return to the header list. If multi, rebuild header list
|
||||
if (onIsMultiPane()) {
|
||||
final Header prefsHeader = getAppPreferencesHeader();
|
||||
this.switchToHeader(prefsHeader.fragment, prefsHeader.fragmentArguments);
|
||||
mDeletingAccountId = account.mId;
|
||||
updateAccounts();
|
||||
} else {
|
||||
// We should only be calling this while showing AccountSettingsFragment,
|
||||
// so a finish() should bring us back to headers. No point hiding the deleted account.
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This AsyncTask looks up an account based on its email address (which is what we get from
|
||||
* the Account Manager). When the account id is determined, we refresh the header list,
|
||||
* which will select the preferences for that account.
|
||||
*/
|
||||
private class GetAccountIdFromAccountTask extends AsyncTask<Intent, Void, Long> {
|
||||
|
||||
@Override
|
||||
protected Long doInBackground(Intent... params) {
|
||||
final Intent intent = params[0];
|
||||
android.accounts.Account acct =
|
||||
intent.getParcelableExtra(EXTRA_ACCOUNT_MANAGER_ACCOUNT);
|
||||
return Utility.getFirstRowLong(AccountSettings.this, Account.CONTENT_URI,
|
||||
Account.ID_PROJECTION, SELECTION_ACCOUNT_EMAIL_ADDRESS,
|
||||
new String[] {acct.name}, null, Account.ID_PROJECTION_COLUMN, -1L);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Long accountId) {
|
||||
if (accountId != -1 && !isCancelled()) {
|
||||
mRequestedAccountId = accountId;
|
||||
invalidateHeaders();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog fragment to show "exit with unsaved changes?" dialog
|
||||
*/
|
||||
public static class UnsavedChangesDialogFragment extends DialogFragment {
|
||||
final static String TAG = "UnsavedChangesDialogFragment";
|
||||
|
||||
// Argument bundle keys
|
||||
private final static String BUNDLE_KEY_HEADER = "UnsavedChangesDialogFragment.Header";
|
||||
private final static String BUNDLE_KEY_BACK = "UnsavedChangesDialogFragment.Back";
|
||||
|
||||
/**
|
||||
* Creates a save changes dialog when the user selects a new header
|
||||
* @param position The new header index to make active if the user accepts the dialog. This
|
||||
* must be a valid header index although there is no error checking.
|
||||
*/
|
||||
public static UnsavedChangesDialogFragment newInstanceForHeader(int position) {
|
||||
final UnsavedChangesDialogFragment f = new UnsavedChangesDialogFragment();
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putInt(BUNDLE_KEY_HEADER, position);
|
||||
f.setArguments(b);
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a save changes dialog when the user navigates "back".
|
||||
* {@link #onBackPressed()} defines in which case this may be triggered.
|
||||
*/
|
||||
public static UnsavedChangesDialogFragment newInstanceForBack() {
|
||||
final UnsavedChangesDialogFragment f = new UnsavedChangesDialogFragment();
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putBoolean(BUNDLE_KEY_BACK, true);
|
||||
f.setArguments(b);
|
||||
return f;
|
||||
}
|
||||
|
||||
// Force usage of newInstance()
|
||||
public UnsavedChangesDialogFragment() {}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final AccountSettings activity = (AccountSettings) getActivity();
|
||||
final int position = getArguments().getInt(BUNDLE_KEY_HEADER);
|
||||
final boolean isBack = getArguments().getBoolean(BUNDLE_KEY_BACK);
|
||||
|
||||
return new AlertDialog.Builder(activity)
|
||||
.setIconAttribute(android.R.attr.alertDialogIcon)
|
||||
.setTitle(android.R.string.dialog_alert_title)
|
||||
.setMessage(R.string.account_settings_exit_server_settings)
|
||||
.setPositiveButton(
|
||||
android.R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (isBack) {
|
||||
activity.forceBack();
|
||||
} else {
|
||||
activity.forceSwitchHeader(position);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(
|
||||
activity.getString(android.R.string.cancel), null)
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog briefly shown in some cases, to indicate the user that login failed. If the user
|
||||
* clicks OK, we simply dismiss the dialog, leaving the user in the account settings for
|
||||
* that account; If the user clicks "cancel", we exit account settings.
|
||||
*/
|
||||
public static class LoginWarningDialog extends DialogFragment
|
||||
implements DialogInterface.OnClickListener {
|
||||
private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name";
|
||||
private String mReason;
|
||||
|
||||
// Public no-args constructor needed for fragment re-instantiation
|
||||
public LoginWarningDialog() {}
|
||||
|
||||
/**
|
||||
* Create a new dialog.
|
||||
*/
|
||||
public static LoginWarningDialog newInstance(String accountName, String reason) {
|
||||
final LoginWarningDialog dialog = new LoginWarningDialog();
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName);
|
||||
dialog.setArguments(b);
|
||||
dialog.mReason = reason;
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME);
|
||||
|
||||
final Context context = getActivity();
|
||||
final Resources res = context.getResources();
|
||||
final AlertDialog.Builder b = new AlertDialog.Builder(context);
|
||||
b.setTitle(R.string.account_settings_login_dialog_title);
|
||||
b.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||
if (mReason != null) {
|
||||
final TextView message = new TextView(context);
|
||||
final String alert = res.getString(
|
||||
R.string.account_settings_login_dialog_reason_fmt, accountName, mReason);
|
||||
SpannableString spannableAlertString = new SpannableString(alert);
|
||||
Linkify.addLinks(spannableAlertString, Linkify.WEB_URLS);
|
||||
message.setText(spannableAlertString);
|
||||
// There must be a better way than specifying size/padding this way
|
||||
// It does work and look right, though
|
||||
final int textSize = res.getDimensionPixelSize(R.dimen.dialog_text_size);
|
||||
message.setTextSize(textSize);
|
||||
final int paddingLeft = res.getDimensionPixelSize(R.dimen.dialog_padding_left);
|
||||
final int paddingOther = res.getDimensionPixelSize(R.dimen.dialog_padding_other);
|
||||
message.setPadding(paddingLeft, paddingOther, paddingOther, paddingOther);
|
||||
message.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
b.setView(message);
|
||||
} else {
|
||||
b.setMessage(res.getString(R.string.account_settings_login_dialog_content_fmt,
|
||||
accountName));
|
||||
}
|
||||
b.setPositiveButton(android.R.string.ok, this);
|
||||
b.setNegativeButton(android.R.string.cancel, this);
|
||||
return b.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dismiss();
|
||||
if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetupDataFragment getSetupData() {
|
||||
return mSetupData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,12 +55,17 @@ import android.widget.TextView;
|
|||
public class AccountSettingsEditQuickResponsesFragment extends Fragment {
|
||||
private Account mAccount;
|
||||
|
||||
private static final String BUNDLE_KEY_ACTIVITY_TITLE
|
||||
= "AccountSettingsEditQuickResponsesFragment.title";
|
||||
private static final String ARG_ACCOUNT = "account";
|
||||
|
||||
// Public no-args constructor needed for fragment re-instantiation
|
||||
public AccountSettingsEditQuickResponsesFragment() {}
|
||||
|
||||
public static Bundle createArgs(final Account account) {
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putParcelable(ARG_ACCOUNT, account);
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
@ -69,11 +74,6 @@ public class AccountSettingsEditQuickResponsesFragment extends Fragment {
|
|||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
// startPreferencePanel launches this fragment with the right title initially, but
|
||||
// if the device is rotated we must set the title ourselves
|
||||
if (savedInstanceState != null) {
|
||||
getActivity().setTitle(savedInstanceState.getString(BUNDLE_KEY_ACTIVITY_TITLE));
|
||||
}
|
||||
|
||||
final SimpleCursorAdapter adapter = new SimpleCursorAdapter(getActivity(),
|
||||
R.layout.quick_response_item, null,
|
||||
|
@ -103,17 +103,12 @@ public class AccountSettingsEditQuickResponsesFragment extends Fragment {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putString(BUNDLE_KEY_ACTIVITY_TITLE, (String) getActivity().getTitle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Bundle args = getArguments();
|
||||
mAccount = args.getParcelable("account");
|
||||
mAccount = args.getParcelable(ARG_ACCOUNT);
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
|
|
@ -17,8 +17,16 @@
|
|||
package com.android.email.activity.setup;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.LoaderManager;
|
||||
import android.content.*;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.Loader;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.media.Ringtone;
|
||||
|
@ -30,15 +38,19 @@ import android.preference.CheckBoxPreference;
|
|||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.Preference.OnPreferenceClickListener;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.provider.CalendarContract;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.Settings;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.util.Linkify;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.email.R;
|
||||
import com.android.email.SecurityPolicy;
|
||||
|
@ -47,9 +59,9 @@ import com.android.email.provider.FolderPickerActivity;
|
|||
import com.android.email.service.EmailServiceUtils;
|
||||
import com.android.email.service.EmailServiceUtils.EmailServiceInfo;
|
||||
import com.android.email2.ui.MailActivityEmail;
|
||||
import com.android.emailcommon.Logging;
|
||||
import com.android.emailcommon.provider.Account;
|
||||
import com.android.emailcommon.provider.EmailContent;
|
||||
import com.android.emailcommon.provider.EmailContent.AccountColumns;
|
||||
import com.android.emailcommon.provider.Mailbox;
|
||||
import com.android.emailcommon.provider.Policy;
|
||||
import com.android.mail.preferences.AccountPreferences;
|
||||
|
@ -57,7 +69,9 @@ import com.android.mail.preferences.FolderPreferences;
|
|||
import com.android.mail.providers.Folder;
|
||||
import com.android.mail.providers.UIProvider;
|
||||
import com.android.mail.ui.MailAsyncTaskLoader;
|
||||
import com.android.mail.ui.settings.MailAccountPrefsFragment;
|
||||
import com.android.mail.ui.settings.SettingsUtils;
|
||||
import com.android.mail.utils.ContentProviderTask.UpdateTask;
|
||||
import com.android.mail.utils.LogUtils;
|
||||
import com.android.mail.utils.NotificationUtils;
|
||||
|
||||
|
@ -72,18 +86,23 @@ import java.util.Map;
|
|||
* TODO: Can we defer calling addPreferencesFromResource() until after we load the account? This
|
||||
* could reduce flicker.
|
||||
*/
|
||||
public class AccountSettingsFragment extends PreferenceFragment
|
||||
public class AccountSettingsFragment extends MailAccountPrefsFragment
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
// Keys used for arguments bundle
|
||||
private static final String BUNDLE_KEY_ACCOUNT_ID = "AccountSettingsFragment.AccountId";
|
||||
private static final String BUNDLE_KEY_ACCOUNT_EMAIL = "AccountSettingsFragment.Email";
|
||||
private static final String ARG_ACCOUNT_ID = "account_id";
|
||||
private static final String ARG_LOGIN_WARNING_FOR_ACCOUNT = "warning_for_account";
|
||||
private static final String ARG_LOGIN_WARNING_REASON_FOR_ACCOUNT = "warning_for_account_reason";
|
||||
|
||||
|
||||
public static final String PREFERENCE_DESCRIPTION = "account_description";
|
||||
private static final String PREFERENCE_NAME = "account_name";
|
||||
private static final String PREFERENCE_SIGNATURE = "account_signature";
|
||||
private static final String PREFERENCE_QUICK_RESPONSES = "account_quick_responses";
|
||||
private static final String PREFERENCE_FREQUENCY = "account_check_frequency";
|
||||
private static final String PREFERENCE_SYNC_WINDOW = "account_sync_window";
|
||||
private static final String PREFERENCE_SYNC_EMAIL = "account_sync_email";
|
||||
private static final String PREFERENCE_SYNC_CONTACTS = "account_sync_contacts";
|
||||
private static final String PREFERENCE_SYNC_CALENDAR = "account_sync_calendar";
|
||||
private static final String PREFERENCE_BACKGROUND_ATTACHMENTS =
|
||||
"account_background_attachments";
|
||||
private static final String PREFERENCE_CATEGORY_DATA_USAGE = "data_usage";
|
||||
|
@ -97,9 +116,6 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
private static final String PREFERENCE_POLICIES_RETRY_ACCOUNT = "policies_retry_account";
|
||||
private static final String PREFERENCE_INCOMING = "incoming";
|
||||
private static final String PREFERENCE_OUTGOING = "outgoing";
|
||||
private static final String PREFERENCE_SYNC_CONTACTS = "account_sync_contacts";
|
||||
private static final String PREFERENCE_SYNC_CALENDAR = "account_sync_calendar";
|
||||
private static final String PREFERENCE_SYNC_EMAIL = "account_sync_email";
|
||||
|
||||
private static final String PREFERENCE_SYSTEM_FOLDERS = "system_folders";
|
||||
private static final String PREFERENCE_SYSTEM_FOLDERS_TRASH = "system_folders_trash";
|
||||
|
@ -116,19 +132,14 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
private EditTextPreference mAccountSignature;
|
||||
private ListPreference mCheckFrequency;
|
||||
private ListPreference mSyncWindow;
|
||||
private CheckBoxPreference mAccountBackgroundAttachments;
|
||||
private CheckBoxPreference mInboxVibrate;
|
||||
private Preference mInboxRingtone;
|
||||
private CheckBoxPreference mSyncContacts;
|
||||
private CheckBoxPreference mSyncCalendar;
|
||||
private CheckBoxPreference mSyncEmail;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private Account mAccount;
|
||||
private com.android.mail.providers.Account mUiAccount;
|
||||
private Callback mCallback = EmptyCallback.INSTANCE;
|
||||
private boolean mSaveOnExit;
|
||||
private EmailServiceInfo mServiceInfo;
|
||||
|
||||
private Ringtone mRingtone;
|
||||
|
||||
|
@ -138,41 +149,29 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
*/
|
||||
private FolderPreferences mInboxFolderPreferences;
|
||||
|
||||
// The ID of the account being edited
|
||||
private long mAccountId;
|
||||
// The email of the account being edited
|
||||
private String mAccountEmail;
|
||||
|
||||
/**
|
||||
* Callback interface that owning activities must provide
|
||||
* If launching with an email address, use this method to build the arguments.
|
||||
*/
|
||||
public interface Callback {
|
||||
public void onSettingsChanged(long accountId, String preference, Object value);
|
||||
public void onEditQuickResponses(com.android.mail.providers.Account account);
|
||||
public void onIncomingSettings(Account account);
|
||||
public void onOutgoingSettings(Account account);
|
||||
public void abandonEdit();
|
||||
}
|
||||
|
||||
private static class EmptyCallback implements Callback {
|
||||
public static final Callback INSTANCE = new EmptyCallback();
|
||||
@Override public void onSettingsChanged(long accountId, String preference, Object value) {}
|
||||
@Override public void onEditQuickResponses(com.android.mail.providers.Account account) {}
|
||||
@Override public void onIncomingSettings(Account account) {}
|
||||
@Override public void onOutgoingSettings(Account account) {}
|
||||
@Override public void abandonEdit() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* If launching with an arguments bundle, use this method to build the arguments.
|
||||
*/
|
||||
public static Bundle buildArguments(long accountId, String email) {
|
||||
Bundle b = new Bundle();
|
||||
b.putLong(BUNDLE_KEY_ACCOUNT_ID, accountId);
|
||||
b.putString(BUNDLE_KEY_ACCOUNT_EMAIL, email);
|
||||
public static Bundle buildArguments(final String email) {
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putString(ARG_ACCOUNT_EMAIL, email);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static String getTitleFromArgs(Bundle args) {
|
||||
return (args == null) ? null : args.getString(BUNDLE_KEY_ACCOUNT_EMAIL);
|
||||
/**
|
||||
* When launching for the login warning, we don't have the account email address, so we use the
|
||||
* account ID, along with a few strings explaining the warning.
|
||||
*/
|
||||
public static Bundle buildArguments(final long accountId, final String warningAccount,
|
||||
final String warningReason) {
|
||||
final Bundle b = new Bundle(3);
|
||||
b.putLong(ARG_ACCOUNT_ID, accountId);
|
||||
b.putString(ARG_LOGIN_WARNING_FOR_ACCOUNT, warningAccount);
|
||||
b.putString(ARG_LOGIN_WARNING_REASON_FOR_ACCOUNT, warningReason);
|
||||
return b;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -198,7 +197,7 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
// If not, activity must call startLoadingAccount() directly
|
||||
Bundle b = getArguments();
|
||||
if (b != null) {
|
||||
mAccountId = b.getLong(BUNDLE_KEY_ACCOUNT_ID, -1);
|
||||
mAccountEmail = b.getString(ARG_ACCOUNT_EMAIL);
|
||||
}
|
||||
if (savedInstanceState != null) {
|
||||
// We won't know what the correct set of sync interval values and strings are until
|
||||
|
@ -233,15 +232,25 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
final Bundle args = new Bundle(1);
|
||||
args.putLong(AccountLoaderCallbacks.ARG_ACCOUNT_ID, mAccountId);
|
||||
if (!TextUtils.isEmpty(mAccountEmail)) {
|
||||
args.putString(AccountLoaderCallbacks.ARG_ACCOUNT_EMAIL, mAccountEmail);
|
||||
} else {
|
||||
args.putLong(AccountLoaderCallbacks.ARG_ACCOUNT_ID,
|
||||
getArguments().getLong(ARG_ACCOUNT_ID, -1));
|
||||
}
|
||||
getLoaderManager().initLoader(0, args, new AccountLoaderCallbacks(getActivity()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (mSaveOnExit) {
|
||||
saveSettings();
|
||||
if (savedInstanceState == null) {
|
||||
final String loginWarningAccount =
|
||||
getArguments().getString(ARG_LOGIN_WARNING_FOR_ACCOUNT);
|
||||
final String loginWarningReason =
|
||||
getArguments().getString(ARG_LOGIN_WARNING_REASON_FOR_ACCOUNT);
|
||||
if (loginWarningAccount != null) {
|
||||
// Show dialog (first time only - don't re-show on a rotation)
|
||||
LoginWarningDialog dialog =
|
||||
LoginWarningDialog.newInstance(loginWarningAccount, loginWarningReason);
|
||||
dialog.show(getFragmentManager(), "loginwarning");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,9 +296,10 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
* @return True to update the state of the Preference with the new value
|
||||
*/
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue){
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
// Can't use a switch here. Falling back to a giant conditional.
|
||||
final String key = preference.getKey();
|
||||
final ContentValues cv = new ContentValues(1);
|
||||
if (key.equals(PREFERENCE_DESCRIPTION)){
|
||||
String summary = newValue.toString().trim();
|
||||
if (TextUtils.isEmpty(summary)) {
|
||||
|
@ -297,15 +307,14 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
}
|
||||
mAccountDescription.setSummary(summary);
|
||||
mAccountDescription.setText(summary);
|
||||
preferenceChanged(PREFERENCE_DESCRIPTION, summary);
|
||||
return false;
|
||||
} else if (key.equals(PREFERENCE_FREQUENCY)) {
|
||||
final String summary = newValue.toString();
|
||||
final int index = mCheckFrequency.findIndexOfValue(summary);
|
||||
mCheckFrequency.setSummary(mCheckFrequency.getEntries()[index]);
|
||||
mCheckFrequency.setValue(summary);
|
||||
preferenceChanged(PREFERENCE_FREQUENCY, newValue);
|
||||
return false;
|
||||
cv.put(AccountColumns.DISPLAY_NAME, summary);
|
||||
} else if (key.equals(PREFERENCE_NAME)) {
|
||||
final String summary = newValue.toString().trim();
|
||||
if (!TextUtils.isEmpty(summary)) {
|
||||
mAccountName.setSummary(summary);
|
||||
mAccountName.setText(summary);
|
||||
cv.put(AccountColumns.SENDER_NAME, summary);
|
||||
}
|
||||
} else if (key.equals(PREFERENCE_SIGNATURE)) {
|
||||
// Clean up signature if it's only whitespace (which is easy to do on a
|
||||
// soft keyboard) but leave whitespace in place otherwise, to give the user
|
||||
|
@ -317,31 +326,87 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
mAccountSignature.setText(signature);
|
||||
SettingsUtils.updatePreferenceSummary(mAccountSignature, signature,
|
||||
R.string.preferences_signature_summary_not_set);
|
||||
preferenceChanged(PREFERENCE_SIGNATURE, signature);
|
||||
return false;
|
||||
} else if (key.equals(PREFERENCE_NAME)) {
|
||||
final String summary = newValue.toString().trim();
|
||||
if (!TextUtils.isEmpty(summary)) {
|
||||
mAccountName.setSummary(summary);
|
||||
mAccountName.setText(summary);
|
||||
preferenceChanged(PREFERENCE_NAME, summary);
|
||||
cv.put(AccountColumns.SIGNATURE, signature);
|
||||
} else if (key.equals(PREFERENCE_FREQUENCY)) {
|
||||
final String summary = newValue.toString();
|
||||
final int index = mCheckFrequency.findIndexOfValue(summary);
|
||||
mCheckFrequency.setSummary(mCheckFrequency.getEntries()[index]);
|
||||
mCheckFrequency.setValue(summary);
|
||||
if (mServiceInfo.syncContacts || mServiceInfo.syncCalendar) {
|
||||
// This account allows syncing of contacts and/or calendar, so we will always have
|
||||
// separate preferences to enable or disable syncing of email, contacts, and
|
||||
// calendar.
|
||||
// The "sync frequency" preference really just needs to control the frequency value
|
||||
// in our database.
|
||||
cv.put(AccountColumns.SYNC_INTERVAL, Integer.parseInt(summary));
|
||||
} else {
|
||||
// This account only syncs email (not contacts or calendar), which means that we
|
||||
// will hide the preference to turn syncing on and off. In this case, we want the
|
||||
// sync frequency preference to also control whether or not syncing is enabled at
|
||||
// all. If sync is turned off, we will display "sync never" regardless of what the
|
||||
// numeric value we have stored says.
|
||||
final android.accounts.Account androidAcct = new android.accounts.Account(
|
||||
mAccount.mEmailAddress, mServiceInfo.accountType);
|
||||
if ((Integer) newValue == Account.CHECK_INTERVAL_NEVER) {
|
||||
// Disable syncing from the account manager. Leave the current sync frequency
|
||||
// in the database.
|
||||
ContentResolver.setSyncAutomatically(androidAcct, EmailContent.AUTHORITY,
|
||||
false);
|
||||
} else {
|
||||
// Enable syncing from the account manager.
|
||||
ContentResolver.setSyncAutomatically(androidAcct, EmailContent.AUTHORITY,
|
||||
true);
|
||||
cv.put(AccountColumns.SYNC_INTERVAL, Integer.parseInt(summary));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (key.equals(PREFERENCE_SYNC_WINDOW)) {
|
||||
final String summary = newValue.toString();
|
||||
int index = mSyncWindow.findIndexOfValue(summary);
|
||||
mSyncWindow.setSummary(mSyncWindow.getEntries()[index]);
|
||||
mSyncWindow.setValue(summary);
|
||||
cv.put(AccountColumns.SYNC_LOOKBACK, Integer.parseInt(summary));
|
||||
} else if (key.equals(PREFERENCE_SYNC_EMAIL)) {
|
||||
final android.accounts.Account androidAcct = new android.accounts.Account(
|
||||
mAccount.mEmailAddress, mServiceInfo.accountType);
|
||||
ContentResolver.setSyncAutomatically(androidAcct, EmailContent.AUTHORITY,
|
||||
(Boolean) newValue);
|
||||
} else if (key.equals(PREFERENCE_SYNC_CONTACTS)) {
|
||||
final android.accounts.Account androidAcct = new android.accounts.Account(
|
||||
mAccount.mEmailAddress, mServiceInfo.accountType);
|
||||
ContentResolver.setSyncAutomatically(androidAcct, ContactsContract.AUTHORITY,
|
||||
(Boolean) newValue);
|
||||
} else if (key.equals(PREFERENCE_SYNC_CALENDAR)) {
|
||||
final android.accounts.Account androidAcct = new android.accounts.Account(
|
||||
mAccount.mEmailAddress, mServiceInfo.accountType);
|
||||
ContentResolver.setSyncAutomatically(androidAcct, CalendarContract.AUTHORITY,
|
||||
(Boolean) newValue);
|
||||
} else if (key.equals(PREFERENCE_BACKGROUND_ATTACHMENTS)) {
|
||||
int newFlags = mAccount.getFlags() & ~(Account.FLAGS_BACKGROUND_ATTACHMENTS);
|
||||
|
||||
newFlags |= (Boolean) newValue ?
|
||||
Account.FLAGS_BACKGROUND_ATTACHMENTS : 0;
|
||||
|
||||
cv.put(AccountColumns.FLAGS, newFlags);
|
||||
} else if (FolderPreferences.PreferenceKeys.NOTIFICATIONS_ENABLED.equals(key)) {
|
||||
mInboxFolderPreferences.setNotificationsEnabled((Boolean) newValue);
|
||||
return true;
|
||||
} else if (FolderPreferences.PreferenceKeys.NOTIFICATION_VIBRATE.equals(key)) {
|
||||
final boolean vibrateSetting = (Boolean) newValue;
|
||||
mInboxVibrate.setChecked(vibrateSetting);
|
||||
mInboxFolderPreferences.setNotificationVibrateEnabled(vibrateSetting);
|
||||
preferenceChanged(FolderPreferences.PreferenceKeys.NOTIFICATION_VIBRATE, newValue);
|
||||
return true;
|
||||
} else if (FolderPreferences.PreferenceKeys.NOTIFICATIONS_ENABLED.equals(key)) {
|
||||
mInboxFolderPreferences.setNotificationsEnabled((Boolean) newValue);
|
||||
preferenceChanged(FolderPreferences.PreferenceKeys.NOTIFICATIONS_ENABLED, newValue);
|
||||
} else if (FolderPreferences.PreferenceKeys.NOTIFICATION_RINGTONE.equals(key)) {
|
||||
return true;
|
||||
} else {
|
||||
// Default behavior, just indicate that the preferences were written
|
||||
preferenceChanged(key, newValue);
|
||||
LogUtils.d(LogUtils.TAG, "Unknown preference key %s", key);
|
||||
return true;
|
||||
}
|
||||
if (cv.size() > 0) {
|
||||
new UpdateTask().run(mContext.getContentResolver(), mAccount.getUri(), cv, null, null);
|
||||
MailActivityEmail.setServicesEnabledAsync(mContext);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -351,14 +416,7 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
}
|
||||
|
||||
/**
|
||||
* Activity provides callbacks here
|
||||
*/
|
||||
public void setCallback(Callback callback) {
|
||||
mCallback = (callback == null) ? EmptyCallback.INSTANCE : callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Async task to load account in order to view/edit it
|
||||
* Async task loader to load account in order to view/edit it
|
||||
*/
|
||||
private static class AccountLoader extends MailAsyncTaskLoader<Map<String, Object>> {
|
||||
public static final String RESULT_KEY_ACCOUNT = "account";
|
||||
|
@ -367,11 +425,13 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
public static final String RESULT_KEY_INBOX = "inbox";
|
||||
|
||||
private final ForceLoadContentObserver mObserver;
|
||||
private final String mAccountEmail;
|
||||
private final long mAccountId;
|
||||
|
||||
private AccountLoader(Context context, long accountId) {
|
||||
private AccountLoader(Context context, String accountEmail, long accountId) {
|
||||
super(context);
|
||||
mObserver = new ForceLoadContentObserver();
|
||||
mAccountEmail = accountEmail;
|
||||
mAccountId = accountId;
|
||||
}
|
||||
|
||||
|
@ -379,7 +439,12 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
public Map<String, Object> loadInBackground() {
|
||||
final Map<String, Object> map = new HashMap<String, Object>();
|
||||
|
||||
Account account = Account.restoreAccountWithId(getContext(), mAccountId, mObserver);
|
||||
final Account account;
|
||||
if (!TextUtils.isEmpty(mAccountEmail)) {
|
||||
account = Account.restoreAccountWithAddress(getContext(), mAccountEmail, mObserver);
|
||||
} else {
|
||||
account = Account.restoreAccountWithId(getContext(), mAccountId, mObserver);
|
||||
}
|
||||
if (account == null) {
|
||||
return map;
|
||||
}
|
||||
|
@ -399,7 +464,8 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
Policy.restorePolicyWithId(getContext(), account.mPolicyKey, mObserver);
|
||||
|
||||
final Cursor uiAccountCursor = getContext().getContentResolver().query(
|
||||
EmailProvider.uiUri("uiaccount", mAccountId), UIProvider.ACCOUNTS_PROJECTION,
|
||||
EmailProvider.uiUri("uiaccount", account.getId()),
|
||||
UIProvider.ACCOUNTS_PROJECTION,
|
||||
null, null, null);
|
||||
|
||||
if (uiAccountCursor != null) {
|
||||
|
@ -457,6 +523,7 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
|
||||
private class AccountLoaderCallbacks
|
||||
implements LoaderManager.LoaderCallbacks<Map<String, Object>> {
|
||||
public static final String ARG_ACCOUNT_EMAIL = "accountEmail";
|
||||
public static final String ARG_ACCOUNT_ID = "accountId";
|
||||
private final Context mContext;
|
||||
|
||||
|
@ -466,9 +533,12 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Map<String, Object>> loader, Map<String, Object> data) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
if (data == null) {
|
||||
mSaveOnExit = false;
|
||||
mCallback.abandonEdit();
|
||||
activity.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -480,33 +550,33 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
final Intent i = AccountSecurity.actionUpdateSecurityIntent(mContext,
|
||||
mAccount.getId(), true);
|
||||
mContext.startActivity(i);
|
||||
mSaveOnExit = false;
|
||||
mCallback.abandonEdit();
|
||||
activity.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
final Folder inbox = (Folder) data.get(AccountLoader.RESULT_KEY_INBOX);
|
||||
|
||||
if (mUiAccount == null || mAccount == null) {
|
||||
mSaveOnExit = false;
|
||||
mCallback.abandonEdit();
|
||||
activity.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
mServiceInfo =
|
||||
EmailServiceUtils.getServiceInfo(mContext, mAccount.getProtocol(mContext));
|
||||
|
||||
if (inbox == null) {
|
||||
mInboxFolderPreferences = null;
|
||||
} else {
|
||||
mInboxFolderPreferences =
|
||||
new FolderPreferences(mContext, mUiAccount.getEmailAddress(), inbox, true);
|
||||
}
|
||||
if (!mSaveOnExit) {
|
||||
loadSettings();
|
||||
}
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Map<String, Object>> onCreateLoader(int id, Bundle args) {
|
||||
return new AccountLoader(mContext, args.getLong(ARG_ACCOUNT_ID));
|
||||
return new AccountLoader(mContext, args.getString(ARG_ACCOUNT_EMAIL),
|
||||
args.getLong(ARG_ACCOUNT_ID));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -565,9 +635,6 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
* Load account data into preference UI. This must be called on the main thread.
|
||||
*/
|
||||
private void loadSettings() {
|
||||
// Once loaded the data is ready to be saved, as well
|
||||
mSaveOnExit = false;
|
||||
|
||||
final AccountPreferences accountPreferences =
|
||||
new AccountPreferences(mContext, mUiAccount.getEmailAddress());
|
||||
if (mInboxFolderPreferences != null) {
|
||||
|
@ -576,9 +643,8 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
}
|
||||
|
||||
final String protocol = mAccount.getProtocol(mContext);
|
||||
final EmailServiceInfo info = EmailServiceUtils.getServiceInfo(mContext, protocol);
|
||||
if (info == null) {
|
||||
LogUtils.e(Logging.LOG_TAG,
|
||||
if (mServiceInfo == null) {
|
||||
LogUtils.e(LogUtils.TAG,
|
||||
"Could not find service info for account %d with protocol %s", mAccount.mId,
|
||||
protocol);
|
||||
getActivity().onBackPressed();
|
||||
|
@ -608,9 +674,9 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
R.string.preferences_signature_summary_not_set);
|
||||
|
||||
mCheckFrequency = (ListPreference) findPreference(PREFERENCE_FREQUENCY);
|
||||
mCheckFrequency.setEntries(info.syncIntervalStrings);
|
||||
mCheckFrequency.setEntryValues(info.syncIntervals);
|
||||
if (info.syncContacts || info.syncCalendar) {
|
||||
mCheckFrequency.setEntries(mServiceInfo.syncIntervalStrings);
|
||||
mCheckFrequency.setEntryValues(mServiceInfo.syncIntervals);
|
||||
if (mServiceInfo.syncContacts || mServiceInfo.syncCalendar) {
|
||||
// This account allows syncing of contacts and/or calendar, so we will always have
|
||||
// separate preferences to enable or disable syncing of email, contacts, and calendar.
|
||||
// The "sync frequency" preference really just needs to control the frequency value
|
||||
|
@ -637,7 +703,7 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
mCallback.onEditQuickResponses(mUiAccount);
|
||||
onEditQuickResponses(mUiAccount);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
@ -646,9 +712,10 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
PreferenceCategory dataUsageCategory =
|
||||
(PreferenceCategory) findPreference(PREFERENCE_CATEGORY_DATA_USAGE);
|
||||
|
||||
if (info.offerLookback) {
|
||||
if (mServiceInfo.offerLookback) {
|
||||
if (mSyncWindow == null) {
|
||||
mSyncWindow = new ListPreference(mContext);
|
||||
mSyncWindow.setKey(PREFERENCE_SYNC_WINDOW);
|
||||
dataUsageCategory.addPreference(mSyncWindow);
|
||||
}
|
||||
mSyncWindow.setTitle(R.string.account_setup_options_mail_window_label);
|
||||
|
@ -665,27 +732,17 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
|
||||
// Must correspond to the hole in the XML file that's reserved.
|
||||
mSyncWindow.setOrder(2);
|
||||
mSyncWindow.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
final String summary = newValue.toString();
|
||||
int index = mSyncWindow.findIndexOfValue(summary);
|
||||
mSyncWindow.setSummary(mSyncWindow.getEntries()[index]);
|
||||
mSyncWindow.setValue(summary);
|
||||
preferenceChanged(preference.getKey(), newValue);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
mSyncWindow.setOnPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
PreferenceCategory folderPrefs =
|
||||
(PreferenceCategory) findPreference(PREFERENCE_SYSTEM_FOLDERS);
|
||||
if (folderPrefs != null) {
|
||||
if (info.requiresSetup) {
|
||||
if (mServiceInfo.requiresSetup) {
|
||||
Preference trashPreference = findPreference(PREFERENCE_SYSTEM_FOLDERS_TRASH);
|
||||
Intent i = new Intent(mContext, FolderPickerActivity.class);
|
||||
Uri uri = EmailContent.CONTENT_URI.buildUpon().appendQueryParameter(
|
||||
"account", Long.toString(mAccountId)).build();
|
||||
"account", Long.toString(mAccount.getId())).build();
|
||||
i.setData(uri);
|
||||
i.putExtra(FolderPickerActivity.MAILBOX_TYPE_EXTRA, Mailbox.TYPE_TRASH);
|
||||
trashPreference.setIntent(i);
|
||||
|
@ -700,16 +757,15 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
}
|
||||
}
|
||||
|
||||
mAccountBackgroundAttachments = (CheckBoxPreference)
|
||||
CheckBoxPreference backgroundAttachments = (CheckBoxPreference)
|
||||
findPreference(PREFERENCE_BACKGROUND_ATTACHMENTS);
|
||||
if (mAccountBackgroundAttachments != null) {
|
||||
if (!info.offerAttachmentPreload) {
|
||||
dataUsageCategory.removePreference(mAccountBackgroundAttachments);
|
||||
mAccountBackgroundAttachments = null;
|
||||
if (backgroundAttachments != null) {
|
||||
if (!mServiceInfo.offerAttachmentPreload) {
|
||||
dataUsageCategory.removePreference(backgroundAttachments);
|
||||
} else {
|
||||
mAccountBackgroundAttachments.setChecked(
|
||||
backgroundAttachments.setChecked(
|
||||
0 != (mAccount.getFlags() & Account.FLAGS_BACKGROUND_ATTACHMENTS));
|
||||
mAccountBackgroundAttachments.setOnPreferenceChangeListener(this);
|
||||
backgroundAttachments.setOnPreferenceChangeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -808,7 +864,7 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
mCallback.onIncomingSettings(mAccount);
|
||||
onIncomingSettings(mAccount);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
@ -816,21 +872,21 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
// Hide the outgoing account setup link if it's not activated
|
||||
Preference prefOutgoing = findPreference(PREFERENCE_OUTGOING);
|
||||
if (prefOutgoing != null) {
|
||||
if (info.usesSmtp && mAccount.mHostAuthSend != null) {
|
||||
if (mServiceInfo.usesSmtp && mAccount.mHostAuthSend != null) {
|
||||
prefOutgoing.setOnPreferenceClickListener(
|
||||
new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
mCallback.onOutgoingSettings(mAccount);
|
||||
onOutgoingSettings(mAccount);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (info.usesSmtp) {
|
||||
if (mServiceInfo.usesSmtp) {
|
||||
// We really ought to have an outgoing host auth but we don't.
|
||||
// There's nothing we can do at this point, so just log the error.
|
||||
LogUtils.e(Logging.LOG_TAG, "Account %d has a bad outbound hostauth",
|
||||
mAccountId);
|
||||
LogUtils.e(LogUtils.TAG, "Account %d has a bad outbound hostauth",
|
||||
mAccount.getId());
|
||||
}
|
||||
PreferenceCategory serverCategory = (PreferenceCategory) findPreference(
|
||||
PREFERENCE_CATEGORY_SERVER);
|
||||
|
@ -838,121 +894,41 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
}
|
||||
}
|
||||
|
||||
mSyncContacts = (CheckBoxPreference) findPreference(PREFERENCE_SYNC_CONTACTS);
|
||||
mSyncCalendar = (CheckBoxPreference) findPreference(PREFERENCE_SYNC_CALENDAR);
|
||||
mSyncEmail = (CheckBoxPreference) findPreference(PREFERENCE_SYNC_EMAIL);
|
||||
if (mSyncContacts != null && mSyncCalendar != null && mSyncEmail != null) {
|
||||
if (info.syncContacts || info.syncCalendar) {
|
||||
if (info.syncContacts) {
|
||||
mSyncContacts.setChecked(ContentResolver
|
||||
final CheckBoxPreference syncContacts =
|
||||
(CheckBoxPreference) findPreference(PREFERENCE_SYNC_CONTACTS);
|
||||
final CheckBoxPreference syncCalendar =
|
||||
(CheckBoxPreference) findPreference(PREFERENCE_SYNC_CALENDAR);
|
||||
final CheckBoxPreference syncEmail =
|
||||
(CheckBoxPreference) findPreference(PREFERENCE_SYNC_EMAIL);
|
||||
if (syncContacts != null && syncCalendar != null && syncEmail != null) {
|
||||
if (mServiceInfo.syncContacts || mServiceInfo.syncCalendar) {
|
||||
if (mServiceInfo.syncContacts) {
|
||||
syncContacts.setChecked(ContentResolver
|
||||
.getSyncAutomatically(androidAcct, ContactsContract.AUTHORITY));
|
||||
mSyncContacts.setOnPreferenceChangeListener(this);
|
||||
syncContacts.setOnPreferenceChangeListener(this);
|
||||
} else {
|
||||
mSyncContacts.setChecked(false);
|
||||
mSyncContacts.setEnabled(false);
|
||||
syncContacts.setChecked(false);
|
||||
syncContacts.setEnabled(false);
|
||||
}
|
||||
if (info.syncCalendar) {
|
||||
mSyncCalendar.setChecked(ContentResolver
|
||||
if (mServiceInfo.syncCalendar) {
|
||||
syncCalendar.setChecked(ContentResolver
|
||||
.getSyncAutomatically(androidAcct, CalendarContract.AUTHORITY));
|
||||
mSyncCalendar.setOnPreferenceChangeListener(this);
|
||||
syncCalendar.setOnPreferenceChangeListener(this);
|
||||
} else {
|
||||
mSyncCalendar.setChecked(false);
|
||||
mSyncCalendar.setEnabled(false);
|
||||
syncCalendar.setChecked(false);
|
||||
syncCalendar.setEnabled(false);
|
||||
}
|
||||
mSyncEmail.setChecked(ContentResolver
|
||||
syncEmail.setChecked(ContentResolver
|
||||
.getSyncAutomatically(androidAcct, EmailContent.AUTHORITY));
|
||||
mSyncEmail.setOnPreferenceChangeListener(this);
|
||||
syncEmail.setOnPreferenceChangeListener(this);
|
||||
} else {
|
||||
dataUsageCategory.removePreference(mSyncContacts);
|
||||
mSyncContacts = null;
|
||||
dataUsageCategory.removePreference(mSyncCalendar);
|
||||
mSyncCalendar = null;
|
||||
dataUsageCategory.removePreference(mSyncEmail);
|
||||
mSyncEmail = null;
|
||||
dataUsageCategory.removePreference(syncContacts);
|
||||
dataUsageCategory.removePreference(syncCalendar);
|
||||
dataUsageCategory.removePreference(syncEmail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called any time a preference is changed.
|
||||
*/
|
||||
private void preferenceChanged(String preference, Object value) {
|
||||
mCallback.onSettingsChanged(mAccountId, preference, value);
|
||||
mSaveOnExit = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: This writes the settings on the UI thread. This has to be done so the settings are
|
||||
* committed before we might be killed.
|
||||
*/
|
||||
private void saveSettings() {
|
||||
// Turn off all controlled flags - will turn them back on while checking UI elements
|
||||
int newFlags = mAccount.getFlags() & ~(Account.FLAGS_BACKGROUND_ATTACHMENTS);
|
||||
|
||||
if (mAccountBackgroundAttachments != null) {
|
||||
newFlags |= mAccountBackgroundAttachments.isChecked() ?
|
||||
Account.FLAGS_BACKGROUND_ATTACHMENTS : 0;
|
||||
}
|
||||
|
||||
final EmailServiceInfo info =
|
||||
EmailServiceUtils.getServiceInfo(mContext, mAccount.getProtocol(mContext));
|
||||
final android.accounts.Account androidAcct = new android.accounts.Account(
|
||||
mAccount.mEmailAddress, info.accountType);
|
||||
|
||||
// If the display name has been cleared, we'll reset it to the default value (email addr)
|
||||
mAccount.setDisplayName(mAccountDescription.getText().trim());
|
||||
// The sender name must never be empty (this is enforced by the preference editor)
|
||||
mAccount.setSenderName(mAccountName.getText().trim());
|
||||
mAccount.setSignature(mAccountSignature.getText());
|
||||
int freq = Integer.parseInt(mCheckFrequency.getValue());
|
||||
if (info.syncContacts || info.syncCalendar) {
|
||||
// This account allows syncing of contacts and/or calendar, so we will always have
|
||||
// separate preferences to enable or disable syncing of email, contacts, and calendar.
|
||||
// The "sync frequency" preference really just needs to control the frequency value
|
||||
// in our database.
|
||||
mAccount.setSyncInterval(Integer.parseInt(mCheckFrequency.getValue()));
|
||||
} else {
|
||||
// This account only syncs email (not contacts or calendar), which means that we will
|
||||
// hide the preference to turn syncing on and off. In this case, we want the sync
|
||||
// frequency preference to also control whether or not syncing is enabled at all. If
|
||||
// sync is turned off, we will display "sync never" regardless of what the numeric
|
||||
// value we have stored says.
|
||||
if (freq == Account.CHECK_INTERVAL_NEVER) {
|
||||
// Disable syncing from the account manager. Leave the current sync frequency
|
||||
// in the database.
|
||||
ContentResolver.setSyncAutomatically(androidAcct, EmailContent.AUTHORITY, false);
|
||||
} else {
|
||||
// Enable syncing from the account manager.
|
||||
ContentResolver.setSyncAutomatically(androidAcct, EmailContent.AUTHORITY, true);
|
||||
mAccount.setSyncInterval(Integer.parseInt(mCheckFrequency.getValue()));
|
||||
}
|
||||
}
|
||||
if (mSyncWindow != null) {
|
||||
mAccount.setSyncLookback(Integer.parseInt(mSyncWindow.getValue()));
|
||||
}
|
||||
mAccount.setFlags(newFlags);
|
||||
|
||||
if (info.syncContacts || info.syncCalendar) {
|
||||
ContentResolver.setSyncAutomatically(androidAcct, ContactsContract.AUTHORITY,
|
||||
mSyncContacts.isChecked());
|
||||
ContentResolver.setSyncAutomatically(androidAcct, CalendarContract.AUTHORITY,
|
||||
mSyncCalendar.isChecked());
|
||||
ContentResolver.setSyncAutomatically(androidAcct, EmailContent.AUTHORITY,
|
||||
mSyncEmail.isChecked());
|
||||
}
|
||||
|
||||
// Commit the changes
|
||||
// Note, this is done in the UI thread because at this point, we must commit
|
||||
// all changes - any time after onPause completes, we could be killed. This is analogous
|
||||
// to the way that SharedPreferences tries to work off-thread in apply(), but will pause
|
||||
// until completion in onPause().
|
||||
ContentValues cv = AccountSettingsUtils.getAccountContentValues(mAccount);
|
||||
mAccount.update(mContext, cv);
|
||||
|
||||
// Run the remaining changes off-thread
|
||||
MailActivityEmail.setServicesEnabledAsync(mContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the system ringtone picker.
|
||||
*/
|
||||
|
@ -969,4 +945,100 @@ public class AccountSettingsFragment extends PreferenceFragment
|
|||
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
|
||||
startActivityForResult(intent, RINGTONE_REQUEST_CODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch to edit quick responses.
|
||||
*/
|
||||
public void onEditQuickResponses(com.android.mail.providers.Account account) {
|
||||
final Bundle args = AccountSettingsEditQuickResponsesFragment.createArgs(account);
|
||||
final PreferenceActivity activity = (PreferenceActivity) getActivity();
|
||||
activity.startPreferencePanel(AccountSettingsEditQuickResponsesFragment.class.getName(),
|
||||
args, R.string.account_settings_edit_quick_responses_label, null, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch to edit incoming settings.
|
||||
*/
|
||||
public void onIncomingSettings(Account account) {
|
||||
final Intent intent =
|
||||
AccountServerSettingsActivity.getIntentForIncoming(getActivity(), account);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch to edit outgoing settings.
|
||||
*/
|
||||
public void onOutgoingSettings(Account account) {
|
||||
final Intent intent =
|
||||
AccountServerSettingsActivity.getIntentForOutgoing(getActivity(), account);
|
||||
getActivity().startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog briefly shown in some cases, to indicate the user that login failed. If the user
|
||||
* clicks OK, we simply dismiss the dialog, leaving the user in the account settings for
|
||||
* that account; If the user clicks "cancel", we exit account settings.
|
||||
*/
|
||||
public static class LoginWarningDialog extends DialogFragment
|
||||
implements DialogInterface.OnClickListener {
|
||||
private static final String BUNDLE_KEY_ACCOUNT_NAME = "account_name";
|
||||
private String mReason;
|
||||
|
||||
// Public no-args constructor needed for fragment re-instantiation
|
||||
public LoginWarningDialog() {}
|
||||
|
||||
/**
|
||||
* Create a new dialog.
|
||||
*/
|
||||
public static LoginWarningDialog newInstance(String accountName, String reason) {
|
||||
final LoginWarningDialog dialog = new LoginWarningDialog();
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putString(BUNDLE_KEY_ACCOUNT_NAME, accountName);
|
||||
dialog.setArguments(b);
|
||||
dialog.mReason = reason;
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final String accountName = getArguments().getString(BUNDLE_KEY_ACCOUNT_NAME);
|
||||
|
||||
final Context context = getActivity();
|
||||
final Resources res = context.getResources();
|
||||
final AlertDialog.Builder b = new AlertDialog.Builder(context);
|
||||
b.setTitle(R.string.account_settings_login_dialog_title);
|
||||
b.setIconAttribute(android.R.attr.alertDialogIcon);
|
||||
if (mReason != null) {
|
||||
final TextView message = new TextView(context);
|
||||
final String alert = res.getString(
|
||||
R.string.account_settings_login_dialog_reason_fmt, accountName, mReason);
|
||||
SpannableString spannableAlertString = new SpannableString(alert);
|
||||
Linkify.addLinks(spannableAlertString, Linkify.WEB_URLS);
|
||||
message.setText(spannableAlertString);
|
||||
// There must be a better way than specifying size/padding this way
|
||||
// It does work and look right, though
|
||||
final int textSize = res.getDimensionPixelSize(R.dimen.dialog_text_size);
|
||||
message.setTextSize(textSize);
|
||||
final int paddingLeft = res.getDimensionPixelSize(R.dimen.dialog_padding_left);
|
||||
final int paddingOther = res.getDimensionPixelSize(R.dimen.dialog_padding_other);
|
||||
message.setPadding(paddingLeft, paddingOther, paddingOther, paddingOther);
|
||||
message.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
b.setView(message);
|
||||
} else {
|
||||
b.setMessage(res.getString(R.string.account_settings_login_dialog_content_fmt,
|
||||
accountName));
|
||||
}
|
||||
b.setPositiveButton(android.R.string.ok, this);
|
||||
b.setNegativeButton(android.R.string.cancel, this);
|
||||
return b.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dismiss();
|
||||
if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||
getActivity().finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
|
||||
import com.android.emailcommon.provider.Account;
|
||||
import com.android.emailcommon.utility.IntentUtilities;
|
||||
|
@ -46,22 +45,10 @@ public class HeadlessAccountSettingsLoader extends Activity {
|
|||
|
||||
protected void onPostExecute(Account result) {
|
||||
// create an Intent to view a new activity
|
||||
final Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
final Intent intent =
|
||||
AccountServerSettingsActivity.getIntentForIncoming(mContext, result);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
// we are navigating explicitly to the AccountSettings activity
|
||||
intent.setClass(mContext, AccountSettings.class);
|
||||
|
||||
// place the account in the intent as an extra
|
||||
intent.putExtra(AccountSettings.EXTRA_ACCOUNT, result);
|
||||
|
||||
// these extras show the "incoming fragment" in the AccountSettings activity by default
|
||||
intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT,
|
||||
AccountSetupIncomingFragment.class.getCanonicalName());
|
||||
intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS,
|
||||
AccountSetupIncomingFragment.getArgs(true));
|
||||
intent.putExtra(PreferenceActivity.EXTRA_NO_HEADERS, true);
|
||||
|
||||
mContext.startActivity(intent);
|
||||
|
||||
finish();
|
||||
|
|
|
@ -76,16 +76,6 @@ public class SetupDataFragment extends Fragment implements Parcelable {
|
|||
mCredentialResults = null;
|
||||
}
|
||||
|
||||
public SetupDataFragment(int flowMode) {
|
||||
this();
|
||||
mFlowMode = flowMode;
|
||||
}
|
||||
|
||||
public SetupDataFragment(int flowMode, Account account) {
|
||||
this(flowMode);
|
||||
setAccount(account);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
|
|
@ -128,9 +128,9 @@ public class AccountSettingsTests extends ActivityInstrumentationTestCase2<Accou
|
|||
|
||||
runTestOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
AccountSettingsFragment f = theActivity.getSettingsFragment();
|
||||
mCheckFrequency =
|
||||
(ListPreference) f.findPreference(PREFERENCE_FREQUENCY);
|
||||
//AccountSettingsFragment f = theActivity.getSettingsFragment();
|
||||
//mCheckFrequency =
|
||||
// (ListPreference) f.findPreference(PREFERENCE_FREQUENCY);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -197,7 +197,9 @@ public class AccountSetupIncomingTests extends
|
|||
final HostAuth auth = account.getOrCreateHostAuthRecv(context);
|
||||
auth.setHostAuthFromString(storeUriString);
|
||||
final SetupDataFragment setupDataFragment =
|
||||
new SetupDataFragment(SetupDataFragment.FLOW_MODE_NORMAL, account);
|
||||
new SetupDataFragment();
|
||||
setupDataFragment.setFlowMode(SetupDataFragment.FLOW_MODE_NORMAL);
|
||||
setupDataFragment.setAccount(account);
|
||||
final Intent i = new Intent(AccountSetupFinal.ACTION_JUMP_TO_INCOMING);
|
||||
i.putExtra(SetupDataFragment.EXTRA_SETUP_DATA, setupDataFragment);
|
||||
return i;
|
||||
|
|
|
@ -172,7 +172,9 @@ public class AccountSetupOptionsTests
|
|||
final HostAuth auth = account.getOrCreateHostAuthRecv(context);
|
||||
auth.setHostAuthFromString(storeUri);
|
||||
final SetupDataFragment setupDataFragment =
|
||||
new SetupDataFragment(SetupDataFragment.FLOW_MODE_NORMAL, account);
|
||||
new SetupDataFragment();
|
||||
setupDataFragment.setFlowMode(SetupDataFragment.FLOW_MODE_NORMAL);
|
||||
setupDataFragment.setAccount(account);
|
||||
final Intent i = new Intent(AccountSetupFinal.ACTION_JUMP_TO_OPTIONS);
|
||||
i.putExtra(SetupDataFragment.EXTRA_SETUP_DATA, setupDataFragment);
|
||||
return i;
|
||||
|
|
|
@ -202,7 +202,9 @@ public class AccountSetupOutgoingTests extends
|
|||
final HostAuth auth = account.getOrCreateHostAuthSend(context);
|
||||
auth.setHostAuthFromString(senderUriString);
|
||||
final SetupDataFragment setupDataFragment =
|
||||
new SetupDataFragment(SetupDataFragment.FLOW_MODE_NORMAL, account);
|
||||
new SetupDataFragment();
|
||||
setupDataFragment.setFlowMode(SetupDataFragment.FLOW_MODE_NORMAL);
|
||||
setupDataFragment.setAccount(account);
|
||||
final Intent i = new Intent(AccountSetupFinal.ACTION_JUMP_TO_OUTGOING);
|
||||
i.putExtra(SetupDataFragment.EXTRA_SETUP_DATA, setupDataFragment);
|
||||
return i;
|
||||
|
|
Loading…
Reference in New Issue