[AW][ComponentUpdater] Override Service#onStartCommand for testing
Override AwComponentUpdateService#onStartCommand to run the native update service. This way it's possible to deterministically force launch the service on devices running android M and below for testing purposes where it's not possible to force launch the job service via `adb shell cmd jobscheduler`. The service isn't exported so other apps can't start the service. The service can be launched using the commandline: `adb shell am startservice <webview-package-name>/org.chromium.android_webview.nonembedded.AwComponentUpdateService` Fixed: 1209275 Test: Manually launch the service via adb, run webview shell and see scheduled jobs Change-Id: I994b46e5b250e4f42498dc20b4b89c11ea452485 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2905562 Reviewed-by: Mugdha Lakhani <nator@chromium.org> Reviewed-by: Richard Coles <torne@chromium.org> Commit-Queue: Hazem Ashmawy <hazems@chromium.org> Cr-Commit-Position: refs/heads/master@{#894619}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
fdb9894661
commit
ebccaf66ab
@ -6,6 +6,7 @@ package org.chromium.android_webview.nonembedded;
|
||||
import android.app.job.JobParameters;
|
||||
import android.app.job.JobService;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.SystemClock;
|
||||
|
||||
@ -48,8 +49,65 @@ public class AwComponentUpdateService extends JobService {
|
||||
private static final String SHARED_PREFERENCES_NAME = "AwComponentUpdateServicePreferences";
|
||||
private static final String KEY_UNEXPECTED_EXIT = "UnexpectedExit";
|
||||
|
||||
/**
|
||||
* The service can be both started by {@link android.app.job.JobScheduler} as a {@link
|
||||
* JobService} and as a started service by calling {@link Context#startService}. These two
|
||||
* states can apply at the same time. The service won't stop until all necessary stop
|
||||
* methods are called:
|
||||
* - Calling jobFinished if it's launched as a JobService.
|
||||
* - Calling stopSelf if it's launched as a start service.
|
||||
*/
|
||||
// If it has a non zero value, then the service is running via onStartCommand.
|
||||
private int mServiceStartedId;
|
||||
|
||||
// If not null then the service is running as a Job service.
|
||||
private JobParameters mJobParameters;
|
||||
|
||||
private boolean isServiceRunning() {
|
||||
return mJobParameters != null || mServiceStartedId != 0;
|
||||
}
|
||||
|
||||
// Called by JobScheduler.
|
||||
@Override
|
||||
public boolean onStartJob(JobParameters params) {
|
||||
assert mJobParameters == null;
|
||||
mJobParameters = params;
|
||||
if (isServiceRunning()) {
|
||||
return true;
|
||||
}
|
||||
return startNativeService();
|
||||
}
|
||||
|
||||
// Called by JobScheduler.
|
||||
@Override
|
||||
public boolean onStopJob(JobParameters params) {
|
||||
setUnexpectedExit(false);
|
||||
mJobParameters = null;
|
||||
|
||||
// This should only be called if the service needs to be shut down before we've called
|
||||
// jobFinished. Request reschedule so we can finish downloading component updates.
|
||||
return /*reschedule= */ true;
|
||||
}
|
||||
|
||||
// For testing only. To manually start the service on Android builds <= M where force running
|
||||
// the job service doesn't work. The service isn't exported, so other apps won't be able to
|
||||
// force start the service.
|
||||
// Note: This can be simpilified when we stop supporting Android M in WebView (no need to store
|
||||
// the state of how the service is running) or when manually starting the service on M isn't
|
||||
// needed.
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (!isServiceRunning() && !startNativeService()) {
|
||||
stopSelf(startId);
|
||||
} else {
|
||||
// Always keep the most recent startId as this is the one that should be used to stop
|
||||
// the service.
|
||||
mServiceStartedId = startId;
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
private boolean startNativeService() {
|
||||
maybeRecordUnexpectedExit();
|
||||
|
||||
// TODO(http://crbug.com/1179297) look at doing this in a task on a background thread
|
||||
@ -62,8 +120,8 @@ public class AwComponentUpdateService extends JobService {
|
||||
recordJobDuration(SystemClock.uptimeMillis() - startTime);
|
||||
recordFilesChanged(count);
|
||||
recordDirectorySize();
|
||||
jobFinished(params, /* needReschedule= */ false);
|
||||
setUnexpectedExit(false);
|
||||
stopService();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
@ -71,13 +129,18 @@ public class AwComponentUpdateService extends JobService {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onStopJob(JobParameters params) {
|
||||
setUnexpectedExit(false);
|
||||
|
||||
// This should only be called if the service needs to be shut down before we've called
|
||||
// jobFinished. Request reschedule so we can finish downloading component updates.
|
||||
return /*reschedule= */ true;
|
||||
// Call the appropriate stop method according to how the service is launched.
|
||||
private void stopService() {
|
||||
// Service is launched as a started service.
|
||||
if (mServiceStartedId > 0) {
|
||||
stopSelf(mServiceStartedId);
|
||||
mServiceStartedId = 0;
|
||||
}
|
||||
// Service is launched as a job service.
|
||||
if (mJobParameters != null) {
|
||||
jobFinished(mJobParameters, /* needReschedule= */ false);
|
||||
mJobParameters = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void recordDirectorySize() {
|
||||
|
Reference in New Issue
Block a user