diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-18 16:35:47 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-18 15:45:54 +0000 |
commit | 32f5a1c56531e4210bc4cf8d8c7825d66e081888 (patch) | |
tree | eeeec6822f4d738d8454525233fd0e2e3a659e6d /chromium/components/background_task_scheduler | |
parent | 99677208ff3b216fdfec551fbe548da5520cd6fb (diff) | |
download | qtwebengine-chromium-32f5a1c56531e4210bc4cf8d8c7825d66e081888.tar.gz |
BASELINE: Update Chromium to 87.0.4280.67
Change-Id: Ib157360be8c2ffb2c73125751a89f60e049c1d54
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/background_task_scheduler')
24 files changed, 0 insertions, 3981 deletions
diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTask.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTask.java deleted file mode 100644 index d3549e233c4..00000000000 --- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTask.java +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler; - -import android.content.Context; - -import androidx.annotation.AnyThread; -import androidx.annotation.MainThread; - -/** - * Entry point for callbacks from {@link BackgroundTaskScheduler}. Any classes implementing - * this interface must have a public constructor which takes no arguments. - * The callbacks will be executed on the main thread, which means that execution logic must be - * offloaded to another {@link Thread}, {@link android.os.Handler} or {@link - * org.chromium.base.task.AsyncTask}. - */ -public interface BackgroundTask { - /** - * Callback to invoke whenever background processing has finished after first returning true - * from {@link #onStartTask(Context, TaskParameters, TaskFinishedCallback)}. - */ - interface TaskFinishedCallback { - /** - * Callback to inform the {@link BackgroundTaskScheduler} that the background processing - * now has finished. When this callback is invoked, the system will stop holding a wakelock. - * - * @param needsReschedule whether this task must be rescheduled. - */ - @AnyThread - void taskFinished(boolean needsReschedule); - } - - /** - * Callback from {@link BackgroundTaskScheduler} when your task should start processing. - * It is invoked on the main thread, and if your task finishes quickly, you should return false - * from this method when you are done processing. If this is a long-running task, you should - * return true from this method, and instead invoke the {@link TaskFinishedCallback} when the - * processing is finished on some other {@link Thread}, {@link android.os.Handler} or - * {@link org.chromium.base.task.AsyncTask}. While this method is running the - * system holds a wakelock. If false is returned from this method, the wakelock is immediately - * released, but if this method returns true, the wakelock is not released until either the - * {@link TaskFinishedCallback} is invoked, or the system calls {@link #onStopTask(Context, - * TaskParameters)}. - * - * @param context the current context. - * @param taskParameters the data passed in as {@link TaskInfo} when the task was scheduled. - * @param callback if the task needs to continue processing after returning from the call to - * {@link #onStartTask(Context, TaskParameters, TaskFinishedCallback)}, this - * callback must be invoked when the processing has finished. - * @return true if the task needs to continue processing work. False if there is no more work. - * @see TaskInfo - */ - @MainThread - boolean onStartTask( - Context context, TaskParameters taskParameters, TaskFinishedCallback callback); - - /** - * Callback from {@link BackgroundTaskScheduler} when the system has determined that the - * execution of the task must stop immediately, even before the {@link TaskFinishedCallback} - * has been invoked. This will typically happen whenever the required conditions for the task - * are no longer met. See {@link TaskInfo}. A wakelock is held by the system while this callback - * is invoked, and immediately released after this method returns. - * - * @param context the current context. - * @param taskParameters the data passed in as {@link TaskInfo} when the task was scheduled. - * @return true if the task needs to be rescheduled according to the rescheduling criteria - * specified when the task was scheduled initially. False if the taskshould not be rescheduled. - * Regardless of the value returned, your task must stop executing. - * @see TaskInfo - */ - @MainThread - boolean onStopTask(Context context, TaskParameters taskParameters); - - /** - * Callback from {@link BackgroundTaskScheduler} when it detects system conditions requiring - * rescheduling, e.g. Google Play Services update or OS upgrade. The task should schedule itself - * again with appropriate parameters. - * - * @param context the current context. - */ - @MainThread - void reschedule(Context context); -} diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskFactory.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskFactory.java deleted file mode 100644 index 92c5a3ee108..00000000000 --- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskFactory.java +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2019 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.components.background_task_scheduler; - -/** - * Generic factory interface to inject into {@link BackgroundTaskSchedulerFactory}. - * Exposes the interface call for getting the BackgroundTask class instance from the task id. - */ -public interface BackgroundTaskFactory { - /** - * Creates a BackgroundTask class instance for a given task id. - * @param taskId the task id for which to create a BackgroundTask class instance. - * @return an instance of the corresponding BackgroundTask class or null if task id is unknown. - */ - BackgroundTask getBackgroundTaskFromTaskId(int taskId); -} diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskScheduler.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskScheduler.java deleted file mode 100644 index bb2f036dd30..00000000000 --- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskScheduler.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler; - -import android.content.Context; - -import androidx.annotation.MainThread; - -/** - * A BackgroundTaskScheduler is used to schedule jobs that run in the background. - * It is backed by system APIs ({@link android.app.job.JobScheduler}) on newer platforms - * and by GCM ({@link com.google.android.gms.gcm.GcmNetworkManager}) on older platforms. - * - * To get an instance of this class, use {@link BackgroundTaskSchedulerFactory#getScheduler()}. - */ -public interface BackgroundTaskScheduler { - /** - * Schedules a background task. See {@link TaskInfo} for information on what types of tasks that - * can be scheduled. - * - * @param context the current context. - * @param taskInfo the information about the task to be scheduled. - * @return true if the schedule operation succeeded, and false otherwise. - * @see TaskInfo - */ - @MainThread - boolean schedule(Context context, TaskInfo taskInfo); - - /** - * Cancels the task specified by the task ID. - * - * @param context the current context. - * @param taskId the ID of the task to cancel. See {@link TaskIds} for a list. - */ - @MainThread - void cancel(Context context, int taskId); - - /** - * Checks whether OS was upgraded and triggers rescheduling if it is necessary. - * Rescheduling is necessary if type of background task scheduler delegate is different for a - * new version of the OS. - * - * @param context the current context. - */ - @MainThread - void checkForOSUpgrade(Context context); - - /** - * Reschedules all the tasks currently scheduler through BackgroundTaskSheduler. - * @param context the current context. - */ - @MainThread - void reschedule(Context context); -} diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java deleted file mode 100644 index 086c81110cb..00000000000 --- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerExternalUma.java +++ /dev/null @@ -1,159 +0,0 @@ -// 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.components.background_task_scheduler; - -import androidx.annotation.VisibleForTesting; - -/** - * Helper class to allow external code (typically Chrome-specific BackgroundTaskScheduler code) to - * report UMA. - */ -public abstract class BackgroundTaskSchedulerExternalUma { - // BackgroundTaskId defined in tools/metrics/histograms/enums.xml - public static final int BACKGROUND_TASK_TEST = 0; - public static final int BACKGROUND_TASK_OMAHA = 1; - public static final int BACKGROUND_TASK_GCM = 2; - public static final int BACKGROUND_TASK_NOTIFICATIONS = 3; - public static final int BACKGROUND_TASK_WEBVIEW_MINIDUMP = 4; - public static final int BACKGROUND_TASK_CHROME_MINIDUMP = 5; - public static final int BACKGROUND_TASK_OFFLINE_PAGES = 6; - public static final int BACKGROUND_TASK_OFFLINE_PREFETCH = 7; - public static final int BACKGROUND_TASK_DOWNLOAD_SERVICE = 8; - public static final int BACKGROUND_TASK_DOWNLOAD_CLEANUP = 9; - public static final int BACKGROUND_TASK_WEBVIEW_VARIATIONS = 10; - public static final int BACKGROUND_TASK_OFFLINE_CONTENT_NOTIFICATION = 11; - public static final int BACKGROUND_TASK_WEBAPK_UPDATE = 12; - public static final int BACKGROUND_TASK_DOWNLOAD_RESUMPTION = 13; - public static final int BACKGROUND_TASK_FEED_REFRESH = 14; - public static final int BACKGROUND_TASK_COMPONENT_UPDATE = 15; - public static final int BACKGROUND_TASK_DEPRECATED_EXPLORE_SITES_REFRESH = 16; - public static final int BACKGROUND_TASK_EXPLORE_SITES_REFRESH = 17; - public static final int BACKGROUND_TASK_DOWNLOAD_AUTO_RESUMPTION = 18; - public static final int BACKGROUND_TASK_ONE_SHOT_SYNC_WAKE_UP = 19; - public static final int BACKGROUND_TASK_NOTIFICATION_SCHEDULER = 20; - public static final int BACKGROUND_TASK_NOTIFICATION_TRIGGER = 21; - public static final int BACKGROUND_TASK_PERIODIC_SYNC_WAKE_UP = 22; - public static final int BACKGROUND_TASK_QUERY_TILE = 23; - public static final int BACKGROUND_TASK_FEEDV2_REFRESH = 24; - public static final int BACKGROUND_TASK_DOWNLOAD_LATER = 25; - // Keep this one at the end and increment appropriately when adding new tasks. - public static final int BACKGROUND_TASK_COUNT = 26; - - protected BackgroundTaskSchedulerExternalUma() {} - - /** - * Reports metrics for when a NativeBackgroundTask loads the native library. - * @param taskId An id from {@link TaskIds}. - * @param serviceManagerOnlyMode Whether the task will start native in Service Manager Only Mode - * (Reduced Mode) instead of Full Browser Mode. - */ - public abstract void reportTaskStartedNative(int taskId, boolean serviceManagerOnlyMode); - - /** - * Report metrics for starting a NativeBackgroundTask. This does not consider tasks that are - * short-circuited before any work is done. - * @param taskId An id from {@link TaskIds}. - * @param serviceManagerOnlyMode Whether the task will run in Service Manager Only Mode (Reduced - * Mode) instead of Full Browser Mode. - */ - public abstract void reportNativeTaskStarted(int taskId, boolean serviceManagerOnlyMode); - - /** - * Reports metrics that a NativeBackgroundTask has been finished cleanly (i.e., no unexpected - * exits because of chrome crash or OOM). This includes tasks that have been stopped due to - * timeout. - * @param taskId An id from {@link TaskIds}. - * @param serviceManagerOnlyMode Whether the task will run in Service Manager Only Mode (Reduced - * Mode) instead of Full Browser Mode. - */ - public abstract void reportNativeTaskFinished(int taskId, boolean serviceManagerOnlyMode); - - /** - * Reports metrics of how Chrome is launched, either in ServiceManager only mode or as full - * browser, as well as either cold start or warm start. - * See {@link org.chromium.content.browser.ServicificationStartupUma} for more details. - * @param startupMode Chrome's startup mode. - */ - public abstract void reportStartupMode(int startupMode); - - /** - * Returns an affix identifying a given task type in names of memory histograms specific to that - * task type. Adding an affix here causes Memory.BackgroundTask.[affix].* histograms to be - * emitted. They still need to be added to histograms.xml. - * @param taskId The task type. - * @return A string with the affix, without separators added, or null if there is no affix - * defined for that task type. - */ - public static String toMemoryHistogramAffixFromTaskId(int taskId) { - switch (taskId) { - case TaskIds.OFFLINE_PAGES_PREFETCH_JOB_ID: - return "OfflinePrefetch"; - default: - return null; - } - } - - @VisibleForTesting - public static int toUmaEnumValueFromTaskId(int taskId) { - switch (taskId) { - case TaskIds.TEST: - return BACKGROUND_TASK_TEST; - case TaskIds.OMAHA_JOB_ID: - return BACKGROUND_TASK_OMAHA; - case TaskIds.GCM_BACKGROUND_TASK_JOB_ID: - return BACKGROUND_TASK_GCM; - case TaskIds.NOTIFICATION_SERVICE_JOB_ID: - return BACKGROUND_TASK_NOTIFICATIONS; - case TaskIds.WEBVIEW_MINIDUMP_UPLOADING_JOB_ID: - return BACKGROUND_TASK_WEBVIEW_MINIDUMP; - case TaskIds.CHROME_MINIDUMP_UPLOADING_JOB_ID: - return BACKGROUND_TASK_CHROME_MINIDUMP; - case TaskIds.OFFLINE_PAGES_BACKGROUND_JOB_ID: - return BACKGROUND_TASK_OFFLINE_PAGES; - case TaskIds.OFFLINE_PAGES_PREFETCH_JOB_ID: - return BACKGROUND_TASK_OFFLINE_PREFETCH; - case TaskIds.DOWNLOAD_SERVICE_JOB_ID: - return BACKGROUND_TASK_DOWNLOAD_SERVICE; - case TaskIds.DOWNLOAD_CLEANUP_JOB_ID: - return BACKGROUND_TASK_DOWNLOAD_CLEANUP; - case TaskIds.DOWNLOAD_AUTO_RESUMPTION_JOB_ID: - return BACKGROUND_TASK_DOWNLOAD_AUTO_RESUMPTION; - case TaskIds.DOWNLOAD_LATER_JOB_ID: - return BACKGROUND_TASK_DOWNLOAD_LATER; - case TaskIds.WEBVIEW_VARIATIONS_SEED_FETCH_JOB_ID: - return BACKGROUND_TASK_WEBVIEW_VARIATIONS; - case TaskIds.OFFLINE_PAGES_PREFETCH_NOTIFICATION_JOB_ID: - return BACKGROUND_TASK_OFFLINE_CONTENT_NOTIFICATION; - case TaskIds.WEBAPK_UPDATE_JOB_ID: - return BACKGROUND_TASK_WEBAPK_UPDATE; - case TaskIds.DOWNLOAD_RESUMPTION_JOB_ID: - return BACKGROUND_TASK_DOWNLOAD_RESUMPTION; - case TaskIds.FEED_REFRESH_JOB_ID: - return BACKGROUND_TASK_FEED_REFRESH; - case TaskIds.COMPONENT_UPDATE_JOB_ID: - return BACKGROUND_TASK_COMPONENT_UPDATE; - case TaskIds.DEPRECATED_EXPLORE_SITES_REFRESH_JOB_ID: - return BACKGROUND_TASK_DEPRECATED_EXPLORE_SITES_REFRESH; - case TaskIds.EXPLORE_SITES_REFRESH_JOB_ID: - return BACKGROUND_TASK_EXPLORE_SITES_REFRESH; - case TaskIds.BACKGROUND_SYNC_ONE_SHOT_JOB_ID: - return BACKGROUND_TASK_ONE_SHOT_SYNC_WAKE_UP; - case TaskIds.NOTIFICATION_SCHEDULER_JOB_ID: - return BACKGROUND_TASK_NOTIFICATION_SCHEDULER; - case TaskIds.NOTIFICATION_TRIGGER_JOB_ID: - return BACKGROUND_TASK_NOTIFICATION_TRIGGER; - case TaskIds.PERIODIC_BACKGROUND_SYNC_CHROME_WAKEUP_TASK_JOB_ID: - return BACKGROUND_TASK_PERIODIC_SYNC_WAKE_UP; - case TaskIds.QUERY_TILE_JOB_ID: - return BACKGROUND_TASK_QUERY_TILE; - case TaskIds.FEEDV2_REFRESH_JOB_ID: - return BACKGROUND_TASK_FEEDV2_REFRESH; - default: - assert false; - } - // Returning a value that is not expected to ever be reported. - return BACKGROUND_TASK_TEST; - } -} diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerFactory.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerFactory.java deleted file mode 100644 index 83f1663c6be..00000000000 --- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/BackgroundTaskSchedulerFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2019 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.components.background_task_scheduler; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.components.background_task_scheduler.internal.BackgroundTaskSchedulerFactoryInternal; -import org.chromium.components.background_task_scheduler.internal.BackgroundTaskSchedulerPrefs; -import org.chromium.components.background_task_scheduler.internal.BackgroundTaskSchedulerUma; - -/** - * A factory for {@link BackgroundTaskScheduler}. - */ -public final class BackgroundTaskSchedulerFactory { - private static BackgroundTaskSchedulerExternalUma sExternalUmaForTesting; - - /** - * @return the current instance of the {@link BackgroundTaskScheduler}. Creates one if none - * exist. - */ - public static BackgroundTaskScheduler getScheduler() { - return BackgroundTaskSchedulerFactoryInternal.getScheduler(); - } - - @VisibleForTesting - public static void setSchedulerForTesting(BackgroundTaskScheduler backgroundTaskScheduler) { - BackgroundTaskSchedulerFactoryInternal.setSchedulerForTesting(backgroundTaskScheduler); - } - - /** - * @param backgroundTaskFactory specific implementation of {@link BackgroundTaskFactory} of - * the caller. - */ - public static void setBackgroundTaskFactory(BackgroundTaskFactory backgroundTaskFactory) { - BackgroundTaskSchedulerFactoryInternal.setBackgroundTaskFactory(backgroundTaskFactory); - } - - /** - * @return The helper class to report UMA. - */ - public static BackgroundTaskSchedulerExternalUma getUmaReporter() { - return sExternalUmaForTesting == null ? BackgroundTaskSchedulerUma.getInstance() - : sExternalUmaForTesting; - } - - @VisibleForTesting - public static void setUmaReporterForTesting(BackgroundTaskSchedulerExternalUma externalUma) { - sExternalUmaForTesting = externalUma; - } - - /** - * Pre-load shared prefs to avoid being blocked on the disk reads in the future. - */ - public static void warmUpSharedPrefs() { - BackgroundTaskSchedulerPrefs.warmUpSharedPrefs(); - } - - // Do not instantiate. - private BackgroundTaskSchedulerFactory() {} -} diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/NativeBackgroundTask.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/NativeBackgroundTask.java deleted file mode 100644 index d0850e9d625..00000000000 --- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/NativeBackgroundTask.java +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler; - -import android.content.Context; - -import androidx.annotation.IntDef; -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.ThreadUtils; -import org.chromium.base.task.PostTask; -import org.chromium.content_public.browser.BrowserStartupController; -import org.chromium.content_public.browser.UiThreadTaskTraits; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Base class implementing {@link BackgroundTask} that adds native initialization, ensuring that - * tasks are run after Chrome is successfully started. - */ -public abstract class NativeBackgroundTask implements BackgroundTask { - /** Specifies which action to take following onStartTaskBeforeNativeLoaded. */ - @IntDef({StartBeforeNativeResult.LOAD_NATIVE, StartBeforeNativeResult.RESCHEDULE, - StartBeforeNativeResult.DONE}) - @Retention(RetentionPolicy.SOURCE) - public @interface StartBeforeNativeResult { - /** Task should continue to load native parts of browser. */ - int LOAD_NATIVE = 0; - /** Task should request rescheduling, without loading native parts of browser. */ - int RESCHEDULE = 1; - /** Task should neither load native parts of browser nor reschedule. */ - int DONE = 2; - } - - /** The id of the task from {@link TaskParameters}. */ - protected int mTaskId; - - /** Indicates that the task has already been stopped. Should only be accessed on UI Thread. */ - private boolean mTaskStopped; - - /** - * If true, the task runs in Service Manager Only Mode. If false, the task runs in Full Browser - * Mode. - */ - private boolean mRunningInServiceManagerOnlyMode; - - /** Make sure that we do not double record task finished metric */ - private boolean mFinishMetricRecorded; - - /** Loads native and handles initialization. */ - private NativeBackgroundTaskDelegate mDelegate; - - protected NativeBackgroundTask() {} - - /** - * Sets the delegate. Must be called before any other public method is invoked. - * @param delegate The delegate to handle native initialization. - */ - public void setDelegate(NativeBackgroundTaskDelegate delegate) { - mDelegate = delegate; - } - - @Override - public final boolean onStartTask( - Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { - ThreadUtils.assertOnUiThread(); - assert mDelegate != null; - - mTaskId = taskParameters.getTaskId(); - - TaskFinishedCallback wrappedCallback = needsReschedule -> { - recordTaskFinishedMetric(); - callback.taskFinished(needsReschedule); - }; - - // WrappedCallback will only be called when the work is done or in onStopTask. If the task - // is short-circuited early (by returning DONE or RESCHEDULE as a StartBeforeNativeResult), - // the wrappedCallback is not called. Thus task-finished metrics are only recorded if - // task-started metrics are. - @StartBeforeNativeResult - int beforeNativeResult = - onStartTaskBeforeNativeLoaded(context, taskParameters, wrappedCallback); - - if (beforeNativeResult == StartBeforeNativeResult.DONE) return false; - - if (beforeNativeResult == StartBeforeNativeResult.RESCHEDULE) { - // Do not pass in wrappedCallback because this is a short-circuit reschedule. For UMA - // purposes, tasks are started when runWithNative is called and does not consider - // short-circuit reschedules such as this. - PostTask.postTask(UiThreadTaskTraits.DEFAULT, buildRescheduleRunnable(callback)); - return true; - } - - assert beforeNativeResult == StartBeforeNativeResult.LOAD_NATIVE; - runWithNative(buildStartWithNativeRunnable(context, taskParameters, wrappedCallback), - buildRescheduleRunnable(wrappedCallback)); - return true; - } - - @Override - public final boolean onStopTask(Context context, TaskParameters taskParameters) { - ThreadUtils.assertOnUiThread(); - assert mDelegate != null; - - mTaskStopped = true; - recordTaskFinishedMetric(); - if (isNativeLoadedInFullBrowserMode()) { - return onStopTaskWithNative(context, taskParameters); - } else { - return onStopTaskBeforeNativeLoaded(context, taskParameters); - } - } - - /** - * Ensure that native is started before running the task. If native fails to start, the task is - * going to be rescheduled, by issuing a {@see TaskFinishedCallback} with parameter set to - * <c>true</c>. - * - * @param startWithNativeRunnable A runnable that will execute #onStartTaskWithNative, after the - * native is loaded. - * @param rescheduleRunnable A runnable that will be called to reschedule the task in case - * native initialization fails. - */ - private final void runWithNative( - final Runnable startWithNativeRunnable, final Runnable rescheduleRunnable) { - if (isNativeLoadedInFullBrowserMode()) { - mRunningInServiceManagerOnlyMode = false; - getUmaReporter().reportNativeTaskStarted(mTaskId, mRunningInServiceManagerOnlyMode); - mDelegate.recordMemoryUsageWithRandomDelay(mTaskId, mRunningInServiceManagerOnlyMode); - PostTask.postTask(UiThreadTaskTraits.DEFAULT, startWithNativeRunnable); - return; - } - - boolean wasInServiceManagerOnlyMode = isNativeLoadedInServiceManagerOnlyMode(); - mRunningInServiceManagerOnlyMode = supportsServiceManagerOnly(); - getUmaReporter().reportNativeTaskStarted(mTaskId, mRunningInServiceManagerOnlyMode); - - PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { - @Override - public void run() { - // If task was stopped before we got here, don't start native initialization. - if (mTaskStopped) return; - - // Record transitions from No Native to Service Manager Only Mode and from No Native - // to Full Browser mode, but not cases in which Service Manager Only Mode was - // already started. - if (!wasInServiceManagerOnlyMode) { - getUmaReporter().reportTaskStartedNative( - mTaskId, mRunningInServiceManagerOnlyMode); - } - - // Start native initialization. - mDelegate.initializeNativeAsync(mTaskId, mRunningInServiceManagerOnlyMode, - startWithNativeRunnable, rescheduleRunnable); - } - }); - } - - /** - * Descendant classes should override this method if they support running in service manager - * only mode. - * - * @return if the task supports running in service manager only mode. - */ - protected boolean supportsServiceManagerOnly() { - return false; - } - - /** - * Method that should be implemented in derived classes to provide implementation of {@link - * BackgroundTask#onStartTask(Context, TaskParameters, TaskFinishedCallback)} run before native - * is loaded. Task implementing the method may decide to not load native if it hasn't been - * loaded yet, by returning DONE, meaning no more work is required for the task, or RESCHEDULE, - * meaning task needs to be immediately rescheduled. - * This method is guaranteed to be called before {@link #onStartTaskWithNative}. - */ - @StartBeforeNativeResult - protected abstract int onStartTaskBeforeNativeLoaded( - Context context, TaskParameters taskParameters, TaskFinishedCallback callback); - - /** - * Method that should be implemented in derived classes to provide implementation of {@link - * BackgroundTask#onStartTask(Context, TaskParameters, TaskFinishedCallback)} when native is - * loaded. - * This method will not be called unless {@link #onStartTaskBeforeNativeLoaded} returns - * LOAD_NATIVE. - */ - protected abstract void onStartTaskWithNative( - Context context, TaskParameters taskParameters, TaskFinishedCallback callback); - - /** Called by {@link #onStopTask} if native part of browser was not loaded. */ - protected abstract boolean onStopTaskBeforeNativeLoaded( - Context context, TaskParameters taskParameters); - - /** Called by {@link #onStopTask} if native part of browser was loaded. */ - protected abstract boolean onStopTaskWithNative(Context context, TaskParameters taskParameters); - - /** Builds a runnable rescheduling task. */ - private Runnable buildRescheduleRunnable(final TaskFinishedCallback callback) { - return new Runnable() { - @Override - public void run() { - ThreadUtils.assertOnUiThread(); - if (mTaskStopped) return; - callback.taskFinished(true); - } - }; - } - - /** Builds a runnable starting task with native portion. */ - private Runnable buildStartWithNativeRunnable(final Context context, - final TaskParameters taskParameters, final TaskFinishedCallback callback) { - return new Runnable() { - @Override - public void run() { - ThreadUtils.assertOnUiThread(); - if (mTaskStopped) return; - onStartTaskWithNative(context, taskParameters, callback); - } - }; - } - - /** Whether the native part of the browser is loaded in Full Browser Mode. */ - private boolean isNativeLoadedInFullBrowserMode() { - return getBrowserStartupController().isFullBrowserStarted(); - } - - /** Whether the native part of the browser is loaded in Service Manager Only Mode. */ - private boolean isNativeLoadedInServiceManagerOnlyMode() { - return getBrowserStartupController().isRunningInServiceManagerMode(); - } - - @VisibleForTesting - protected BrowserStartupController getBrowserStartupController() { - return BrowserStartupController.getInstance(); - } - - private void recordTaskFinishedMetric() { - ThreadUtils.assertOnUiThread(); - if (!mFinishMetricRecorded) { - mFinishMetricRecorded = true; - getUmaReporter().reportNativeTaskFinished(mTaskId, mRunningInServiceManagerOnlyMode); - } - } - - private BackgroundTaskSchedulerExternalUma getUmaReporter() { - return mDelegate.getUmaReporter(); - } -} diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/NativeBackgroundTaskDelegate.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/NativeBackgroundTaskDelegate.java deleted file mode 100644 index d604d303ab2..00000000000 --- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/NativeBackgroundTaskDelegate.java +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2020 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.components.background_task_scheduler; - -/** - * Delegate for {@link NativeBackgroundTask} that handles native initialization, and runs the task - * after Chrome is successfully started. - */ -public interface NativeBackgroundTaskDelegate { - /** - * Initializes native and runs the task. - * @param taskId The id of the associated task. - * @param serviceManagerOnlyMode Whether only ServiceManager should be launched during the - * startup, without running remaining parts of the Chrome. - * @param onSuccess The runnable that represents the task to be run after loading - * native successfully. - * @param onFailure The runnable to be run in case the initialization fails. - */ - void initializeNativeAsync( - int taskId, boolean serviceManagerOnlyMode, Runnable onSuccess, Runnable onFailure); - - /** - * Records memory usage after loading native. - * @param taskId The id of the associated task. - * @param serviceManagerOnlyMode Whether only ServiceManager was launched during startup. - */ - void recordMemoryUsageWithRandomDelay(int taskId, boolean serviceManagerOnlyMode); - - /** @return Helper class to report UMA stats. */ - BackgroundTaskSchedulerExternalUma getUmaReporter(); -} diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java deleted file mode 100644 index c31b6515905..00000000000 --- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskInfo.java +++ /dev/null @@ -1,737 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler; - -import android.content.Context; -import android.os.Bundle; - -import androidx.annotation.IntDef; -import androidx.annotation.NonNull; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * TaskInfo represents a request to run a specific {@link BackgroundTask} given the required - * parameters, such as whether a special type of network is available. - */ -public class TaskInfo { - public static final String SERIALIZED_TASK_EXTRAS = "serialized_task_extras"; - private static final String TAG = "BkgrdTaskInfo"; - - /** - * Common interface for all types of task information. - */ - public interface TimingInfo { - /** - * Receives a {@link TimingInfoVisitor}, which will perform actions on this object. - * @param visitor object that will perform actions on this instance. - */ - void accept(TimingInfoVisitor visitor); - } - - /** - * Common interface for actions over TimingInfo implementations. - * - * This implements the Visitor design pattern over {@link TimingInfo} objects. - * For a guide on how to use it, see the `Performing actions over TimingInfo objects` section - * in //components/background_task_scheduler/README.md. - */ - public interface TimingInfoVisitor { - /** - * Applies actions on a given {@link OneOffInfo}. This affects information regarding - * timing for a one-off task. - * @param oneOffInfo object to act on. - */ - void visit(OneOffInfo oneOffInfo); - /** - * Applies actions on a given {@link PeriodicInfo}. This affects information regarding - * timing for a periodic task. - * @param periodicInfo object to act on. - */ - void visit(PeriodicInfo periodicInfo); - /** - * Applies actions on a given {@link ExactInfo}. This affects information regarding - * timing for an exact task. - * @param exactInfo object to act on. - */ - void visit(ExactInfo exactInfo); - } - - /** - * Specifies information regarding one-off tasks. - */ - public static class OneOffInfo implements TimingInfo { - private final long mWindowStartTimeMs; - private final long mWindowEndTimeMs; - private final boolean mHasWindowStartTimeConstraint; - private final boolean mExpiresAfterWindowEndTime; - - private OneOffInfo(Builder builder) { - mWindowStartTimeMs = builder.mWindowStartTimeMs; - mWindowEndTimeMs = builder.mWindowEndTimeMs; - mHasWindowStartTimeConstraint = builder.mHasWindowStartTimeConstraint; - mExpiresAfterWindowEndTime = builder.mExpiresAfterWindowEndTime; - } - - /** - * @return the start of the window that the task can begin executing as a delta in - * milliseconds from now. - */ - public long getWindowStartTimeMs() { - return mWindowStartTimeMs; - } - - /** - * @return the end of the window that the task can begin executing as a delta in - * milliseconds from now. - */ - public long getWindowEndTimeMs() { - return mWindowEndTimeMs; - } - - /** - * @return whether this one-off task has a window start time constraint. - */ - public boolean hasWindowStartTimeConstraint() { - return mHasWindowStartTimeConstraint; - } - - /** - * @return whether this one-off task expires after {@link #getWindowEndTimeMs()} - * False by default. - */ - public boolean expiresAfterWindowEndTime() { - return mExpiresAfterWindowEndTime; - } - - /** - * Checks if a one-off task expired. - * @param scheduleTimeMs the time at which the task was scheduled. - * @param endTimeMs the time at which the task was set to expire. - * @param currentTimeMs the current time to check for expiration. - * @return true if the task expired and false otherwise. - */ - public static boolean getExpirationStatus( - long scheduleTimeMs, long endTimeMs, long currentTimeMs) { - return currentTimeMs >= scheduleTimeMs + endTimeMs; - } - - @Override - public void accept(TimingInfoVisitor visitor) { - visitor.visit(this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("{"); - if (hasWindowStartTimeConstraint()) { - sb.append("windowStartTimeMs: ").append(mWindowStartTimeMs).append(", "); - } - sb.append("windowEndTimeMs: ").append(mWindowEndTimeMs).append(", "); - sb.append("expiresAfterWindowEndTime (+flex): ").append(mExpiresAfterWindowEndTime); - sb.append("}"); - return sb.toString(); - } - - /** - * @return a new {@link Builder} object to set the values of the one-off task. - */ - public static Builder create() { - return new Builder(); - } - - /** - * A helper builder to provide a way to build {@link OneOffInfo}. - * - * @see #create() - */ - public static final class Builder { - private long mWindowStartTimeMs; - private long mWindowEndTimeMs; - // By default, a {@link OneOffInfo} doesn't have a set start time. The start time is - // considered the time of scheduling the task. - private boolean mHasWindowStartTimeConstraint; - // By default, a {@link OneOffInfo} doesn't have the expiration feature activated. - private boolean mExpiresAfterWindowEndTime; - - public Builder setWindowStartTimeMs(long windowStartTimeMs) { - mWindowStartTimeMs = windowStartTimeMs; - mHasWindowStartTimeConstraint = true; - return this; - } - - public Builder setWindowEndTimeMs(long windowEndTimeMs) { - mWindowEndTimeMs = windowEndTimeMs; - return this; - } - - public Builder setExpiresAfterWindowEndTime(boolean expiresAfterWindowEndTime) { - mExpiresAfterWindowEndTime = expiresAfterWindowEndTime; - return this; - } - - /** - * Build the {@link OneOffInfo object} specified by this builder. - * - * @return the {@link OneOffInfo} object. - */ - public OneOffInfo build() { - return new OneOffInfo(this); - } - } - } - - /** - * Specifies information regarding periodic tasks. - */ - public static class PeriodicInfo implements TimingInfo { - private final long mIntervalMs; - private final long mFlexMs; - private final boolean mHasFlex; - private final boolean mExpiresAfterWindowEndTime; - - private PeriodicInfo(PeriodicInfo.Builder builder) { - mIntervalMs = builder.mIntervalMs; - mFlexMs = builder.mFlexMs; - mHasFlex = builder.mHasFlex; - mExpiresAfterWindowEndTime = builder.mExpiresAfterWindowEndTime; - } - - /** - * @return the interval between occurrences of this task in milliseconds. - */ - public long getIntervalMs() { - return mIntervalMs; - } - - /** - * @return the flex time for this task. The task can execute at any time in a window of flex - * length at the end of the period. It is reported in milliseconds. - */ - public long getFlexMs() { - return mFlexMs; - } - - /** - * @return true whether this task has defined a flex time. False otherwise. - */ - public boolean hasFlex() { - return mHasFlex; - } - - /** - * @return whether this periodic task expires after {@link #getIntervalMs()} + - * {@link #getFlexMs()} - * False by default. - */ - public boolean expiresAfterWindowEndTime() { - return mExpiresAfterWindowEndTime; - } - - /** - * Checks if a periodic task expired. - * @param scheduleTimeMs the time at which the task was scheduled. - * @param intervalTimeMs the interval at which the periodic task was scheduled. - * @param flexTimeMs the flex time of the task, either set by the caller or the default one. - * @param currentTimeMs the current time to check for expiration. - * @return true if the task expired and false otherwise. - */ - public static boolean getExpirationStatus( - long scheduleTimeMs, long intervalTimeMs, long flexTimeMs, long currentTimeMs) { - // Whether the task is executed during the wanted time window is determined here. The - // position of the current time in relation to the time window is calculated here. - // This position is compared with the time window margins. - // For example, if a task is scheduled at 6am with an interval of 5h and a flex of - // 5min, the valid starting times in that day are: 10:55am to 11am, 3:55pm to 4pm and - // 8:55pm to 9pm. For 7pm as the current time, the time in the interval window is 3h. - // This is not inside a valid starting time, so the task is considered expired. - // Similarly, for 8:58pm as the current time, the time in the interval window is 4h - // and 58min, which fits in a valid interval window. - // In the case of a flex value equal or bigger than the interval value, the task - // never expires. - long timeSinceScheduledMs = currentTimeMs - scheduleTimeMs; - long deltaTimeComparedToWindowMs = timeSinceScheduledMs % intervalTimeMs; - return deltaTimeComparedToWindowMs < intervalTimeMs - flexTimeMs - && flexTimeMs < intervalTimeMs; - } - - @Override - public void accept(TimingInfoVisitor visitor) { - visitor.visit(this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("{"); - sb.append("intervalMs: ").append(mIntervalMs).append(", "); - if (mHasFlex) { - sb.append(", flexMs: ").append(mFlexMs).append(", "); - } - sb.append("expiresAfterWindowEndTime (+flex): ").append(mExpiresAfterWindowEndTime); - sb.append("}"); - return sb.toString(); - } - - /** - * @return a new {@link OneOffInfo.Builder} object to set the values of the one-off task. - */ - public static PeriodicInfo.Builder create() { - return new PeriodicInfo.Builder(); - } - - /** - * A helper builder to provide a way to build {@link OneOffInfo}. - * - * @see #create() - */ - public static final class Builder { - private long mIntervalMs; - private long mFlexMs; - // By default, a {@link PeriodicInfo} doesn't have a specified flex and the default - // one will be used in the scheduler. - private boolean mHasFlex; - // By default, a {@link PeriodicInfo} doesn't have the expiration feature activated. - private boolean mExpiresAfterWindowEndTime; - - public Builder setIntervalMs(long intervalMs) { - mIntervalMs = intervalMs; - return this; - } - - public Builder setFlexMs(long flexMs) { - mFlexMs = flexMs; - mHasFlex = true; - return this; - } - - public Builder setExpiresAfterWindowEndTime(boolean expiresAfterWindowEndTime) { - mExpiresAfterWindowEndTime = expiresAfterWindowEndTime; - return this; - } - /** - * Build the {@link PeriodicInfo object} specified by this builder. - * - * @return the {@link PeriodicInfo} object. - */ - public PeriodicInfo build() { - return new PeriodicInfo(this); - } - } - } - - /** - * Specifies information regarding exact tasks. - */ - public static class ExactInfo implements TimingInfo { - private final long mTriggerAtMs; - - private ExactInfo(Builder builder) { - mTriggerAtMs = builder.mTriggerAtMs; - } - - public long getTriggerAtMs() { - return mTriggerAtMs; - } - - @Override - public void accept(TimingInfoVisitor visitor) { - visitor.visit(this); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder("{"); - sb.append("triggerAtMs: ").append(mTriggerAtMs).append("}"); - return sb.toString(); - } - - /** - * @return a new {@link Builder} object to set the values of the exact task. - */ - public static Builder create() { - return new Builder(); - } - - /** - * A helper builder to provide a way to build {@link ExactInfo}. - * - * @see #create() - */ - public static final class Builder { - private long mTriggerAtMs; - - /** - * Sets the exact UTC timestamp at which to schedule the exact task. - * @param triggerAtMs the UTC timestamp at which the task should be started. - * @return the {@link Builder} for creating the {@link ExactInfo} object. - */ - public Builder setTriggerAtMs(long triggerAtMs) { - mTriggerAtMs = triggerAtMs; - return this; - } - - /** - * Build the {@link ExactInfo object} specified by this builder. - * - * @return the {@link ExactInfo} object. - */ - public ExactInfo build() { - return new ExactInfo(this); - } - } - } - - @IntDef({NetworkType.NONE, NetworkType.ANY, NetworkType.UNMETERED}) - @Retention(RetentionPolicy.SOURCE) - public @interface NetworkType { - /** - * This task has no requirements for network connectivity. Default. - * - * @see NetworkType - */ - int NONE = 0; - /** - * This task requires network connectivity. - * - * @see NetworkType - */ - int ANY = 1; - /** - * This task requires network connectivity that is unmetered. - * - * @see NetworkType - */ - int UNMETERED = 2; - } - - /** - * The task ID should be unique across all tasks. A list of such unique IDs exists in - * {@link TaskIds}. - */ - private final int mTaskId; - - /** - * The extras to provide to the {@link BackgroundTask} when it is run. - */ - @NonNull - private final Bundle mExtras; - - /** - * The type of network the task requires to run. - */ - @NetworkType - private final int mRequiredNetworkType; - - /** - * Whether the task requires charging to run. - */ - private final boolean mRequiresCharging; - - /** - * Whether or not to persist this task across device reboots. - */ - private final boolean mIsPersisted; - - /** - * Whether this task should override any preexisting tasks with the same task id. - */ - private final boolean mUpdateCurrent; - - /** - * Task information regarding a type of task. - */ - private final TimingInfo mTimingInfo; - - private TaskInfo(Builder builder) { - mTaskId = builder.mTaskId; - mExtras = builder.mExtras == null ? new Bundle() : builder.mExtras; - mRequiredNetworkType = builder.mRequiredNetworkType; - mRequiresCharging = builder.mRequiresCharging; - mIsPersisted = builder.mIsPersisted; - mUpdateCurrent = builder.mUpdateCurrent; - mTimingInfo = builder.mTimingInfo; - } - - /** - * @return the unique ID of this task. - */ - public int getTaskId() { - return mTaskId; - } - - /** - * @return the extras that will be provided to the {@link BackgroundTask}. - */ - @NonNull - public Bundle getExtras() { - return mExtras; - } - - /** - * @return the type of network the task requires to run. - */ - @NetworkType - public int getRequiredNetworkType() { - return mRequiredNetworkType; - } - - /** - * @return whether the task requires charging to run. - */ - public boolean requiresCharging() { - return mRequiresCharging; - } - - /** - * @return whether or not to persist this task across device reboots. - */ - public boolean isPersisted() { - return mIsPersisted; - } - - /** - * @return whether this task should override any preexisting tasks with the same task id. - */ - public boolean shouldUpdateCurrent() { - return mUpdateCurrent; - } - - /** - * @return Whether or not this task is a periodic task. - */ - @Deprecated - public boolean isPeriodic() { - return mTimingInfo instanceof PeriodicInfo; - } - - /** - * This is part of a {@link TaskInfo} iff the task is a one-off task. - * - * @return the specific data if it is a one-off tasks and null otherwise. - */ - @Deprecated - public OneOffInfo getOneOffInfo() { - if (mTimingInfo instanceof OneOffInfo) return (OneOffInfo) mTimingInfo; - return null; - } - - /** - * This is part of a {@link TaskInfo} iff the task is a periodic task. - * - * @return the specific data that if it is a periodic tasks and null otherwise. - */ - @Deprecated - public PeriodicInfo getPeriodicInfo() { - if (mTimingInfo instanceof PeriodicInfo) return (PeriodicInfo) mTimingInfo; - return null; - } - - /** - * @return the specific data based on the type of task. - */ - public TimingInfo getTimingInfo() { - return mTimingInfo; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("{"); - sb.append("taskId: ").append(mTaskId); - sb.append(", extras: ").append(mExtras); - sb.append(", requiredNetworkType: ").append(mRequiredNetworkType); - sb.append(", requiresCharging: ").append(mRequiresCharging); - sb.append(", isPersisted: ").append(mIsPersisted); - sb.append(", updateCurrent: ").append(mUpdateCurrent); - sb.append(", timingInfo: ").append(mTimingInfo); - sb.append("}"); - return sb.toString(); - } - - /** - * Creates a task that holds all information necessary to schedule it. - * - * @param taskId the unique task ID for this task. Should be listed in {@link TaskIds}. - * @param timingInfo the task information specific to each type of task. - * @return the builder which can be used to continue configuration and {@link Builder#build()}. - * @see TaskIds - */ - public static Builder createTask(int taskId, TimingInfo timingInfo) { - return new Builder(taskId).setTimingInfo(timingInfo); - } - - /** - * Schedule a one-off task to execute within a deadline. If windowEndTimeMs is 0, the task will - * run as soon as possible. For executing a task within a time window, see - * {@link #createOneOffTask(int, long, long)}. - * - * @param taskId the unique task ID for this task. Should be listed in {@link TaskIds}. - * @param windowEndTimeMs the end of the window that the task can begin executing as a delta in - * milliseconds from now. Note that the task begins executing at this point even if the - * prerequisite conditions are not met. - * @return the builder which can be used to continue configuration and {@link Builder#build()}. - * @see TaskIds - * - * @deprecated the {@see #createTask(int, Class, TimingInfo)} method should be used instead. - * This method requires an additional step for the caller: the creation of the specific - * {@link TimingInfo} object with the wanted properties. - */ - @Deprecated - public static Builder createOneOffTask(int taskId, long windowEndTimeMs) { - TimingInfo oneOffInfo = OneOffInfo.create().setWindowEndTimeMs(windowEndTimeMs).build(); - return new Builder(taskId).setTimingInfo(oneOffInfo); - } - - /** - * Schedule a one-off task to execute within a time window. For executing a task within a - * deadline, see {@link #createOneOffTask(int, long)}, - * - * @param taskId the unique task ID for this task. Should be listed in {@link TaskIds}. - * @param windowStartTimeMs the start of the window that the task can begin executing as a delta - * in milliseconds from now. - * @param windowEndTimeMs the end of the window that the task can begin executing as a delta in - * milliseconds from now. Note that the task begins executing at this point even if the - * prerequisite conditions are not met. - * @return the builder which can be used to continue configuration and {@link Builder#build()}. - * @see TaskIds - * - * @deprecated the {@see #createTask(int, Class, TimingInfo)} method should be used instead. - * This method requires an additional step for the caller: the creation of the specific - * {@link TimingInfo} object with the wanted properties. - */ - @Deprecated - public static Builder createOneOffTask( - int taskId, long windowStartTimeMs, long windowEndTimeMs) { - TimingInfo oneOffInfo = OneOffInfo.create() - .setWindowStartTimeMs(windowStartTimeMs) - .setWindowEndTimeMs(windowEndTimeMs) - .build(); - return new Builder(taskId).setTimingInfo(oneOffInfo); - } - - /** - * Schedule a periodic task that will recur at the specified interval, without the need to - * be rescheduled. The task will continue to recur until - * {@link BackgroundTaskScheduler#cancel(Context, int)} is invoked with the task ID from this - * {@link TaskInfo}. - * The flex time specifies how close to the end of the interval you are willing to execute. - * Instead of executing at the exact interval, the task will execute at the interval or up to - * flex milliseconds before. - * - * @param taskId the unique task ID for this task. Should be listed in {@link TaskIds}. - * @param intervalMs the interval between occurrences of this task in milliseconds. - * @param flexMs the flex time for this task. The task can execute at any time in a window of - * flex - * length at the end of the period. It is reported in milliseconds. - * @return the builder which can be used to continue configuration and {@link Builder#build()}. - * @see TaskIds - * - * @deprecated the {@see #createTask(int, TimingInfo)} method should be used instead. - * This method requires an additional step for the caller: the creation of the specific - * {@link TimingInfo} object with the wanted properties. - */ - @Deprecated - public static Builder createPeriodicTask(int taskId, long intervalMs, long flexMs) { - TimingInfo periodicInfo = - PeriodicInfo.create().setIntervalMs(intervalMs).setFlexMs(flexMs).build(); - return new Builder(taskId).setTimingInfo(periodicInfo); - } - - /** - * A helper builder to provide a way to build {@link TaskInfo}. To create a {@link Builder} - * use the createTask method on {@link TaskInfo}. - * - * @see @createTask(int, Class, TimingInfo) - */ - public static final class Builder { - private final int mTaskId; - - private Bundle mExtras; - @NetworkType - private int mRequiredNetworkType; - private boolean mRequiresCharging; - private boolean mIsPersisted; - private boolean mUpdateCurrent; - private TimingInfo mTimingInfo; - - Builder(int taskId) { - mTaskId = taskId; - } - - Builder setTimingInfo(TimingInfo timingInfo) { - mTimingInfo = timingInfo; - return this; - } - - /** - * Set the optional extra values necessary for this task. Must only ever contain simple - * values supported by {@link android.os.BaseBundle}. All other values are thrown away. - * If the extras for this builder are not set, or set to null, the resulting - * {@link TaskInfo} will have an empty bundle (i.e. not null). - * - * @param bundle the bundle of extra values necessary for this task. - * @return this {@link Builder}. - */ - public Builder setExtras(Bundle bundle) { - mExtras = bundle; - return this; - } - - /** - * Set the type of network the task requires to run. - * - * @param networkType the {@link NetworkType} required for this task. - * @return this {@link Builder}. - */ - public Builder setRequiredNetworkType(@NetworkType int networkType) { - mRequiredNetworkType = networkType; - return this; - } - - /** - * Set whether the task requires charging to run. - * - * @param requiresCharging true if this task requires charging. - * @return this {@link Builder}. - */ - public Builder setRequiresCharging(boolean requiresCharging) { - mRequiresCharging = requiresCharging; - return this; - } - - /** - * Set whether or not to persist this task across device reboots. - * - * @param isPersisted true if this task should be persisted across reboots. - * @return this {@link Builder}. - */ - public Builder setIsPersisted(boolean isPersisted) { - mIsPersisted = isPersisted; - return this; - } - - /** - * Set whether this task should override any preexisting tasks with the same task id. - * - * @param updateCurrent true if this task should overwrite a currently existing task with - * the same ID, if it exists. - * @return this {@link Builder}. - */ - public Builder setUpdateCurrent(boolean updateCurrent) { - mUpdateCurrent = updateCurrent; - return this; - } - - /** - * Build the {@link TaskInfo object} specified by this builder. - * - * @return the {@link TaskInfo} object. - */ - public TaskInfo build() { - return new TaskInfo(this); - } - } -} diff --git a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskParameters.java b/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskParameters.java deleted file mode 100644 index 721d6b3536b..00000000000 --- a/chromium/components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler/TaskParameters.java +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler; - -import android.content.Context; -import android.os.Bundle; - -import androidx.annotation.NonNull; - -/** - * TaskParameters are passed to {@link BackgroundTask}s whenever they are invoked. It contains the - * task ID and the extras that the caller of - * {@link BackgroundTaskScheduler#schedule(Context, TaskInfo)} passed in with the {@link TaskInfo}. - */ -public class TaskParameters { - private final int mTaskId; - private final Bundle mExtras; - - private TaskParameters(Builder builder) { - mTaskId = builder.mTaskId; - mExtras = builder.mExtras == null ? new Bundle() : builder.mExtras; - } - - /** - * @return the task ID. - */ - public int getTaskId() { - return mTaskId; - } - - /** - * @return the extras for this task. - */ - @NonNull - public Bundle getExtras() { - return mExtras; - } - - /** Creates a builder for task parameters. */ - public static Builder create(int taskId) { - return new Builder(taskId); - } - - /** Class for building a task parameters object. Public for testing */ - public static final class Builder { - private final int mTaskId; - private Bundle mExtras; - - Builder(int taskId) { - mTaskId = taskId; - } - - public Builder addExtras(Bundle extras) { - mExtras = extras; - return this; - } - - public TaskParameters build() { - return new TaskParameters(this); - } - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskBroadcastReceiver.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskBroadcastReceiver.java deleted file mode 100644 index 34ac07dcdd9..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskBroadcastReceiver.java +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2019 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.components.background_task_scheduler.internal; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkInfo; -import android.os.BatteryManager; -import android.os.Build; -import android.os.PowerManager; -import android.text.format.DateUtils; - -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; -import org.chromium.base.task.PostTask; -import org.chromium.components.background_task_scheduler.BackgroundTask; -import org.chromium.components.background_task_scheduler.TaskInfo; -import org.chromium.components.background_task_scheduler.TaskParameters; -import org.chromium.content_public.browser.UiThreadTaskTraits; - -/** - * Starts running the BackgroundTask at the specified triggering time. - * - * Receives the information through a broadcast, which is synchronous in the Main thread. The - * execution of the task will be detached to a best effort task. - */ -public class BackgroundTaskBroadcastReceiver extends BroadcastReceiver { - private static final String TAG = "BkgrdTaskBR"; - private static final String WAKELOCK_TAG = "Chromium:" + TAG; - - // Wakelock is only held for 3 minutes, in order to be consistent with the restrictions of - // the GcmTaskService: - // https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmTaskService. - // Here the waiting is done for only 90% of this time. - private static final long MAX_TIMEOUT_MS = 162 * DateUtils.SECOND_IN_MILLIS; - - private static class TaskExecutor implements BackgroundTask.TaskFinishedCallback { - private final Context mContext; - private final PowerManager.WakeLock mWakeLock; - private final TaskParameters mTaskParams; - private final BackgroundTask mBackgroundTask; - - private boolean mHasExecuted; - - public TaskExecutor(Context context, PowerManager.WakeLock wakeLock, - TaskParameters taskParams, BackgroundTask backgroundTask) { - mContext = context; - mWakeLock = wakeLock; - mTaskParams = taskParams; - mBackgroundTask = backgroundTask; - } - - public void execute() { - ThreadUtils.assertOnUiThread(); - - boolean needsBackground = mBackgroundTask.onStartTask(mContext, mTaskParams, this); - BackgroundTaskSchedulerUma.getInstance().reportTaskStarted(mTaskParams.getTaskId()); - if (!needsBackground) return; - - PostTask.postDelayedTask(UiThreadTaskTraits.BEST_EFFORT, this::timeout, MAX_TIMEOUT_MS); - } - - @Override - public void taskFinished(boolean needsReschedule) { - PostTask.postTask(UiThreadTaskTraits.BEST_EFFORT, () -> finished(needsReschedule)); - } - - private void timeout() { - ThreadUtils.assertOnUiThread(); - if (mHasExecuted) return; - mHasExecuted = true; - - Log.w(TAG, "Task execution failed. Task timed out."); - BackgroundTaskSchedulerUma.getInstance().reportTaskStopped(mTaskParams.getTaskId()); - - boolean reschedule = mBackgroundTask.onStopTask(mContext, mTaskParams); - if (reschedule) { - BackgroundTaskSchedulerUma.getInstance().reportTaskRescheduled(); - mBackgroundTask.reschedule(mContext); - } - } - - private void finished(boolean reschedule) { - ThreadUtils.assertOnUiThread(); - if (mHasExecuted) return; - mHasExecuted = true; - - if (reschedule) { - BackgroundTaskSchedulerUma.getInstance().reportTaskRescheduled(); - mBackgroundTask.reschedule(mContext); - } - // TODO(crbug.com/970160): Add UMA to record how long the tasks need to complete. - } - } - - @Override - public void onReceive(Context context, Intent intent) { - final TaskParameters taskParams = - BackgroundTaskSchedulerAlarmManager.getTaskParametersFromIntent(intent); - if (taskParams == null) { - Log.w(TAG, "Failed to retrieve task parameters."); - return; - } - - int taskId = taskParams.getTaskId(); - ScheduledTaskProto.ScheduledTask scheduledTask = - BackgroundTaskSchedulerPrefs.getScheduledTask(taskId); - if (scheduledTask == null) { - Log.e(TAG, "Cannot get information about task with task ID " + taskId); - return; - } - - // Only continue if network requirements match network status. - if (!networkRequirementsMet(context, taskId, - convertToTaskInfoNetworkType(scheduledTask.getRequiredNetworkType()))) { - Log.w(TAG, - "Failed to start task. Network requirements not satisfied for task with task ID" - + taskId); - return; - } - - // Check if battery requirements match. - if (!batteryRequirementsMet(context, taskId, scheduledTask.getRequiresCharging())) { - Log.w(TAG, - "Failed to start task. Battery requirements not satisfied for task with task ID" - + taskId); - return; - } - - final BackgroundTask backgroundTask = - BackgroundTaskSchedulerFactoryInternal.getBackgroundTaskFromTaskId(taskId); - if (backgroundTask == null) { - Log.w(TAG, "Failed to start task. Could not instantiate BackgroundTask class."); - // Cancel task if the BackgroundTask class is not found anymore. We assume this means - // that the task has been deprecated. - BackgroundTaskSchedulerFactoryInternal.getScheduler().cancel( - ContextUtils.getApplicationContext(), taskParams.getTaskId()); - return; - } - - // Keep the CPU on through a wake lock. - PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - PowerManager.WakeLock wakeLock = - powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG); - wakeLock.acquire(MAX_TIMEOUT_MS); - - TaskExecutor taskExecutor = new TaskExecutor(context, wakeLock, taskParams, backgroundTask); - PostTask.postTask(UiThreadTaskTraits.BEST_EFFORT, taskExecutor::execute); - } - - private boolean networkRequirementsMet(Context context, int taskId, int requiredNetworkType) { - if (requiredNetworkType == TaskInfo.NetworkType.NONE) return true; - - ConnectivityManager connectivityManager = - (ConnectivityManager) context.getApplicationContext().getSystemService( - Context.CONNECTIVITY_SERVICE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Network network = connectivityManager.getActiveNetwork(); - if (requiredNetworkType == TaskInfo.NetworkType.ANY) return (network != null); - } else { - NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); - if (requiredNetworkType == TaskInfo.NetworkType.ANY) return (networkInfo != null); - } - - return (!connectivityManager.isActiveNetworkMetered()); - } - - private boolean batteryRequirementsMet(Context context, int taskId, boolean requiresCharging) { - if (!requiresCharging) return true; - BatteryManager batteryManager = - (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - return batteryManager.isCharging(); - } - - IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); - Intent batteryStatus = context.registerReceiver(null, intentFilter); - int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); - return status == BatteryManager.BATTERY_STATUS_CHARGING - || status == BatteryManager.BATTERY_STATUS_FULL; - } - - private @TaskInfo.NetworkType int convertToTaskInfoNetworkType( - ScheduledTaskProto.ScheduledTask.RequiredNetworkType networkType) { - switch (networkType) { - case NONE: - return TaskInfo.NetworkType.NONE; - case ANY: - return TaskInfo.NetworkType.ANY; - case UNMETERED: - return TaskInfo.NetworkType.UNMETERED; - default: - assert false : "Incorrect value of RequiredNetworkType"; - return -1; - } - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskGcmTaskService.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskGcmTaskService.java deleted file mode 100644 index cf2b7598bf8..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskGcmTaskService.java +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler.internal; - -import android.os.Build; - -import androidx.annotation.VisibleForTesting; - -import com.google.android.gms.gcm.GcmNetworkManager; -import com.google.android.gms.gcm.GcmTaskService; -import com.google.android.gms.gcm.TaskParams; - -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; -import org.chromium.components.background_task_scheduler.BackgroundTask; -import org.chromium.components.background_task_scheduler.TaskParameters; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -/** Delegates calls out to various tasks that need to run in the background. */ -public class BackgroundTaskGcmTaskService extends GcmTaskService { - private static final String TAG = "BkgrdTaskGcmTS"; - - private BackgroundTaskSchedulerGcmNetworkManager.Clock mClock = System::currentTimeMillis; - - @VisibleForTesting - void setClockForTesting(BackgroundTaskSchedulerGcmNetworkManager.Clock clock) { - mClock = clock; - } - - /** Class that waits for the processing to be done. */ - private static class Waiter { - // Wakelock is only held for 3 minutes by default for GcmTaskService. - private static final long MAX_TIMEOUT_SECONDS = 179; - private final CountDownLatch mLatch; - private long mWaiterTimeoutSeconds; - private boolean mIsRescheduleNeeded; - private boolean mHasTaskTimedOut; - - public Waiter(long waiterTimeoutSeconds) { - mLatch = new CountDownLatch(1); - mWaiterTimeoutSeconds = Math.min(waiterTimeoutSeconds, MAX_TIMEOUT_SECONDS); - } - - /** Start waiting for the processing to finish. */ - public void startWaiting() { - try { - mHasTaskTimedOut = !mLatch.await(mWaiterTimeoutSeconds, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Log.d(TAG, "Waiter interrupted while waiting."); - } - } - - /** Called to finish waiting. */ - public void onWaitDone(boolean needsRescheduling) { - mIsRescheduleNeeded = needsRescheduling; - mLatch.countDown(); - } - - /** @return Whether last task timed out. */ - public boolean hasTaskTimedOut() { - return mHasTaskTimedOut; - } - - /** @return Whether task needs to be rescheduled. */ - public boolean isRescheduleNeeded() { - return mIsRescheduleNeeded; - } - } - - private static class TaskFinishedCallbackGcmTaskService - implements BackgroundTask.TaskFinishedCallback { - private final Waiter mWaiter; - - public TaskFinishedCallbackGcmTaskService(Waiter waiter) { - mWaiter = waiter; - } - - @Override - public void taskFinished(final boolean needsReschedule) { - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - mWaiter.onWaitDone(needsReschedule); - } - }); - } - } - - @Override - public int onRunTask(TaskParams params) { - final TaskParameters taskParams = - BackgroundTaskSchedulerGcmNetworkManager.getTaskParametersFromTaskParams(params); - - final BackgroundTask backgroundTask = - BackgroundTaskSchedulerFactoryInternal.getBackgroundTaskFromTaskId( - taskParams.getTaskId()); - if (backgroundTask == null) { - Log.w(TAG, "Failed to start task. Could not instantiate BackgroundTask class."); - // Cancel task if the BackgroundTask class is not found anymore. We assume this means - // that the task has been deprecated. - BackgroundTaskSchedulerFactoryInternal.getScheduler().cancel( - ContextUtils.getApplicationContext(), taskParams.getTaskId()); - return GcmNetworkManager.RESULT_FAILURE; - } - - if (BackgroundTaskSchedulerGcmNetworkManager.didTaskExpire( - params, mClock.currentTimeMillis())) { - BackgroundTaskSchedulerUma.getInstance().reportTaskExpired(taskParams.getTaskId()); - return GcmNetworkManager.RESULT_FAILURE; - } - - final Waiter waiter = new Waiter(Waiter.MAX_TIMEOUT_SECONDS); - - final AtomicBoolean taskNeedsBackgroundProcessing = new AtomicBoolean(); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - BackgroundTaskSchedulerUma.getInstance().reportTaskStarted(taskParams.getTaskId()); - taskNeedsBackgroundProcessing.set( - backgroundTask.onStartTask(ContextUtils.getApplicationContext(), taskParams, - new TaskFinishedCallbackGcmTaskService(waiter))); - } - }); - - if (!taskNeedsBackgroundProcessing.get()) return GcmNetworkManager.RESULT_SUCCESS; - - waiter.startWaiting(); - - if (waiter.isRescheduleNeeded()) return GcmNetworkManager.RESULT_RESCHEDULE; - if (!waiter.hasTaskTimedOut()) return GcmNetworkManager.RESULT_SUCCESS; - - final AtomicBoolean taskNeedsRescheduling = new AtomicBoolean(); - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - BackgroundTaskSchedulerUma.getInstance().reportTaskStopped(taskParams.getTaskId()); - taskNeedsRescheduling.set(backgroundTask.onStopTask( - ContextUtils.getApplicationContext(), taskParams)); - } - }); - - if (taskNeedsRescheduling.get()) return GcmNetworkManager.RESULT_RESCHEDULE; - - return GcmNetworkManager.RESULT_SUCCESS; - } - - @Override - public void onInitializeTasks() { - // Ignore the event on OSs supporting JobScheduler. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) return; - BackgroundTaskSchedulerFactoryInternal.getScheduler().reschedule( - ContextUtils.getApplicationContext()); - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskJobService.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskJobService.java deleted file mode 100644 index 91c58877455..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskJobService.java +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler.internal; - -import android.annotation.TargetApi; -import android.app.job.JobParameters; -import android.app.job.JobService; -import android.os.Build; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; -import org.chromium.components.background_task_scheduler.BackgroundTask; -import org.chromium.components.background_task_scheduler.TaskParameters; - -import java.util.HashMap; -import java.util.Map; - -/** Delegates calls out to various tasks that need to run in the background. */ -@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1) -public class BackgroundTaskJobService extends JobService { - private static final String TAG = "BkgrdTaskJS"; - - private BackgroundTaskSchedulerJobService.Clock mClock = System::currentTimeMillis; - - @VisibleForTesting - void setClockForTesting(BackgroundTaskSchedulerJobService.Clock clock) { - mClock = clock; - } - - private static class TaskFinishedCallbackJobService - implements BackgroundTask.TaskFinishedCallback { - private final BackgroundTaskJobService mJobService; - private final BackgroundTask mBackgroundTask; - private final JobParameters mParams; - - TaskFinishedCallbackJobService(BackgroundTaskJobService jobService, - BackgroundTask backgroundTask, JobParameters params) { - mJobService = jobService; - mBackgroundTask = backgroundTask; - mParams = params; - } - - @Override - public void taskFinished(final boolean needsReschedule) { - // Need to remove the current task from the currently running tasks. All other access - // happens on the main thread, so do this removal also on the main thread. - // To ensure that a new job is not immediately scheduled in between removing the task - // from being a current task and before calling jobFinished, leading to us finishing - // something with the same ID, call - // {@link JobService#jobFinished(JobParameters, boolean} also on the main thread. - ThreadUtils.runOnUiThreadBlocking(new Runnable() { - @Override - public void run() { - if (!isCurrentBackgroundTaskForJobId()) { - Log.e(TAG, "Tried finishing non-current BackgroundTask."); - return; - } - - mJobService.mCurrentTasks.remove(mParams.getJobId()); - mJobService.jobFinished(mParams, needsReschedule); - } - }); - } - - private boolean isCurrentBackgroundTaskForJobId() { - return mJobService.mCurrentTasks.get(mParams.getJobId()) == mBackgroundTask; - } - } - - private final Map<Integer, BackgroundTask> mCurrentTasks = new HashMap<>(); - - @Override - public boolean onStartJob(JobParameters params) { - ThreadUtils.assertOnUiThread(); - BackgroundTask backgroundTask = - BackgroundTaskSchedulerFactoryInternal.getBackgroundTaskFromTaskId( - params.getJobId()); - if (backgroundTask == null) { - Log.w(TAG, "Failed to start task. Could not instantiate BackgroundTask class."); - // Cancel task if the BackgroundTask class is not found anymore. We assume this means - // that the task has been deprecated. - BackgroundTaskSchedulerFactoryInternal.getScheduler().cancel( - ContextUtils.getApplicationContext(), params.getJobId()); - return false; - } - - if (BackgroundTaskSchedulerJobService.didTaskExpire(params, mClock.currentTimeMillis())) { - BackgroundTaskSchedulerUma.getInstance().reportTaskExpired(params.getJobId()); - return false; - } - - mCurrentTasks.put(params.getJobId(), backgroundTask); - - TaskParameters taskParams = - BackgroundTaskSchedulerJobService.getTaskParametersFromJobParameters(params); - - BackgroundTaskSchedulerUma.getInstance().reportTaskStarted(taskParams.getTaskId()); - boolean taskNeedsBackgroundProcessing = - backgroundTask.onStartTask(ContextUtils.getApplicationContext(), taskParams, - new TaskFinishedCallbackJobService(this, backgroundTask, params)); - - if (!taskNeedsBackgroundProcessing) mCurrentTasks.remove(params.getJobId()); - return taskNeedsBackgroundProcessing; - } - - @Override - public boolean onStopJob(JobParameters params) { - ThreadUtils.assertOnUiThread(); - if (!mCurrentTasks.containsKey(params.getJobId())) { - Log.w(TAG, - "Failed to stop job, because job with job id " + params.getJobId() - + " does not exist."); - return false; - } - - BackgroundTask backgroundTask = mCurrentTasks.get(params.getJobId()); - - TaskParameters taskParams = - BackgroundTaskSchedulerJobService.getTaskParametersFromJobParameters(params); - BackgroundTaskSchedulerUma.getInstance().reportTaskStopped(taskParams.getTaskId()); - boolean taskNeedsReschedule = - backgroundTask.onStopTask(ContextUtils.getApplicationContext(), taskParams); - mCurrentTasks.remove(params.getJobId()); - return taskNeedsReschedule; - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerAlarmManager.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerAlarmManager.java deleted file mode 100644 index 0b277b3666b..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerAlarmManager.java +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2019 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.components.background_task_scheduler.internal; - -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; -import org.chromium.components.background_task_scheduler.TaskInfo; -import org.chromium.components.background_task_scheduler.TaskParameters; - -/** - * An implementation of {@link BackgroundTaskSchedulerDelegate} that uses the system API - * {@link AlarmManager} to schedule jobs. - */ -public class BackgroundTaskSchedulerAlarmManager implements BackgroundTaskSchedulerDelegate { - private static final String TAG = "BkgrdTaskSchedulerAM"; - - /** - * Retrieves the {@link TaskParameters} from the {@link Intent}. - * - * @param intent the {@link Intent} to extract the {@link TaskParameters} from. - * @return the {@link TaskParameters} for the current job. - */ - static TaskParameters getTaskParametersFromIntent(Intent intent) { - Bundle extras = intent.getExtras(); - - int taskId = extras.getInt(BACKGROUND_TASK_ID_KEY, /* defaultValue= */ 0); - if (taskId == 0) { - Log.e(TAG, "Cannot not get task ID from intent extras."); - return null; - } - - ScheduledTaskProto.ScheduledTask scheduledTask = - BackgroundTaskSchedulerPrefs.getScheduledTask(taskId); - - if (scheduledTask == null) { - Log.e(TAG, "Cannot get information about task with task ID " + taskId); - return null; - } - - Bundle taskExtras = - ExtrasToProtoConverter.convertProtoExtrasToExtras(scheduledTask.getExtrasList()); - if (taskExtras == null) { - Log.e(TAG, "Cannot get extras data for task ID " + taskId); - return null; - } - - TaskParameters.Builder builder = TaskParameters.create(taskId); - builder.addExtras(taskExtras); - return builder.build(); - } - - @VisibleForTesting - static PendingIntent createPendingIntentFromTaskId(Context context, int taskId) { - Intent intent = new Intent(context, BackgroundTaskBroadcastReceiver.class) - .putExtra(BACKGROUND_TASK_ID_KEY, taskId); - return PendingIntent.getBroadcast( - context, taskId, intent, PendingIntent.FLAG_CANCEL_CURRENT); - } - - @Override - public boolean schedule(Context context, TaskInfo taskInfo) { - ThreadUtils.assertOnUiThread(); - - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - PendingIntent pendingIntent = createPendingIntentFromTaskId(context, taskInfo.getTaskId()); - - AlarmManagerVisitor alarmManagerVisitor = - new AlarmManagerVisitor(alarmManager, pendingIntent); - taskInfo.getTimingInfo().accept(alarmManagerVisitor); - - return true; - } - - private static class AlarmManagerVisitor implements TaskInfo.TimingInfoVisitor { - private AlarmManager mAlarmManager; - private PendingIntent mPendingIntent; - - AlarmManagerVisitor(AlarmManager alarmManager, PendingIntent pendingIntent) { - mAlarmManager = alarmManager; - mPendingIntent = pendingIntent; - } - - @Override - public void visit(TaskInfo.OneOffInfo oneOffInfo) { - throw new RuntimeException("One-off tasks should not be scheduled with " - + "AlarmManager."); - } - - @Override - public void visit(TaskInfo.PeriodicInfo periodicInfo) { - throw new RuntimeException("Periodic tasks should not be scheduled with " - + "AlarmManager."); - } - - @Override - public void visit(TaskInfo.ExactInfo exactInfo) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - mAlarmManager.setExactAndAllowWhileIdle( - /*type= */ AlarmManager.RTC_WAKEUP, exactInfo.getTriggerAtMs(), - mPendingIntent); - return; - } - - mAlarmManager.setExact( - /*type= */ AlarmManager.RTC_WAKEUP, exactInfo.getTriggerAtMs(), mPendingIntent); - } - } - - @Override - public void cancel(Context context, int taskId) { - ThreadUtils.assertOnUiThread(); - - PendingIntent pendingIntent = createPendingIntentFromTaskId(context, taskId); - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - alarmManager.cancel(pendingIntent); - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerDelegate.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerDelegate.java deleted file mode 100644 index d3fe624cdb1..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerDelegate.java +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler.internal; - -import android.content.Context; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.components.background_task_scheduler.TaskInfo; - -/** - * The internal representation of a {@link BackgroundTaskScheduler} to make it possible to use - * system APIs ({@link android.app.job.JobScheduler} on newer platforms and GCM - * ({@link com.google.android.gms.gcm.GcmNetworkManager}) on older platforms. - */ -interface BackgroundTaskSchedulerDelegate { - @VisibleForTesting - String BACKGROUND_TASK_ID_KEY = "_background_task_id"; - @VisibleForTesting - String BACKGROUND_TASK_EXTRAS_KEY = "_background_task_extras"; - @VisibleForTesting - String BACKGROUND_TASK_SCHEDULE_TIME_KEY = "_background_task_schedule_time"; - @VisibleForTesting - String BACKGROUND_TASK_END_TIME_KEY = "_background_task_end_time"; - @VisibleForTesting - String BACKGROUND_TASK_INTERVAL_TIME_KEY = "_background_task_interval_time"; - @VisibleForTesting - String BACKGROUND_TASK_FLEX_TIME_KEY = "_background_task_flex_time"; - - /** - * Schedules a background task. See {@link TaskInfo} for information on what types of tasks that - * can be scheduled. - * - * @param context the current context. - * @param taskInfo the information about the task to be scheduled. - * @return true if the schedule operation succeeded, and false otherwise. - * @see TaskInfo - */ - boolean schedule(Context context, TaskInfo taskInfo); - - /** - * Cancels the task specified by the task ID. - * - * @param context the current context. - * @param taskId the ID of the task to cancel. See {@link TaskIds} for a list. - */ - void cancel(Context context, int taskId); -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerFactoryInternal.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerFactoryInternal.java deleted file mode 100644 index 523cc619533..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerFactoryInternal.java +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2020 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.components.background_task_scheduler.internal; - -import android.os.Build; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.ThreadUtils; -import org.chromium.components.background_task_scheduler.BackgroundTask; -import org.chromium.components.background_task_scheduler.BackgroundTaskFactory; -import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler; - -/** - * A factory for {@link BackgroundTaskScheduler} that ensures there is only ever a single instance. - */ -public final class BackgroundTaskSchedulerFactoryInternal { - private static BackgroundTaskScheduler sBackgroundTaskScheduler; - private static BackgroundTaskFactory sBackgroundTaskFactory; - - static BackgroundTaskSchedulerDelegate getSchedulerDelegateForSdk(int sdkInt) { - if (sdkInt >= Build.VERSION_CODES.M) { - return new BackgroundTaskSchedulerJobService(); - } else { - return new BackgroundTaskSchedulerGcmNetworkManager(); - } - } - - /** - * @return the current instance of the {@link BackgroundTaskScheduler}. Creates one if none - * exist. - */ - public static BackgroundTaskScheduler getScheduler() { - ThreadUtils.assertOnUiThread(); - if (sBackgroundTaskScheduler == null) { - sBackgroundTaskScheduler = new BackgroundTaskSchedulerImpl( - getSchedulerDelegateForSdk(Build.VERSION.SDK_INT), - new BackgroundTaskSchedulerAlarmManager()); - } - return sBackgroundTaskScheduler; - } - - @VisibleForTesting - public static void setSchedulerForTesting(BackgroundTaskScheduler backgroundTaskScheduler) { - sBackgroundTaskScheduler = backgroundTaskScheduler; - } - - /** See {@code BackgroundTaskSchedulerFactory#getBackgroundTaskFromTaskId}. */ - public static BackgroundTask getBackgroundTaskFromTaskId(int taskId) { - assert sBackgroundTaskFactory != null; - return sBackgroundTaskFactory.getBackgroundTaskFromTaskId(taskId); - } - - /** See {@code BackgroundTaskSchedulerFactory#setBackgroundTaskFactory}. */ - public static void setBackgroundTaskFactory(BackgroundTaskFactory backgroundTaskFactory) { - sBackgroundTaskFactory = backgroundTaskFactory; - } - - // Do not instantiate. - private BackgroundTaskSchedulerFactoryInternal() {} -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerGcmNetworkManager.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerGcmNetworkManager.java deleted file mode 100644 index e0325089930..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerGcmNetworkManager.java +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler.internal; - -import android.content.Context; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; -import com.google.android.gms.gcm.GcmNetworkManager; -import com.google.android.gms.gcm.OneoffTask; -import com.google.android.gms.gcm.PeriodicTask; -import com.google.android.gms.gcm.Task; -import com.google.android.gms.gcm.TaskParams; - -import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; -import org.chromium.components.background_task_scheduler.TaskInfo; -import org.chromium.components.background_task_scheduler.TaskParameters; - -import java.util.concurrent.TimeUnit; - -/** - * An implementation of {@link BackgroundTaskSchedulerDelegate} that uses the Play Services - * {@link GcmNetworkManager} to schedule jobs. - */ -class BackgroundTaskSchedulerGcmNetworkManager implements BackgroundTaskSchedulerDelegate { - private static final String TAG = "BkgrdTaskSchedGcmNM"; - - /** Delta time for expiration checks, after the end time. */ - static final long DEADLINE_DELTA_MS = 1000; - - /** Clock to use so we can mock time in tests. */ - public interface Clock { long currentTimeMillis(); } - - private static Clock sClock = System::currentTimeMillis; - - @VisibleForTesting - static void setClockForTesting(Clock clock) { - sClock = clock; - } - - /** - * Checks if a task expired, based on the current time of the service. - * - * @param taskParams parameters sent to the service, which contain the scheduling information - * regarding expiration. - * @param currentTimeMs the current time of the service. - * @return true if the task expired and false otherwise. - */ - static boolean didTaskExpire(TaskParams taskParams, long currentTimeMs) { - Bundle extras = taskParams.getExtras(); - if (extras == null || !extras.containsKey(BACKGROUND_TASK_SCHEDULE_TIME_KEY)) { - return false; - } - - long scheduleTimeMs = extras.getLong(BACKGROUND_TASK_SCHEDULE_TIME_KEY); - if (extras.containsKey(BACKGROUND_TASK_END_TIME_KEY)) { - long endTimeMs = - extras.getLong(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_END_TIME_KEY); - return TaskInfo.OneOffInfo.getExpirationStatus( - scheduleTimeMs, endTimeMs, currentTimeMs); - } else { - long intervalTimeMs = extras.getLong(BACKGROUND_TASK_INTERVAL_TIME_KEY); - - // If flex is never set, it is given a default value of 10% of the period time, as - // per the GcmNetworkManager behaviour. This default value is set in - // https://developers.google.com/android/reference/com/google/android/gms/gcm/PeriodicTask. - double defaultFlexAsFractionOfInterval = 0.1f; - - long flexTimeMs = extras.getLong(BACKGROUND_TASK_FLEX_TIME_KEY, - /*defaultValue=*/(long) (defaultFlexAsFractionOfInterval * intervalTimeMs)); - - return TaskInfo.PeriodicInfo.getExpirationStatus( - scheduleTimeMs, intervalTimeMs, flexTimeMs, currentTimeMs); - } - } - - /** - * Retrieves the {@link TaskParameters} from the {@link TaskParams}, which are passed as - * one of the keys. Only values valid for {@link android.os.BaseBundle} are supported, and other - * values are stripped at the time when the task is scheduled. - * - * @param taskParams the {@link TaskParams} to extract the {@link TaskParameters} from. - * @return the {@link TaskParameters} for the current job. - */ - static TaskParameters getTaskParametersFromTaskParams(@NonNull TaskParams taskParams) { - int taskId; - try { - taskId = Integer.parseInt(taskParams.getTag()); - } catch (NumberFormatException e) { - Log.e(TAG, "Cound not parse task ID from task tag: " + taskParams.getTag()); - return null; - } - - TaskParameters.Builder builder = TaskParameters.create(taskId); - - Bundle extras = taskParams.getExtras(); - Bundle taskExtras = extras.getBundle(BACKGROUND_TASK_EXTRAS_KEY); - builder.addExtras(taskExtras); - - return builder.build(); - } - - @VisibleForTesting - static Task createTaskFromTaskInfo(@NonNull TaskInfo taskInfo) { - Bundle taskExtras = new Bundle(); - taskExtras.putBundle(BACKGROUND_TASK_EXTRAS_KEY, taskInfo.getExtras()); - - TaskBuilderVisitor taskBuilderVisitor = new TaskBuilderVisitor(taskExtras); - taskInfo.getTimingInfo().accept(taskBuilderVisitor); - Task.Builder builder = taskBuilderVisitor.getBuilder(); - - builder.setPersisted(taskInfo.isPersisted()) - .setRequiredNetwork(getGcmNetworkManagerNetworkTypeFromTypeFromTaskNetworkType( - taskInfo.getRequiredNetworkType())) - .setRequiresCharging(taskInfo.requiresCharging()) - .setService(BackgroundTaskGcmTaskService.class) - .setTag(taskIdToTaskTag(taskInfo.getTaskId())) - .setUpdateCurrent(taskInfo.shouldUpdateCurrent()); - - return builder.build(); - } - - private static class TaskBuilderVisitor implements TaskInfo.TimingInfoVisitor { - private Task.Builder mBuilder; - private final Bundle mTaskExtras; - - TaskBuilderVisitor(Bundle taskExtras) { - mTaskExtras = taskExtras; - } - - // Only valid after a TimingInfo object was visited. - Task.Builder getBuilder() { - return mBuilder; - } - - @Override - public void visit(TaskInfo.OneOffInfo oneOffInfo) { - if (oneOffInfo.expiresAfterWindowEndTime()) { - mTaskExtras.putLong(BACKGROUND_TASK_SCHEDULE_TIME_KEY, sClock.currentTimeMillis()); - mTaskExtras.putLong(BACKGROUND_TASK_END_TIME_KEY, oneOffInfo.getWindowEndTimeMs()); - } - - OneoffTask.Builder builder = new OneoffTask.Builder(); - long windowStartSeconds = oneOffInfo.hasWindowStartTimeConstraint() - ? TimeUnit.MILLISECONDS.toSeconds(oneOffInfo.getWindowStartTimeMs()) - : 0; - long windowEndTimeMs = oneOffInfo.getWindowEndTimeMs(); - if (oneOffInfo.expiresAfterWindowEndTime()) { - windowEndTimeMs += DEADLINE_DELTA_MS; - } - builder.setExecutionWindow( - windowStartSeconds, TimeUnit.MILLISECONDS.toSeconds(windowEndTimeMs)); - builder.setExtras(mTaskExtras); - mBuilder = builder; - } - - @Override - public void visit(TaskInfo.PeriodicInfo periodicInfo) { - if (periodicInfo.expiresAfterWindowEndTime()) { - mTaskExtras.putLong(BACKGROUND_TASK_SCHEDULE_TIME_KEY, sClock.currentTimeMillis()); - mTaskExtras.putLong( - BACKGROUND_TASK_INTERVAL_TIME_KEY, periodicInfo.getIntervalMs()); - if (periodicInfo.hasFlex()) { - mTaskExtras.putLong(BACKGROUND_TASK_FLEX_TIME_KEY, periodicInfo.getFlexMs()); - } - } - - PeriodicTask.Builder builder = new PeriodicTask.Builder(); - builder.setPeriod(TimeUnit.MILLISECONDS.toSeconds(periodicInfo.getIntervalMs())); - if (periodicInfo.hasFlex()) { - builder.setFlex(TimeUnit.MILLISECONDS.toSeconds(periodicInfo.getFlexMs())); - } - builder.setExtras(mTaskExtras); - mBuilder = builder; - } - - @Override - public void visit(TaskInfo.ExactInfo exactInfo) { - throw new RuntimeException("Exact tasks should not be scheduled with " - + "GcmNetworkManager."); - } - } - - private static int getGcmNetworkManagerNetworkTypeFromTypeFromTaskNetworkType( - @TaskInfo.NetworkType int networkType) { - switch (networkType) { - // This is correct: GcmNM ANY means no network is guaranteed. - case TaskInfo.NetworkType.NONE: - return Task.NETWORK_STATE_ANY; - case TaskInfo.NetworkType.ANY: - return Task.NETWORK_STATE_CONNECTED; - case TaskInfo.NetworkType.UNMETERED: - return Task.NETWORK_STATE_UNMETERED; - default: - assert false; - } - return Task.NETWORK_STATE_ANY; - } - - @Override - public boolean schedule(Context context, @NonNull TaskInfo taskInfo) { - ThreadUtils.assertOnUiThread(); - - GcmNetworkManager gcmNetworkManager = getGcmNetworkManager(context); - if (gcmNetworkManager == null) { - Log.e(TAG, "GcmNetworkManager is not available."); - return false; - } - - try { - Task task = createTaskFromTaskInfo(taskInfo); - gcmNetworkManager.schedule(task); - } catch (IllegalArgumentException e) { - String gcmErrorMessage = e.getMessage() == null ? "null." : e.getMessage(); - Log.e(TAG, - "GcmNetworkManager failed to schedule task, gcm message: " + gcmErrorMessage); - return false; - } - - return true; - } - - @Override - public void cancel(Context context, int taskId) { - ThreadUtils.assertOnUiThread(); - - GcmNetworkManager gcmNetworkManager = getGcmNetworkManager(context); - if (gcmNetworkManager == null) { - Log.e(TAG, "GcmNetworkManager is not available."); - return; - } - - try { - gcmNetworkManager.cancelTask( - taskIdToTaskTag(taskId), BackgroundTaskGcmTaskService.class); - } catch (IllegalArgumentException e) { - Log.e(TAG, "GcmNetworkManager failed to cancel task."); - } - } - - private GcmNetworkManager getGcmNetworkManager(Context context) { - if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) - == ConnectionResult.SUCCESS) { - return GcmNetworkManager.getInstance(context); - } - return null; - } - - private static String taskIdToTaskTag(int taskId) { - return Integer.toString(taskId); - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerImpl.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerImpl.java deleted file mode 100644 index 40dc884cbb2..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerImpl.java +++ /dev/null @@ -1,231 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler.internal; - -import android.content.Context; -import android.os.Build; - -import org.chromium.base.BuildConfig; -import org.chromium.base.CommandLine; -import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; -import org.chromium.base.TraceEvent; -import org.chromium.components.background_task_scheduler.BackgroundTask; -import org.chromium.components.background_task_scheduler.BackgroundTaskScheduler; -import org.chromium.components.background_task_scheduler.TaskInfo; - -import java.util.Map; -import java.util.Set; - -/** - * This {@link BackgroundTaskScheduler} is the only one used in production code, and it is used to - * schedule jobs that run in the background. - * - * To get an instance of this class, use {@link BackgroundTaskSchedulerFactory#getScheduler()}. - */ -class BackgroundTaskSchedulerImpl implements BackgroundTaskScheduler { - private static final String TAG = "BkgrdTaskScheduler"; - private static final String SWITCH_IGNORE_BACKGROUND_TASKS = "ignore-background-tasks"; - - private final BackgroundTaskSchedulerDelegate mSchedulerDelegate; - private final BackgroundTaskSchedulerDelegate mAlarmManagerDelegate; - - /** Constructor only for {@link BackgroundTaskSchedulerFactory} and internal component tests. */ - BackgroundTaskSchedulerImpl(BackgroundTaskSchedulerDelegate schedulerDelegate, - BackgroundTaskSchedulerDelegate alarmManagerDelegate) { - mSchedulerDelegate = schedulerDelegate; - mAlarmManagerDelegate = alarmManagerDelegate; - } - - @Override - public boolean schedule(Context context, TaskInfo taskInfo) { - if (CommandLine.getInstance().hasSwitch(SWITCH_IGNORE_BACKGROUND_TASKS)) { - // When background tasks finish executing, they leave a cached process, which - // artificially inflates startup metrics that are based on events near to process - // creation. - return true; - } - try (TraceEvent te = TraceEvent.scoped( - "BackgroundTaskScheduler.schedule", Integer.toString(taskInfo.getTaskId()))) { - ThreadUtils.assertOnUiThread(); - - SchedulingVisitor schedulingVisitor = new SchedulingVisitor(context, taskInfo); - taskInfo.getTimingInfo().accept(schedulingVisitor); - boolean success = schedulingVisitor.getSuccess(); - BackgroundTaskSchedulerUma.getInstance().reportTaskScheduled( - taskInfo.getTaskId(), success); - - // Retain expiration metrics - MetricsVisitor metricsVisitor = new MetricsVisitor(taskInfo.getTaskId()); - taskInfo.getTimingInfo().accept(metricsVisitor); - - if (success) { - BackgroundTaskSchedulerPrefs.addScheduledTask(taskInfo); - } - return success; - } - } - - private class SchedulingVisitor implements TaskInfo.TimingInfoVisitor { - private Context mContext; - private TaskInfo mTaskInfo; - private boolean mSuccess; - - SchedulingVisitor(Context context, TaskInfo taskInfo) { - mContext = context; - mTaskInfo = taskInfo; - } - - // Only valid after a TimingInfo object was visited. - boolean getSuccess() { - return mSuccess; - } - - @Override - public void visit(TaskInfo.OneOffInfo oneOffInfo) { - mSuccess = mSchedulerDelegate.schedule(mContext, mTaskInfo); - } - - @Override - public void visit(TaskInfo.PeriodicInfo periodicInfo) { - mSuccess = mSchedulerDelegate.schedule(mContext, mTaskInfo); - } - - @Override - public void visit(TaskInfo.ExactInfo exactInfo) { - mSuccess = mAlarmManagerDelegate.schedule(mContext, mTaskInfo); - } - } - - // TODO(crbug.com/996178): Update the documentation for the expiration feature. - private class MetricsVisitor implements TaskInfo.TimingInfoVisitor { - private final int mTaskId; - - MetricsVisitor(int taskId) { - mTaskId = taskId; - } - - @Override - public void visit(TaskInfo.OneOffInfo oneOffInfo) { - BackgroundTaskSchedulerUma.getInstance().reportTaskCreatedAndExpirationState( - mTaskId, oneOffInfo.expiresAfterWindowEndTime()); - } - - @Override - public void visit(TaskInfo.PeriodicInfo periodicInfo) { - BackgroundTaskSchedulerUma.getInstance().reportTaskCreatedAndExpirationState( - mTaskId, periodicInfo.expiresAfterWindowEndTime()); - } - - @Override - public void visit(TaskInfo.ExactInfo exactInfo) { - BackgroundTaskSchedulerUma.getInstance().reportExactTaskCreated(mTaskId); - } - } - - @Override - public void cancel(Context context, int taskId) { - try (TraceEvent te = TraceEvent.scoped( - "BackgroundTaskScheduler.cancel", Integer.toString(taskId))) { - ThreadUtils.assertOnUiThread(); - BackgroundTaskSchedulerUma.getInstance().reportTaskCanceled(taskId); - - ScheduledTaskProto.ScheduledTask scheduledTask = - BackgroundTaskSchedulerPrefs.getScheduledTask(taskId); - BackgroundTaskSchedulerPrefs.removeScheduledTask(taskId); - - if (scheduledTask == null) { - Log.e(TAG, - "Task cannot be canceled because no data was found in" - + "storage or data was invalid"); - return; - } - - selectDelegateAndCancel(context, scheduledTask.getType(), taskId); - } - } - - @Override - public void checkForOSUpgrade(Context context) { - try (TraceEvent te = TraceEvent.scoped("BackgroundTaskScheduler.checkForOSUpgrade")) { - ThreadUtils.assertOnUiThread(); - int oldSdkInt = BackgroundTaskSchedulerPrefs.getLastSdkVersion(); - int newSdkInt = Build.VERSION.SDK_INT; - - // Update tasks stored in the old format to the proto format at Chrome Startup, if - // tasks are found to be stored in the old format. This allows to keep only one - // implementation of the storage methods. - BackgroundTaskSchedulerPrefs.migrateStoredTasksToProto(); - - if (oldSdkInt != newSdkInt) { - // Save the current SDK version to preferences. - BackgroundTaskSchedulerPrefs.setLastSdkVersion(newSdkInt); - } - - // No OS upgrade detected or OS upgrade does not change delegate. - if (oldSdkInt == newSdkInt || !osUpgradeChangesDelegateType(oldSdkInt, newSdkInt)) { - BackgroundTaskSchedulerUma.getInstance().flushStats(); - return; - } - - BackgroundTaskSchedulerUma.getInstance().removeCachedStats(); - - // Explicitly create and invoke old delegate type to cancel all scheduled tasks. - // All preference entries are kept until reschedule call, which removes then then. - BackgroundTaskSchedulerDelegate oldDelegate = - BackgroundTaskSchedulerFactoryInternal.getSchedulerDelegateForSdk(oldSdkInt); - Set<Integer> scheduledTaskIds = BackgroundTaskSchedulerPrefs.getScheduledTaskIds(); - for (int taskId : scheduledTaskIds) { - oldDelegate.cancel(context, taskId); - } - - reschedule(context); - } - } - - @Override - public void reschedule(Context context) { - try (TraceEvent te = TraceEvent.scoped("BackgroundTaskScheduler.reschedule")) { - ThreadUtils.assertOnUiThread(); - Map<Integer, ScheduledTaskProto.ScheduledTask> scheduledTasks = - BackgroundTaskSchedulerPrefs.getScheduledTasks(); - BackgroundTaskSchedulerPrefs.removeAllTasks(); - for (Map.Entry<Integer, ScheduledTaskProto.ScheduledTask> entry : - scheduledTasks.entrySet()) { - final BackgroundTask backgroundTask = - BackgroundTaskSchedulerFactoryInternal.getBackgroundTaskFromTaskId( - entry.getKey()); - if (backgroundTask == null) { - Log.w(TAG, - "Cannot reschedule task for task id " + entry.getKey() + ". Could not " - + "instantiate BackgroundTask class."); - // Cancel task if the BackgroundTask class is not found anymore. We assume this - // means that the task has been deprecated. - selectDelegateAndCancel(context, entry.getValue().getType(), entry.getKey()); - continue; - } - - BackgroundTaskSchedulerUma.getInstance().reportTaskRescheduled(); - backgroundTask.reschedule(context); - } - } - } - - private boolean osUpgradeChangesDelegateType(int oldSdkInt, int newSdkInt) { - // Assuming no upgrades from L->N (without going through M) allows us to remove - // GCMNetworkManager codepaths for Monochrome and above. - return BuildConfig.MIN_SDK_VERSION < Build.VERSION_CODES.N - && oldSdkInt < Build.VERSION_CODES.M && newSdkInt >= Build.VERSION_CODES.M; - } - - private void selectDelegateAndCancel( - Context context, ScheduledTaskProto.ScheduledTask.Type taskType, int taskId) { - if (taskType == ScheduledTaskProto.ScheduledTask.Type.EXACT) { - mAlarmManagerDelegate.cancel(context, taskId); - } else { - mSchedulerDelegate.cancel(context, taskId); - } - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerJobService.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerJobService.java deleted file mode 100644 index a013c1c4d22..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerJobService.java +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler.internal; - -import android.annotation.TargetApi; -import android.app.job.JobInfo; -import android.app.job.JobParameters; -import android.app.job.JobScheduler; -import android.content.ComponentName; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.os.PersistableBundle; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.Log; -import org.chromium.base.ThreadUtils; -import org.chromium.components.background_task_scheduler.TaskInfo; -import org.chromium.components.background_task_scheduler.TaskParameters; - -import java.util.List; - -/** - * An implementation of {@link BackgroundTaskSchedulerDelegate} that uses the system - * {@link JobScheduler} to schedule jobs. - */ -@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1) -class BackgroundTaskSchedulerJobService implements BackgroundTaskSchedulerDelegate { - private static final String TAG = "BkgrdTaskSchedulerJS"; - - /** Delta time for expiration checks. Used to make checks after the end time. */ - static final long DEADLINE_DELTA_MS = 1000; - - /** Clock to use so we can mock time in tests. */ - public interface Clock { long currentTimeMillis(); } - - private static Clock sClock = System::currentTimeMillis; - - @VisibleForTesting - static void setClockForTesting(Clock clock) { - sClock = clock; - } - - /** - * Checks if a task expired, based on the current time of the service. - * - * @param jobParameters parameters sent to the service, which contain the scheduling information - * regarding expiration. - * @param currentTimeMs the current time of the service. - * @return true if the task expired and false otherwise. - */ - static boolean didTaskExpire(JobParameters jobParameters, long currentTimeMs) { - PersistableBundle extras = jobParameters.getExtras(); - if (extras == null || !extras.containsKey(BACKGROUND_TASK_SCHEDULE_TIME_KEY)) { - return false; - } - - long scheduleTimeMs = extras.getLong(BACKGROUND_TASK_SCHEDULE_TIME_KEY); - if (extras.containsKey(BACKGROUND_TASK_END_TIME_KEY)) { - long endTimeMs = extras.getLong(BACKGROUND_TASK_END_TIME_KEY); - return TaskInfo.OneOffInfo.getExpirationStatus( - scheduleTimeMs, endTimeMs, currentTimeMs); - } else { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - // Before Android N, there was no control over when the job will execute within - // the given interval. This makes it impossible to check for an expiration time. - return false; - } - - long intervalTimeMs = extras.getLong(BACKGROUND_TASK_INTERVAL_TIME_KEY); - // Based on the JobInfo documentation, attempting to declare a smaller period than - // this when scheduling a job will result in a job that is still periodic, but will - // run with this effective period. - if (intervalTimeMs < JobInfo.getMinPeriodMillis()) { - intervalTimeMs = JobInfo.getMinPeriodMillis(); - } - - // Since Android N, there was a minimum of 5 min set for the flex value. This - // value is considerably lower from the previous one, since the minimum value - // allowed for the interval time is of 15 min: - // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/oreo-release/core/java/android/app/job/JobInfo.java. - long flexTimeMs = extras.getLong(BACKGROUND_TASK_FLEX_TIME_KEY, /*defaultValue=*/ - JobInfo.getMinFlexMillis()); - - return TaskInfo.PeriodicInfo.getExpirationStatus( - scheduleTimeMs, intervalTimeMs, flexTimeMs, currentTimeMs); - } - } - - /** - * Retrieves the {@link TaskParameters} from the {@link JobParameters}, which are passed as - * one of the keys. Only values valid for {@link android.os.BaseBundle} are supported, and other - * values are stripped at the time when the task is scheduled. - * - * @param jobParameters the {@link JobParameters} to extract the {@link TaskParameters} from. - * @return the {@link TaskParameters} for the current job. - */ - static TaskParameters getTaskParametersFromJobParameters(JobParameters jobParameters) { - TaskParameters.Builder builder = TaskParameters.create(jobParameters.getJobId()); - - PersistableBundle jobExtras = jobParameters.getExtras(); - PersistableBundle persistableTaskExtras = - jobExtras.getPersistableBundle(BACKGROUND_TASK_EXTRAS_KEY); - - Bundle taskExtras = new Bundle(); - taskExtras.putAll(persistableTaskExtras); - builder.addExtras(taskExtras); - - return builder.build(); - } - - @VisibleForTesting - static JobInfo createJobInfoFromTaskInfo(Context context, TaskInfo taskInfo) { - PersistableBundle jobExtras = new PersistableBundle(); - - PersistableBundle persistableBundle = getTaskExtrasAsPersistableBundle(taskInfo); - jobExtras.putPersistableBundle(BACKGROUND_TASK_EXTRAS_KEY, persistableBundle); - - JobInfo.Builder builder = - new JobInfo - .Builder(taskInfo.getTaskId(), - new ComponentName(context, BackgroundTaskJobService.class)) - .setPersisted(taskInfo.isPersisted()) - .setRequiresCharging(taskInfo.requiresCharging()) - .setRequiredNetworkType(getJobInfoNetworkTypeFromTaskNetworkType( - taskInfo.getRequiredNetworkType())); - - JobInfoBuilderVisitor jobInfoBuilderVisitor = new JobInfoBuilderVisitor(builder, jobExtras); - taskInfo.getTimingInfo().accept(jobInfoBuilderVisitor); - builder = jobInfoBuilderVisitor.getBuilder(); - - return builder.build(); - } - - private static class JobInfoBuilderVisitor implements TaskInfo.TimingInfoVisitor { - private final JobInfo.Builder mBuilder; - private final PersistableBundle mJobExtras; - - JobInfoBuilderVisitor(JobInfo.Builder builder, PersistableBundle jobExtras) { - mBuilder = builder; - mJobExtras = jobExtras; - } - - // Only valid after a TimingInfo object was visited. - JobInfo.Builder getBuilder() { - return mBuilder; - } - - @Override - public void visit(TaskInfo.OneOffInfo oneOffInfo) { - if (oneOffInfo.expiresAfterWindowEndTime()) { - mJobExtras.putLong( - BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_SCHEDULE_TIME_KEY, - sClock.currentTimeMillis()); - mJobExtras.putLong(BackgroundTaskSchedulerDelegate.BACKGROUND_TASK_END_TIME_KEY, - oneOffInfo.getWindowEndTimeMs()); - } - mBuilder.setExtras(mJobExtras); - - if (oneOffInfo.hasWindowStartTimeConstraint()) { - mBuilder.setMinimumLatency(oneOffInfo.getWindowStartTimeMs()); - } - long windowEndTimeMs = oneOffInfo.getWindowEndTimeMs(); - if (oneOffInfo.expiresAfterWindowEndTime()) { - windowEndTimeMs += DEADLINE_DELTA_MS; - } - mBuilder.setOverrideDeadline(windowEndTimeMs); - } - - @Override - public void visit(TaskInfo.PeriodicInfo periodicInfo) { - if (periodicInfo.expiresAfterWindowEndTime()) { - mJobExtras.putLong(BACKGROUND_TASK_SCHEDULE_TIME_KEY, sClock.currentTimeMillis()); - mJobExtras.putLong(BACKGROUND_TASK_INTERVAL_TIME_KEY, periodicInfo.getIntervalMs()); - if (periodicInfo.hasFlex()) { - mJobExtras.putLong(BACKGROUND_TASK_FLEX_TIME_KEY, periodicInfo.getFlexMs()); - } - } - mBuilder.setExtras(mJobExtras); - - if (periodicInfo.hasFlex() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - mBuilder.setPeriodic(periodicInfo.getIntervalMs(), periodicInfo.getFlexMs()); - return; - } - mBuilder.setPeriodic(periodicInfo.getIntervalMs()); - } - - @Override - public void visit(TaskInfo.ExactInfo exactInfo) { - throw new RuntimeException("Exact tasks should not be scheduled with " - + "JobScheduler."); - } - } - - private static int getJobInfoNetworkTypeFromTaskNetworkType( - @TaskInfo.NetworkType int networkType) { - // The values are hard coded to represent the same as the network type from JobService. - return networkType; - } - - private static PersistableBundle getTaskExtrasAsPersistableBundle(TaskInfo taskInfo) { - Bundle taskExtras = taskInfo.getExtras(); - BundleToPersistableBundleConverter.Result convertedData = - BundleToPersistableBundleConverter.convert(taskExtras); - if (convertedData.hasErrors()) { - Log.w(TAG, - "Failed converting extras to PersistableBundle: " - + convertedData.getFailedKeysErrorString()); - } - return convertedData.getPersistableBundle(); - } - - @Override - public boolean schedule(Context context, TaskInfo taskInfo) { - ThreadUtils.assertOnUiThread(); - - JobInfo jobInfo = createJobInfoFromTaskInfo(context, taskInfo); - - JobScheduler jobScheduler = - (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); - - if (!taskInfo.shouldUpdateCurrent() && hasPendingJob(jobScheduler, taskInfo.getTaskId())) { - return true; - } - // This can fail on heavily modified android builds. Catch so we don't crash. - try { - return jobScheduler.schedule(jobInfo) == JobScheduler.RESULT_SUCCESS; - } catch (Exception e) { - // Typically we don't catch RuntimeException, but this time we do want to catch it - // because we are worried about android as modified by device manufacturers. - Log.e(TAG, "Unable to schedule with Android.", e); - return false; - } - } - - @Override - public void cancel(Context context, int taskId) { - ThreadUtils.assertOnUiThread(); - JobScheduler jobScheduler = - (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); - try { - jobScheduler.cancel(taskId); - } catch (NullPointerException exception) { - Log.e(TAG, "Failed to cancel task: " + taskId); - } - } - - private boolean hasPendingJob(JobScheduler jobScheduler, int jobId) { - List<JobInfo> pendingJobs = jobScheduler.getAllPendingJobs(); - for (JobInfo pendingJob : pendingJobs) { - if (pendingJob.getId() == jobId) return true; - } - - return false; - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerPrefs.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerPrefs.java deleted file mode 100644 index bedf11cb0dc..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerPrefs.java +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler.internal; - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.util.Base64; - -import androidx.annotation.VisibleForTesting; - -import com.google.protobuf.InvalidProtocolBufferException; - -import org.chromium.base.ContextUtils; -import org.chromium.base.Log; -import org.chromium.base.StrictModeContext; -import org.chromium.base.TraceEvent; -import org.chromium.components.background_task_scheduler.TaskInfo; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Class handling shared preference entries for BackgroundTaskScheduler. - */ -public class BackgroundTaskSchedulerPrefs { - private static final String TAG = "BTSPrefs"; - @VisibleForTesting - static final String KEY_SCHEDULED_TASKS = "bts_scheduled_tasks"; - private static final String KEY_LAST_SDK_VERSION = "bts_last_sdk_version"; - private static final String PREF_PACKAGE = "org.chromium.components.background_task_scheduler"; - - /** - * Class abstracting conversions between a string kept in shared preferences and actual values - * held there. - */ - @VisibleForTesting - static class ScheduledTaskPreferenceEntry { - private static final String ENTRY_SEPARATOR = ":"; - private int mTaskId; - - /** - * Parses a preference entry from input string. - * - * @param entry An input string to parse. - * @return A parsed entry or null if the input is not valid. - */ - public static ScheduledTaskPreferenceEntry parseEntry(String entry) { - if (entry == null) return null; - - String[] entryParts = entry.split(ENTRY_SEPARATOR); - if (entryParts.length != 2 || entryParts[0].isEmpty() || entryParts[1].isEmpty()) { - return null; - } - int taskId = 0; - try { - taskId = Integer.parseInt(entryParts[1]); - } catch (NumberFormatException e) { - return null; - } - return new ScheduledTaskPreferenceEntry(taskId); - } - - public ScheduledTaskPreferenceEntry(int taskId) { - mTaskId = taskId; - } - - /** Gets the ID of the task in this entry. */ - public int getTaskId() { - return mTaskId; - } - } - - static void migrateStoredTasksToProto() { - try (TraceEvent te = TraceEvent.scoped( - "BackgroundTaskSchedulerPrefs.migrateStoredTasksToProto")) { - Set<String> scheduledTasks = - ContextUtils.getAppSharedPreferences().getStringSet(KEY_SCHEDULED_TASKS, null); - - if (scheduledTasks == null) return; - ContextUtils.getAppSharedPreferences().edit().remove(KEY_SCHEDULED_TASKS).apply(); - - SharedPreferences.Editor editor = getSharedPreferences().edit(); - for (String entry : scheduledTasks) { - ScheduledTaskPreferenceEntry parsed = - ScheduledTaskPreferenceEntry.parseEntry(entry); - if (parsed == null) { - Log.w(TAG, "Scheduled task could not be parsed from storage."); - continue; - } - editor.putString( - String.valueOf(parsed.getTaskId()), getEmptySerializedScheduledTaskProto()); - BackgroundTaskSchedulerUma.getInstance().reportMigrationToProto(parsed.getTaskId()); - } - editor.apply(); - } - } - - private static String getEmptySerializedScheduledTaskProto() { - ScheduledTaskProto.ScheduledTask scheduledTask = - ScheduledTaskProto.ScheduledTask.newBuilder().build(); - return Base64.encodeToString(scheduledTask.toByteArray(), Base64.DEFAULT); - } - - /** Adds a task to scheduler's preferences, so that it can be rescheduled with OS upgrade. */ - public static void addScheduledTask(TaskInfo taskInfo) { - try (TraceEvent te = TraceEvent.scoped("BackgroundTaskSchedulerPrefs.addScheduledTask", - Integer.toString(taskInfo.getTaskId()))) { - ScheduledTaskProtoVisitor visitor = new ScheduledTaskProtoVisitor(taskInfo.getExtras(), - taskInfo.getRequiredNetworkType(), taskInfo.requiresCharging()); - taskInfo.getTimingInfo().accept(visitor); - - getSharedPreferences() - .edit() - .putString(String.valueOf(taskInfo.getTaskId()), - visitor.getSerializedScheduledTask()) - .apply(); - } - } - - private static class ScheduledTaskProtoVisitor implements TaskInfo.TimingInfoVisitor { - private String mSerializedScheduledTask; - private final Bundle mExtras; - @TaskInfo.NetworkType - private final int mRequiredNetworkType; - private final boolean mRequiresCharging; - - ScheduledTaskProtoVisitor(Bundle extras, @TaskInfo.NetworkType int requiredNetworkType, - boolean requiresCharging) { - mExtras = extras; - mRequiredNetworkType = requiredNetworkType; - mRequiresCharging = requiresCharging; - } - - // Only valid after a TimingInfo object was visited. - String getSerializedScheduledTask() { - return mSerializedScheduledTask; - } - - @Override - public void visit(TaskInfo.OneOffInfo oneOffInfo) { - try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - ScheduledTaskProto.ScheduledTask scheduledTask = - ScheduledTaskProto.ScheduledTask.newBuilder() - .setType(ScheduledTaskProto.ScheduledTask.Type.ONE_OFF) - .build(); - mSerializedScheduledTask = - Base64.encodeToString(scheduledTask.toByteArray(), Base64.DEFAULT); - } - } - - @Override - public void visit(TaskInfo.PeriodicInfo periodicInfo) { - ScheduledTaskProto.ScheduledTask scheduledTask = - ScheduledTaskProto.ScheduledTask.newBuilder() - .setType(ScheduledTaskProto.ScheduledTask.Type.PERIODIC) - .build(); - mSerializedScheduledTask = - Base64.encodeToString(scheduledTask.toByteArray(), Base64.DEFAULT); - } - - @Override - public void visit(TaskInfo.ExactInfo exactInfo) { - ScheduledTaskProto.ScheduledTask scheduledTask = - ScheduledTaskProto.ScheduledTask.newBuilder() - .setType(ScheduledTaskProto.ScheduledTask.Type.EXACT) - .setTriggerMs(exactInfo.getTriggerAtMs()) - .setRequiredNetworkType( - convertToRequiredNetworkType(mRequiredNetworkType)) - .setRequiresCharging(mRequiresCharging) - .addAllExtras( - ExtrasToProtoConverter.convertExtrasToProtoExtras(mExtras)) - .build(); - mSerializedScheduledTask = - Base64.encodeToString(scheduledTask.toByteArray(), Base64.DEFAULT); - } - } - - /** Removes a task from scheduler's preferences. */ - public static void removeScheduledTask(int taskId) { - try (TraceEvent te = TraceEvent.scoped("BackgroundTaskSchedulerPrefs.removeScheduledTask", - Integer.toString(taskId))) { - getSharedPreferences().edit().remove(String.valueOf(taskId)).apply(); - } - } - - /** Gets a set of scheduled task IDs. */ - public static Set<Integer> getScheduledTaskIds() { - try (TraceEvent te = - TraceEvent.scoped("BackgroundTaskSchedulerPrefs.getScheduledTaskIds")) { - Set<Integer> result = new HashSet<>(); - for (String key : getSharedPreferences().getAll().keySet()) { - try { - result.add(Integer.valueOf(key)); - } catch (NumberFormatException e) { - Log.e(TAG, "Incorrect task id: " + key); - } - } - return result; - } - } - - /** - * Gets information associated with a task id. - * @param taskId the task id for which to retrieve data. - * @return stored data or null if data not found or invalid. - */ - public static ScheduledTaskProto.ScheduledTask getScheduledTask(int taskId) { - String serialized = getSharedPreferences().getString(String.valueOf(taskId), null); - if (serialized == null) { - Log.e(TAG, "No data found for task id: " + taskId); - return null; - } - - try { - return ScheduledTaskProto.ScheduledTask.parseFrom(Base64.decode(serialized, 0)); - } catch (InvalidProtocolBufferException e) { - Log.e(TAG, "Invalid protocol buffer: " + e); - removeScheduledTask(taskId); - return null; - } - } - - /** - * Gets all current scheduled task. - * @return map of task ids associated with scheduled task protos. - */ - public static Map<Integer, ScheduledTaskProto.ScheduledTask> getScheduledTasks() { - try (TraceEvent te = TraceEvent.scoped("BackgroundTaskSchedulerPrefs.getScheduledTasks")) { - Map<Integer, ScheduledTaskProto.ScheduledTask> result = new HashMap<>(); - for (Map.Entry<String, ?> entry : getSharedPreferences().getAll().entrySet()) { - try { - int taskId = Integer.valueOf(entry.getKey()); - ScheduledTaskProto.ScheduledTask scheduledTask = - ScheduledTaskProto.ScheduledTask.parseFrom( - Base64.decode(String.valueOf(entry.getValue()), 0)); - - result.put(taskId, scheduledTask); - } catch (NumberFormatException e) { - Log.e(TAG, "Incorrect task id: " + entry.getKey()); - } catch (InvalidProtocolBufferException e) { - Log.e(TAG, "Invalid protocol buffer: " + e); - removeScheduledTask(Integer.valueOf(entry.getKey())); - } - } - return result; - } - } - - /** - * Removes all scheduled tasks from shared preferences store. Removes tasks from the old - * storage format and from the proto format. - */ - public static void removeAllTasks() { - try (TraceEvent te = TraceEvent.scoped("BackgroundTaskSchedulerPrefs.removeAllTasks")) { - ContextUtils.getAppSharedPreferences().edit().remove(KEY_SCHEDULED_TASKS).apply(); - getSharedPreferences().edit().clear().apply(); - } - } - - /** - * Pre-load shared prefs to avoid being blocked on the disk reads in the future. - */ - public static void warmUpSharedPrefs() { - try (TraceEvent te = TraceEvent.scoped("BackgroundTaskSchedulerPrefs.warmUpSharedPrefs")) { - getSharedPreferences(); - } - } - - /** Returns the BackgroundTaskScheduler SharedPreferences. */ - private static SharedPreferences getSharedPreferences() { - return ContextUtils.getApplicationContext().getSharedPreferences( - PREF_PACKAGE, Context.MODE_PRIVATE); - } - - /** Gets the last SDK version on which this instance ran. Defaults to current SDK version. */ - public static int getLastSdkVersion() { - try (TraceEvent te = TraceEvent.scoped("BackgroundTaskSchedulerPrefs.getLastSdkVersion")) { - int sdkInt = ContextUtils.getAppSharedPreferences().getInt( - KEY_LAST_SDK_VERSION, Build.VERSION.SDK_INT); - return sdkInt; - } - } - - /** Gets the last SDK version on which this instance ran. */ - public static void setLastSdkVersion(int sdkVersion) { - try (TraceEvent te = TraceEvent.scoped("BackgroundTaskSchedulerPrefs.setLastSdkVersion", - Integer.toString(sdkVersion))) { - ContextUtils.getAppSharedPreferences() - .edit() - .putInt(KEY_LAST_SDK_VERSION, sdkVersion) - .apply(); - } - } - - private static ScheduledTaskProto.ScheduledTask.RequiredNetworkType - convertToRequiredNetworkType(@TaskInfo.NetworkType int networkType) { - switch (networkType) { - case TaskInfo.NetworkType.NONE: - return ScheduledTaskProto.ScheduledTask.RequiredNetworkType.NONE; - case TaskInfo.NetworkType.ANY: - return ScheduledTaskProto.ScheduledTask.RequiredNetworkType.ANY; - case TaskInfo.NetworkType.UNMETERED: - return ScheduledTaskProto.ScheduledTask.RequiredNetworkType.UNMETERED; - default: - assert false : "Incorrect value of TaskInfo.NetworkType"; - return ScheduledTaskProto.ScheduledTask.RequiredNetworkType.NONE; - } - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUma.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUma.java deleted file mode 100644 index 90d3677df9a..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerUma.java +++ /dev/null @@ -1,301 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler.internal; - -import android.content.SharedPreferences; - -import androidx.annotation.VisibleForTesting; - -import org.chromium.base.ContextUtils; -import org.chromium.base.ThreadUtils; -import org.chromium.base.library_loader.LibraryLoader; -import org.chromium.base.metrics.RecordHistogram; -import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerExternalUma; - -import java.util.HashSet; -import java.util.Set; - -/** - * Helper class to report UMA. - */ -public class BackgroundTaskSchedulerUma extends BackgroundTaskSchedulerExternalUma { - static final String KEY_CACHED_UMA = "bts_cached_uma"; - - private static BackgroundTaskSchedulerUma sInstance; - - private static class CachedUmaEntry { - private static final String SEPARATOR = ":"; - private String mEvent; - private int mValue; - private int mCount; - - /** - * Parses a cached UMA entry from a string. - * - * @param entry A serialized entry from preferences store. - * @return A parsed CachedUmaEntry object, or <c>null</c> if parsing failed. - */ - public static CachedUmaEntry parseEntry(String entry) { - if (entry == null) return null; - - String[] entryParts = entry.split(SEPARATOR); - if (entryParts.length != 3 || entryParts[0].isEmpty() || entryParts[1].isEmpty() - || entryParts[2].isEmpty()) { - return null; - } - int value = -1; - int count = -1; - try { - value = Integer.parseInt(entryParts[1]); - count = Integer.parseInt(entryParts[2]); - } catch (NumberFormatException e) { - return null; - } - return new CachedUmaEntry(entryParts[0], value, count); - } - - /** Returns a string for partial matching of the prefs entry. */ - public static String getStringForPartialMatching(String event, int value) { - return event + SEPARATOR + value + SEPARATOR; - } - - public CachedUmaEntry(String event, int value, int count) { - mEvent = event; - mValue = value; - mCount = count; - } - - /** Converts cached UMA entry to a string in format: EVENT:VALUE:COUNT. */ - @Override - public String toString() { - return mEvent + SEPARATOR + mValue + SEPARATOR + mCount; - } - - /** Gets the name of the event (UMA). */ - public String getEvent() { - return mEvent; - } - - /** Gets the value of the event (concrete value of the enum). */ - public int getValue() { - return mValue; - } - - /** Gets the count of events that happened. */ - public int getCount() { - return mCount; - } - - /** Increments the count of the event. */ - public void increment() { - mCount++; - } - } - - public static BackgroundTaskSchedulerUma getInstance() { - if (sInstance == null) { - sInstance = new BackgroundTaskSchedulerUma(); - } - return sInstance; - } - - @VisibleForTesting - public static void setInstanceForTesting(BackgroundTaskSchedulerUma instance) { - sInstance = instance; - } - - /** Reports metrics for task scheduling and whether it was successful. */ - public void reportTaskScheduled(int taskId, boolean success) { - if (success) { - cacheEvent("Android.BackgroundTaskScheduler.TaskScheduled.Success", - toUmaEnumValueFromTaskId(taskId)); - } else { - cacheEvent("Android.BackgroundTaskScheduler.TaskScheduled.Failure", - toUmaEnumValueFromTaskId(taskId)); - } - } - - /** Reports metrics for creating an exact tasks. */ - public void reportExactTaskCreated(int taskId) { - cacheEvent("Android.BackgroundTaskScheduler.ExactTaskCreated", - toUmaEnumValueFromTaskId(taskId)); - } - - /** Reports metrics for task scheduling with the expiration feature activated. */ - public void reportTaskCreatedAndExpirationState(int taskId, boolean expires) { - if (expires) { - cacheEvent("Android.BackgroundTaskScheduler.TaskCreated.WithExpiration", - toUmaEnumValueFromTaskId(taskId)); - } else { - cacheEvent("Android.BackgroundTaskScheduler.TaskCreated.WithoutExpiration", - toUmaEnumValueFromTaskId(taskId)); - } - } - - /** Reports metrics for not starting a task because of expiration. */ - public void reportTaskExpired(int taskId) { - cacheEvent("Android.BackgroundTaskScheduler.TaskExpired", toUmaEnumValueFromTaskId(taskId)); - } - - /** Reports metrics for task canceling. */ - public void reportTaskCanceled(int taskId) { - cacheEvent( - "Android.BackgroundTaskScheduler.TaskCanceled", toUmaEnumValueFromTaskId(taskId)); - } - - /** Reports metrics for starting a task. */ - public void reportTaskStarted(int taskId) { - cacheEvent("Android.BackgroundTaskScheduler.TaskStarted", toUmaEnumValueFromTaskId(taskId)); - } - - /** Reports metrics for stopping a task. */ - public void reportTaskStopped(int taskId) { - cacheEvent("Android.BackgroundTaskScheduler.TaskStopped", toUmaEnumValueFromTaskId(taskId)); - } - - /** Reports metrics for rescheduling a task. */ - public void reportTaskRescheduled() { - cacheEvent("Android.BackgroundTaskScheduler.TaskRescheduled", 0); - } - - /** Reports metrics for migrating scheduled tasks to Protocol Buffer data format. */ - public void reportMigrationToProto(int taskId) { - cacheEvent("Android.BackgroundTaskScheduler.MigrationToProto", - toUmaEnumValueFromTaskId(taskId)); - } - - @Override - public void reportTaskStartedNative(int taskId, boolean serviceManagerOnlyMode) { - int umaEnumValue = toUmaEnumValueFromTaskId(taskId); - cacheEvent("Android.BackgroundTaskScheduler.TaskLoadedNative", umaEnumValue); - if (serviceManagerOnlyMode) { - cacheEvent( - "Android.BackgroundTaskScheduler.TaskLoadedNative.ReducedMode", umaEnumValue); - } else { - cacheEvent( - "Android.BackgroundTaskScheduler.TaskLoadedNative.FullBrowser", umaEnumValue); - } - } - - @Override - public void reportNativeTaskStarted(int taskId, boolean serviceManagerOnlyMode) { - int umaEnumValue = toUmaEnumValueFromTaskId(taskId); - cacheEvent("Android.NativeBackgroundTask.TaskStarted", umaEnumValue); - if (serviceManagerOnlyMode) { - cacheEvent("Android.NativeBackgroundTask.TaskStarted.ReducedMode", umaEnumValue); - } else { - cacheEvent("Android.NativeBackgroundTask.TaskStarted.FullBrowser", umaEnumValue); - } - } - - @Override - public void reportNativeTaskFinished(int taskId, boolean serviceManagerOnlyMode) { - int umaEnumValue = toUmaEnumValueFromTaskId(taskId); - cacheEvent("Android.NativeBackgroundTask.TaskFinished", umaEnumValue); - if (serviceManagerOnlyMode) { - cacheEvent("Android.NativeBackgroundTask.TaskFinished.ReducedMode", umaEnumValue); - } else { - cacheEvent("Android.NativeBackgroundTask.TaskFinished.FullBrowser", umaEnumValue); - } - } - - @Override - public void reportStartupMode(int startupMode) { - // We don't record full browser's warm startup since most of the full browser warm startup - // don't even reach here. - if (startupMode < 0) return; - - cacheEvent("Servicification.Startup3", startupMode); - } - - /** Method that actually invokes histogram recording. Extracted for testing. */ - @VisibleForTesting - void recordEnumeratedHistogram(String histogram, int value, int maxCount) { - RecordHistogram.recordEnumeratedHistogram(histogram, value, maxCount); - } - - /** Records histograms for cached stats. Should only be called when native is initialized. */ - public void flushStats() { - assertNativeIsLoaded(); - ThreadUtils.assertOnUiThread(); - - Set<String> cachedUmaStrings = getCachedUmaEntries(ContextUtils.getAppSharedPreferences()); - - for (String cachedUmaString : cachedUmaStrings) { - CachedUmaEntry entry = CachedUmaEntry.parseEntry(cachedUmaString); - if (entry == null) continue; - for (int i = 0; i < entry.getCount(); i++) { - recordEnumeratedHistogram( - entry.getEvent(), entry.getValue(), BACKGROUND_TASK_COUNT); - } - } - - // Once all metrics are reported, we can simply remove the shared preference key. - removeCachedStats(); - } - - /** Removes all of the cached stats without reporting. */ - public void removeCachedStats() { - ThreadUtils.assertOnUiThread(); - ContextUtils.getAppSharedPreferences().edit().remove(KEY_CACHED_UMA).apply(); - } - - /** Caches the event to be reported through UMA in shared preferences. */ - @VisibleForTesting - void cacheEvent(String event, int value) { - SharedPreferences prefs = ContextUtils.getAppSharedPreferences(); - Set<String> cachedUmaStrings = getCachedUmaEntries(prefs); - String partialMatch = CachedUmaEntry.getStringForPartialMatching(event, value); - - String existingEntry = null; - for (String cachedUmaString : cachedUmaStrings) { - if (cachedUmaString.startsWith(partialMatch)) { - existingEntry = cachedUmaString; - break; - } - } - - Set<String> setToWriteBack = new HashSet<>(cachedUmaStrings); - CachedUmaEntry entry = null; - if (existingEntry != null) { - entry = CachedUmaEntry.parseEntry(existingEntry); - if (entry == null) { - entry = new CachedUmaEntry(event, value, 1); - } - setToWriteBack.remove(existingEntry); - entry.increment(); - } else { - entry = new CachedUmaEntry(event, value, 1); - } - - setToWriteBack.add(entry.toString()); - updateCachedUma(prefs, setToWriteBack); - } - - @VisibleForTesting - static Set<String> getCachedUmaEntries(SharedPreferences prefs) { - Set<String> cachedUmaEntries = prefs.getStringSet(KEY_CACHED_UMA, new HashSet<>()); - return sanitizeEntrySet(cachedUmaEntries); - } - - @VisibleForTesting - static void updateCachedUma(SharedPreferences prefs, Set<String> cachedUma) { - ThreadUtils.assertOnUiThread(); - SharedPreferences.Editor editor = prefs.edit(); - editor.putStringSet(KEY_CACHED_UMA, sanitizeEntrySet(cachedUma)); - editor.apply(); - } - - void assertNativeIsLoaded() { - assert LibraryLoader.getInstance().isInitialized(); - } - - private static Set<String> sanitizeEntrySet(Set<String> set) { - if (set != null && set.contains(null)) { - set.remove(null); - } - return set; - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BundleToPersistableBundleConverter.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BundleToPersistableBundleConverter.java deleted file mode 100644 index 0e16236e37e..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BundleToPersistableBundleConverter.java +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2017 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.components.background_task_scheduler.internal; - -import android.annotation.TargetApi; -import android.os.Build; -import android.os.Bundle; -import android.os.PersistableBundle; - -import androidx.annotation.NonNull; - -import java.util.HashSet; -import java.util.Set; - -/** - * Converts from {@link Bundle} to {@link PersistableBundle}. - * - * The {@link android.app.job.JobScheduler} API requires the use of {@link PersistableBundle} in - * the {@link android.app.job.JobInfo}, but that was added in API 21 (Lollipop). A later change - * related to booleans means that this class required API 22 (Lollipop MR1). - * the API of the {@link BackgroundTaskScheduler} needs to take a {@link Bundle}, but convert it to - * a {@link PersistableBundle} in the case of using {@link android.app.job.JobScheduler} as the - * backend for scheduling. - */ -@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1) -class BundleToPersistableBundleConverter { - /** - * A Result which contains the resulting {@link PersistableBundle} after a conversion, and also - * contains a set of all the failed keys. - */ - static class Result { - @NonNull - private final PersistableBundle mBundle; - @NonNull - private final Set<String> mFailedKeys; - - private Result(@NonNull PersistableBundle bundle, @NonNull Set<String> failedKeys) { - mBundle = bundle; - mFailedKeys = failedKeys; - } - - boolean hasErrors() { - return mFailedKeys.size() > 0; - } - - @NonNull - PersistableBundle getPersistableBundle() { - return mBundle; - } - - @NonNull - Set<String> getFailedKeys() { - return mFailedKeys; - } - - String getFailedKeysErrorString() { - StringBuilder sb = new StringBuilder(); - sb.append("{"); - boolean first = true; - for (String key : mFailedKeys) { - if (!first) sb.append(", "); - first = false; - - sb.append(key); - } - sb.append("}"); - return sb.toString(); - } - } - - /** - * Copy all entries in the {@link Bundle} that can be part of a {@link PersistableBundle}. - * - * @param bundle the {@link Bundle} to convert. - * @return a result object contain the resulting {@link PersistableBundle} and whether any of - * the keys failed. - */ - static Result convert(Bundle bundle) { - PersistableBundle persistableBundle = new PersistableBundle(); - Set<String> failedKeys = new HashSet<>(); - for (String key : bundle.keySet()) { - Object obj = bundle.get(key); - if (obj == null) { - persistableBundle.putString(key, null); - } else if (obj instanceof Boolean) { - persistableBundle.putBoolean(key, (Boolean) obj); - } else if (obj instanceof boolean[]) { - persistableBundle.putBooleanArray(key, (boolean[]) obj); - } else if (obj instanceof Double) { - persistableBundle.putDouble(key, (Double) obj); - } else if (obj instanceof double[]) { - persistableBundle.putDoubleArray(key, (double[]) obj); - } else if (obj instanceof Integer) { - persistableBundle.putInt(key, (Integer) obj); - } else if (obj instanceof int[]) { - persistableBundle.putIntArray(key, (int[]) obj); - } else if (obj instanceof Long) { - persistableBundle.putLong(key, (Long) obj); - } else if (obj instanceof long[]) { - persistableBundle.putLongArray(key, (long[]) obj); - } else if (obj instanceof String) { - persistableBundle.putString(key, (String) obj); - } else if (obj instanceof String[]) { - persistableBundle.putStringArray(key, (String[]) obj); - } else { - failedKeys.add(key); - } - } - return new Result(persistableBundle, failedKeys); - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/ExtrasToProtoConverter.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/ExtrasToProtoConverter.java deleted file mode 100644 index 7351475e5a2..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/ExtrasToProtoConverter.java +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright 2019 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.components.background_task_scheduler.internal; - -import android.os.Bundle; - -import org.chromium.base.Log; - -import java.util.ArrayList; -import java.util.List; - -/** - * Converts the extras from {@link Bundle} to the specific proto representation in - * {@link ScheduledTaskProto.ScheduledTask}. - */ -public final class ExtrasToProtoConverter { - private static final String TAG = "BTSExtrasC"; - - private ExtrasToProtoConverter() {} - - /** - * Converts information stored in a {@link Bundle} to its proto buffer representation to be - * stored by {@link BackgroundTaskSchedulerPrefs}. In case null values are passed, they are - * stored as null Strings. - * - * @param extras the extras stored for the {@link BackgroundTask}. - * @return a list of proto messages representing each extra. - */ - static List<ScheduledTaskProto.ScheduledTask.ExtraItem> convertExtrasToProtoExtras( - Bundle extras) { - List<ScheduledTaskProto.ScheduledTask.ExtraItem> protoExtras = new ArrayList<>(); - - for (String key : extras.keySet()) { - Object obj = extras.get(key); - - ScheduledTaskProto.ScheduledTask.ExtraItem.Type type; - List<ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue> values = new ArrayList<>(); - - if (obj instanceof Boolean) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.SINGLE; - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setBooleanValue((Boolean) obj) - .build()); - } else if (obj instanceof boolean[]) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.BOOLEAN_ARRAY; - boolean[] bundleValues = extras.getBooleanArray(key); - for (int i = 0; i < bundleValues.length; i++) { - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setBooleanValue(bundleValues[i]) - .build()); - } - } else if (obj instanceof Double) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.SINGLE; - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setDoubleValue((Double) obj) - .build()); - } else if (obj instanceof double[]) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.DOUBLE_ARRAY; - double[] bundleValues = extras.getDoubleArray(key); - for (int i = 0; i < bundleValues.length; i++) { - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setDoubleValue(bundleValues[i]) - .build()); - } - } else if (obj instanceof Integer) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.SINGLE; - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setIntValue((Integer) obj) - .build()); - } else if (obj instanceof int[]) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.INT_ARRAY; - int[] bundleValues = extras.getIntArray(key); - for (int i = 0; i < bundleValues.length; i++) { - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setIntValue(bundleValues[i]) - .build()); - } - } else if (obj instanceof Long) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.SINGLE; - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setLongValue((Long) obj) - .build()); - } else if (obj instanceof long[]) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.LONG_ARRAY; - long[] bundleValues = extras.getLongArray(key); - for (int i = 0; i < bundleValues.length; i++) { - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setLongValue(bundleValues[i]) - .build()); - } - } else if (obj instanceof String) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.SINGLE; - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setStringValue((String) obj) - .build()); - } else if (obj instanceof String[]) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.STRING_ARRAY; - String[] bundleValues = extras.getStringArray(key); - for (int i = 0; i < bundleValues.length; i++) { - values.add(ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue.newBuilder() - .setStringValue(bundleValues[i]) - .build()); - } - } else if (obj == null) { - type = ScheduledTaskProto.ScheduledTask.ExtraItem.Type.NULL; - } else { - Log.e(TAG, "Value not in the list of supported extras for key " + key + ": " + obj); - continue; - } - - protoExtras.add(ScheduledTaskProto.ScheduledTask.ExtraItem.newBuilder() - .setKey(key) - .setType(type) - .addAllValues(values) - .build()); - } - - return protoExtras; - } - - /** - * Converts information stored in the proto buffer to a {@link Bundle} to be used by the - * {@link BackgroundTask}. - * - * @param protoExtras list of {@link ScheduledTaskProto.ScheduledTask.ExtraItem} objects that - * store the extras for the {@link BackgroundTask}. - * @return a {@link Bundle} object with all the extras. - */ - static Bundle convertProtoExtrasToExtras( - List<ScheduledTaskProto.ScheduledTask.ExtraItem> protoExtras) { - Bundle extras = new Bundle(); - - for (ScheduledTaskProto.ScheduledTask.ExtraItem protoExtra : protoExtras) { - List<ScheduledTaskProto.ScheduledTask.ExtraItem.ExtraValue> protoValues = - protoExtra.getValuesList(); - - switch (protoExtra.getType()) { - case SINGLE: - switch (protoValues.get(0).getOneofValueCase()) { - case BOOLEAN_VALUE: - extras.putBoolean( - protoExtra.getKey(), protoValues.get(0).getBooleanValue()); - break; - case DOUBLE_VALUE: - extras.putDouble( - protoExtra.getKey(), protoValues.get(0).getDoubleValue()); - break; - case INT_VALUE: - extras.putInt(protoExtra.getKey(), protoValues.get(0).getIntValue()); - break; - case LONG_VALUE: - extras.putLong(protoExtra.getKey(), protoValues.get(0).getLongValue()); - break; - case STRING_VALUE: - extras.putString( - protoExtra.getKey(), protoValues.get(0).getStringValue()); - break; - default: - Log.e(TAG, - "For key " + protoExtra.getKey() + " no value was set," - + " even though the extra was not null."); - return null; - } - break; - case BOOLEAN_ARRAY: - boolean[] booleanValues = new boolean[protoValues.size()]; - for (int i = 0; i < protoValues.size(); i++) { - booleanValues[i] = protoValues.get(i).getBooleanValue(); - } - extras.putBooleanArray(protoExtra.getKey(), booleanValues); - break; - case DOUBLE_ARRAY: - double[] doubleValues = new double[protoValues.size()]; - for (int i = 0; i < protoValues.size(); i++) { - doubleValues[i] = protoValues.get(i).getDoubleValue(); - } - extras.putDoubleArray(protoExtra.getKey(), doubleValues); - break; - case INT_ARRAY: - int[] intValues = new int[protoValues.size()]; - for (int i = 0; i < protoValues.size(); i++) { - intValues[i] = protoValues.get(i).getIntValue(); - } - extras.putIntArray(protoExtra.getKey(), intValues); - break; - case LONG_ARRAY: - long[] longValues = new long[protoValues.size()]; - for (int i = 0; i < protoValues.size(); i++) { - longValues[i] = protoValues.get(i).getLongValue(); - } - extras.putLongArray(protoExtra.getKey(), longValues); - break; - case STRING_ARRAY: - String[] stringValues = new String[protoValues.size()]; - for (int i = 0; i < protoValues.size(); i++) { - stringValues[i] = protoValues.get(i).getStringValue(); - } - extras.putStringArray(protoExtra.getKey(), stringValues); - break; - case NULL: - extras.putString(protoExtra.getKey(), null); - break; - default: - Log.e(TAG, - "For key " + protoExtra.getKey() - + " an invalid type was found: " + protoExtra.getType()); - } - } - - return extras; - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/NativeTaskScheduler.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/NativeTaskScheduler.java deleted file mode 100644 index bf79a17add1..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/NativeTaskScheduler.java +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2020 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.components.background_task_scheduler.internal; - -import org.chromium.base.ContextUtils; -import org.chromium.base.annotations.CalledByNative; -import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory; -import org.chromium.components.background_task_scheduler.TaskInfo; - -/** - * Invokes {@link BackgroundTaskScheduler} methods for the tasks scheduled through native interface. - */ -public class NativeTaskScheduler { - @CalledByNative - private static boolean schedule(TaskInfo taskInfo) { - return BackgroundTaskSchedulerFactory.getScheduler().schedule( - ContextUtils.getApplicationContext(), taskInfo); - } - - @CalledByNative - private static void cancel(int taskId) { - BackgroundTaskSchedulerFactory.getScheduler().cancel( - ContextUtils.getApplicationContext(), taskId); - } -} diff --git a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/TaskInfoBridge.java b/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/TaskInfoBridge.java deleted file mode 100644 index 99704ba583d..00000000000 --- a/chromium/components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/TaskInfoBridge.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2020 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.components.background_task_scheduler.internal; - -import android.os.Bundle; - -import org.chromium.base.annotations.CalledByNative; -import org.chromium.components.background_task_scheduler.TaskInfo; - -/** - * Converts native task info params to Java {@link TaskInfo}. - */ -public class TaskInfoBridge { - @CalledByNative - private static TaskInfo.TimingInfo createPeriodicInfo( - long intervalMs, long flexMs, boolean expiresAfterWindowEndTime) { - TaskInfo.PeriodicInfo.Builder builder = - TaskInfo.PeriodicInfo.create() - .setIntervalMs(intervalMs) - .setExpiresAfterWindowEndTime(expiresAfterWindowEndTime); - if (flexMs > 0) builder.setFlexMs(flexMs); - return builder.build(); - } - - @CalledByNative - private static TaskInfo.TimingInfo createOneOffInfo( - long windowStartTimeMs, long windowEndTimeMs, boolean expiresAfterWindowEndTime) { - TaskInfo.OneOffInfo.Builder builder = - TaskInfo.OneOffInfo.create() - .setWindowEndTimeMs(windowEndTimeMs) - .setExpiresAfterWindowEndTime(expiresAfterWindowEndTime); - if (windowStartTimeMs > 0) builder.setWindowStartTimeMs(windowStartTimeMs); - return builder.build(); - } - - @CalledByNative - private static TaskInfo.TimingInfo createExactInfo(long triggerAtMs) { - TaskInfo.TimingInfo timingInfo = - TaskInfo.ExactInfo.create().setTriggerAtMs(triggerAtMs).build(); - return timingInfo; - } - - @CalledByNative - private static TaskInfo createTaskInfo( - int taskId, TaskInfo.TimingInfo timingInfo, String extras) { - Bundle bundle = new Bundle(); - bundle.putString(TaskInfo.SERIALIZED_TASK_EXTRAS, extras); - TaskInfo taskInfo = TaskInfo.createTask(taskId, timingInfo) - .setRequiredNetworkType(TaskInfo.NetworkType.ANY) - .setRequiresCharging(false) - .setUpdateCurrent(true) - .setIsPersisted(true) - .setExtras(bundle) - .build(); - return taskInfo; - } -} |