1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-08-13 17:03:48 -04:00

Improved synchronization timing and WakeLock algorithm. This new

approach should guarantee that the syncing never stalls just because a
single attempt exceeds the (currently 10 minute) WakeLock timeout.  At
the sync frequency, K-9 will wakeup again and refresh the WakeLock for
another go at syncing.  This should make synchronization much more
reliable in the face of slow or unavailable connections, in particular
ones which hit the socket read timeouts.

Also, fixed the audible notifications so that the ringtone selected
is always for one of the accounts with new unread mail.

Developers now have the option to turn on a fast-flashing LED during
synchronization in order to observe whether synchronization is
happening while the handset is apparently asleep.  I think this option
would be aggravating to non-developer users.  See
Email.NOTIFICATION_LED_WHILE_SYNCING


Issue 175
Issue 170
This commit is contained in:
Daniel Applebaum 2009-01-11 23:43:32 +00:00
parent f0867387c8
commit 65bbc7e68a
3 changed files with 98 additions and 37 deletions

View File

@ -132,7 +132,12 @@ public class Email extends Application {
/**
* Time the LED is off when blicking on new email notification
*/
public static final int NOTIFICATION_LED_OFF_TIME = 2000;
public static final int NOTIFICATION_LED_OFF_TIME = 2000;
public static final boolean NOTIFICATION_LED_WHILE_SYNCING = false;
public static final int NOTIFICATION_LED_DIM_COLOR = 0x77770077;
public static final int NOTIFICATION_LED_FAST_ON_TIME = 100;
public static final int NOTIFICATION_LED_FAST_OFF_TIME = 100;
// Must not conflict with an account number
public static final int FETCHING_EMAIL_NOTIFICATION_ID = -4;

View File

@ -105,6 +105,8 @@ public class MessagingController implements Runnable {
//private Set<MessagingListener> mListeners = Collections.synchronizedSet(new HashSet<MessagingListener>());
private Set<MessagingListener> mListeners = new CopyOnWriteArraySet<MessagingListener>();
private MessagingListener checkMailListener = null;
private boolean mBusy;
private Application mApplication;
@ -462,6 +464,7 @@ public class MessagingController implements Runnable {
Log.v(Email.LOG_TAG, debugLine);
}
log(debugLine);
for (MessagingListener l : getListeners()) {
l.synchronizeMailboxStarted(account, folder);
}
@ -945,7 +948,6 @@ s * critical data as fast as possible, and then we'll fill in the de
" with " + newMessages.size() + " new messages");
}
for (MessagingListener l : getListeners()) {
l.synchronizeMailboxFinished(
account,
@ -2066,7 +2068,6 @@ s * critical data as fast as possible, and then we'll fill in the de
public void checkMail(final Context context, final Account account,
final MessagingListener listener) {
for (MessagingListener l : getListeners()) {
l.checkMailStarted(context, account);
}
@ -2114,6 +2115,14 @@ s * critical data as fast as possible, and then we'll fill in the de
notif.setLatestEventInfo(context, context.getString(R.string.notification_bg_send_title),
account.getDescription() , pi);
notif.flags = Notification.FLAG_ONGOING_EVENT;
if (Email.NOTIFICATION_LED_WHILE_SYNCING) {
notif.flags |= Notification.FLAG_SHOW_LIGHTS;
notif.ledARGB = Email.NOTIFICATION_LED_DIM_COLOR;
notif.ledOnMS = Email.NOTIFICATION_LED_FAST_ON_TIME;
notif.ledOffMS = Email.NOTIFICATION_LED_FAST_OFF_TIME;
}
notifMgr.notify(Email.FETCHING_EMAIL_NOTIFICATION_ID, notif);
try
{
@ -2220,6 +2229,13 @@ s * critical data as fast as possible, and then we'll fill in the de
notif.setLatestEventInfo(context, context.getString(R.string.notification_bg_sync_title), account.getDescription()
+ context.getString(R.string.notification_bg_title_separator) + folder.getName(), pi);
notif.flags = Notification.FLAG_ONGOING_EVENT;
if (Email.NOTIFICATION_LED_WHILE_SYNCING) {
notif.flags |= Notification.FLAG_SHOW_LIGHTS;
notif.ledARGB = Email.NOTIFICATION_LED_DIM_COLOR;
notif.ledOnMS = Email.NOTIFICATION_LED_FAST_ON_TIME;
notif.ledOffMS = Email.NOTIFICATION_LED_FAST_OFF_TIME;
}
notifMgr.notify(Email.FETCHING_EMAIL_NOTIFICATION_ID, notif);
try
{
@ -2261,6 +2277,7 @@ s * critical data as fast as possible, and then we'll fill in the de
for (MessagingListener l : getListeners()) {
l.checkMailFinished(context, account);
}
}
}
);
@ -2301,4 +2318,22 @@ s * critical data as fast as possible, and then we'll fill in the de
public String description;
}
public MessagingListener getCheckMailListener()
{
return checkMailListener;
}
public void setCheckMailListener(MessagingListener checkMailListener)
{
if (this.checkMailListener != null)
{
removeListener(this.checkMailListener);
}
this.checkMailListener = checkMailListener;
if (this.checkMailListener != null)
{
addListener(this.checkMailListener);
}
}
}

View File

@ -70,14 +70,32 @@ public class MailService extends Service {
super.onStart(intent, startId);
this.mStartId = startId;
MessagingController.getInstance(getApplication()).addListener(mListener);
// MessagingController.getInstance(getApplication()).addListener(mListener);
if (ACTION_CHECK_MAIL.equals(intent.getAction())) {
//if (Config.LOGV) {
MessagingController.getInstance(getApplication()).log("***** MailService *****: checking mail");
Log.v(Email.LOG_TAG, "***** MailService *****: checking mail");
//}
mListener.wakeLockAcquire();
MessagingController.getInstance(getApplication()).checkMail(this, null, mListener);
MessagingController controller = MessagingController.getInstance(getApplication());
Listener listener = (Listener)controller.getCheckMailListener();
if (listener == null)
{
MessagingController.getInstance(getApplication()).log("***** MailService *****: starting new check");
mListener.wakeLockAcquire();
controller.setCheckMailListener(mListener);
controller.checkMail(this, null, mListener);
}
else
{
MessagingController.getInstance(getApplication()).log("***** MailService *****: renewing WakeLock");
listener.wakeLockAcquire();
}
reschedule();
stopSelf(startId);
}
else if (ACTION_CANCEL.equals(intent.getAction())) {
if (Config.LOGV) {
@ -102,7 +120,7 @@ public class MailService extends Service {
public void onDestroy() {
Log.v(Email.LOG_TAG, "***** MailService *****: onDestroy()");
super.onDestroy();
MessagingController.getInstance(getApplication()).removeListener(mListener);
// MessagingController.getInstance(getApplication()).removeListener(mListener);
}
private void cancel() {
@ -152,20 +170,25 @@ public class MailService extends Service {
}
class Listener extends MessagingListener {
HashMap<Account, Integer> accountsWithNewMail = new HashMap<Account, Integer>();
HashMap<String, Integer> accountsWithNewMail = new HashMap<String, Integer>();
private WakeLock wakeLock = null;
// wakelock strategy is to be very conservative. If there is any reason to release, then release
// don't want to take the chance of running wild
public synchronized void wakeLockAcquire()
{
if (wakeLock == null)
{
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Email");
wakeLock.setReferenceCounted(false);
wakeLock.acquire(Email.WAKE_LOCK_TIMEOUT);
}
WakeLock oldWakeLock = wakeLock;
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Email");
wakeLock.setReferenceCounted(false);
wakeLock.acquire(Email.WAKE_LOCK_TIMEOUT);
if (oldWakeLock != null)
{
oldWakeLock.release();
}
}
public synchronized void wakeLockRelease()
{
@ -182,15 +205,7 @@ public class MailService extends Service {
@Override
public void checkMailFailed(Context context, Account account, String reason) {
try
{
reschedule();
}
finally
{
wakeLockRelease();
}
stopSelf(mStartId);
release();
}
@Override
@ -200,7 +215,7 @@ public class MailService extends Service {
int totalMessagesInMailbox,
int numNewMessages) {
if (account.isNotifyNewMail() && numNewMessages > 0) {
accountsWithNewMail.put(account, numNewMessages);
accountsWithNewMail.put(account.getUuid(), numNewMessages);
}
}
@ -244,11 +259,14 @@ public class MailService extends Service {
Log.e(Email.LOG_TAG, "***** MailService *****: couldn't get unread count for account " +
thisAccount.getDescription(), me);
}
if (ringtone == null)
if (accountsWithNewMail.containsKey(thisAccount.getUuid()))
{
ringtone = thisAccount.getRingtone();
if (ringtone == null)
{
ringtone = thisAccount.getRingtone();
}
vibrate |= thisAccount.isVibrate();
}
vibrate |= thisAccount.isVibrate();
}
}
if (notice.length() > 0)
@ -266,6 +284,8 @@ public class MailService extends Service {
notif.setLatestEventInfo(context, getString(R.string.notification_new_title),
notice, pi);
Log.v(Email.LOG_TAG, "Using ringtone " + ringtone + " and vibrate = " + vibrate);
// notif.defaults = Notification.DEFAULT_LIGHTS;
notif.sound = TextUtils.isEmpty(ringtone) ? null : Uri.parse(ringtone);
if (vibrate) {
@ -281,6 +301,15 @@ public class MailService extends Service {
}
}
private void release()
{
MessagingController controller = MessagingController.getInstance(getApplication());
controller.setCheckMailListener(null);
reschedule();
wakeLockRelease();
stopSelf(mStartId);
}
@Override
public void checkMailFinished(Context context, Account account) {
@ -292,15 +321,7 @@ public class MailService extends Service {
}
finally
{
try
{
reschedule();
}
finally
{
wakeLockRelease();
}
stopSelf(mStartId);
release();
}
}
}