Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(594)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java

Issue 2825783003: [Android] Native initialization task for BackgroundTaskScheduler (Closed)
Patch Set: Addressing CR feedback Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/android/java_sources.gni » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java b/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..e4db6141e79e7496e2b2f98e9b07a4549f845176
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTask.java
@@ -0,0 +1,185 @@
+// 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.chrome.browser.background_task_scheduler;
+
+import android.content.Context;
+import android.support.annotation.IntDef;
+
+import org.chromium.base.Log;
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.library_loader.LibraryProcessType;
+import org.chromium.base.library_loader.ProcessInitException;
+import org.chromium.chrome.browser.init.BrowserParts;
+import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
+import org.chromium.chrome.browser.init.EmptyBrowserParts;
+import org.chromium.components.background_task_scheduler.BackgroundTask;
+import org.chromium.components.background_task_scheduler.TaskParameters;
+import org.chromium.content.browser.BrowserStartupController;
+
+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 {
+ private static final String TAG = "BTS_NativeBkgrdTask";
+
+ /** Specifies which action to take following onStartTaskBeforeNativeLoaded. */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({LOAD_NATIVE, RESCHEDULE, DONE})
+ public @interface StartBeforeNativeResult {}
+ /** Task should continue to load native parts of browser. */
+ public static final int LOAD_NATIVE = 0;
+ /** Task should request rescheduling, without loading native parts of browser. */
+ public static final int RESCHEDULE = 1;
+ /** Task should neither load native parts of browser nor reschedule. */
+ public static final int DONE = 2;
+
+ protected NativeBackgroundTask() {}
+
+ /** Indicates that the task has already been stopped. Should only be accessed on UI Thread. */
+ private boolean mTaskStopped;
+
+ @Override
+ public final boolean onStartTask(
+ Context context, TaskParameters taskParameters, TaskFinishedCallback callback) {
+ ThreadUtils.assertOnUiThread();
+ @StartBeforeNativeResult
+ int beforeNativeResult = onStartTaskBeforeNativeLoaded(context, taskParameters, callback);
+
+ if (beforeNativeResult == DONE) return false;
+
+ if (beforeNativeResult == RESCHEDULE) {
+ ThreadUtils.postOnUiThread(buildRescheduleRunnable(callback));
+ return true;
+ }
+
+ assert beforeNativeResult == LOAD_NATIVE;
+ runWithNative(context, buildStartWithNativeRunnable(context, taskParameters, callback),
+ buildRescheduleRunnable(callback));
+ return true;
+ }
+
+ @Override
+ public final boolean onStopTask(Context context, TaskParameters taskParameters) {
+ ThreadUtils.assertOnUiThread();
+ mTaskStopped = true;
+ if (isNativeLoaded()) {
+ 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 context the current context
+ * @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.
+ */
+ protected final void runWithNative(final Context context,
+ final Runnable startWithNativeRunnable, final Runnable rescheduleRunnable) {
+ if (isNativeLoaded()) {
+ ThreadUtils.postOnUiThread(startWithNativeRunnable);
+ return;
+ }
+
+ final BrowserParts parts = new EmptyBrowserParts() {
+ @Override
+ public void finishNativeInitialization() {
+ ThreadUtils.postOnUiThread(startWithNativeRunnable);
+ }
+ @Override
+ public void onStartupFailure() {
+ ThreadUtils.postOnUiThread(rescheduleRunnable);
+ }
+ };
+
+ ThreadUtils.postOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ // If task was stopped before we got here, don't start native initialization.
+ if (mTaskStopped) return;
+ try {
+ ChromeBrowserInitializer.getInstance(context).handlePreNativeStartup(parts);
+
+ ChromeBrowserInitializer.getInstance(context).handlePostNativeStartup(
+ true /* isAsync */, parts);
+ } catch (ProcessInitException e) {
+ Log.e(TAG, "ProcessInitException while starting the browser process.");
+ rescheduleRunnable.run();
+ return;
+ }
+ }
+ });
+ }
+
+ /**
+ * 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. */
+ private boolean isNativeLoaded() {
+ return BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER)
+ .isStartupSuccessfullyCompleted();
+ }
+}
« no previous file with comments | « no previous file | chrome/android/java_sources.gni » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698