Commit f9c846ab authored by Gustav Sennton's avatar Gustav Sennton Committed by Commit Bot

Move UI-thread-posting into WebViewChromiumRunQueue.

A lot of classes in the glue depend on the
WebViewChromiumFactoryProvider because they need to post tasks to the UI
thread.
In this CL we move that task-posting functionality into
WebViewChromiumRunQueue to allow glue classes (including classes shared
between the webkit glue and the support library glue) to depend on
WebViewChromiumRunQueue instead of WebViewChromiumFactoryProvider.

We're leaving the original methods in WebViewChromiumFactoryProvider for
now to avoid having to change all callers at the same time.

Bug: 813089
Change-Id: I5f01179b1917df9aaa345f53f2292bcab8238368
Reviewed-on: https://chromium-review.googlesource.com/924184Reviewed-by: default avatarBo <boliu@chromium.org>
Commit-Queue: Gustav Sennton <gsennton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537345}
parent 465eba70
...@@ -49,7 +49,6 @@ import java.io.File; ...@@ -49,7 +49,6 @@ import java.io.File;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask; import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
/** /**
* Entry point to the WebView. The system framework talks to this class to get instances of the * Entry point to the WebView. The system framework talks to this class to get instances of the
...@@ -72,32 +71,15 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider { ...@@ -72,32 +71,15 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
return mRunQueue; return mRunQueue;
} }
private <T> T runBlockingFuture(FutureTask<T> task) {
if (!mAwInit.hasStarted()) throw new RuntimeException("Must be started before we block!");
if (ThreadUtils.runningOnUiThread()) {
throw new IllegalStateException("This method should only be called off the UI thread");
}
mRunQueue.addTask(task);
try {
return task.get(4, TimeUnit.SECONDS);
} catch (java.util.concurrent.TimeoutException e) {
throw new RuntimeException("Probable deadlock detected due to WebView API being called "
+ "on incorrect thread while the UI thread is blocked.", e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// We have a 4 second timeout to try to detect deadlocks to detect and aid in debuggin // We have a 4 second timeout to try to detect deadlocks to detect and aid in debuggin
// deadlocks. // deadlocks.
// Do not call this method while on the UI thread! // Do not call this method while on the UI thread!
/* package */ void runVoidTaskOnUiThreadBlocking(Runnable r) { /* package */ void runVoidTaskOnUiThreadBlocking(Runnable r) {
FutureTask<Void> task = new FutureTask<Void>(r, null); mRunQueue.runVoidTaskOnUiThreadBlocking(r);
runBlockingFuture(task);
} }
/* package */ <T> T runOnUiThreadBlocking(Callable<T> c) { /* package */ <T> T runOnUiThreadBlocking(Callable<T> c) {
return runBlockingFuture(new FutureTask<T>(c)); return mRunQueue.runBlockingFuture(new FutureTask<T>(c));
} }
/* package */ void addTask(Runnable task) { /* package */ void addTask(Runnable task) {
......
...@@ -7,7 +7,10 @@ package org.chromium.android_webview; ...@@ -7,7 +7,10 @@ package org.chromium.android_webview;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
/** /**
* Queue used for running tasks, initiated through WebView APIs, on the UI thread. * Queue used for running tasks, initiated through WebView APIs, on the UI thread.
...@@ -62,4 +65,33 @@ public class WebViewChromiumRunQueue { ...@@ -62,4 +65,33 @@ public class WebViewChromiumRunQueue {
public boolean chromiumHasStarted() { public boolean chromiumHasStarted() {
return mChromiumHasStartedCallable.hasStarted(); return mChromiumHasStartedCallable.hasStarted();
} }
public <T> T runBlockingFuture(FutureTask<T> task) {
if (!chromiumHasStarted()) throw new RuntimeException("Must be started before we block!");
if (ThreadUtils.runningOnUiThread()) {
throw new IllegalStateException("This method should only be called off the UI thread");
}
addTask(task);
try {
return task.get(4, TimeUnit.SECONDS);
} catch (java.util.concurrent.TimeoutException e) {
throw new RuntimeException("Probable deadlock detected due to WebView API being called "
+ "on incorrect thread while the UI thread is blocked.",
e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// We have a 4 second timeout to try to detect deadlocks to detect and aid in debugging
// deadlocks.
// Do not call this method while on the UI thread!
public void runVoidTaskOnUiThreadBlocking(Runnable r) {
FutureTask<Void> task = new FutureTask<Void>(r, null);
runBlockingFuture(task);
}
public <T> T runOnUiThreadBlocking(Callable<T> c) {
return runBlockingFuture(new FutureTask<T>(c));
}
} }
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