Don't use a repeating alarm for AttachmentDownloadService
* Guarantees we can't have runaway alarms * Manually merged from Email1 Bug: 6494254 Change-Id: I7f272f650ab34d50ec71ad503951ada3bbf203af
This commit is contained in:
parent
671965f494
commit
323eea8ac8
|
@ -62,7 +62,7 @@ public class AttachmentDownloadService extends Service implements Runnable {
|
||||||
// Our idle time, waiting for notifications; this is something of a failsafe
|
// Our idle time, waiting for notifications; this is something of a failsafe
|
||||||
private static final int PROCESS_QUEUE_WAIT_TIME = 30 * ((int)DateUtils.MINUTE_IN_MILLIS);
|
private static final int PROCESS_QUEUE_WAIT_TIME = 30 * ((int)DateUtils.MINUTE_IN_MILLIS);
|
||||||
// How often our watchdog checks for callback timeouts
|
// How often our watchdog checks for callback timeouts
|
||||||
private static final int WATCHDOG_CHECK_INTERVAL = 15 * ((int)DateUtils.SECOND_IN_MILLIS);
|
private static final int WATCHDOG_CHECK_INTERVAL = 20 * ((int)DateUtils.SECOND_IN_MILLIS);
|
||||||
// How long we'll wait for a callback before canceling a download and retrying
|
// How long we'll wait for a callback before canceling a download and retrying
|
||||||
private static final int CALLBACK_TIMEOUT = 30 * ((int)DateUtils.SECOND_IN_MILLIS);
|
private static final int CALLBACK_TIMEOUT = 30 * ((int)DateUtils.SECOND_IN_MILLIS);
|
||||||
// Try to download an attachment in the background this many times before giving up
|
// Try to download an attachment in the background this many times before giving up
|
||||||
|
@ -235,7 +235,6 @@ public class AttachmentDownloadService extends Service implements Runnable {
|
||||||
/*package*/ class DownloadSet extends TreeSet<DownloadRequest> {
|
/*package*/ class DownloadSet extends TreeSet<DownloadRequest> {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private PendingIntent mWatchdogPendingIntent;
|
private PendingIntent mWatchdogPendingIntent;
|
||||||
private AlarmManager mAlarmManager;
|
|
||||||
|
|
||||||
/*package*/ DownloadSet(Comparator<? super DownloadRequest> comparator) {
|
/*package*/ DownloadSet(Comparator<? super DownloadRequest> comparator) {
|
||||||
super(comparator);
|
super(comparator);
|
||||||
|
@ -407,20 +406,13 @@ public class AttachmentDownloadService extends Service implements Runnable {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelWatchdogAlarm() {
|
|
||||||
if (mAlarmManager != null && mWatchdogPendingIntent != null) {
|
|
||||||
mAlarmManager.cancel(mWatchdogPendingIntent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Watchdog for downloads; we use this in case we are hanging on a download, which might
|
* Watchdog for downloads; we use this in case we are hanging on a download, which might
|
||||||
* have failed silently (the connection dropped, for example)
|
* have failed silently (the connection dropped, for example)
|
||||||
*/
|
*/
|
||||||
private void onWatchdogAlarm() {
|
private void onWatchdogAlarm() {
|
||||||
// If our service instance is gone, just leave (but cancel alarm first!)
|
// If our service instance is gone, just leave
|
||||||
if (mStop) {
|
if (mStop) {
|
||||||
cancelWatchdogAlarm();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
@ -434,14 +426,17 @@ public class AttachmentDownloadService extends Service implements Runnable {
|
||||||
cancelDownload(req);
|
cancelDownload(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If there are downloads in progress, reset alarm
|
|
||||||
if (mDownloadsInProgress.isEmpty()) {
|
|
||||||
cancelWatchdogAlarm();
|
|
||||||
}
|
|
||||||
// Check whether we can start new downloads...
|
// Check whether we can start new downloads...
|
||||||
if (mConnectivityManager != null && mConnectivityManager.hasConnectivity()) {
|
if (mConnectivityManager != null && mConnectivityManager.hasConnectivity()) {
|
||||||
processQueue();
|
processQueue();
|
||||||
}
|
}
|
||||||
|
// If there are downloads in progress, reset alarm
|
||||||
|
if (!mDownloadsInProgress.isEmpty()) {
|
||||||
|
if (MailActivityEmail.DEBUG) {
|
||||||
|
Log.d(TAG, "Reschedule watchdog...");
|
||||||
|
}
|
||||||
|
setWatchdogAlarm();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -475,6 +470,19 @@ public class AttachmentDownloadService extends Service implements Runnable {
|
||||||
return mDownloadsInProgress.get(attachmentId);
|
return mDownloadsInProgress.get(attachmentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setWatchdogAlarm() {
|
||||||
|
// Lazily initialize the pending intent
|
||||||
|
if (mWatchdogPendingIntent == null) {
|
||||||
|
Intent intent = new Intent(mContext, Watchdog.class);
|
||||||
|
mWatchdogPendingIntent =
|
||||||
|
PendingIntent.getBroadcast(mContext, 0, intent, 0);
|
||||||
|
}
|
||||||
|
// Set the alarm
|
||||||
|
AlarmManager am = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + WATCHDOG_CHECK_INTERVAL,
|
||||||
|
mWatchdogPendingIntent);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do the work of starting an attachment download using the EmailService interface, and
|
* Do the work of starting an attachment download using the EmailService interface, and
|
||||||
* set our watchdog alarm
|
* set our watchdog alarm
|
||||||
|
@ -489,20 +497,7 @@ public class AttachmentDownloadService extends Service implements Runnable {
|
||||||
req.inProgress = true;
|
req.inProgress = true;
|
||||||
mDownloadsInProgress.put(req.attachmentId, req);
|
mDownloadsInProgress.put(req.attachmentId, req);
|
||||||
service.loadAttachment(req.attachmentId, req.priority != PRIORITY_FOREGROUND);
|
service.loadAttachment(req.attachmentId, req.priority != PRIORITY_FOREGROUND);
|
||||||
// Lazily initialize our (reusable) pending intent
|
setWatchdogAlarm();
|
||||||
if (mWatchdogPendingIntent == null) {
|
|
||||||
createWatchdogPendingIntent(mContext);
|
|
||||||
}
|
|
||||||
// Set the alarm
|
|
||||||
mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
|
|
||||||
System.currentTimeMillis() + WATCHDOG_CHECK_INTERVAL, WATCHDOG_CHECK_INTERVAL,
|
|
||||||
mWatchdogPendingIntent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*package*/ void createWatchdogPendingIntent(Context context) {
|
|
||||||
Intent alarmIntent = new Intent(context, Watchdog.class);
|
|
||||||
mWatchdogPendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
|
|
||||||
mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelDownload(DownloadRequest req) {
|
private void cancelDownload(DownloadRequest req) {
|
||||||
|
|
|
@ -119,7 +119,6 @@ public class AttachmentDownloadServiceTests extends AccountTestCase {
|
||||||
|
|
||||||
// Process the queue; attachment 1 should be marked "in progress", and should be in
|
// Process the queue; attachment 1 should be marked "in progress", and should be in
|
||||||
// the in-progress map
|
// the in-progress map
|
||||||
mDownloadSet.createWatchdogPendingIntent(mContext);
|
|
||||||
mDownloadSet.processQueue();
|
mDownloadSet.processQueue();
|
||||||
DownloadRequest req = mDownloadSet.findDownloadRequest(att1.mId);
|
DownloadRequest req = mDownloadSet.findDownloadRequest(att1.mId);
|
||||||
assertNotNull(req);
|
assertNotNull(req);
|
||||||
|
@ -183,10 +182,12 @@ public class AttachmentDownloadServiceTests extends AccountTestCase {
|
||||||
mUsableSpace = usable;
|
mUsableSpace = usable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getTotalSpace() {
|
public long getTotalSpace() {
|
||||||
return mTotalSpace;
|
return mTotalSpace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getUsableSpace() {
|
public long getUsableSpace() {
|
||||||
return mUsableSpace;
|
return mUsableSpace;
|
||||||
}
|
}
|
||||||
|
@ -195,6 +196,7 @@ public class AttachmentDownloadServiceTests extends AccountTestCase {
|
||||||
mMockFile.mLength = length;
|
mMockFile.mLength = length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public File[] listFiles() {
|
public File[] listFiles() {
|
||||||
return mFiles;
|
return mFiles;
|
||||||
}
|
}
|
||||||
|
@ -211,6 +213,7 @@ public class AttachmentDownloadServiceTests extends AccountTestCase {
|
||||||
super("_mock");
|
super("_mock");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long length() {
|
public long length() {
|
||||||
return mLength;
|
return mLength;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue