mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 06:35:42 +00:00
Bug 769520 - Part 2: In debug builds, assert IME code is running on UI thread. r=blassey
This commit is contained in:
parent
512dd48b54
commit
ad761ffffb
@ -6,19 +6,12 @@
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.gfx.CairoImage;
|
||||
import org.mozilla.gecko.gfx.BufferedCairoImage;
|
||||
import org.mozilla.gecko.gfx.FloatSize;
|
||||
import org.mozilla.gecko.gfx.GeckoLayerClient;
|
||||
import org.mozilla.gecko.gfx.IntSize;
|
||||
import org.mozilla.gecko.gfx.Layer;
|
||||
import org.mozilla.gecko.gfx.LayerController;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.gfx.PluginLayer;
|
||||
import org.mozilla.gecko.gfx.RectUtils;
|
||||
import org.mozilla.gecko.gfx.SurfaceTextureLayer;
|
||||
import org.mozilla.gecko.gfx.ViewportMetrics;
|
||||
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
@ -27,7 +20,6 @@ import java.util.regex.Matcher;
|
||||
import java.util.zip.*;
|
||||
import java.net.URL;
|
||||
import java.nio.*;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.concurrent.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.net.*;
|
||||
@ -40,7 +32,6 @@ import android.text.*;
|
||||
import android.text.format.Time;
|
||||
import android.view.*;
|
||||
import android.view.inputmethod.*;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.content.*;
|
||||
import android.content.res.*;
|
||||
import android.graphics.*;
|
||||
@ -94,7 +85,7 @@ abstract public class GeckoApp
|
||||
public static boolean mDOMFullScreen = false;
|
||||
protected MenuPanel mMenuPanel;
|
||||
protected Menu mMenu;
|
||||
private static GeckoThread sGeckoThread = null;
|
||||
private static GeckoThread sGeckoThread;
|
||||
public Handler mMainHandler;
|
||||
private GeckoProfile mProfile;
|
||||
public static boolean sIsGeckoReady = false;
|
||||
@ -3220,6 +3211,28 @@ abstract public class GeckoApp
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void assertOnUiThread() {
|
||||
Thread uiThread = mAppContext.getMainLooper().getThread();
|
||||
assertOnThread(uiThread);
|
||||
}
|
||||
|
||||
public static void assertOnGeckoThread() {
|
||||
assertOnThread(sGeckoThread);
|
||||
}
|
||||
|
||||
private 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() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
// SDK version 15 accessibility methods retrieved through reflection.
|
||||
private static class AccessibilityCompat {
|
||||
private static boolean mInitialized = false;
|
||||
|
@ -134,7 +134,8 @@ public class GeckoInputConnection
|
||||
@Override
|
||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
if (mCommittingText)
|
||||
Log.e(LOGTAG, "Please report this bug:", new IllegalStateException("commitText, but already committing text?!"));
|
||||
Log.e(LOGTAG, "Please report this bug:",
|
||||
new IllegalStateException("commitText, but already committing text?!"));
|
||||
|
||||
mCommittingText = true;
|
||||
replaceText(text, newCursorPosition, false);
|
||||
@ -321,6 +322,7 @@ public class GeckoInputConnection
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, String.format("IME: replaceText(\"%s\", %d, %b)",
|
||||
text, newCursorPosition, composing));
|
||||
GeckoApp.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (text == null)
|
||||
@ -699,10 +701,14 @@ public class GeckoInputConnection
|
||||
}
|
||||
|
||||
private void endComposition() {
|
||||
if (DEBUG) Log.d(LOGTAG, "IME: endComposition: IME_COMPOSITION_END");
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "IME: endComposition: IME_COMPOSITION_END");
|
||||
GeckoApp.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (!hasCompositionString())
|
||||
Log.e(LOGTAG, "Please report this bug:", new IllegalStateException("endComposition, but not composing text?!"));
|
||||
Log.e(LOGTAG, "Please report this bug:",
|
||||
new IllegalStateException("endComposition, but not composing text?!"));
|
||||
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
GeckoEvent.createIMEEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0));
|
||||
@ -711,7 +717,10 @@ public class GeckoInputConnection
|
||||
}
|
||||
|
||||
private void sendTextToGecko(CharSequence text, int caretPos) {
|
||||
if (DEBUG) Log.d(LOGTAG, "IME: sendTextToGecko(\"" + text + "\")");
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "IME: sendTextToGecko(\"" + text + "\")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
}
|
||||
|
||||
// Handle composition text styles
|
||||
if (text != null && text instanceof Spanned) {
|
||||
@ -809,19 +818,19 @@ public class GeckoInputConnection
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_PHONE;
|
||||
else if (mIMETypeHint.equalsIgnoreCase("number") ||
|
||||
mIMETypeHint.equalsIgnoreCase("range"))
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_NUMBER |
|
||||
InputType.TYPE_NUMBER_FLAG_SIGNED |
|
||||
InputType.TYPE_NUMBER_FLAG_DECIMAL;
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_NUMBER
|
||||
| InputType.TYPE_NUMBER_FLAG_SIGNED
|
||||
| InputType.TYPE_NUMBER_FLAG_DECIMAL;
|
||||
else if (mIMETypeHint.equalsIgnoreCase("datetime") ||
|
||||
mIMETypeHint.equalsIgnoreCase("datetime-local"))
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_DATETIME |
|
||||
InputType.TYPE_DATETIME_VARIATION_NORMAL;
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_DATETIME
|
||||
| InputType.TYPE_DATETIME_VARIATION_NORMAL;
|
||||
else if (mIMETypeHint.equalsIgnoreCase("date"))
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_DATETIME |
|
||||
InputType.TYPE_DATETIME_VARIATION_DATE;
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_DATETIME
|
||||
| InputType.TYPE_DATETIME_VARIATION_DATE;
|
||||
else if (mIMETypeHint.equalsIgnoreCase("time"))
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_DATETIME |
|
||||
InputType.TYPE_DATETIME_VARIATION_TIME;
|
||||
outAttrs.inputType = InputType.TYPE_CLASS_DATETIME
|
||||
| InputType.TYPE_DATETIME_VARIATION_TIME;
|
||||
|
||||
if (mIMEActionHint.equalsIgnoreCase("go"))
|
||||
outAttrs.imeOptions = EditorInfo.IME_ACTION_GO;
|
||||
@ -875,6 +884,7 @@ public class GeckoInputConnection
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "IME: processKeyDown(keyCode=" + keyCode + ", event=" + event + ", "
|
||||
+ isPreIme + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (keyCode > KeyEvent.getMaxKeyCode())
|
||||
@ -937,6 +947,7 @@ public class GeckoInputConnection
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "IME: processKeyUp(keyCode=" + keyCode + ", event=" + event + ", "
|
||||
+ isPreIme + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
}
|
||||
|
||||
if (keyCode > KeyEvent.getMaxKeyCode())
|
||||
@ -1104,7 +1115,6 @@ public class GeckoInputConnection
|
||||
postToUiThread(new Runnable() {
|
||||
public void run() {
|
||||
final View v = GeckoApp.mAppContext.getLayerController().getView();
|
||||
if (DEBUG) Log.d(LOGTAG, "IME: v=" + v);
|
||||
|
||||
final InputMethodManager imm = getInputMethodManager();
|
||||
if (imm == null)
|
||||
@ -1205,29 +1215,34 @@ public class GeckoInputConnection
|
||||
private static final class DebugGeckoInputConnection extends GeckoInputConnection {
|
||||
public DebugGeckoInputConnection(View targetView) {
|
||||
super(targetView);
|
||||
GeckoApp.assertOnUiThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beginBatchEdit() {
|
||||
Log.d(LOGTAG, "IME: beginBatchEdit");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.beginBatchEdit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean endBatchEdit() {
|
||||
Log.d(LOGTAG, "IME: endBatchEdit");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.endBatchEdit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitCompletion(CompletionInfo text) {
|
||||
Log.d(LOGTAG, "IME: commitCompletion");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.commitCompletion(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
Log.d(LOGTAG, String.format("IME: commitText(\"%s\", %d)", text, newCursorPosition));
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.commitText(text, newCursorPosition);
|
||||
}
|
||||
|
||||
@ -1235,12 +1250,14 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
public boolean deleteSurroundingText(int leftLength, int rightLength) {
|
||||
Log.d(LOGTAG, "IME: deleteSurroundingText(leftLen=" + leftLength + ", rightLen="
|
||||
+ rightLength + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.deleteSurroundingText(leftLength, rightLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finishComposingText() {
|
||||
Log.d(LOGTAG, "IME: finishComposingText");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.finishComposingText();
|
||||
}
|
||||
|
||||
@ -1248,18 +1265,21 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
public Editable getEditable() {
|
||||
Editable editable = super.getEditable();
|
||||
Log.d(LOGTAG, "IME: getEditable -> " + editable);
|
||||
GeckoApp.assertOnUiThread();
|
||||
return editable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performContextMenuAction(int id) {
|
||||
Log.d(LOGTAG, "IME: performContextMenuAction");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.performContextMenuAction(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtractedText getExtractedText(ExtractedTextRequest req, int flags) {
|
||||
Log.d(LOGTAG, "IME: getExtractedText");
|
||||
GeckoApp.assertOnUiThread();
|
||||
ExtractedText extract = super.getExtractedText(req, flags);
|
||||
if (extract != null)
|
||||
Log.d(LOGTAG, String.format(
|
||||
@ -1271,6 +1291,7 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
@Override
|
||||
public CharSequence getTextAfterCursor(int length, int flags) {
|
||||
Log.d(LOGTAG, "IME: getTextAfterCursor(length=" + length + ", flags=" + flags + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
CharSequence s = super.getTextAfterCursor(length, flags);
|
||||
Log.d(LOGTAG, ". . . getTextAfterCursor returns \"" + s + "\"");
|
||||
return s;
|
||||
@ -1279,6 +1300,7 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
@Override
|
||||
public CharSequence getTextBeforeCursor(int length, int flags) {
|
||||
Log.d(LOGTAG, "IME: getTextBeforeCursor");
|
||||
GeckoApp.assertOnUiThread();
|
||||
CharSequence s = super.getTextBeforeCursor(length, flags);
|
||||
Log.d(LOGTAG, ". . . getTextBeforeCursor returns \"" + s + "\"");
|
||||
return s;
|
||||
@ -1287,24 +1309,28 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
@Override
|
||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
Log.d(LOGTAG, String.format("IME: setComposingText(\"%s\", %d)", text, newCursorPosition));
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.setComposingText(text, newCursorPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingRegion(int start, int end) {
|
||||
Log.d(LOGTAG, "IME: setComposingRegion(start=" + start + ", end=" + end + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.setComposingRegion(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSelection(int start, int end) {
|
||||
Log.d(LOGTAG, "IME: setSelection(start=" + start + ", end=" + end + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.setSelection(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getComposingText() {
|
||||
Log.d(LOGTAG, "IME: getComposingText");
|
||||
GeckoApp.assertOnUiThread();
|
||||
String s = super.getComposingText();
|
||||
Log.d(LOGTAG, ". . . getComposingText: Composing text = \"" + s + "\"");
|
||||
return s;
|
||||
@ -1313,12 +1339,15 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
@Override
|
||||
public boolean onKeyDel() {
|
||||
Log.d(LOGTAG, "IME: onKeyDel");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.onKeyDel();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void notifyTextChange(InputMethodManager imm, String text,
|
||||
int start, int oldEnd, int newEnd) {
|
||||
// notifyTextChange() call is posted to UI thread from notifyIMEChange().
|
||||
GeckoApp.assertOnUiThread();
|
||||
Log.d(LOGTAG, String.format(
|
||||
"IME: >notifyTextChange(\"%s\", start=%d, oldEnd=%d, newEnd=%d)",
|
||||
text, start, oldEnd, newEnd));
|
||||
@ -1327,6 +1356,8 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
|
||||
@Override
|
||||
protected void notifySelectionChange(InputMethodManager imm, int start, int end) {
|
||||
// notifySelectionChange() call is posted to UI thread from notifyIMEChange().
|
||||
GeckoApp.assertOnUiThread();
|
||||
Log.d(LOGTAG, String.format("IME: >notifySelectionChange(start=%d, end=%d)", start, end));
|
||||
super.notifySelectionChange(imm, start, end);
|
||||
}
|
||||
@ -1334,6 +1365,7 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
@Override
|
||||
protected void resetCompositionState() {
|
||||
Log.d(LOGTAG, "IME: resetCompositionState");
|
||||
GeckoApp.assertOnUiThread();
|
||||
if (hasCompositionString()) {
|
||||
Log.d(LOGTAG, "resetCompositionState() is abandoning an active composition string");
|
||||
}
|
||||
@ -1344,12 +1376,14 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
Log.d(LOGTAG, String.format("IME: onTextChanged(\"%s\" start=%d, before=%d, count=%d)",
|
||||
s, start, before, count));
|
||||
GeckoApp.assertOnUiThread();
|
||||
super.onTextChanged(s, start, before, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
Log.d(LOGTAG, "IME: afterTextChanged(\"" + s + "\")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
super.afterTextChanged(s);
|
||||
}
|
||||
|
||||
@ -1357,30 +1391,35 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
Log.d(LOGTAG, String.format("IME: beforeTextChanged(\"%s\", start=%d, count=%d, after=%d)",
|
||||
s, start, count, after));
|
||||
GeckoApp.assertOnUiThread();
|
||||
super.beforeTextChanged(s, start, count, after);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||
Log.d(LOGTAG, "IME: onCreateInputConnection called");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.onCreateInputConnection(outAttrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
|
||||
Log.d(LOGTAG, "IME: onKeyPreIme(keyCode=" + keyCode + ", event=" + event + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.onKeyPreIme(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
Log.d(LOGTAG, "IME: onKeyDown(keyCode=" + keyCode + ", event=" + event + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
Log.d(LOGTAG, "IME: onKeyUp(keyCode=" + keyCode + ", event=" + event + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@ -1388,18 +1427,21 @@ private static final class DebugGeckoInputConnection extends GeckoInputConnectio
|
||||
public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
|
||||
Log.d(LOGTAG, "IME: onKeyMultiple(keyCode=" + keyCode + ", repeatCount=" + repeatCount
|
||||
+ ", event=" + event + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.onKeyMultiple(keyCode, repeatCount, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
|
||||
Log.d(LOGTAG, "IME: onKeyLongPress(keyCode=" + keyCode + ", event=" + event + ")");
|
||||
GeckoApp.assertOnUiThread();
|
||||
return super.onKeyLongPress(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyIME(int type, int state) {
|
||||
Log.d(LOGTAG, String.format("IME: >notifyIME(type=%d, state=%d)", type, state));
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
super.notifyIME(type, state);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user