mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 14:25:52 +00:00
Bug 838177 - Add more debugging output to GeckoEditable and GeckoInputConnection; r=cpeterson
This commit is contained in:
parent
cd8dd057b0
commit
3cb8a6523e
@ -23,6 +23,7 @@ import android.text.TextUtils;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@ -191,6 +192,8 @@ final class GeckoEditable
|
||||
void offer(Action action) {
|
||||
if (DEBUG) {
|
||||
assertOnIcThread();
|
||||
Log.d(LOGTAG, "offer: Action(" +
|
||||
getConstantName(Action.class, "TYPE_", action.mType) + ")");
|
||||
}
|
||||
/* Events don't need update because they generate text/selection
|
||||
notifications which will do the updating for us */
|
||||
@ -261,8 +264,14 @@ final class GeckoEditable
|
||||
assertOnIcThread();
|
||||
}
|
||||
if (mFocused && !mActions.isEmpty()) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "syncWithGecko blocking on thread " +
|
||||
Thread.currentThread().getName());
|
||||
}
|
||||
mActionsActive.acquireUninterruptibly();
|
||||
mActionsActive.release();
|
||||
} else if (DEBUG && !mFocused) {
|
||||
Log.d(LOGTAG, "skipped syncWithGecko (no focus)");
|
||||
}
|
||||
}
|
||||
|
||||
@ -445,7 +454,8 @@ final class GeckoEditable
|
||||
rangeStart = rangeEnd;
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, " added " + rangeType + " : " + rangeStyles +
|
||||
Log.d(LOGTAG, " added " + rangeType +
|
||||
" : " + Integer.toHexString(rangeStyles) +
|
||||
" : " + Integer.toHexString(rangeForeColor) +
|
||||
" : " + Integer.toHexString(rangeBackColor));
|
||||
}
|
||||
@ -459,6 +469,9 @@ final class GeckoEditable
|
||||
|
||||
@Override
|
||||
public void sendEvent(final GeckoEvent event) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "sendEvent(" + event + ")");
|
||||
}
|
||||
if (!onIcThread()) {
|
||||
// Events may get dispatched to the main thread;
|
||||
// reroute to our IC thread instead
|
||||
@ -585,6 +598,10 @@ final class GeckoEditable
|
||||
}
|
||||
final Action action = mActionQueue.peek();
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "reply: Action(" +
|
||||
getConstantName(Action.class, "TYPE_", action.mType) + ")");
|
||||
}
|
||||
switch (action.mType) {
|
||||
case Action.TYPE_SET_SELECTION:
|
||||
final int len = mText.length();
|
||||
@ -629,6 +646,12 @@ final class GeckoEditable
|
||||
if (DEBUG) {
|
||||
// GeckoEditableListener methods should all be called from the Gecko thread
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
// NOTIFY_IME_REPLY_EVENT is logged separately, inside geckoActionReply()
|
||||
if (type != NOTIFY_IME_REPLY_EVENT) {
|
||||
Log.d(LOGTAG, "notifyIME(" +
|
||||
getConstantName(GeckoEditableListener.class, "NOTIFY_IME_", type) +
|
||||
", " + state + ")");
|
||||
}
|
||||
}
|
||||
if (type == NOTIFY_IME_REPLY_EVENT) {
|
||||
try {
|
||||
@ -636,6 +659,8 @@ final class GeckoEditable
|
||||
// When mFocused is false, the reply is for a stale action,
|
||||
// and we should not do anything
|
||||
geckoActionReply();
|
||||
} else if (DEBUG) {
|
||||
Log.d(LOGTAG, "discarding stale reply");
|
||||
}
|
||||
} finally {
|
||||
// Ensure action is always removed from queue
|
||||
@ -669,6 +694,11 @@ final class GeckoEditable
|
||||
final String modeHint, final String actionHint) {
|
||||
// Because we want to be able to bind GeckoEditable to the newest LayerView instance,
|
||||
// this can be called from the Java IC thread in addition to the Gecko thread.
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "notifyIMEEnabled(" +
|
||||
getConstantName(GeckoEditableListener.class, "IME_STATE_", state) +
|
||||
", \"" + typeHint + "\", \"" + modeHint + "\", \"" + actionHint + "\")");
|
||||
}
|
||||
geckoPostToIc(new Runnable() {
|
||||
public void run() {
|
||||
// Make sure there are no other things going on
|
||||
@ -691,6 +721,7 @@ final class GeckoEditable
|
||||
if (DEBUG) {
|
||||
// GeckoEditableListener methods should all be called from the Gecko thread
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
Log.d(LOGTAG, "onSelectionChange(" + start + ", " + end + ")");
|
||||
}
|
||||
if (start < 0 || start > mText.length() || end < 0 || end > mText.length()) {
|
||||
throw new IllegalArgumentException("invalid selection notification range");
|
||||
@ -739,6 +770,8 @@ final class GeckoEditable
|
||||
if (DEBUG) {
|
||||
// GeckoEditableListener methods should all be called from the Gecko thread
|
||||
GeckoApp.assertOnGeckoThread();
|
||||
Log.d(LOGTAG, "onTextChange(\"" + text + "\", " + start + ", " +
|
||||
unboundedOldEnd + ", " + unboundedNewEnd + ")");
|
||||
}
|
||||
if (start < 0 || start > unboundedOldEnd) {
|
||||
throw new IllegalArgumentException("invalid text notification range");
|
||||
@ -812,7 +845,20 @@ final class GeckoEditable
|
||||
|
||||
// InvocationHandler interface
|
||||
|
||||
private static StringBuilder debugAppend(StringBuilder sb, Object obj) {
|
||||
static String getConstantName(Class<?> cls, String prefix, Object value) {
|
||||
for (Field fld : cls.getDeclaredFields()) {
|
||||
try {
|
||||
if (fld.getName().startsWith(prefix) &&
|
||||
fld.get(null).equals(value)) {
|
||||
return fld.getName();
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
}
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
static StringBuilder debugAppend(StringBuilder sb, Object obj) {
|
||||
if (obj == null) {
|
||||
sb.append("null");
|
||||
} else if (obj instanceof GeckoEditable) {
|
||||
|
@ -63,6 +63,8 @@ class GeckoInputConnection
|
||||
private void runOnIcThread(Handler icHandler, final Runnable runnable) {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnUiThread();
|
||||
Log.d(LOGTAG, "runOnIcThread() on thread " +
|
||||
icHandler.getLooper().getThread().getName());
|
||||
}
|
||||
Runnable runner = new Runnable() {
|
||||
@Override public void run() {
|
||||
@ -91,6 +93,7 @@ class GeckoInputConnection
|
||||
public void endWaitForUiThread() {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnUiThread();
|
||||
Log.d(LOGTAG, "endWaitForUiThread()");
|
||||
}
|
||||
try {
|
||||
mIcRunnableSync.put(mIcSignalRunnable);
|
||||
@ -101,6 +104,8 @@ class GeckoInputConnection
|
||||
public void waitForUiThread(Handler icHandler) {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnThread(icHandler.getLooper().getThread());
|
||||
Log.d(LOGTAG, "waitForUiThread() blocking on thread " +
|
||||
icHandler.getLooper().getThread().getName());
|
||||
}
|
||||
try {
|
||||
Runnable runnable = null;
|
||||
@ -132,6 +137,7 @@ class GeckoInputConnection
|
||||
final Object[] args) throws Throwable {
|
||||
if (DEBUG) {
|
||||
GeckoApp.assertOnThread(uiHandler.getLooper().getThread());
|
||||
Log.d(LOGTAG, "UiEditable." + method.getName() + "() blocking");
|
||||
}
|
||||
synchronized (icHandler) {
|
||||
// Now we are on UI thread
|
||||
@ -148,6 +154,10 @@ class GeckoInputConnection
|
||||
} catch (Exception e) {
|
||||
mUiEditableException = e;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "UiEditable." + method.getName() +
|
||||
"() returning");
|
||||
}
|
||||
icHandler.notify();
|
||||
}
|
||||
}
|
||||
@ -580,6 +590,12 @@ class GeckoInputConnection
|
||||
| EditorInfo.IME_FLAG_NO_FULLSCREEN;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "mapped IME states to: inputType = " +
|
||||
Integer.toHexString(outAttrs.inputType) + ", imeOptions = " +
|
||||
Integer.toHexString(outAttrs.imeOptions));
|
||||
}
|
||||
|
||||
String prevInputMethod = mCurrentInputMethod;
|
||||
mCurrentInputMethod = InputMethods.getCurrentInputMethod(app);
|
||||
if (DEBUG) {
|
||||
@ -838,10 +854,12 @@ final class DebugGeckoInputConnection
|
||||
implements InvocationHandler {
|
||||
|
||||
private InputConnection mProxy;
|
||||
private StringBuilder mCallLevel;
|
||||
|
||||
private DebugGeckoInputConnection(View targetView,
|
||||
GeckoEditableClient editable) {
|
||||
super(targetView, editable);
|
||||
mCallLevel = new StringBuilder();
|
||||
}
|
||||
|
||||
public static GeckoEditableListener create(View targetView,
|
||||
@ -857,47 +875,43 @@ final class DebugGeckoInputConnection
|
||||
return (GeckoEditableListener)dgic.mProxy;
|
||||
}
|
||||
|
||||
private static StringBuilder debugAppend(StringBuilder sb, Object obj) {
|
||||
if (obj == null) {
|
||||
sb.append("null");
|
||||
} else if (obj instanceof GeckoEditable) {
|
||||
sb.append("GeckoEditable");
|
||||
} else if (Proxy.isProxyClass(obj.getClass())) {
|
||||
debugAppend(sb, Proxy.getInvocationHandler(obj));
|
||||
} else if (obj instanceof CharSequence) {
|
||||
sb.append("\"").append(obj.toString().replace('\n', '\u21b2')).append("\"");
|
||||
} else if (obj.getClass().isArray()) {
|
||||
sb.append(obj.getClass().getComponentType().getSimpleName()).append("[")
|
||||
.append(java.lang.reflect.Array.getLength(obj)).append("]");
|
||||
} else {
|
||||
sb.append(obj.toString());
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
|
||||
Object ret = method.invoke(this, args);
|
||||
if (ret == this) {
|
||||
ret = mProxy;
|
||||
}
|
||||
|
||||
StringBuilder log = new StringBuilder(method.getName());
|
||||
log.append("(");
|
||||
StringBuilder log = new StringBuilder(mCallLevel);
|
||||
log.append("> ").append(method.getName()).append("(");
|
||||
for (Object arg : args) {
|
||||
debugAppend(log, arg).append(", ");
|
||||
// translate argument values to constant names
|
||||
if ("notifyIME".equals(method.getName()) && arg == args[0]) {
|
||||
log.append(GeckoEditable.getConstantName(
|
||||
GeckoEditableListener.class, "NOTIFY_IME_", arg));
|
||||
} else if ("notifyIMEEnabled".equals(method.getName()) && arg == args[0]) {
|
||||
log.append(GeckoEditable.getConstantName(
|
||||
GeckoEditableListener.class, "IME_STATE_", arg));
|
||||
} else {
|
||||
GeckoEditable.debugAppend(log, arg);
|
||||
}
|
||||
log.append(", ");
|
||||
}
|
||||
if (args.length > 0) {
|
||||
log.setLength(log.length() - 2);
|
||||
}
|
||||
if (method.getReturnType().equals(Void.TYPE)) {
|
||||
log.append(")");
|
||||
} else {
|
||||
debugAppend(log.append(") = "), ret);
|
||||
}
|
||||
log.append(")");
|
||||
Log.d(LOGTAG, log.toString());
|
||||
|
||||
mCallLevel.append(' ');
|
||||
Object ret = method.invoke(this, args);
|
||||
if (ret == this) {
|
||||
ret = mProxy;
|
||||
}
|
||||
mCallLevel.setLength(Math.max(0, mCallLevel.length() - 1));
|
||||
|
||||
log.setLength(mCallLevel.length());
|
||||
log.append("< ").append(method.getName());
|
||||
if (!method.getReturnType().equals(Void.TYPE)) {
|
||||
GeckoEditable.debugAppend(log.append(": "), ret);
|
||||
}
|
||||
Log.d(LOGTAG, log.toString());
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user