Commit 6f908c81 authored by Karolina Soltys's avatar Karolina Soltys Committed by Commit Bot

[scheduler] Migration from ThreadUtils to BrowserThreadUtils.

I created a new class, BrowserThreadUtils, in content_public/browser. It
has all of the functionalities of base/ThreadUtils that we want to
retain, but uses PostTask. Running blocking tasks has been moved to
a new class TestThreadUtils, because it is not supposed to be used by
production code.

This is part of an ongoing effort to unify Java and C++ scheduling:
http://go/migrating-threadutils-to-posttask

Bug: 863341
Change-Id: Id7da815b63dd2f5c57b01a093401e1c73a5d57db
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1489243
Commit-Queue: Karolina Soltys <ksolt@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Auto-Submit: Karolina Soltys <ksolt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638208}
parent 3c3b0e53
...@@ -116,6 +116,7 @@ android_library("content_java") { ...@@ -116,6 +116,7 @@ android_library("content_java") {
"java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java", "java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java",
"java/src/org/chromium/content/browser/BindingManager.java", "java/src/org/chromium/content/browser/BindingManager.java",
"java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java", "java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java",
"java/src/org/chromium/content/browser/BrowserThreadUtilsImpl.java",
"java/src/org/chromium/content/browser/ServicificationStartupUma.java", "java/src/org/chromium/content/browser/ServicificationStartupUma.java",
"java/src/org/chromium/content/browser/ChildProcessCreationParamsImpl.java", "java/src/org/chromium/content/browser/ChildProcessCreationParamsImpl.java",
"java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java", "java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java",
...@@ -241,6 +242,7 @@ android_library("content_java") { ...@@ -241,6 +242,7 @@ android_library("content_java") {
"java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java", "java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java",
"java/src/org/chromium/content_public/browser/BrowserStartupController.java", "java/src/org/chromium/content_public/browser/BrowserStartupController.java",
"java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java", "java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java",
"java/src/org/chromium/content_public/browser/BrowserThreadUtils.java",
"java/src/org/chromium/content_public/browser/ContentViewStatics.java", "java/src/org/chromium/content_public/browser/ContentViewStatics.java",
"java/src/org/chromium/content_public/browser/DeviceUtils.java", "java/src/org/chromium/content_public/browser/DeviceUtils.java",
"java/src/org/chromium/content_public/browser/InputMethodManagerWrapper.java", "java/src/org/chromium/content_public/browser/InputMethodManagerWrapper.java",
......
// 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.content.browser;
import android.os.Handler;
import android.os.Looper;
import org.chromium.base.task.PostTask;
import org.chromium.content_public.browser.UiThreadTaskTraits;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import javax.annotation.concurrent.GuardedBy;
/**
* Helper methods to deal with UI thread related tasks.
*/
public class BrowserThreadUtilsImpl {
private BrowserThreadUtilsImpl() {}
private static final Object sLock = new Object();
@GuardedBy("sLock")
private static boolean sWillOverride;
@GuardedBy("sLock")
private static Handler sUiThreadHandler;
private static boolean sThreadAssertsDisabled;
public static void setWillOverrideUiThread(boolean willOverrideUiThread) {
synchronized (sLock) {
sWillOverride = willOverrideUiThread;
}
}
public static void setUiThread(Looper looper) {
synchronized (sLock) {
if (looper == null) {
// Used to reset the looper after tests.
sUiThreadHandler = null;
return;
}
if (sUiThreadHandler != null && sUiThreadHandler.getLooper() != looper) {
throw new RuntimeException("UI thread looper is already set to "
+ sUiThreadHandler.getLooper() + " (Main thread looper is "
+ Looper.getMainLooper() + "), cannot set to new looper " + looper);
} else {
sUiThreadHandler = new Handler(looper);
}
}
}
public static Handler getUiThreadHandler() {
synchronized (sLock) {
if (sUiThreadHandler == null) {
if (sWillOverride) {
throw new RuntimeException("Did not yet override the UI thread");
}
sUiThreadHandler = new Handler(Looper.getMainLooper());
}
return sUiThreadHandler;
}
}
public static Looper getUiThreadLooper() {
return getUiThreadHandler().getLooper();
}
/**
* Run the supplied FutureTask on the main thread. The task will run immediately if the current
* thread is the main thread.
*
* @param task The FutureTask to run
* @return The queried task (to aid inline construction)
*/
public static <T> FutureTask<T> runOnUiThread(FutureTask<T> task) {
PostTask.runOrPostTask(UiThreadTaskTraits.DEFAULT, task);
return task;
}
/**
* Run the supplied Callable on the main thread. The task will run immediately if the current
* thread is the main thread.
*
* @param c The Callable to run
* @return A FutureTask wrapping the callable to retrieve results
*/
public static <T> FutureTask<T> runOnUiThread(Callable<T> c) {
return runOnUiThread(new FutureTask<T>(c));
}
/**
* Throw an exception (when DCHECKs are enabled) if currently not running on the UI thread.
*
* Can be disabled by setThreadAssertsDisabledForTesting(true).
*/
public static void assertOnUiThread() {
if (sThreadAssertsDisabled) return;
assert runningOnUiThread() : "Must be called on the UI thread.";
}
/**
* Throw an exception (regardless of build) if currently not running on the UI thread.
*
* Can be disabled by setThreadAssertsEnabledForTesting(false).
*
* @see #assertOnUiThread()
*/
public static void checkUiThread() {
if (!sThreadAssertsDisabled && !runningOnUiThread()) {
throw new IllegalStateException("Must be called on the UI thread.");
}
}
/**
* Throw an exception (when DCHECKs are enabled) if currently running on the UI thread.
*
* Can be disabled by setThreadAssertsDisabledForTesting(true).
*/
public static void assertOnBackgroundThread() {
if (sThreadAssertsDisabled) return;
assert !runningOnUiThread() : "Must be called on a thread other than UI.";
}
/**
* Disables thread asserts.
*
* Can be used by tests where code that normally runs multi-threaded is going to run
* single-threaded for the test (otherwise asserts that are valid in production would fail in
* those tests).
*/
public static void setThreadAssertsDisabledForTesting(boolean disabled) {
sThreadAssertsDisabled = disabled;
}
/**
* @return true iff the current thread is the main (UI) thread.
*/
public static boolean runningOnUiThread() {
return getUiThreadHandler().getLooper() == Looper.myLooper();
}
}
// 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.content_public.browser;
import android.os.Handler;
import android.os.Looper;
import org.chromium.content.browser.BrowserThreadUtilsImpl;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* Helper methods to deal with UI thread related tasks.
*/
public class BrowserThreadUtils {
private BrowserThreadUtils() {}
/**
* Sets a flag specifying that a new UI thread handler is being created to
* avoid creating it twice.
*/
public static void setWillOverrideUiThread(boolean willOverrideUiThread) {
BrowserThreadUtilsImpl.setWillOverrideUiThread(willOverrideUiThread);
}
/**
* Sets a specific Looper as the UI thread.
*
* @param The looper to be used as the UI thread.
*/
public static void setUiThread(Looper looper) {
BrowserThreadUtilsImpl.setUiThread(looper);
}
/**
* @return The Handler for the UI thread.
*/
public static Handler getUiThreadHandler() {
return BrowserThreadUtilsImpl.getUiThreadHandler();
}
/**
* @return The Looper for the UI thread.
*/
public static Looper getUiThreadLooper() {
return BrowserThreadUtilsImpl.getUiThreadLooper();
}
/**
* Run the supplied FutureTask on the main thread. The task will run immediately if the current
* thread is the main thread.
*
* @param task The FutureTask to run
* @return The queried task (to aid inline construction)
*/
public static <T> FutureTask<T> runOnUiThread(FutureTask<T> task) {
return BrowserThreadUtilsImpl.runOnUiThread(task);
}
/**
* Run the supplied Callable on the main thread. The task will run immediately if the current
* thread is the main thread.
*
* @param c The Callable to run
* @return A FutureTask wrapping the callable to retrieve results
*/
public static <T> FutureTask<T> runOnUiThread(Callable<T> c) {
return BrowserThreadUtilsImpl.runOnUiThread(c);
}
/**
* Throw an exception (when DCHECKs are enabled) if currently not running on the UI thread.
*
* Can be disabled by setThreadAssertsDisabledForTesting(true).
*/
public static void assertOnUiThread() {
BrowserThreadUtilsImpl.assertOnUiThread();
}
/**
* Throw an exception (regardless of build) if currently not running on the UI thread.
*
* Can be disabled by setThreadAssertsEnabledForTesting(false).
*
* @see #assertOnUiThread()
*/
public static void checkUiThread() {
BrowserThreadUtilsImpl.checkUiThread();
}
/**
* Throw an exception (when DCHECKs are enabled) if currently running on the UI thread.
*
* Can be disabled by setThreadAssertsDisabledForTesting(true).
*/
public static void assertOnBackgroundThread() {
BrowserThreadUtilsImpl.assertOnBackgroundThread();
}
/**
* @return true iff the current thread is the main (UI) thread.
*/
public static boolean runningOnUiThread() {
return BrowserThreadUtilsImpl.runningOnUiThread();
}
}
...@@ -51,6 +51,7 @@ android_library("content_java_test_support") { ...@@ -51,6 +51,7 @@ android_library("content_java_test_support") {
"javatests/src/org/chromium/content_public/browser/test/util/TestCallbackHelperContainer.java", "javatests/src/org/chromium/content_public/browser/test/util/TestCallbackHelperContainer.java",
"javatests/src/org/chromium/content_public/browser/test/util/TestInputMethodManagerWrapper.java", "javatests/src/org/chromium/content_public/browser/test/util/TestInputMethodManagerWrapper.java",
"javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java", "javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java",
"javatests/src/org/chromium/content_public/browser/test/util/TestThreadUtils.java",
"javatests/src/org/chromium/content_public/browser/test/util/TestTouchUtils.java", "javatests/src/org/chromium/content_public/browser/test/util/TestTouchUtils.java",
"javatests/src/org/chromium/content_public/browser/test/util/TestWebContentsObserver.java", "javatests/src/org/chromium/content_public/browser/test/util/TestWebContentsObserver.java",
"javatests/src/org/chromium/content_public/browser/test/util/TouchCommon.java", "javatests/src/org/chromium/content_public/browser/test/util/TouchCommon.java",
......
// 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.content_public.browser.test.util;
import org.chromium.base.task.PostTask;
import org.chromium.content.browser.BrowserThreadUtilsImpl;
import org.chromium.content_public.browser.UiThreadTaskTraits;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* Helper methods to deal with threading related tasks.
*/
public class TestThreadUtils {
/**
* Run the supplied Runnable on the main thread. The method will block until the Runnable
* completes.
*
* @param r The Runnable to run.
*/
public static void runOnUiThreadBlocking(final Runnable r) {
if (BrowserThreadUtilsImpl.runningOnUiThread()) {
r.run();
} else {
FutureTask<Void> task = new FutureTask<Void>(r, null);
PostTask.postTask(UiThreadTaskTraits.DEFAULT, task);
try {
task.get();
} catch (Exception e) {
throw new RuntimeException("Exception occurred while waiting for runnable", e);
}
}
}
/**
* Run the supplied Callable on the main thread, wrapping any exceptions in a RuntimeException.
* The method will block until the Callable completes.
*
* @param c The Callable to run
* @return The result of the callable
*/
public static <T> T runOnUiThreadBlockingNoException(Callable<T> c) {
try {
return runOnUiThreadBlocking(c);
} catch (ExecutionException e) {
throw new RuntimeException("Error occurred waiting for callable", e);
}
}
/**
* Run the supplied Callable on the main thread, The method will block until the Callable
* completes.
*
* @param c The Callable to run
* @return The result of the callable
* @throws ExecutionException c's exception
*/
public static <T> T runOnUiThreadBlocking(Callable<T> c) throws ExecutionException {
FutureTask<T> task = new FutureTask<T>(c);
BrowserThreadUtilsImpl.runOnUiThread(task);
try {
return task.get();
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted waiting for callable", e);
}
}
/**
* Disables thread asserts.
*
* Can be used by tests where code that normally runs multi-threaded is going to run
* single-threaded for the test (otherwise asserts that are valid in production would fail in
* those tests).
*/
public static void setThreadAssertsDisabled(boolean disabled) {
BrowserThreadUtilsImpl.setThreadAssertsDisabledForTesting(disabled);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment