mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
Bug 802130 - Move assertOnThread functions to a new ThreadUtils class. r=mfinkle
This commit is contained in:
parent
ef2c6a1e5d
commit
82468ce27b
@ -18,6 +18,7 @@ import org.mozilla.gecko.updater.UpdateServiceHelper;
|
||||
import org.mozilla.gecko.util.GeckoBackgroundThread;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.GeckoEventResponder;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UiAsyncTask;
|
||||
|
||||
import org.json.JSONArray;
|
||||
@ -1372,6 +1373,8 @@ abstract public class GeckoApp
|
||||
((GeckoApplication)getApplication()).initialize();
|
||||
|
||||
mAppContext = this;
|
||||
ThreadUtils.setUiThread(Thread.currentThread());
|
||||
|
||||
Tabs.getInstance().attachToActivity(this);
|
||||
Favicons.getInstance().attachToContext(this);
|
||||
|
||||
@ -1632,6 +1635,7 @@ abstract public class GeckoApp
|
||||
|
||||
if (!mIsRestoringActivity) {
|
||||
sGeckoThread = new GeckoThread(intent, passedUri);
|
||||
ThreadUtils.setGeckoThread(sGeckoThread);
|
||||
}
|
||||
if (!ACTION_DEBUG.equals(action) &&
|
||||
GeckoThread.checkAndSetLaunchState(GeckoThread.LaunchState.Launching, GeckoThread.LaunchState.Launched)) {
|
||||
@ -2638,26 +2642,4 @@ abstract public class GeckoApp
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void assertOnUiThread() {
|
||||
Thread uiThread = mAppContext.getMainLooper().getThread();
|
||||
assertOnThread(uiThread);
|
||||
}
|
||||
|
||||
public static void assertOnGeckoThread() {
|
||||
assertOnThread(sGeckoThread);
|
||||
}
|
||||
|
||||
public static void assertOnThread(Thread expectedThread) {
|
||||
Thread currentThread = Thread.currentThread();
|
||||
long currentThreadId = currentThread.getId();
|
||||
long expectedThreadId = expectedThread.getId();
|
||||
|
||||
if (currentThreadId != expectedThreadId) {
|
||||
throw new IllegalThreadStateException("Expected thread " + expectedThreadId + " (\""
|
||||
+ expectedThread.getName()
|
||||
+ "\"), but running on thread " + currentThreadId
|
||||
+ " (\"" + currentThread.getName() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.gfx.InputConnectionHandler;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
@ -233,7 +234,7 @@ final class GeckoEditable
|
||||
|
||||
void poll() {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
ThreadUtils.assertOnGeckoThread();
|
||||
}
|
||||
if (mActions.isEmpty()) {
|
||||
throw new IllegalStateException("empty actions queue");
|
||||
@ -251,7 +252,7 @@ final class GeckoEditable
|
||||
|
||||
Action peek() {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
ThreadUtils.assertOnGeckoThread();
|
||||
}
|
||||
if (mActions.isEmpty()) {
|
||||
throw new IllegalStateException("empty actions queue");
|
||||
@ -304,7 +305,7 @@ final class GeckoEditable
|
||||
}
|
||||
|
||||
private void assertOnIcThread() {
|
||||
GeckoApp.assertOnThread(mIcRunHandler.getLooper().getThread());
|
||||
ThreadUtils.assertOnThread(mIcRunHandler.getLooper().getThread());
|
||||
}
|
||||
|
||||
private void geckoPostToIc(Runnable runnable) {
|
||||
@ -598,7 +599,7 @@ final class GeckoEditable
|
||||
private void geckoActionReply() {
|
||||
if (DEBUG) {
|
||||
// GeckoEditableListener methods should all be called from the Gecko thread
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
ThreadUtils.assertOnGeckoThread();
|
||||
}
|
||||
final Action action = mActionQueue.peek();
|
||||
|
||||
@ -650,7 +651,7 @@ final class GeckoEditable
|
||||
public void notifyIME(final int type, final int state) {
|
||||
if (DEBUG) {
|
||||
// GeckoEditableListener methods should all be called from the Gecko thread
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
ThreadUtils.assertOnGeckoThread();
|
||||
// NOTIFY_IME_REPLY_EVENT is logged separately, inside geckoActionReply()
|
||||
if (type != NOTIFY_IME_REPLY_EVENT) {
|
||||
Log.d(LOGTAG, "notifyIME(" +
|
||||
@ -727,7 +728,7 @@ final class GeckoEditable
|
||||
public void onSelectionChange(final int start, final int end) {
|
||||
if (DEBUG) {
|
||||
// GeckoEditableListener methods should all be called from the Gecko thread
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
ThreadUtils.assertOnGeckoThread();
|
||||
Log.d(LOGTAG, "onSelectionChange(" + start + ", " + end + ")");
|
||||
}
|
||||
if (start < 0 || start > mText.length() || end < 0 || end > mText.length()) {
|
||||
@ -777,7 +778,7 @@ final class GeckoEditable
|
||||
final int unboundedOldEnd, final int unboundedNewEnd) {
|
||||
if (DEBUG) {
|
||||
// GeckoEditableListener methods should all be called from the Gecko thread
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
ThreadUtils.assertOnGeckoThread();
|
||||
Log.d(LOGTAG, "onTextChange(\"" + text + "\", " + start + ", " +
|
||||
unboundedOldEnd + ", " + unboundedNewEnd + ")");
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.gfx.InputConnectionHandler;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.R;
|
||||
import android.content.Context;
|
||||
@ -45,14 +46,14 @@ class GeckoInputConnection
|
||||
|
||||
private static Handler sBackgroundHandler;
|
||||
|
||||
private class ThreadUtils {
|
||||
private class InputThreadUtils {
|
||||
private Editable mUiEditable;
|
||||
private Object mUiEditableReturn;
|
||||
private Exception mUiEditableException;
|
||||
private final SynchronousQueue<Runnable> mIcRunnableSync;
|
||||
private final Runnable mIcSignalRunnable;
|
||||
|
||||
public ThreadUtils() {
|
||||
public InputThreadUtils() {
|
||||
mIcRunnableSync = new SynchronousQueue<Runnable>();
|
||||
mIcSignalRunnable = new Runnable() {
|
||||
@Override public void run() {
|
||||
@ -62,7 +63,7 @@ class GeckoInputConnection
|
||||
|
||||
private void runOnIcThread(Handler icHandler, final Runnable runnable) {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnUiThread();
|
||||
ThreadUtils.assertOnUiThread();
|
||||
Log.d(LOGTAG, "runOnIcThread() on thread " +
|
||||
icHandler.getLooper().getThread().getName());
|
||||
}
|
||||
@ -92,7 +93,7 @@ class GeckoInputConnection
|
||||
|
||||
public void endWaitForUiThread() {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnUiThread();
|
||||
ThreadUtils.assertOnUiThread();
|
||||
Log.d(LOGTAG, "endWaitForUiThread()");
|
||||
}
|
||||
try {
|
||||
@ -103,7 +104,7 @@ class GeckoInputConnection
|
||||
|
||||
public void waitForUiThread(Handler icHandler) {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnThread(icHandler.getLooper().getThread());
|
||||
ThreadUtils.assertOnThread(icHandler.getLooper().getThread());
|
||||
Log.d(LOGTAG, "waitForUiThread() blocking on thread " +
|
||||
icHandler.getLooper().getThread().getName());
|
||||
}
|
||||
@ -120,7 +121,7 @@ class GeckoInputConnection
|
||||
public Editable getEditableForUiThread(final Handler uiHandler,
|
||||
final Handler icHandler) {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnThread(uiHandler.getLooper().getThread());
|
||||
ThreadUtils.assertOnThread(uiHandler.getLooper().getThread());
|
||||
}
|
||||
if (icHandler.getLooper() == uiHandler.getLooper()) {
|
||||
// IC thread is UI thread; safe to use Editable directly
|
||||
@ -136,7 +137,7 @@ class GeckoInputConnection
|
||||
final Method method,
|
||||
final Object[] args) throws Throwable {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnThread(uiHandler.getLooper().getThread());
|
||||
ThreadUtils.assertOnThread(uiHandler.getLooper().getThread());
|
||||
Log.d(LOGTAG, "UiEditable." + method.getName() + "() blocking");
|
||||
}
|
||||
synchronized (icHandler) {
|
||||
@ -177,7 +178,7 @@ class GeckoInputConnection
|
||||
}
|
||||
}
|
||||
|
||||
private final ThreadUtils mThreadUtils = new ThreadUtils();
|
||||
private final InputThreadUtils mThreadUtils = new InputThreadUtils();
|
||||
|
||||
// Managed only by notifyIMEEnabled; see comments in notifyIMEEnabled
|
||||
private int mIMEState;
|
||||
|
@ -37,6 +37,7 @@ UTIL_JAVA_FILES := \
|
||||
util/INIParser.java \
|
||||
util/INISection.java \
|
||||
util/StringUtils.java \
|
||||
util/ThreadUtils.java \
|
||||
util/UiAsyncTask.java \
|
||||
$(NULL)
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.util.GeckoEventResponder;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.widget.DateTimePicker;
|
||||
|
||||
import org.json.JSONArray;
|
||||
@ -298,7 +299,7 @@ public class PromptService implements OnClickListener, OnCancelListener, OnItemC
|
||||
}
|
||||
|
||||
public void show(String aTitle, String aText, PromptListItem[] aMenuList, boolean aMultipleSelection) {
|
||||
GeckoApp.assertOnUiThread();
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
// treat actions that show a dialog as if preventDefault by content to prevent panning
|
||||
GeckoApp.mAppContext.getLayerView().abortPanning();
|
||||
@ -394,7 +395,7 @@ public class PromptService implements OnClickListener, OnCancelListener, OnItemC
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface aDialog, int aWhich) {
|
||||
GeckoApp.assertOnUiThread();
|
||||
ThreadUtils.assertOnUiThread();
|
||||
JSONObject ret = new JSONObject();
|
||||
try {
|
||||
int button = -1;
|
||||
@ -436,13 +437,13 @@ public class PromptService implements OnClickListener, OnCancelListener, OnItemC
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
GeckoApp.assertOnUiThread();
|
||||
ThreadUtils.assertOnUiThread();
|
||||
mSelected[position] = !mSelected[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel(DialogInterface aDialog) {
|
||||
GeckoApp.assertOnUiThread();
|
||||
ThreadUtils.assertOnUiThread();
|
||||
JSONObject ret = new JSONObject();
|
||||
try {
|
||||
ret.put("button", -1);
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.mozilla.gecko.GeckoApp;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import org.mozilla.gecko.GeckoThread;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
@ -75,7 +75,7 @@ public class GLController {
|
||||
}
|
||||
|
||||
synchronized void surfaceDestroyed() {
|
||||
GeckoApp.assertOnUiThread();
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
mSurfaceValid = false;
|
||||
mEGLSurface = null;
|
||||
@ -94,7 +94,7 @@ public class GLController {
|
||||
}
|
||||
|
||||
synchronized void surfaceChanged(int newWidth, int newHeight) {
|
||||
GeckoApp.assertOnUiThread();
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
mWidth = newWidth;
|
||||
mHeight = newHeight;
|
||||
@ -161,7 +161,7 @@ public class GLController {
|
||||
}
|
||||
|
||||
void createCompositor() {
|
||||
GeckoApp.assertOnUiThread();
|
||||
ThreadUtils.assertOnUiThread();
|
||||
|
||||
if (mCompositorCreated) {
|
||||
// If the compositor has already been created, just resume it instead. We don't need
|
||||
|
@ -35,11 +35,12 @@ public final class GeckoBackgroundThread extends Thread {
|
||||
// Get a Handler for a looper thread, or create one if it doesn't yet exist.
|
||||
public static synchronized Handler getHandler() {
|
||||
if (sHandler == null) {
|
||||
GeckoBackgroundThread lt = new GeckoBackgroundThread();
|
||||
lt.start();
|
||||
try {
|
||||
sHandler = lt.mHandlerQueue.take();
|
||||
} catch (InterruptedException ie) {}
|
||||
GeckoBackgroundThread lt = new GeckoBackgroundThread();
|
||||
ThreadUtils.setBackgroundThread(lt);
|
||||
lt.start();
|
||||
try {
|
||||
sHandler = lt.mHandlerQueue.take();
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
return sHandler;
|
||||
}
|
||||
|
61
mobile/android/base/util/ThreadUtils.java
Normal file
61
mobile/android/base/util/ThreadUtils.java
Normal file
@ -0,0 +1,61 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.util;
|
||||
|
||||
public final class ThreadUtils {
|
||||
private static Thread sUiThread;
|
||||
private static Thread sGeckoThread;
|
||||
private static Thread sBackgroundThread;
|
||||
|
||||
public static void setUiThread(Thread thread) {
|
||||
sUiThread = thread;
|
||||
}
|
||||
|
||||
public static void setGeckoThread(Thread thread) {
|
||||
sGeckoThread = thread;
|
||||
}
|
||||
|
||||
public static void setBackgroundThread(Thread thread) {
|
||||
sBackgroundThread = thread;
|
||||
}
|
||||
|
||||
public static Thread getUiThread() {
|
||||
return sUiThread;
|
||||
}
|
||||
|
||||
public static Thread getGeckoThread() {
|
||||
return sGeckoThread;
|
||||
}
|
||||
|
||||
public static Thread getBackgroundThread() {
|
||||
return sBackgroundThread;
|
||||
}
|
||||
|
||||
public static void assertOnUiThread() {
|
||||
assertOnThread(getUiThread());
|
||||
}
|
||||
|
||||
public static void assertOnGeckoThread() {
|
||||
assertOnThread(getGeckoThread());
|
||||
}
|
||||
|
||||
public static void assertOnBackgroundThread() {
|
||||
assertOnThread(getBackgroundThread());
|
||||
}
|
||||
|
||||
public static void assertOnThread(Thread expectedThread) {
|
||||
Thread currentThread = Thread.currentThread();
|
||||
long currentThreadId = currentThread.getId();
|
||||
long expectedThreadId = expectedThread.getId();
|
||||
|
||||
if (currentThreadId != expectedThreadId) {
|
||||
throw new IllegalThreadStateException("Expected thread " + expectedThreadId + " (\""
|
||||
+ expectedThread.getName()
|
||||
+ "\"), but running on thread " + currentThreadId
|
||||
+ " (\"" + currentThread.getName() + ")");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user