386 lines
14 KiB
Java
386 lines
14 KiB
Java
/*
|
|
* Copyright (C) 2011 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.ActionBar;
|
|
import android.app.Activity;
|
|
import android.content.ContentUris;
|
|
import android.content.ContentValues;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.res.Resources;
|
|
import android.net.Uri;
|
|
import android.os.Bundle;
|
|
import android.preference.ListPreference;
|
|
import android.preference.Preference;
|
|
import android.preference.Preference.OnPreferenceChangeListener;
|
|
import android.preference.PreferenceActivity;
|
|
import android.view.MenuItem;
|
|
|
|
import com.android.email.R;
|
|
import com.android.email2.ui.MailActivityEmail;
|
|
import com.android.emailcommon.Logging;
|
|
import com.android.emailcommon.provider.Account;
|
|
import com.android.emailcommon.provider.EmailContent.AccountColumns;
|
|
import com.android.emailcommon.provider.EmailContent.MailboxColumns;
|
|
import com.android.emailcommon.provider.Mailbox;
|
|
import com.android.emailcommon.provider.Policy;
|
|
import com.android.emailcommon.utility.EmailAsyncTask;
|
|
import com.android.mail.utils.LogUtils;
|
|
import com.google.common.base.Objects;
|
|
import com.google.common.base.Preconditions;
|
|
|
|
/**
|
|
* "Mailbox settings" activity.
|
|
*
|
|
* It's used to update per-mailbox sync settings. It normally updates Mailbox settings, unless
|
|
* the target mailbox is Inbox, in which case it updates Account settings instead.
|
|
*
|
|
* All changes made by the user will not be immediately saved to the database, as changing the
|
|
* sync window may result in removal of messages. Instead, we only save to the database in {@link
|
|
* #onDestroy()}, unless it's called for configuration changes.
|
|
*/
|
|
public class MailboxSettings extends PreferenceActivity {
|
|
private static final String EXTRA_MAILBOX_ID = "MAILBOX_ID";
|
|
private static final String BUNDLE_ACCOUNT = "MailboxSettings.account";
|
|
private static final String BUNDLE_MAILBOX = "MailboxSettings.mailbox";
|
|
private static final String BUNDLE_NEEDS_SAVE = "MailboxSettings.needsSave";
|
|
|
|
private static final String PREF_CHECK_FREQUENCY_KEY = "check_frequency";
|
|
private static final String PREF_SYNC_WINDOW_KEY = "sync_window";
|
|
|
|
private final EmailAsyncTask.Tracker mTaskTracker = new EmailAsyncTask.Tracker();
|
|
|
|
// Account and Mailbox -- directly loaded by LoadMailboxTask
|
|
private Account mAccount;
|
|
private Mailbox mMailbox;
|
|
private boolean mNeedsSave;
|
|
|
|
private ListPreference mSyncIntervalPref;
|
|
private ListPreference mSyncLookbackPref;
|
|
|
|
/**
|
|
* Starts the activity for a mailbox.
|
|
*/
|
|
public static final void start(Activity parent, long mailboxId) {
|
|
Intent i = new Intent(parent, MailboxSettings.class);
|
|
i.putExtra(EXTRA_MAILBOX_ID, mailboxId);
|
|
parent.startActivity(i);
|
|
}
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
|
|
final long mailboxId = getIntent().getLongExtra(EXTRA_MAILBOX_ID, Mailbox.NO_MAILBOX);
|
|
if (mailboxId == Mailbox.NO_MAILBOX) {
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
addPreferencesFromResource(R.xml.mailbox_preferences);
|
|
|
|
mSyncIntervalPref = (ListPreference) findPreference(PREF_CHECK_FREQUENCY_KEY);
|
|
mSyncLookbackPref = (ListPreference) findPreference(PREF_SYNC_WINDOW_KEY);
|
|
|
|
mSyncIntervalPref.setOnPreferenceChangeListener(mPreferenceChanged);
|
|
mSyncLookbackPref.setOnPreferenceChangeListener(mPreferenceChanged);
|
|
|
|
// Make them disabled until we load data
|
|
enablePreferences(false);
|
|
|
|
if (savedInstanceState != null) {
|
|
mAccount = savedInstanceState.getParcelable(BUNDLE_ACCOUNT);
|
|
mMailbox = savedInstanceState.getParcelable(BUNDLE_MAILBOX);
|
|
mNeedsSave = savedInstanceState.getBoolean(BUNDLE_NEEDS_SAVE);
|
|
}
|
|
if (mAccount == null) {
|
|
new LoadMailboxTask(mailboxId).executeParallel((Void[]) null);
|
|
} else {
|
|
onDataLoaded();
|
|
}
|
|
|
|
// Always show "app up" as we expect our parent to be an Email activity.
|
|
ActionBar actionBar = getActionBar();
|
|
if (actionBar != null) {
|
|
actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
|
|
}
|
|
}
|
|
|
|
private void enablePreferences(boolean enabled) {
|
|
mSyncIntervalPref.setEnabled(enabled);
|
|
mSyncLookbackPref.setEnabled(enabled);
|
|
}
|
|
|
|
@Override
|
|
protected void onSaveInstanceState(Bundle outState) {
|
|
super.onSaveInstanceState(outState);
|
|
outState.putParcelable(BUNDLE_ACCOUNT, mAccount);
|
|
outState.putParcelable(BUNDLE_MAILBOX, mMailbox);
|
|
outState.putBoolean(BUNDLE_NEEDS_SAVE, mNeedsSave);
|
|
}
|
|
|
|
/**
|
|
* We save all the settings in onDestroy, *unless it's for configuration changes*.
|
|
*/
|
|
@Override
|
|
protected void onDestroy() {
|
|
mTaskTracker.cancellAllInterrupt();
|
|
if (!isChangingConfigurations()) {
|
|
saveToDatabase();
|
|
}
|
|
super.onDestroy();
|
|
}
|
|
|
|
/**
|
|
* Loads {@link #mAccount} and {@link #mMailbox}.
|
|
*/
|
|
private class LoadMailboxTask extends EmailAsyncTask<Void, Void, Void> {
|
|
private final long mMailboxId;
|
|
|
|
public LoadMailboxTask(long mailboxId) {
|
|
super(mTaskTracker);
|
|
mMailboxId = mailboxId;
|
|
}
|
|
|
|
@Override
|
|
protected Void doInBackground(Void... params) {
|
|
final Context c = MailboxSettings.this;
|
|
mMailbox = Mailbox.restoreMailboxWithId(c, mMailboxId);
|
|
if (mMailbox != null) {
|
|
mAccount = Account.restoreAccountWithId(c, mMailbox.mAccountKey);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
protected void onSuccess(Void result) {
|
|
if ((mAccount == null) || (mMailbox == null)) {
|
|
finish(); // Account or mailbox removed.
|
|
return;
|
|
}
|
|
onDataLoaded();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setup the entries and entry values for the sync lookback preference
|
|
* @param context the caller's context
|
|
* @param pref a ListPreference to be set up
|
|
* @param account the Account (or owner of a Mailbox) whose preference is being set
|
|
*/
|
|
public static void setupLookbackPreferenceOptions(Context context, ListPreference pref,
|
|
Account account) {
|
|
Resources resources = context.getResources();
|
|
// Load the complete list of entries/values
|
|
CharSequence[] entries =
|
|
resources.getTextArray(R.array.account_settings_mail_window_entries);
|
|
CharSequence[] values =
|
|
resources.getTextArray(R.array.account_settings_mail_window_values);
|
|
// If we have a maximum lookback policy, enforce it
|
|
if (account.mPolicyKey > 0) {
|
|
Policy policy = Policy.restorePolicyWithId(context, account.mPolicyKey);
|
|
if (policy != null && (policy.mMaxEmailLookback != 0)) {
|
|
int maxEntry = policy.mMaxEmailLookback + 1;
|
|
// Copy the proper number of values into new entries/values array
|
|
CharSequence[] policyEntries = new CharSequence[maxEntry];
|
|
CharSequence[] policyValues = new CharSequence[maxEntry];
|
|
for (int i = 0; i < maxEntry; i++) {
|
|
policyEntries[i] = entries[i];
|
|
policyValues[i] = values[i];
|
|
}
|
|
// Point entries/values to the new arrays
|
|
entries = policyEntries;
|
|
values = policyValues;
|
|
}
|
|
}
|
|
// Set up the preference
|
|
pref.setEntries(entries);
|
|
pref.setEntryValues(values);
|
|
}
|
|
|
|
/**
|
|
* Called when {@link #mAccount} and {@link #mMailbox} are loaded (either by the async task
|
|
* or from the saved state).
|
|
*/
|
|
private void onDataLoaded() {
|
|
Preconditions.checkNotNull(mAccount);
|
|
Preconditions.checkNotNull(mMailbox);
|
|
|
|
// Update the title with the mailbox name.
|
|
ActionBar actionBar = getActionBar();
|
|
String mailboxName = mMailbox.mDisplayName;
|
|
if (actionBar != null) {
|
|
actionBar.setTitle(mailboxName);
|
|
actionBar.setSubtitle(getString(R.string.mailbox_settings_activity_title));
|
|
} else {
|
|
setTitle(getString(R.string.mailbox_settings_activity_title_with_mailbox, mailboxName));
|
|
}
|
|
|
|
setupLookbackPreferenceOptions(this, mSyncLookbackPref, mAccount);
|
|
|
|
// Set default value & update summary
|
|
mSyncIntervalPref.setValue(String.valueOf(getSyncInterval()));
|
|
mSyncLookbackPref.setValue(String.valueOf(getSyncLookback()));
|
|
|
|
updatePreferenceSummary();
|
|
|
|
// Make then enabled
|
|
enablePreferences(true);
|
|
}
|
|
|
|
private void updatePreferenceSummary() {
|
|
mSyncIntervalPref.setSummary(mSyncIntervalPref.getEntry());
|
|
mSyncLookbackPref.setSummary(mSyncLookbackPref.getEntry());
|
|
}
|
|
|
|
/**
|
|
* @return current sync interval setting from the objects
|
|
*/
|
|
private int getSyncInterval() {
|
|
int syncInterval;
|
|
if (mMailbox.mType == Mailbox.TYPE_INBOX) {
|
|
syncInterval = mAccount.mSyncInterval;
|
|
} else {
|
|
if (mMailbox.mSyncInterval == 0) {
|
|
// 0 is the default value, and it means "don't sync" (for non-inbox mailboxes)
|
|
syncInterval = Mailbox.CHECK_INTERVAL_NEVER;
|
|
} else {
|
|
syncInterval = mMailbox.mSyncInterval;
|
|
}
|
|
}
|
|
// In the case of the internal push states, use "push"
|
|
if (syncInterval == Mailbox.CHECK_INTERVAL_PING ||
|
|
syncInterval == Mailbox.CHECK_INTERVAL_PUSH_HOLD) {
|
|
syncInterval = Mailbox.CHECK_INTERVAL_PUSH;
|
|
}
|
|
return syncInterval;
|
|
}
|
|
|
|
/**
|
|
* @return current sync lookback setting from the objects
|
|
*/
|
|
private int getSyncLookback() {
|
|
if (mMailbox.mType == Mailbox.TYPE_INBOX) {
|
|
return mAccount.mSyncLookback;
|
|
} else {
|
|
// Here, 0 is valid and means "use the account default sync window".
|
|
return mMailbox.mSyncLookback;
|
|
}
|
|
}
|
|
|
|
private final OnPreferenceChangeListener mPreferenceChanged = new OnPreferenceChangeListener() {
|
|
@Override
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
final ListPreference lp = (ListPreference) preference;
|
|
if (Objects.equal(lp.getValue(), newValue)) {
|
|
return false;
|
|
}
|
|
mNeedsSave = true;
|
|
if (MailActivityEmail.DEBUG) {
|
|
LogUtils.i(Logging.LOG_TAG, "Setting changed");
|
|
}
|
|
// In order to set the current entry to the summary, we need to udpate the value
|
|
// manually, rather than letting the framework do that (by returning true).
|
|
lp.setValue((String) newValue);
|
|
updatePreferenceSummary();
|
|
updateObjects();
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Updates {@link #mAccount}/{@link #mMailbox}, but doesn't save to the database yet.
|
|
*/
|
|
private void updateObjects() {
|
|
final int syncInterval = Integer.valueOf(mSyncIntervalPref.getValue());
|
|
final int syncLookback = Integer.valueOf(mSyncLookbackPref.getValue());
|
|
if (MailActivityEmail.DEBUG) {
|
|
LogUtils.i(Logging.LOG_TAG, "Updating object: " + syncInterval + "," + syncLookback);
|
|
}
|
|
if (mMailbox.mType == Mailbox.TYPE_INBOX) {
|
|
mAccount.mSyncInterval = syncInterval;
|
|
mAccount.mSyncLookback = syncLookback;
|
|
} else {
|
|
mMailbox.mSyncInterval = syncInterval;
|
|
mMailbox.mSyncLookback = syncLookback;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save changes to the database.
|
|
*
|
|
* Note it's called from {@link #onDestroy()}, which is called on the UI thread where we're not
|
|
* allowed to touch the database, so it uses {@link EmailAsyncTask} to do the save on a bg
|
|
* thread. This unfortunately means there's a chance that the app gets killed before the save is
|
|
* finished.
|
|
*/
|
|
private void saveToDatabase() {
|
|
if (!mNeedsSave) {
|
|
return;
|
|
}
|
|
LogUtils.i(Logging.LOG_TAG, "Saving mailbox settings...");
|
|
enablePreferences(false);
|
|
|
|
// Since the activity will be destroyed...
|
|
// Create local references (Although it's really okay to touch members of a destroyed
|
|
// activity...)
|
|
final Account account = mAccount;
|
|
final Mailbox mailbox = mMailbox;
|
|
final Context context = getApplicationContext();
|
|
|
|
new EmailAsyncTask<Void, Void, Void> (null /* no cancel */) {
|
|
@Override
|
|
protected Void doInBackground(Void... params) {
|
|
final ContentValues cv = new ContentValues();
|
|
final Uri uri;
|
|
|
|
if (mailbox.mType == Mailbox.TYPE_INBOX) {
|
|
cv.put(AccountColumns.SYNC_INTERVAL, account.mSyncInterval);
|
|
cv.put(AccountColumns.SYNC_LOOKBACK, account.mSyncLookback);
|
|
uri = ContentUris.withAppendedId(Account.CONTENT_URI, account.mId);
|
|
} else {
|
|
cv.put(MailboxColumns.SYNC_INTERVAL, mailbox.mSyncInterval);
|
|
cv.put(MailboxColumns.SYNC_LOOKBACK, mailbox.mSyncLookback);
|
|
uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailbox.mId);
|
|
}
|
|
context.getContentResolver().update(uri, cv, null, null);
|
|
|
|
LogUtils.i(Logging.LOG_TAG, "Saved: " + uri);
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
protected void onSuccess(Void result) {
|
|
// must be called on the ui thread
|
|
//***
|
|
//RefreshManager.getInstance(context).refreshMessageList(account.mId, mailbox.mId,
|
|
// true);
|
|
}
|
|
}.executeSerial((Void [])null);
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
if (item.getItemId() == android.R.id.home) {
|
|
onBackPressed();
|
|
return true;
|
|
}
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
}
|