Commit f9c0e04c authored by qinmin's avatar qinmin Committed by Commit bot
Browse files

capping how many times background download resumption can automatically start

If download gets interrupted due to browser kill, we schedule a browser
restart.
And we could stuck in a cycle of kill->restart->kill.
This CL caps the number of auto resumptions.
And reset the cap when user relaunches chrome.

BUG=623242

Review-Url: https://codereview.chromium.org/2094033002
Cr-Commit-Position: refs/heads/master@{#402340}
parent 7bcf27ec
......@@ -70,6 +70,7 @@ import org.chromium.chrome.browser.datausage.DataUseTabUIManager;
import org.chromium.chrome.browser.device.DeviceClassManager;
import org.chromium.chrome.browser.dom_distiller.DistilledPagePrefsView;
import org.chromium.chrome.browser.dom_distiller.ReaderModeManager;
import org.chromium.chrome.browser.download.DownloadManagerService;
import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager;
import org.chromium.chrome.browser.gsa.ContextReporter;
import org.chromium.chrome.browser.gsa.GSAServiceClient;
......@@ -917,7 +918,8 @@ public abstract class ChromeActivity extends AsyncInitializationActivity
} else {
removeWindowBackground();
}
DownloadManagerService.getDownloadManagerService(
getApplicationContext()).onActivityLaunched();
super.finishNativeInitialization();
}
......
......@@ -316,6 +316,14 @@ public class DownloadManagerService extends BroadcastReceiver implements
scheduleUpdateIfNeeded();
}
/**
* Called when browser activity is launched. For background resumption and cancellation, this
* will not be called.
*/
public void onActivityLaunched() {
DownloadNotificationService.clearResumptionAttemptLeft();
}
/**
* Clear any pending OMA downloads by reading them from shared prefs.
* TODO(qinmin): move this to a separate class.
......
......@@ -62,6 +62,8 @@ public class DownloadNotificationService extends Service {
private static final String NEXT_DOWNLOAD_NOTIFICATION_ID = "NextDownloadNotificationId";
// Notification Id starting value, to avoid conflicts from IDs used in prior versions.
private static final int STARTING_NOTIFICATION_ID = 1000000;
private static final String AUTO_RESUMPTION_ATTEMPT_LEFT = "ResumptionAttemptLeft";
private static final int MAX_RESUMPTION_ATTEMPT_LEFT = 5;
@VisibleForTesting static final int SECONDS_PER_MINUTE = 60;
@VisibleForTesting static final int SECONDS_PER_HOUR = 60 * 60;
@VisibleForTesting static final int SECONDS_PER_DAY = 24 * 60 * 60;
......@@ -73,6 +75,7 @@ public class DownloadNotificationService extends Service {
private SharedPreferences mSharedPrefs;
private Context mContext;
private int mNextNotificationId;
private int mNumAutoResumptionAttemptLeft;
/**
* Class for clients to access.
......@@ -126,8 +129,10 @@ public class DownloadNotificationService extends Service {
allowMeteredConnection = true;
}
}
DownloadResumptionScheduler.getDownloadResumptionScheduler(mContext).schedule(
allowMeteredConnection);
if (mNumAutoResumptionAttemptLeft > 0) {
DownloadResumptionScheduler.getDownloadResumptionScheduler(mContext).schedule(
allowMeteredConnection);
}
}
stopSelf();
}
......@@ -137,8 +142,19 @@ public class DownloadNotificationService extends Service {
if (isDownloadOperationIntent(intent)) {
handleDownloadOperation(intent);
DownloadResumptionScheduler.getDownloadResumptionScheduler(mContext).cancelTask();
// Limit the number of auto resumption attempts in case Chrome falls into a vicious
// cycle.
if (intent.getAction() == ACTION_DOWNLOAD_RESUME_ALL) {
if (mNumAutoResumptionAttemptLeft > 0) {
mNumAutoResumptionAttemptLeft--;
updateResumptionAttemptLeft();
}
} else {
// Reset number of attempts left if the action is triggered by user.
mNumAutoResumptionAttemptLeft = MAX_RESUMPTION_ATTEMPT_LEFT;
clearResumptionAttemptLeft();
}
}
// This should restart the service after Chrome gets killed. However, this
// doesn't work on Android 4.4.2.
return START_STICKY;
......@@ -149,6 +165,26 @@ public class DownloadNotificationService extends Service {
return mBinder;
}
/**
* Helper method to update the remaining number of background resumption attempts left.
* @param attamptLeft Number of attempt left.
*/
private void updateResumptionAttemptLeft() {
SharedPreferences.Editor editor = mSharedPrefs.edit();
editor.putInt(AUTO_RESUMPTION_ATTEMPT_LEFT, mNumAutoResumptionAttemptLeft);
editor.apply();
}
/**
* Helper method to clear the remaining number of background resumption attempts left.
*/
static void clearResumptionAttemptLeft() {
SharedPreferences SharedPrefs = ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor editor = SharedPrefs.edit();
editor.remove(AUTO_RESUMPTION_ATTEMPT_LEFT);
editor.apply();
}
/**
* Add a in-progress download notification.
* @param downloadGuid GUID of the download.
......@@ -547,10 +583,12 @@ public class DownloadNotificationService extends Service {
}
/**
* Parse the DownloadSharedPreferenceEntry from the shared preference and return a list of them.
* @return a list of parsed DownloadSharedPreferenceEntry.
* Parse a list of the DownloadSharedPreferenceEntry and the number of auto resumption attempt
* left from the shared preference.
*/
void parseDownloadSharedPrefs() {
mNumAutoResumptionAttemptLeft = mSharedPrefs.getInt(AUTO_RESUMPTION_ATTEMPT_LEFT,
MAX_RESUMPTION_ATTEMPT_LEFT);
if (!mSharedPrefs.contains(PENDING_DOWNLOAD_NOTIFICATIONS)) return;
Set<String> entries = DownloadManagerService.getStoredDownloadInfo(
mSharedPrefs, PENDING_DOWNLOAD_NOTIFICATIONS);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment