Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.chrome.browser.background_task_scheduler; | |
| 6 | |
| 7 import android.content.Context; | |
| 8 import android.support.annotation.IntDef; | |
| 9 | |
| 10 import org.chromium.base.Log; | |
| 11 import org.chromium.base.ThreadUtils; | |
| 12 import org.chromium.base.library_loader.LibraryProcessType; | |
| 13 import org.chromium.base.library_loader.ProcessInitException; | |
| 14 import org.chromium.chrome.browser.init.BrowserParts; | |
| 15 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; | |
| 16 import org.chromium.chrome.browser.init.EmptyBrowserParts; | |
| 17 import org.chromium.components.background_task_scheduler.BackgroundTask; | |
| 18 import org.chromium.components.background_task_scheduler.TaskParameters; | |
| 19 import org.chromium.content.browser.BrowserStartupController; | |
| 20 | |
| 21 import java.lang.annotation.Retention; | |
| 22 import java.lang.annotation.RetentionPolicy; | |
| 23 | |
| 24 /** | |
| 25 * Base class implementing {@link BackgroundTask} that adds native initializatio n, ensuring that | |
| 26 * tasks are run after Chrome is successfully started. | |
| 27 * Background tasks that require native parts of browser to be started should ex tend this class | |
| 28 * instead of implementing the interface directly. {@link #onStartTaskWithNative (Context, | |
| 29 * TaskParameters, TaskFinishedCallback)} method should be implemented instead o f {@link | |
| 30 * #onStartTask(Context, TaskParameters, TaskFinishedCallback)}. | |
|
Ted C
2017/05/23 20:52:55
I'd argue the last sentence isn't necessary, onSta
fgorski
2017/05/23 21:35:02
Done.
| |
| 31 */ | |
| 32 public abstract class NativeBackgroundTask implements BackgroundTask { | |
| 33 private static final String TAG = "BTS_NativeBkgrdTask"; | |
| 34 | |
| 35 /** Specifies which action to take following onStartTaskBeforeNativeLoaded. */ | |
| 36 @Retention(RetentionPolicy.SOURCE) | |
| 37 @IntDef({LOAD_NATIVE, RESCHEDULE, DONE}) | |
| 38 public @interface StartBeforeNativeResult {} | |
| 39 /** Task should continue to load native parts of browser. */ | |
| 40 public static final int LOAD_NATIVE = 0; | |
| 41 /** Task should request rescheduling, without loading native parts of browse r. */ | |
| 42 public static final int RESCHEDULE = 1; | |
| 43 /** Task should neither load native parts of browser nor reschedule. */ | |
| 44 public static final int DONE = 2; | |
| 45 | |
| 46 protected NativeBackgroundTask() {} | |
| 47 | |
| 48 private boolean mTaskStopped; | |
|
nyquist
2017/05/23 20:14:28
Nit: Could you add a comment that this must only e
fgorski
2017/05/23 21:35:02
Done.
| |
| 49 | |
| 50 @Override | |
| 51 public final boolean onStartTask( | |
| 52 Context context, TaskParameters taskParameters, TaskFinishedCallback callback) { | |
| 53 @StartBeforeNativeResult | |
| 54 int beforeNativeResult = onStartTaskBeforeNativeLoaded(context, taskPara meters, callback); | |
| 55 | |
| 56 if (beforeNativeResult == DONE) return false; | |
| 57 | |
| 58 if (beforeNativeResult == RESCHEDULE) { | |
| 59 ThreadUtils.postOnUiThread(buildRescheduleRunnable(callback)); | |
| 60 return true; | |
| 61 } | |
| 62 | |
| 63 assert beforeNativeResult == LOAD_NATIVE; | |
| 64 runWithNative(context, buildStartWithNativeRunnable(context, taskParamet ers, callback), | |
| 65 buildRescheduleRunnable(callback)); | |
| 66 return true; | |
| 67 } | |
| 68 | |
| 69 @Override | |
| 70 public final boolean onStopTask(Context context, TaskParameters taskParamete rs) { | |
| 71 mTaskStopped = true; | |
| 72 if (isNativeLoaded()) { | |
| 73 return onStopTaskWithNative(context, taskParameters); | |
| 74 } else { | |
| 75 return onStopTaskBeforeNativeLoaded(context, taskParameters); | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 /** | |
| 80 * Ensure that native is started before running the task. If native fails to start, the task is | |
| 81 * going to be rescheduled, by issuing a {@see TaskFinishedCallback} with pa rameter set to | |
| 82 * <c>true</c>. | |
| 83 * | |
| 84 * @param context the current context | |
| 85 * @param startWithNativeRunnable A runnable that will execute #onStartTaskW ithNative, after the | |
| 86 * native is loaded. | |
| 87 * @param rescheduleRunnable A runnable that will be called to reschedule th e task in case | |
| 88 * native initialization fails. | |
| 89 */ | |
| 90 protected final void runWithNative(final Context context, | |
| 91 final Runnable startWithNativeRunnable, final Runnable rescheduleRun nable) { | |
| 92 if (isNativeLoaded()) { | |
| 93 ThreadUtils.postOnUiThread(startWithNativeRunnable); | |
| 94 return; | |
| 95 } | |
| 96 | |
| 97 final BrowserParts parts = new EmptyBrowserParts() { | |
| 98 @Override | |
| 99 public void finishNativeInitialization() { | |
| 100 startWithNativeRunnable.run(); | |
| 101 } | |
| 102 @Override | |
| 103 public void onStartupFailure() { | |
| 104 rescheduleRunnable.run(); | |
| 105 } | |
| 106 }; | |
| 107 | |
| 108 ThreadUtils.postOnUiThread(new Runnable() { | |
| 109 @Override | |
| 110 public void run() { | |
| 111 try { | |
| 112 ChromeBrowserInitializer.getInstance(context).handlePreNativ eStartup(parts); | |
|
Ted C
2017/05/23 20:52:55
Should this do:
if (mTaskStopped) return;
fgorski
2017/05/23 21:35:02
I am putting it before the try, presuming you didn
Ted C
2017/05/23 22:06:43
Nope, that's right
| |
| 113 ChromeBrowserInitializer.getInstance(context).handlePostNati veStartup( | |
| 114 true /* isAsync */, parts); | |
| 115 } catch (ProcessInitException e) { | |
| 116 Log.e(TAG, "ProcessInitException while starting the browser process."); | |
| 117 if (!mTaskStopped) { | |
| 118 rescheduleRunnable.run(); | |
| 119 } | |
| 120 return; | |
| 121 } | |
| 122 } | |
| 123 }); | |
| 124 } | |
| 125 | |
| 126 /** | |
| 127 * Method that should be implemented in derived classes to provide implement ation of {@link | |
| 128 * BackgroundTask#onStartTask(Context, TaskParameters, TaskFinishedCallback) } run before native | |
| 129 * is loaded. Task implementing the method may decide to not load native if it hasn't been | |
| 130 * loaded yet, by returning DONE, meaning no more work is required for the t ask, or RESCHEDULE, | |
| 131 * meaning task needs to be immediately rescheduled. | |
| 132 * This method is guaranteed to be called before {@link #onStartTaskWithNati ve}. | |
| 133 */ | |
| 134 @StartBeforeNativeResult | |
| 135 protected abstract int onStartTaskBeforeNativeLoaded( | |
| 136 Context context, TaskParameters taskParameters, TaskFinishedCallback callback); | |
| 137 | |
| 138 /** | |
| 139 * Method that should be implemented in derived classes to provide implement ation of {@link | |
| 140 * BackgroundTask#onStartTask(Context, TaskParameters, TaskFinishedCallback) } when native is | |
| 141 * loaded. | |
| 142 * This method will not be called unless {@link #onStartTaskBeforeNativeLoad ed} returns | |
| 143 * LOAD_NATIVE. | |
| 144 */ | |
| 145 protected abstract void onStartTaskWithNative( | |
| 146 Context context, TaskParameters taskParameters, TaskFinishedCallback callback); | |
| 147 | |
| 148 /** Called by {@link #onStopTask} if native part of browser was not loaded. */ | |
| 149 protected abstract boolean onStopTaskBeforeNativeLoaded( | |
| 150 Context context, TaskParameters taskParameters); | |
| 151 | |
| 152 /** Called by {@link #onStopTask} if native part of browser was loaded. */ | |
| 153 protected abstract boolean onStopTaskWithNative(Context context, TaskParamet ers taskParameters); | |
| 154 | |
| 155 /** Builds a runnable rescheduling task. */ | |
| 156 private Runnable buildRescheduleRunnable(final TaskFinishedCallback callback ) { | |
| 157 return new Runnable() { | |
| 158 @Override | |
| 159 public void run() { | |
| 160 callback.taskFinished(true); | |
|
Ted C
2017/05/23 20:52:55
Same question as above. Should this do:
if (mTas
fgorski
2017/05/23 21:35:02
Done.
Good point. I went ahead and added checks in
| |
| 161 } | |
| 162 }; | |
| 163 } | |
| 164 | |
| 165 /** Builds a runnable starting task with native portion. */ | |
| 166 private Runnable buildStartWithNativeRunnable(final Context context, | |
| 167 final TaskParameters taskParameters, final TaskFinishedCallback call back) { | |
| 168 return new Runnable() { | |
| 169 @Override | |
| 170 public void run() { | |
| 171 onStartTaskWithNative(context, taskParameters, callback); | |
|
Ted C
2017/05/23 20:52:55
same about mTaskStopped?
fgorski
2017/05/23 21:35:02
Done.
| |
| 172 } | |
| 173 }; | |
| 174 } | |
| 175 | |
| 176 /** Whether the native part of the browser is loaded. */ | |
| 177 private boolean isNativeLoaded() { | |
| 178 return BrowserStartupController.get(LibraryProcessType.PROCESS_BROWSER) | |
| 179 .isStartupSuccessfullyCompleted(); | |
| 180 } | |
| 181 } | |
| OLD | NEW |