blob: a69002506f083faeacd65a9853b88b4bf6583b65 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.component_updater;
import android.os.Build;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import org.chromium.base.ContextUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.components.background_task_scheduler.BackgroundTask.TaskFinishedCallback;
import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory;
import org.chromium.components.background_task_scheduler.TaskIds;
import org.chromium.components.background_task_scheduler.TaskInfo;
/** Java-side implementation of the component update scheduler using the BackgroundTaskScheduler. */
@JNINamespace("component_updater")
public class UpdateScheduler {
private static UpdateScheduler sInstance;
private TaskFinishedCallback mTaskFinishedCallback;
private long mNativeScheduler;
private long mDelayMs;
@CalledByNative
/* package */ static UpdateScheduler getInstance() {
if (sInstance == null) {
sInstance = new UpdateScheduler();
}
return sInstance;
}
@CalledByNative
/* package */ static boolean isAvailable() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|| GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
ContextUtils.getApplicationContext())
== ConnectionResult.SUCCESS;
}
/* package */ void onStartTaskBeforeNativeLoaded(TaskFinishedCallback callback) {
mTaskFinishedCallback = callback;
}
/* package */ void onStartTaskWithNative() {
assert mNativeScheduler != 0;
nativeOnStartTask(mNativeScheduler);
}
/* package */ void onStopTask() {
if (mNativeScheduler != 0) {
nativeOnStopTask(mNativeScheduler);
}
mTaskFinishedCallback = null;
scheduleInternal(mDelayMs);
}
/* package */ void reschedule() {
scheduleInternal(mDelayMs);
}
private UpdateScheduler() {}
private void scheduleInternal(long delayMs) {
// Skip re-scheduling if we are currently running the update task. Otherwise, the current
// update tasks would be cancelled.
if (mTaskFinishedCallback != null) return;
TaskInfo taskInfo = TaskInfo.createOneOffTask(TaskIds.COMPONENT_UPDATE_JOB_ID,
UpdateTask.class, delayMs, Integer.MAX_VALUE)
.setUpdateCurrent(true)
.setRequiredNetworkType(TaskInfo.NETWORK_TYPE_UNMETERED)
.setIsPersisted(true)
.build();
BackgroundTaskSchedulerFactory.getScheduler().schedule(
ContextUtils.getApplicationContext(), taskInfo);
}
@CalledByNative
private void schedule(long initialDelayMs, long delayMs) {
mDelayMs = delayMs;
scheduleInternal(initialDelayMs);
}
@CalledByNative
private void finishTask(boolean reschedule) {
assert mTaskFinishedCallback != null;
mTaskFinishedCallback.taskFinished(false);
mTaskFinishedCallback = null;
if (reschedule) {
scheduleInternal(mDelayMs);
}
}
@CalledByNative
private void setNativeScheduler(long nativeScheduler) {
mNativeScheduler = nativeScheduler;
}
@CalledByNative
private void cancelTask() {
BackgroundTaskSchedulerFactory.getScheduler().cancel(
ContextUtils.getApplicationContext(), TaskIds.COMPONENT_UPDATE_JOB_ID);
}
private native void nativeOnStartTask(long nativeBackgroundTaskUpdateScheduler);
private native void nativeOnStopTask(long nativeBackgroundTaskUpdateScheduler);
}