Merge pull request #2449 from k9mail/root-classes-cleanup

Root classes cleanup
This commit is contained in:
Vincent Breitmoser 2017-03-30 13:20:49 +02:00 committed by GitHub
commit 62df90d13b
11 changed files with 1003 additions and 1128 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
package com.fsck.k9; package com.fsck.k9;
public interface BaseAccount { public interface BaseAccount {
public String getEmail(); String getEmail();
public void setEmail(String email); void setEmail(String email);
public String getDescription(); String getDescription();
public void setDescription(String description); void setDescription(String description);
public String getUuid(); String getUuid();
} }

View file

@ -8,7 +8,7 @@ import java.util.regex.Pattern;
public class EmailAddressValidator implements Validator { public class EmailAddressValidator implements Validator {
private static final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile( private static final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile(
"[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" + "[a-zA-Z0-9\\+\\.\\_\\%\\-]{1,256}" +
"\\@" + "\\@" +
"[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" + "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
"(" + "(" +

View file

@ -13,9 +13,6 @@ import com.fsck.k9.preferences.StorageEditor;
* list, message list and in the message view. * list, message list and in the message view.
*/ */
public class FontSizes { public class FontSizes {
/*
* Keys for the preference storage.
*/
private static final String ACCOUNT_NAME = "fontSizeAccountName"; private static final String ACCOUNT_NAME = "fontSizeAccountName";
private static final String ACCOUNT_DESCRIPTION = "fontSizeAccountDescription"; private static final String ACCOUNT_DESCRIPTION = "fontSizeAccountDescription";
private static final String FOLDER_NAME = "fontSizeFolderName"; private static final String FOLDER_NAME = "fontSizeFolderName";
@ -34,9 +31,6 @@ public class FontSizes {
private static final String MESSAGE_VIEW_CONTENT_PERCENT = "fontSizeMessageViewContentPercent"; private static final String MESSAGE_VIEW_CONTENT_PERCENT = "fontSizeMessageViewContentPercent";
private static final String MESSAGE_COMPOSE_INPUT = "fontSizeMessageComposeInput"; private static final String MESSAGE_COMPOSE_INPUT = "fontSizeMessageComposeInput";
/*
* Values for the font sizes in SP (Scale-independent Pixels)
*/
public static final int FONT_DEFAULT = -1; // Don't force-reset the size of this setting public static final int FONT_DEFAULT = -1; // Don't force-reset the size of this setting
public static final int FONT_10SP = 10; public static final int FONT_10SP = 10;
public static final int FONT_12SP = 12; public static final int FONT_12SP = 12;
@ -47,90 +41,25 @@ public class FontSizes {
public static final int LARGE = 22; // ?android:attr/textAppearanceLarge public static final int LARGE = 22; // ?android:attr/textAppearanceLarge
/**
* Font size of account names in the account list activity.
*/
private int accountName; private int accountName;
/**
* Font size of account descriptions in the account list activity.
*/
private int accountDescription; private int accountDescription;
/**
* Font size of folder names in the folder list activity.
*/
private int folderName; private int folderName;
/**
* Font size of the folder status in the folder list activity.
*/
private int folderStatus; private int folderStatus;
/**
* Font size of message subjects in the message list activity.
*/
private int messageListSubject; private int messageListSubject;
/**
* Font size of message senders in the message list activity.
*/
private int messageListSender; private int messageListSender;
/**
* Font size of message dates in the message list activity.
*/
private int messageListDate; private int messageListDate;
/**
* Font size of message preview in the message list activity.
*/
private int messageListPreview; private int messageListPreview;
/**
* Font size of the message sender in the message view activity.
*/
private int messageViewSender; private int messageViewSender;
/**
* Font size of the message receiver(s) (To) in the message view activity.
*/
private int messageViewTo; private int messageViewTo;
/**
* Font size of the message receiver(s) (CC) in the message view activity.
*/
private int messageViewCC; private int messageViewCC;
/**
* Font size of additional headers in the message view activity.
*/
private int messageViewAdditionalHeaders; private int messageViewAdditionalHeaders;
/**
* Font size of the message subject in the message view activity.
*/
private int messageViewSubject; private int messageViewSubject;
/**
* Font size of the message date and time in the message view activity.
*/
private int messageViewDate; private int messageViewDate;
/**
* Font size of the message content in the message view activity, as percent from default size.
*/
private int messageViewContentPercent; private int messageViewContentPercent;
/**
* Font size for the input fields in the message compose activity.
*/
private int messageComposeInput; private int messageComposeInput;
/**
* Create a <code>FontSizes</code> object with default values.
*/
public FontSizes() { public FontSizes() {
accountName = FONT_DEFAULT; accountName = FONT_DEFAULT;
accountDescription = FONT_DEFAULT; accountDescription = FONT_DEFAULT;
@ -154,11 +83,6 @@ public class FontSizes {
messageComposeInput = MEDIUM; messageComposeInput = MEDIUM;
} }
/**
* Permanently save the font size settings.
*
* @param editor Used to save the font size settings.
*/
public void save(StorageEditor editor) { public void save(StorageEditor editor) {
editor.putInt(ACCOUNT_NAME, accountName); editor.putInt(ACCOUNT_NAME, accountName);
editor.putInt(ACCOUNT_DESCRIPTION, accountDescription); editor.putInt(ACCOUNT_DESCRIPTION, accountDescription);
@ -182,11 +106,6 @@ public class FontSizes {
editor.putInt(MESSAGE_COMPOSE_INPUT, messageComposeInput); editor.putInt(MESSAGE_COMPOSE_INPUT, messageComposeInput);
} }
/**
* Load the font size settings from permanent storage.
*
* @param storage Used to load the font size settings.
*/
public void load(Storage storage) { public void load(Storage storage) {
accountName = storage.getInt(ACCOUNT_NAME, accountName); accountName = storage.getInt(ACCOUNT_NAME, accountName);
accountDescription = storage.getInt(ACCOUNT_DESCRIPTION, accountDescription); accountDescription = storage.getInt(ACCOUNT_DESCRIPTION, accountDescription);

View file

@ -4,51 +4,52 @@ import java.io.Serializable;
public class Identity implements Serializable { public class Identity implements Serializable {
private static final long serialVersionUID = -1666669071480985760L; private static final long serialVersionUID = -1666669071480985760L;
private String mDescription;
private String mName; private String description;
private String mEmail; private String name;
private String mSignature; private String email;
private boolean mSignatureUse; private String signature;
private boolean signatureUse;
private String replyTo; private String replyTo;
public synchronized String getName() { public synchronized String getName() {
return mName; return name;
} }
public synchronized void setName(String name) { public synchronized void setName(String name) {
mName = name; this.name = name;
} }
public synchronized String getEmail() { public synchronized String getEmail() {
return mEmail; return email;
} }
public synchronized void setEmail(String email) { public synchronized void setEmail(String email) {
mEmail = email; this.email = email;
} }
public synchronized boolean getSignatureUse() { public synchronized boolean getSignatureUse() {
return mSignatureUse; return signatureUse;
} }
public synchronized void setSignatureUse(boolean signatureUse) { public synchronized void setSignatureUse(boolean signatureUse) {
mSignatureUse = signatureUse; this.signatureUse = signatureUse;
} }
public synchronized String getSignature() { public synchronized String getSignature() {
return mSignature; return signature;
} }
public synchronized void setSignature(String signature) { public synchronized void setSignature(String signature) {
mSignature = signature; this.signature = signature;
} }
public synchronized String getDescription() { public synchronized String getDescription() {
return mDescription; return description;
} }
public synchronized void setDescription(String description) { public synchronized void setDescription(String description) {
mDescription = description; this.description = description;
} }
public synchronized String getReplyTo() { public synchronized String getReplyTo() {
@ -61,6 +62,7 @@ public class Identity implements Serializable {
@Override @Override
public synchronized String toString() { public synchronized String toString() {
return "Account.Identity(description=" + mDescription + ", name=" + mName + ", email=" + mEmail + ", replyTo=" + replyTo + ", signature=" + mSignature; return "Account.Identity(description=" + description + ", name=" + name + ", email=" + email + ", replyTo=" + replyTo + ", signature=" +
signature;
} }
} }

View file

@ -4,97 +4,83 @@ package com.fsck.k9;
* Describes how a notification should behave. * Describes how a notification should behave.
*/ */
public class NotificationSetting { public class NotificationSetting {
private boolean ringEnabled;
private String ringtoneUri;
/** private boolean ledEnabled;
* Ring notification kill switch. Allow disabling ringtones without losing private int ledColor;
* ringtone selection.
*/
private boolean mRing;
private String mRingtoneUri; private boolean vibrateEnabled;
/** private int vibratePattern;
* LED kill switch. private int vibrateTimes;
*/
private boolean mLed;
private int mLedColor;
/**
* Vibration kill switch.
*/
private boolean mVibrate;
private int mVibratePattern;
private int mVibrateTimes;
/** /**
* Set the ringtone kill switch. Allow to disable ringtone without losing * Set the ringtone kill switch. Allow to disable ringtone without losing
* ringtone selection. * ringtone selection.
* *
* @param ring * @param ringEnabled
* <code>true</code> to allow ringtones, <code>false</code> * <code>true</code> to allow ringtones, <code>false</code>
* otherwise. * otherwise.
*/ */
public synchronized void setRing(boolean ring) { public synchronized void setRingEnabled(boolean ringEnabled) {
mRing = ring; this.ringEnabled = ringEnabled;
} }
/** /**
* @return <code>true</code> if ringtone is allowed to play, * @return <code>true</code> if ringtone is allowed to play,
* <code>false</code> otherwise. * <code>false</code> otherwise.
*/ */
public synchronized boolean shouldRing() { public synchronized boolean isRingEnabled() {
return mRing; return ringEnabled;
} }
public synchronized String getRingtone() { public synchronized String getRingtone() {
return mRingtoneUri; return ringtoneUri;
} }
public synchronized void setRingtone(String ringtoneUri) { public synchronized void setRingtone(String ringtoneUri) {
mRingtoneUri = ringtoneUri; this.ringtoneUri = ringtoneUri;
} }
public synchronized boolean isLed() { public synchronized boolean isLedEnabled() {
return mLed; return ledEnabled;
} }
public synchronized void setLed(final boolean led) { public synchronized void setLed(final boolean led) {
mLed = led; ledEnabled = led;
} }
public synchronized int getLedColor() { public synchronized int getLedColor() {
return mLedColor; return ledColor;
} }
public synchronized void setLedColor(int color) { public synchronized void setLedColor(int color) {
mLedColor = color; ledColor = color;
} }
public synchronized boolean shouldVibrate() { public synchronized boolean isVibrateEnabled() {
return mVibrate; return vibrateEnabled;
} }
public synchronized void setVibrate(boolean vibrate) { public synchronized void setVibrate(boolean vibrate) {
mVibrate = vibrate; vibrateEnabled = vibrate;
} }
public synchronized int getVibratePattern() { public synchronized int getVibratePattern() {
return mVibratePattern; return vibratePattern;
} }
public synchronized int getVibrateTimes() { public synchronized int getVibrateTimes() {
return mVibrateTimes; return vibrateTimes;
} }
public synchronized void setVibratePattern(int pattern) { public synchronized void setVibratePattern(int pattern) {
mVibratePattern = pattern; vibratePattern = pattern;
} }
public synchronized void setVibrateTimes(int times) { public synchronized void setVibrateTimes(int times) {
mVibrateTimes = times; vibrateTimes = times;
} }
@ -108,7 +94,7 @@ public class NotificationSetting {
*/ */
public long[] getVibration() { public long[] getVibration() {
return getVibration(mVibratePattern, mVibrateTimes); return getVibration(vibratePattern, vibrateTimes);
} }
public static long[] getVibration(int pattern, int times) { public static long[] getVibration(int pattern, int times) {
@ -149,6 +135,4 @@ public class NotificationSetting {
return repeatedPattern; return repeatedPattern;
} }
} }

View file

@ -31,26 +31,26 @@ public class Preferences {
} }
private Storage mStorage; private Storage storage;
private Map<String, Account> accounts = null; private Map<String, Account> accounts = null;
private List<Account> accountsInOrder = null; private List<Account> accountsInOrder = null;
private Account newAccount; private Account newAccount;
private Context mContext; private Context context;
private Preferences(Context context) { private Preferences(Context context) {
mStorage = Storage.getStorage(context); storage = Storage.getStorage(context);
mContext = context; this.context = context;
if (mStorage.isEmpty()) { if (storage.isEmpty()) {
Timber.i("Preferences storage is zero-size, importing from Android-style preferences"); Timber.i("Preferences storage is zero-size, importing from Android-style preferences");
StorageEditor editor = mStorage.edit(); StorageEditor editor = storage.edit();
editor.copy(context.getSharedPreferences("AndroidMail.Main", Context.MODE_PRIVATE)); editor.copy(context.getSharedPreferences("AndroidMail.Main", Context.MODE_PRIVATE));
editor.commit(); editor.commit();
} }
} }
public synchronized void loadAccounts() { public synchronized void loadAccounts() {
accounts = new HashMap<String, Account>(); accounts = new HashMap<>();
accountsInOrder = new LinkedList<Account>(); accountsInOrder = new LinkedList<>();
String accountUuids = getStorage().getString("accountUuids", null); String accountUuids = getStorage().getString("accountUuids", null);
if ((accountUuids != null) && (accountUuids.length() != 0)) { if ((accountUuids != null) && (accountUuids.length() != 0)) {
String[] uuids = accountUuids.split(","); String[] uuids = accountUuids.split(",");
@ -80,7 +80,7 @@ public class Preferences {
loadAccounts(); loadAccounts();
} }
return Collections.unmodifiableList(new ArrayList<Account>(accountsInOrder)); return Collections.unmodifiableList(new ArrayList<>(accountsInOrder));
} }
/** /**
@ -91,9 +91,9 @@ public class Preferences {
*/ */
public synchronized Collection<Account> getAvailableAccounts() { public synchronized Collection<Account> getAvailableAccounts() {
List<Account> allAccounts = getAccounts(); List<Account> allAccounts = getAccounts();
Collection<Account> retval = new ArrayList<Account>(accounts.size()); Collection<Account> retval = new ArrayList<>(accounts.size());
for (Account account : allAccounts) { for (Account account : allAccounts) {
if (account.isEnabled() && account.isAvailable(mContext)) { if (account.isEnabled() && account.isAvailable(context)) {
retval.add(account); retval.add(account);
} }
} }
@ -105,13 +105,12 @@ public class Preferences {
if (accounts == null) { if (accounts == null) {
loadAccounts(); loadAccounts();
} }
Account account = accounts.get(uuid);
return account; return accounts.get(uuid);
} }
public synchronized Account newAccount() { public synchronized Account newAccount() {
newAccount = new Account(mContext); newAccount = new Account(context);
accounts.put(newAccount.getUuid(), newAccount); accounts.put(newAccount.getUuid(), newAccount);
accountsInOrder.add(newAccount); accountsInOrder.add(newAccount);
@ -165,10 +164,10 @@ public class Preferences {
} }
public Storage getStorage() { public Storage getStorage() {
return mStorage; return storage;
} }
public static <T extends Enum<T>> T getEnumStringPref(Storage storage, String key, T defaultEnum) { static <T extends Enum<T>> T getEnumStringPref(Storage storage, String key, T defaultEnum) {
String stringPref = storage.getString(key, null); String stringPref = storage.getString(key, null);
if (stringPref == null) { if (stringPref == null) {

View file

@ -29,50 +29,31 @@ import timber.log.Timber;
* This class used to "throttle" a flow of events. * This class used to "throttle" a flow of events.
* *
* When {@link #onEvent()} is called, it calls the callback in a certain timeout later. * When {@link #onEvent()} is called, it calls the callback in a certain timeout later.
* Initially {@link #mMinTimeout} is used as the timeout, but if it gets multiple {@link #onEvent} * Initially {@link #minTimeout} is used as the timeout, but if it gets multiple {@link #onEvent}
* calls in a certain amount of time, it extends the timeout, until it reaches {@link #mMaxTimeout}. * calls in a certain amount of time, it extends the timeout, until it reaches {@link #maxTimeout}.
* *
* This class is primarily used to throttle content changed events. * This class is primarily used to throttle content changed events.
*/ */
public class Throttle { public class Throttle {
public static final boolean DEBUG = false; // Don't submit with true private static final int TIMEOUT_EXTEND_INTERVAL = 500;
public static final int DEFAULT_MIN_TIMEOUT = 150;
public static final int DEFAULT_MAX_TIMEOUT = 2500;
/* package */ static final int TIMEOUT_EXTEND_INTERVAL = 500;
private static Timer TIMER = new Timer(); private static Timer TIMER = new Timer();
private final Clock mClock; private final Clock clock;
private final Timer mTimer; private final Timer timer;
/** Name of the instance. Only for logging. */ private final String name;
private final String mName; private final Handler handler;
private final Runnable callback;
/** Handler for UI thread. */ private final int minTimeout;
private final Handler mHandler; private final int maxTimeout;
private int currentTimeout;
/** Callback to be called */
private final Runnable mCallback;
/** Minimum (default) timeout, in milliseconds. */
private final int mMinTimeout;
/** Max timeout, in milliseconds. */
private final int mMaxTimeout;
/** Current timeout, in milliseconds. */
private int mTimeout;
/** When {@link #onEvent()} was last called. */ /** When {@link #onEvent()} was last called. */
private long mLastEventTime; private long lastEventTime;
private MyTimerTask mRunningTimerTask; private MyTimerTask runningTimerTask;
/** Constructor with default timeout */
public Throttle(String name, Runnable callback, Handler handler) {
this(name, callback, handler, DEFAULT_MIN_TIMEOUT, DEFAULT_MAX_TIMEOUT);
}
/** Constructor that takes custom timeout */ /** Constructor that takes custom timeout */
public Throttle(String name, Runnable callback, Handler handler,int minTimeout, public Throttle(String name, Runnable callback, Handler handler,int minTimeout,
@ -81,64 +62,60 @@ public class Throttle {
} }
/** Constructor for tests */ /** Constructor for tests */
/* package */ Throttle(String name, Runnable callback, Handler handler,int minTimeout, private Throttle(String name, Runnable callback, Handler handler, int minTimeout,
int maxTimeout, Clock clock, Timer timer) { int maxTimeout, Clock clock, Timer timer) {
if (maxTimeout < minTimeout) { if (maxTimeout < minTimeout) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
mName = name; this.name = name;
mCallback = callback; this.callback = callback;
mClock = clock; this.clock = clock;
mTimer = timer; this.timer = timer;
mHandler = handler; this.handler = handler;
mMinTimeout = minTimeout; this.minTimeout = minTimeout;
mMaxTimeout = maxTimeout; this.maxTimeout = maxTimeout;
mTimeout = mMinTimeout; currentTimeout = this.minTimeout;
}
private void debugLog(String message) {
Timber.d("Throttle: [%s] %s", mName, message);
} }
private boolean isCallbackScheduled() { private boolean isCallbackScheduled() {
return mRunningTimerTask != null; return runningTimerTask != null;
} }
public void cancelScheduledCallback() { public void cancelScheduledCallback() {
if (mRunningTimerTask != null) { if (runningTimerTask != null) {
if (DEBUG) debugLog("Canceling scheduled callback"); Timber.d("Throttle: [%s] %s", name, "Canceling scheduled callback");
mRunningTimerTask.cancel(); runningTimerTask.cancel();
mRunningTimerTask = null; runningTimerTask = null;
} }
} }
/* package */ void updateTimeout() { private void updateTimeout() {
final long now = mClock.getTime(); final long now = clock.getTime();
if ((now - mLastEventTime) <= TIMEOUT_EXTEND_INTERVAL) { if ((now - lastEventTime) <= TIMEOUT_EXTEND_INTERVAL) {
mTimeout *= 2; currentTimeout *= 2;
if (mTimeout >= mMaxTimeout) { if (currentTimeout >= maxTimeout) {
mTimeout = mMaxTimeout; currentTimeout = maxTimeout;
} }
if (DEBUG) debugLog("Timeout extended " + mTimeout); Timber.d("Throttle: [%s] %s", name, "Timeout extended " + currentTimeout);
} else { } else {
mTimeout = mMinTimeout; currentTimeout = minTimeout;
if (DEBUG) debugLog("Timeout reset to " + mTimeout); Timber.d("Throttle: [%s] %s", name, "Timeout reset to " + currentTimeout);
} }
mLastEventTime = now; lastEventTime = now;
} }
public void onEvent() { public void onEvent() {
if (DEBUG) debugLog("onEvent"); Timber.d("Throttle: [%s] %s", name, "onEvent");
updateTimeout(); updateTimeout();
if (isCallbackScheduled()) { if (isCallbackScheduled()) {
if (DEBUG) debugLog(" callback already scheduled"); Timber.d("Throttle: [%s] %s", name, " callback already scheduled");
} else { } else {
if (DEBUG) debugLog(" scheduling callback"); Timber.d("Throttle: [%s] %s", name, " scheduling callback");
mRunningTimerTask = new MyTimerTask(); runningTimerTask = new MyTimerTask();
mTimer.schedule(mRunningTimerTask, mTimeout); timer.schedule(runningTimerTask, currentTimeout);
} }
} }
@ -150,7 +127,7 @@ public class Throttle {
@Override @Override
public void run() { public void run() {
mHandler.post(new HandlerRunnable()); handler.post(new HandlerRunnable());
} }
@Override @Override
@ -162,20 +139,12 @@ public class Throttle {
private class HandlerRunnable implements Runnable { private class HandlerRunnable implements Runnable {
@Override @Override
public void run() { public void run() {
mRunningTimerTask = null; runningTimerTask = null;
if (!mCanceled) { // This check has to be done on the UI thread. if (!mCanceled) { // This check has to be done on the UI thread.
if (DEBUG) debugLog("Kicking callback"); Timber.d("Throttle: [%s] %s", name, "Kicking callback");
mCallback.run(); callback.run();
} }
} }
} }
} }
/* package */ int getTimeoutForTest() {
return mTimeout;
}
/* package */ long getLastEventTimeForTest() {
return mLastEventTime;
}
} }

View file

@ -76,9 +76,9 @@ class DeviceNotifications extends BaseNotifications {
NotificationSetting notificationSetting = account.getNotificationSetting(); NotificationSetting notificationSetting = account.getNotificationSetting();
controller.configureNotification( controller.configureNotification(
builder, builder,
(notificationSetting.shouldRing()) ? notificationSetting.getRingtone() : null, (notificationSetting.isRingEnabled()) ? notificationSetting.getRingtone() : null,
(notificationSetting.shouldVibrate()) ? notificationSetting.getVibration() : null, (notificationSetting.isVibrateEnabled()) ? notificationSetting.getVibration() : null,
(notificationSetting.isLed()) ? notificationSetting.getLedColor() : null, (notificationSetting.isLedEnabled()) ? notificationSetting.getLedColor() : null,
NOTIFICATION_LED_BLINK_SLOW, NOTIFICATION_LED_BLINK_SLOW,
ringAndVibrate); ringAndVibrate);

View file

@ -82,7 +82,7 @@ public class RemoteControlService extends CoreService {
account.setNotifyNewMail(Boolean.parseBoolean(notificationEnabled)); account.setNotifyNewMail(Boolean.parseBoolean(notificationEnabled));
} }
if (ringEnabled != null) { if (ringEnabled != null) {
account.getNotificationSetting().setRing(Boolean.parseBoolean(ringEnabled)); account.getNotificationSetting().setRingEnabled(Boolean.parseBoolean(ringEnabled));
} }
if (vibrateEnabled != null) { if (vibrateEnabled != null) {
account.getNotificationSetting().setVibrate(Boolean.parseBoolean(vibrateEnabled)); account.getNotificationSetting().setVibrate(Boolean.parseBoolean(vibrateEnabled));