replicant-packages_apps_Email/src/com/android/email/activity/setup/MailboxSettings.java

322 lines
12 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 com.android.email.Email;
import com.android.email.FolderProperties;
import com.android.email.R;
import com.android.email.RefreshManager;
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.utility.EmailAsyncTask;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
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.util.Log;
/**
* "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();
}
}
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();
}
}
/**
* 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.
setTitle(getString(R.string.mailbox_settings_activity_title_with_mailbox,
FolderProperties.getInstance(this).getDisplayName(mMailbox)));
// Special case: If setting inbox, don't show "Use account's default".
if (mMailbox.mType == Mailbox.TYPE_INBOX) {
mSyncLookbackPref.setEntries(R.array.account_settings_mail_window_entries);
mSyncLookbackPref.setEntryValues(R.array.account_settings_mail_window_values);
}
// 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() {
if (mMailbox.mType == Mailbox.TYPE_INBOX) {
return mAccount.mSyncInterval;
} else {
if (mMailbox.mSyncInterval == 0) {
// 0 is the default value, and it means "don't sync" (for non-inbox mailboxes)
return Mailbox.CHECK_INTERVAL_NEVER;
}
return mMailbox.mSyncInterval;
}
}
/**
* @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 (Email.DEBUG) {
Log.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 (Email.DEBUG) {
Log.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;
}
Log.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 = this.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);
Log.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);
}
}